- 本篇博客知识点:
- Spring Boot 项目中引入 MyBatis
- MyBatis 的配置
- 通用 Entity,Dao 和 Mapper 的生成
- MyBatis 分页插件 PageHelper
准备工作
- 接上篇博客: springboot与shiro实现权限管理系统(一)
- new 一个 modules,新建springboot子项目,命名为code2,然后将code1中所有内容复制到code2,code2将在code1的基础上进行增加与修改。
- 此篇博客对应代码:code2
- Gitee地址指路:https://gitee.com/alinxi/ShiroTest
1. 引入Mybatis依赖
-
添加jdbc、MySQL、Druid、mybatis以及pageHelper的依赖
<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.10</version> </dependency> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper</artifactId> <version>5.1.10</version> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.1</version> </dependency>
-
数据源配置
spring: datasource: url:jdbc:mysql://localhost:3305/acs?useUnicode=true&characterEncoding=utf-8 username: root password: 123456 type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.jdbc.Driver
-
在
/src/main/resources
下创建 MyBatis 配置文件mybatis-config.xml
并进行配置<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <settings> <setting name="useGeneratedKeys" value="true"/> <setting name="mapUnderscoreToCamelCase" value="true"/> <setting name="logImpl" value="SLF4J"/> <setting name="cacheEnabled" value="true"/> <setting name="localCacheScope" value="SESSION"/> </settings> </configuration>
-
在 mybatis-config.xml 中添加 PageHelper 插件的配置
<!--添加对PageHelper插件的配置--> <plugins> <plugin interceptor="com.github.pagehelper.PageInterceptor"> <property name="dialect" value="mysql"></property> <property name="offsetAsPageNum" value="true"></property> <property name="rowBoundsWithCount" value="true"></property> <property name="pageSizeZero" value="true"></property> <property name="reasonable" value="false"></property> <property name="params" value="pageNum=pageHelperStart;pageSize=PageHelperRows;"></property> <property name="supportMethodsArguments" value="false"></property> <property name="returnPageInfo" value="none"></property> </plugin> </plugins>
-
在 Application.java 中指定 MapperScan 位置。
@MapperScan 注解在应用启动时会将扫描到的 dao 注册到 bean 容器中。@MapperScan("com.acs.code2.ds.dao") @SpringBootApplication @EnableSwagger2 public class Code2Application { public static void main(String[] args) { SpringApplication.run(Code2Application.class, args); } }
2. 生成Entity, Dao, Mapper
- 上篇博客完成了数据库的创建,至于 Entity,Dao 和 Mapper 相关代码的生成方式则有很多种,且不同项目往往有自己的规范和生成工具,比如IDEA 的 groovy 脚本,再比如renren_generator项目。
- 代码生成后的截图如下:
- 这里对sys_role生成的代码进行说明。
-
Entity : 这里使用了 lombok 提供的
@Data
注解,@Data
注解集 lombok 的其他几个注解@ToString, @EqualsAndHashCode, @Getter/@Setter
功能于一身,在代码编译时(javac)会自动生成toString,hashCode,equals,getter/setter
等方法。@Data public class SysRole implements Serializable { private Integer id; private Timestamp insertTime; private Timestamp updateTime; private String roleName; }
-
Dao文件
@Repository public interface SysRoleDao extends BaseDao<SysRole> { } public interface BaseDao<T> { T find(Integer id); int delete(Integer id); int insert(T t); int update(T t); }
-
Mapper文件: 我们将数据表(sys_role)的列名和实体类(SysRole.java)字段名间的映射保存到 id 为 BaseResultMap 的 标签中,这样以 SysRole 为返回实体的查询()语句就可以复用这一映射。
id 为 Base_Column_List 的 标签对数据表的所有字段名称进行了列举,这样在需要的地方就可以通过 直接嵌入这部分 SQL 进行复用。
<?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.acs.admin.ds.dao.SysRoleDao"> <resultMap id="BaseResultMap" type="com.acs.code2.ds.entity.SysRole"> <id column="id" jdbcType="INTEGER" property="id"/> <result column="id" jdbcType="INTEGER" property="id"/> <result column="insert_time" jdbcType="TIMESTAMP" property="insertTime"/> <result column="update_time" jdbcType="TIMESTAMP" property="updateTime"/> <result column="role_name" jdbcType="VARCHAR" property="roleName"/> </resultMap> <sql id="Base_Column_List"> id, insert_time, update_time, role_name </sql> <select id="find" parameterType="java.lang.Integer" resultMap="BaseResultMap"> select <include refid="Base_Column_List"/> from sys_role where id = #{id} </select> <delete id="delete" parameterType="java.lang.Integer"> delete from sys_role where id = #{id} </delete> <insert id="insert" parameterType="com.acs.code2.ds.entity.SysRole" useGeneratedKeys="true" keyProperty="id"> insert into sys_role <trim prefix="(" suffix=")" suffixOverrides=","> <if test="id != null"> id, </if> <if test="insertTime != null"> insert_time, </if> <if test="updateTime != null"> update_time, </if> <if test="roleName != null"> role_name, </if> </trim> <trim prefix="values (" suffix=")" suffixOverrides=","> <if test="id != null"> #{id}, </if> <if test="insertTime != null"> #{insertTime}, </if> <if test="updateTime != null"> #{updateTime}, </if> <if test="roleName != null"> #{roleName}, </if> </trim> </insert> <update id="update" parameterType="com.acs.code2.ds.entity.SysRole"> update sys_role <set> <if test="id != null"> and id = #{id} </if> <if test="insertTime != null"> and insert_time = #{insertTime} </if> <if test="updateTime != null"> and update_time = #{updateTime} </if> <if test="roleName != null"> and role_name = #{roleName} </if> </set> where id = #{id} </update> </mapper>
-
3. 本篇知识点总结
01 | mybatis相关属性
-
useGeneratedKeys:允许 JDBC 支持自动生成主键,这样 Mapper(Mapper 主要有两种形式:XML 和 java 注解)中的 insert 操作会将自增的 id 回填到 Entity 中。useGeneratedKeys 是一个全局配置,但只对接口映射器(注解的方式)有效,对 XML 无效,因此在 XML 中我们还是需要为每个 insert 语句进行下面的指定:
<insert id="insert" useGeneratedKeys="true" keyProperty="id"></insert>
-
mapUnderscoreToCamelCase:将下划线风格的数据库列名自动映射为 java 字段的驼峰风格。
logImpl:将 SQL 执行语句通过日志打印出来。 -
这里额外提一下 MyBatis 中的两种缓存机制:
- localCacheScope:控制一级缓存生效范围,有 SESSION 和 STATEMENT 两种。MyBatis 会将 Mapper 中的查询语句()映射为 MappedStatement,执行查询时 MappedStatement 及其查询参数和返回结果会被缓存,下次同样的查询被执行时可以直接从缓存中获取结果。
- cacheEnabled:控制二级缓存,一级缓存的最大生效范围是 SESSION,如果需要在多个 SESSION(即跨 SqlSession 实例)中进行缓存共享,就需要启用二级缓存。
MyBatis 的两种缓存对提高查询效率有一定帮助,而且默认也都是开启的,但实际开发过程中有时需要除去所有 “干扰” ,通过 Debug 快速定位问题,此时我们可以将 localCacheScope 设置为 STATEMENT,并将 cacheEnabled 设置为 false。
完成。