生活不易、且行且珍惜。网站首页 程序人生
从零开始做网站2-springboot整合mybatis
发布时间:2022-05-12 18:11编辑:zj 阅读:文章分类:
网站互动QQ群:170915747
昨天把项目建好了,底子有了然后就是进行下一步开发了,先整合下Mybatis,使用Mybatis框架做数据持久化操作。
MyBatis配置模式是指使用mybatis配置文件的方式与SpringBoot进行整合,相对应的就有mybatis-config.xml(用于配置驼峰命名,也可以省略这个文件)、XxxMapper.xml文件。
主要步骤为:
导入mybatis官方starter
编写mapper接口。标准@Mapper注解
编写sql映射文件并绑定mapper接口
在application.yaml中指定Mapper配置文件的位置,以及指定全局配置文件的信息
注解模式使用
主要步骤:
导入mybatis官方依赖
注解方式编写mapper接口
在application.yaml中指定Mapper配置文件的位置,以及指定全局配置文件的信息
注解模式比配置模式少了编写Mapper.xml文件,简化了简单SQL语句的xml文件编写。
混合模式
在实际项目开发中涉及很多复杂业务及连表查询SQL,可以配合使用注解与配置模式,达到最佳实践的目的。
实际项目操作步骤:
引入mybatis-starter
配置application.yaml中,指定mapper-location位置即可
编写Mapper接口并标注@Mapper注解
简单方法直接注解方式
复杂方法编写mapper.xml进行绑定映射
主启动类上使用@MapperScan("com.fengye.springboot_mybatis.mapper") 简化Mapper接口,包下所有接口就可以不用标注@Mapper注解
1.导入mybatis整合依赖,mybatis-spring-boot-starter类似一个中间件,链接springBoot和Mybatis
<!-- mybatis整合 --> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.2.0</version> </dependency>
2.在SpringBoot配置文件中定义数据源,并整合mybatis相关的配置,去applicaton.properties配置一下数据库
#定义数据源 spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8 spring.datasource.username=root spring.datasource.password=123456 #springboot整合mybatis的配置 #指定实体类位置,在mapper中就不用写全路径 mybatis.type-aliases-package: com.zjlovelt.entity #映射mapper的位置,和dao层接口对应,一定要对应mapper映射xml文件的所在路径 mybatis.mapper-locations=classpath:mapping/*.xml # 配置打印 SQL 语句 mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
然后在SpringBoot启动类上添加mapper接口扫描注解
@SpringBootApplication //添加扫描mybatis的dao层接口,生成实现类 @MapperScan(value = "com.zjlovelt.mapper") public class LtBlogApplication { public static void main(String[] args) { SpringApplication.run(LtBlogApplication.class, args); } }
在pom.xml 中添加资源打包配置
<build> <plugins> <resources> <!--没有写到 resources 目录下的 xml 文件需要以下配置--> <resource> <directory>src/main/java</directory> <includes> <include>**/*.xml</include> </includes> <filtering>false</filtering> </resource> <!--指定 resources 目录下的哪些文件需要编译--> <resource> <directory>src/main/resources</directory> <!-- excludes和includes二选一使用即可 --> <!-- 不包含的文件,支持通配符 --> <excludes> <exclude>*.txt</exclude> </excludes> <!-- 包含的文件,支持通配符 --> <includes> <include>*.properties</include> <include>**/*.xml</include> </includes> <filtering>false</filtering> </resource> </resource> </resources> </build>
配置都搞完了,就可以开始测试了,测试一下查询文章详情的接口,看看数据库操作是否ok了
新建文章详情表
在数据库表中插入一条测试数据
新建实体类
package com.zjlovelt.entity; import com.fasterxml.jackson.annotation.JsonFormat; import com.zjlovelt.common.constance.Constance; import com.zjlovelt.common.constance.DictionaryConstance; import com.zjlovelt.mapper.SysDataDictionaryMapper; import lombok.Data; import java.io.Serializable; import java.sql.Timestamp; import java.text.SimpleDateFormat; import java.util.logging.SimpleFormatter; @Data public class ArticleInfo implements Serializable { private static final long serialVersionUID = 1L; private Long articleId; private String type; //类别 private String title; //文章标题 private String articleImg; //插图 private String keyword; //关键字/标签 private String summary; //摘要 private String content; //文章内容 private String author; //作者 private String accessNum; //浏览数 private String status; //状态(用于主页显示) @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") private Timestamp articleDate; //发布日期 ...... ...... //临时字段 private Boolean statusName; //用于接受前端参数 private String articleDateStr; //用于接受前端参数 private String typeName; private String statusStr; private String[] keywordArr; /** * code转名称 * * @param sysDataDictionaryMapper */ public void convertCodeToName(SysDataDictionaryMapper sysDataDictionaryMapper) { //文章类别 if (this.getType() != null) { SysDataDictionary dataDictionary = sysDataDictionaryMapper.findByCategoryidAndValue(DictionaryConstance.ARTICLE_TYPE, this.getType()); if (dataDictionary != null) { this.setTypeName(dataDictionary.getName()); } } //文章状态 if(this.getStatus() != null){ if(this.getStatus().equals(Constance.DelFlag_NO)){ this.setStatusStr("不推荐"); }else{ this.setStatusStr("推荐"); } } //返回给前端的一些字段 if(this.getStatus() != null){ if(this.getStatus().equals(Constance.DelFlag_NO)){ this.setStatusName(false); }else{ this.setStatusName(true); } } } }
新建dao层mapper接口
package com.zjlovelt.mapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.zjlovelt.entity.ArticleInfo; import com.zjlovelt.entity.SysDataDictionary; import org.springframework.stereotype.Repository; import java.util.List; @Repository public interface ArticleInfoMapper { ArticleInfo selectByPrimaryKey(Long articleId); }
新建mapper.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > <mapper namespace="com.zjlovelt.mapper.ArticleInfoMapper" > <resultMap id="BaseResultMap" type="com.zjlovelt.entity.ArticleInfo" > <id column="article_id" property="articleId" jdbcType="BIGINT" /> <result column="type" property="type" jdbcType="VARCHAR" /> <result column="title" property="title" jdbcType="VARCHAR" /> <result column="article_img" property="articleImg" jdbcType="VARCHAR" /> <result column="keyword" property="keyword" jdbcType="VARCHAR" /> <result column="summary" property="summary" jdbcType="VARCHAR" /> <result column="author" property="author" jdbcType="VARCHAR" /> <result column="access_num" property="accessNum" jdbcType="INTEGER" /> <result column="status" property="status" jdbcType="CHAR" /> <result column="article_date" property="articleDate" jdbcType="TIMESTAMP" /> <result column="thumbs_num" property="thumbsNum" jdbcType="INTEGER" /> <result column="parent" property="parent" jdbcType="VARCHAR" /> <result column="pageUrl" property="pageUrl" jdbcType="VARCHAR" /> <result column="update_by" property="updateBy" jdbcType="VARCHAR" /> <result column="update_date" property="updateDate" jdbcType="TIMESTAMP" /> <result column="create_by" property="createBy" jdbcType="VARCHAR" /> <result column="create_date" property="createDate" jdbcType="TIMESTAMP" /> <result column="remark" property="remark" jdbcType="VARCHAR" /> <result column="del_flag" property="delFlag" jdbcType="CHAR" /> </resultMap> <resultMap id="ResultMapWithBLOBs" type="com.zjlovelt.entity.ArticleInfo" extends="BaseResultMap" > <result column="content" property="content" jdbcType="LONGVARCHAR" /> </resultMap> <sql id="Base_Column_List" > article_id, type, title, article_img, keyword, summary, author, access_num, status, article_date, thumbs_num, parent, pageUrl, update_by, update_date, create_by, create_date, remark, del_flag </sql> <sql id="Blob_Column_List" > content </sql> <select id="selectByPrimaryKey" resultMap="ResultMapWithBLOBs" parameterType="java.lang.Long" > select <include refid="Base_Column_List" /> , <include refid="Blob_Column_List" /> from article_info where article_id = #{articleId,jdbcType=BIGINT} </select> </mapper>
新建业务实现service层
package com.zjlovelt.service; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.zjlovelt.common.constance.Constance; import com.zjlovelt.common.id.IdGenerator; import com.zjlovelt.common.result.Result; import com.zjlovelt.mapper.ArticleInfoMapper; import com.zjlovelt.entity.ArticleInfo; import com.zjlovelt.mapper.SysDataDictionaryMapper; import com.zjlovelt.shiro.JwtUtils; import com.zjlovelt.utils.Tools; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import javax.servlet.http.HttpServletRequest; import java.sql.Timestamp; import java.util.HashMap; import java.util.List; import java.util.Map; @Service public class ArticleInfoService { @Autowired private ArticleInfoMapper articleInfoMapper; @Autowired private SysDataDictionaryMapper dataDictionaryMapper; public ArticleInfo getArticleInfo(Long articleId){ ArticleInfo model = articleInfoMapper.selectByPrimaryKey(articleId); model.convertCodeToName(dataDictionaryMapper); return model; } }
新建controller层
package com.zjlovelt.controller; import com.zjlovelt.common.result.Result; import com.zjlovelt.entity.ArticleInfo; import com.zjlovelt.service.ArticleInfoService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.List; @RequestMapping("/article") @RestController public class ArticleInfoController { @Autowired private ArticleInfoService articleInfoService; /** * 获取文章详情内容 * @param id * @return */ @RequestMapping("getInfoById") public ArticleInfo getInfoById(Long articleId){ return articleInfoService.getArticleInfo(articleId); } }
然后就是运行项目项目
再用postman测试接口
完美~
springboot整合mybatis中需要注意的地方
1.配置文件方面
常见的有两种形式properties和yml格式,如果是yml格式务必注意空格的使用,不要用tab,有时不小心多敲一个空格也会让你格外的头疼。同时注意缩进的对齐。
2.出现Invalid bound statement (not found)错误
一般来说报这种错误,都会通过下面几种方法查找。
检查Mapper.xml的命名空间是否正确。这个主要检查的是namespace中的名字和其dao层的接口类是否对应。
检查dao层的方法名和Mapper.xml中的方法名是否一致。
检查Mapper.xml中的parameterType和resultMap/resultType是否正确。
查看mybatis的xml路径配置是否正确
3、项目结构问题
springboot项目在启动时会依据启动类所在包逐级向下扫描,如果你的dao层,service层和controller层在一个模块中,一定要把他们放到启动类所在目录或者他的子目录下。如果是多模块配置通过依赖的形式使用那么一定要注意包名的书写,和启动类所在包名保持一样,因为它是以包名进行的扫描。所以乱写的话会直接导致扫描不到需要的组件bean
————————————————————
之前建的Springboot项目打包方式是war,后面改成jar重新选择了。
改变理由:之所以选war是因为对war最熟悉,之前工作基本都是这个,对tomcat也很了解,而且war包后面部署好修改代码可以局部更新某一个文件,但是jar就不行了,不过还是选择用jar是因为做这个项目毕竟是为了学习,自然不能一直用熟悉的,而且jar有个好处就是到时候部署肯定和我自己博客在一个服务器,部署个jar包也不用放在一个tomcat下面或者再去配个tomcat了,考虑深远,完美~
选war包和jar包创建的spring boot目录有点小区别,首先是这个ServletInitializer类没有 具体区别可以参考:
https://www.jianshu.com/p/cb5cb5937686最后,开发计划更新~~ 后面会一直更新开发计划,因为文章是在开发时写的,而发布是在后面,所以文章发布时间会比实际开发和写文章的日期要晚点。
#去评论一下
标签:#Springboot#Vue
版权声明:本博客的所有原创内容皆为作品作者所有
转载请注明:来自ZJBLOG 链接:www.zjhuiwan.cn


「万物皆有时,比如你我相遇」
感谢大佬打赏【请选择支付宝或微信,再选择金额】
使用微信扫描二维码完成支付
