插件简介
PageHelper
与通用 Mapper
作者为同一人 abel533 ,使用这两个插件可以极大地简化 MyBatis
的开发,如果你想深入了解Mybatis以及插件开发可以购买作者的书籍。
分页插件 PageHelper
GitHub地址:https://github.com/pagehelper/Mybatis-PageHelper
如果你也在用 MyBatis,建议尝试该分页插件,这一定是最方便使用的分页插件
在没有分页插件之前,写一个分页需要两条 SQL
语句,一条查询一条统计,然后计算封装 PageBean
,这样的代码冗余而又枯燥,更重要的一点是数据库迁移,众所周知不同的数据库分页写法是不同的,而Mybatis
不同于 Hibernate
的是它只提供动态 SQL
和结果集映射。值得庆幸的是,它虽然没有为分页提供良好的解决方案,但却提供了 Interceptor
以供开发者自己扩展,这也是这款分页插件的由来….
通用Mapper
GitHub地址:https://github.com/abel533/Mapper/
文档地址:https://github.com/abel533/Mapper/wiki
gitee地址:https://gitee.com/free/Mapper
通用Mapper都可以极大的方便开发人员。可以随意的按照自己的需要选择通用方法,还可以很方便的开发自己的通用方法。
极其方便的使用MyBatis单表的增删改查。
支持单表操作,不支持通用的多表联合查询。
添加依赖
org.springframework.boot
spring-boot-starter-web
org.mybatis.spring.boot
mybatis-spring-boot-starter
1.3.2
tk.mybatis
mapper-spring-boot-starter
2.0.3
com.github.pagehelper
pagehelper-spring-boot-starter
1.2.5
mysql
mysql-connector-java
runtime
org.springframework.boot
spring-boot-devtools
true
org.springframework.boot
spring-boot-starter-test
test
相关配置
spring:
application:
name: spring-boot-mbg
datasource:
url: jdbc:mysql://localhost:3306/test_db?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&useSSL=false
username: root
password: mysql123
driver-class-name: com.mysql.jdbc.Driver
mybatis:
config-location: classpath:mybatis/mybatis-config.xml # mybatis配置文件位置
mapper-locations: classpath:mybatis/mappers/*.xml # mapper映射文件位置
type-aliases-package: com.example.springbootmybatis.entity # 别名包
mapper:
mappers:
- com.example.springbootmbg.common.MyBaseMapper
identity: MYSQL # 取回主键的方式 MYSQL: SELECT LAST_INSERT_ID()
order: AFTER # 还可设置为 mapper.before = false
not-empty: true # insertSelective 和 updateByPrimaryKeySelective 中,是否判断字符串类型 !=''
style: camelhumpAndLowercase # 实体和表转换时的默认规则:驼峰转下划线小写形式
enableMethodAnnotation: true # 是否支持(getter 和 setter)在方法上使用注解,默认false
enumAsSimpleType: true # 枚举类型当成基本类型对待
pagehelper:
helper-dialect: mysql
reasonable: false
support-methods-arguments: true
params: count=countSql
# mybatis sql日志
logging:
level:
com:
example:
springbootmbg:
mapper: debug
属性解释
通用Mapper
通用Mapper
属性配置上面的注释已经很清楚了,这里不再做过多解释,唯一一点是 mappers
配置的是自定义的 MyBaseMapper
接口,具体下面介绍。
更多 通用Mapper
属性配置可参考官方文档 3.配置介绍部分
PageHelper
helperDialect
:分页插件会自动检测当前的数据库链接,自动选择合适的分页方式。 你可以配置 helperDialect
属性来指定分页插件使用哪种方言。配置时,可以使用下面的缩写值:
oracle
, mysql
, mariadb
, sqlite
, hsqldb
, postgresql
, db2
, sqlserver
, informix
, h2
, sqlserver2012
, derby
特别注意:使用 SqlServer2012
数据库时,需要手动指定为 sqlserver2012
,否则会使用 SqlServer2005
的方式进行分页。
reasonable
:分页合理化参数,默认值为 false
,直接根据参数进行查询 。当该参数设置为 true
时,pageNum<=0
时会查询第一页, pageNum>pages
(超过总数时),会查询最后一页。
supportMethodsArguments
:支持通过 Mapper
接口参数来传递分页参数,默认值 false
,分页插件会从查询方法的参数值中,自动根据上面 params
配置的字段中取值,查找到合适的值时就会自动分页。 使用方法可以参考测试代码中的 com.github.pagehelper.test.basic
包下的 ArgumentsMapTest
和 ArgumentsObjTest
。
params
:为了支持 startPage(Object params)
方法,增加了该参数来配置参数映射,用于从对象中根据属性名取值, 可以配置 pageNum
, pageSize
, count
, pageSizeZero
, reasonable
,不配置映射的用默认值, 默认值为pageNum=pageNum;pageSize=pageSize;count=countSql;reasonable=reasonable;pageSizeZero=pageSizeZero
。
更多 PageHelper
属性配置可参考官方使用方法部分
MyBatis sql日志
对于 MyBatis sql
日志可以像上面那样在 application.yml
文件中配置,但在项目中往往使用 logback
日志框架,因此可以在 logback-spring.xml
配置文件中添加如下 logger
MyBatis配置文件 mybatis-config.xml
src/main/resource/mybatis/mybatis-config.xml
Spring DevTools 配置
在使用 DevTools
时,通用Mapper
经常会出现 class x.x.A cannot be cast to x.x.A。
同一个类如果使用了不同的类加载器,就会产生这样的错误,所以解决方案就是让 通用Mapper
和实体类使用相同的类加载器即可。
DevTools
默认会对 IDE
中引入的所有项目使用 restart 类加载器
,对于引入的 jar
包使用 base 类加载器
,因此只要保证 通用Mapper
的 jar
包使用 restart 类加载器
即可。
在 src/main/resources
中创建 META-INF
目录,在此目录下添加 spring-devtools.properties
配置,内容如下:
restart.include.mapper=/mapper-[\\w-\\.]+jar
restart.include.pagehelper=/pagehelper-[\\w-\\.]+jar
使用这个配置后,就会使用 restart 类加载器
加载 include
进去的 jar
包。
以上 Spring DevTools 配置
内容引自官方Spring 集成示例——集成Spring Boot部分
通用Mapper MBG代码生成
Maven集成MBG插件
pom.xml
org.springframework.boot
spring-boot-maven-plugin
org.mybatis.generator
mybatis-generator-maven-plugin
1.3.6
${basedir}/src/main/resources/generator/generatorConfig.xml
true
true
mysql
mysql-connector-java
5.1.46
tk.mybatis
mapper
4.0.0
MBG配置文件
详细配置参数可参考http://git.oschina.net/free/Mybatis_Utils/blob/master/MybatisGeneator/MybatisGeneator.md 和官方文档 4.1专用代码生成器部分在此不作过多解释
src/main/resources/generator/generatorConfig.xml
标签需要根据数据库表自行增添
com.example.springbootmbg.common.MyBaseMapper
package com.example.springbootmbg.common; import tk.mybatis.mapper.common.Mapper; import tk.mybatis.mapper.common.MySqlMapper; public interface MyBaseMapper
extends Mapper , MySqlMapper { //TODO //FIXME 特别注意,该接口不能被扫描到,否则会出错 } 很简单的一个接口,继承了
通用Mapper
提供的tk.mybatis.mapper.common.Mapper
及tk.mybatis.mapper.common.MySqlMapper
接口,MBG
生成的Mapper
接口都会继承这个接口,从而间接继承前面提到的两个接口,从而获得通用Mapper
的魔力(其实就是获得了一系列通用Mapper
提供的单表增、删、改、查方法而已),具体方法可以查看那两个接口。扫描Mapper接口所在的包
需要在启动类上添加
@MapperScan
注解,但请注意这个注解不是提供的MyBatis
而是org.mybatis.spring.annotation.MapperScan
通用Mapper
提供的tk.mybatis.spring.annotation.MapperScan
package com.example.springbootmbg; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import tk.mybatis.spring.annotation.MapperScan; @SpringBootApplication @MapperScan(basePackages = {"com.example.springbootmbg.mapper"}) public class SpringBootMbgApplication { public static void main(String[] args) { SpringApplication.run(SpringBootMbgApplication.class, args); } }
注意:这里有个坑就是这个自定义
MyBaseMapper
接口不能被扫描到,否则会报错,因此上面将该接口放在了别的包下。不嫌麻烦的话可以去
MBG
生成的每个Mapper
接口上添加@Mapper
注解使用MBG生成实体类、Mapper接口及xml映射文件
在项目
Maven
插件中找到mybatis-generator
插件,点击mybatis-generator:generate
一下就可以了,如果数据库连接信息配置正确的话,不出意外就会顺利在配置的目录下生成对应的实体类、Mapper接口及xml映射文件啦。为示例这里创建一张用户表
CREATE TABLE `tb_user` ( `id` varchar(64) NOT NULL COMMENT '用户id', `username` varchar(64) NOT NULL COMMENT '用户名', `password` varchar(64) NOT NULL COMMENT '用户密码', `face_icon` varchar(255) DEFAULT NULL COMMENT '用户头像', `nickname` varchar(64) NOT NULL COMMENT '用户昵称', `fans_counts` int(11) DEFAULT '0' COMMENT '用户粉丝数', `follow_counts` int(11) DEFAULT '0' COMMENT '关注其他用户数', `receive_like_counts` int(11) DEFAULT '0' COMMENT '收到的喜欢数目', `create_time` datetime NOT NULL COMMENT '创建时间', `update_time` datetime NOT NULL COMMENT '更新时间', PRIMARY KEY (`id`), UNIQUE KEY `idx_username` (`username`) USING BTREE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='用户表';
生成的代码大致像下面这样
com.example.springbootmbg.entity.user
package com.example.springbootmbg.entity; import java.util.Date; import javax.persistence.*; @Table(name = "tb_user") public class User { /** * 用户id */ @Id private String id; /** * 用户名 */ private String username; /** * 用户密码 */ private String password; /** * 用户头像 */ @Column(name = "face_icon") private String faceIcon; /** * 用户昵称 */ private String nickname; /** * 用户粉丝数 */ @Column(name = "fans_counts") private Integer fansCounts; /** * 关注其他用户数 */ @Column(name = "follow_counts") private Integer followCounts; /** * 收到的喜欢数目 */ @Column(name = "receive_like_counts") private Integer receiveLikeCounts; /** * 创建时间 */ @Column(name = "create_time") private Date createTime; /** * 更新时间 */ @Column(name = "update_time") private Date updateTime; // setters and getters }
通用Mapper
会用到Jpa
的几个简单注解,这里不做解释
com.example.springbootmbg.mapper.UserMapper
package com.example.springbootmbg.mapper; import com.example.springbootmbg.common.MyBaseMapper; import com.example.springbootmbg.entity.User; import org.springframework.stereotype.Repository; @Repository public interface UserMapper extends MyBaseMapper
{ } 生成的代码不带
@Repository
注解
src/main/resource/mybatis/mappers/UserMapper.xml
测试
com.example.springbootmbg.mapper.UserMapperTest
package com.example.springbootmbg.mapper; import com.example.springbootmbg.entity.User; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; import org.junit.Test; import org.junit.runner.RunWith; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import java.util.Date; import java.util.List; import java.util.UUID; @SpringBootTest @RunWith(SpringRunner.class) public class UserMapperTest { @Autowired private UserMapper userMapper; private static final Logger logger = LoggerFactory.getLogger(UserMapperTest.class); @Test public void testInsert() { User user = new User(); user.setId(UUID.randomUUID().toString().replaceAll("-", "")); user.setUsername("aaa"); user.setPassword("123456"); user.setNickname("aaa"); user.setCreateTime(new Date()); user.setUpdateTime(new Date()); userMapper.insertSelective(user); User user2 = new User(); user2.setId(UUID.randomUUID().toString().replaceAll("-", "")); user2.setUsername("bbb"); user2.setPassword("123456"); user2.setNickname("bbb"); user2.setCreateTime(new Date()); user2.setUpdateTime(new Date()); userMapper.insertSelective(user2); } @Test public void testPage() { PageHelper.startPage(1, 10); List
userList = userMapper.selectAll(); PageInfo pageInfo = new PageInfo<>(userList); logger.info("pageInfo: {}", pageInfo); } }