mybatis
简介
MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
官方地址:https://mybatis.org/mybatis-3/zh/index.html
springboot集成
详细参考:Spring boot Mybatis 整合(注解版)
-
添加依赖
<dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>${mybatis-spring-boot-starter.version}</version> </dependency> -
配置 application.properties
#mybatis config mybatis.mapper-locations=classpath:/mappers/**/*.xml # model 包名 mybatis.type-aliases-package=com.xxx.model mybatis.configuration.map-underscore-to-camel-case=true mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl -
在代码中使用:
在启动类添加包扫描(建议)或者在mapper文件添加@Mapper注解,使用的时候把mapper文件当作普通的类注入就可以了。
//在启动类添加包扫描 @MapperScan("com.xxx.mapper") public class XxxApplication { public static void main(String[] args) { SpringApplication.run(XxxApplication.class, args); } } //在mapper文件添加@Mapper注解 @Mapper public interface XxxMapper { int deleteByPrimaryKey(Long id); int insert(Xxx record); int insertSelective(Xxx record); Xxx selectByPrimaryKey(Long id); int updateByPrimaryKeySelective(Xxx record); int updateByPrimaryKey(Xxx record); }
mybatis-generator
mybatis-generator是mybatis代码生成器,方便基于mysql表生成Mybatis适合的实体、Mapper接口和xml映射文件
mybatis generator详解:MyBatis Generator 详解
在MavenPom文件添加mybatis-generator-maven-plugin
<build>
<plugins>
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.7</version>
<configuration>
<!--mybatis的代码生成器的配置文件-->
<configurationFile>src/main/resources/generator-config.xml</configurationFile>
<!--允许覆盖生成的文件-->
<overwrite>true</overwrite>
<verbose>true</verbose>
</configuration>
<dependencies>
<!-- mysql的JDBC驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<!--tk.mybatis 依赖,可选 -->
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper</artifactId>
<version>${tk.mapper.version}</version>
</dependency>
</dependencies>
</plugin>
<plugins>
</build>
generator-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<!-- 配置table表信息内容体,targetRuntime指定采用MyBatis3的版本 -->
<context id="tables" targetRuntime="MyBatis3">
<property name="javaFileEncoding" value="UTF-8"/>
<!-- 抑制生成注释,由于生成的注释都是英文的,可以不让它生成 -->
<commentGenerator>
<property name="suppressAllComments" value="true"/>
</commentGenerator>
<!-- 配置数据库连接信息 -->
<jdbcConnection driverClass="com.mysql.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/cne_sys?characterEncoding=utf-8"
userId="root"
password="xxxxxxxx">
</jdbcConnection>
<!-- 生成model类,targetPackage指定model类的包名, targetProject指定生成的model放在哪个工程下面-->
<javaModelGenerator targetPackage="com.xxx.model" targetProject="src/main/java">
<property name="enableSubPackages" value="false"/>
<property name="trimStrings" value="false"/>
</javaModelGenerator>
<!-- 生成MyBatis的Mapper.xml文件,targetPackage指定mapper.xml文件的包名, targetProject指定生成的mapper.xml放在哪个工程下面 -->
<sqlMapGenerator targetPackage="mappers" targetProject="src/main/resources">
<property name="enableSubPackages" value="false"/>
</sqlMapGenerator>
<!-- 生成MyBatis的Mapper接口类文件,targetPackage指定Mapper接口类的包名, targetProject指定生成的Mapper接口放在哪个工程下面 -->
<javaClientGenerator type="XMLMAPPER" targetPackage="com.xxx.mapper"
targetProject="src/main/java">
<property name="enableSubPackages" value="false"/>
</javaClientGenerator>
<!-- 数据库表名及对应的Java模型类名 -->
<table tableName="tbl_user" domainObjectName="User" enableCountByExample="false"
enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false"
selectByExampleQueryId="false"/>
</context>
</generatorConfiguration>
MybatixX Idea 快捷开发插件
简介
MybatisX 是一款基于 IDEA 的快速开发插件,为效率而生。说明:MybatisX快速开发插件
安装
安装方法:打开 IDEA,进入 File -> Settings -> Plugins -> Browse Repositories,输入 mybatisx 搜索并安装。
功能
- XML 跳转
- 生成代码(需先在 idea 配置 Database 配置数据源)
- 重置模板
- JPA 提示
生成代码的模板配置
按照指定目录找到插件模板配置目录 Scratches and Consoles -> Extensions -> MybatisX
这里会提供默认模板: 例如在 1.4.13 提供了模板: default-all,default,mybatis-plus2,mybatis-plus3
如果想重置默认模板, 可以右键点击 MybatisX 目录,选择 Restore Default Extensions 选项

自定义模板内容
| 名称 | 含义 |
|---|---|
| tableClass.fullClassName | 类的全称(包括包名) |
| tableClass.shortClassName | 类的简称 |
| tableClass.tableName | 表名 |
| tableClass.pkFields | 表的所有主键字段 |
| tableClass.allFields | 表的所有字段 |
| tableClass.baseFields | 排除主键和 blob 的所有字段 |
| tableClass.baseBlobFields | 排除主键的所有字段 |
| tableClass.remark | 表注释 |
字段信息
| 名称 | 含义 |
|---|---|
| field.fieldName | 字段名称 |
| field.columnName | 列名称 |
| field.jdbcType | jdbc 类型 |
| field.columnLength | 列段长度 |
| field.columnScale | 列的精度 |
| field.columnIsArray | 字段类型是不是数组类型 |
| field.shortTypeName | java 类型短名称, 通常用于定义字段 |
| field.fullTypeName | java 类型的长名称, 通常用于导入 |
| field.remark | 字段注释 |
| field.autoIncrement | 是否自增 |
| field.nullable | 是否允许为空 |
配置信息
| 名称 | 含义 |
|---|---|
| baseInfo.shortClassName | 配置名称 |
| baseInfo.tableName | 配置文件名称 |
| baseInfo.pkFields | 配置名称 |
| baseInfo.allFields | 后缀 |
| baseInfo.baseFields | 包名 |
| baseInfo.baseBlobFields | 模板内容 |
| baseInfo.remark | 相对模块的资源文件路径 |
mybatis分页插件pageHelper
相关介绍如下
使用说明
-
添加依赖
<dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper-spring-boot-starter</artifactId> <version>${pagehelper.version}</version> </dependency> -
配置 application.properties
# pageHelper分页插件配置 pagehelper.helper-dialect=mysql pagehelper.reasonable=true pagehelper.support-methods-arguments=true pagehelper.params=countSql参数说明:
分页插件可选参数如下:
dialect:默认情况下会使用 PageHelper 方式进行分页,如果想要实现自己的分页逻辑,可以实现Dialect(com.github.pagehelper.Dialect) 接口,然后配置该属性为实现类的全限定名称。
下面几个参数都是针对默认 dialect 情况下的参数。使用自定义 dialect 实现时,下面的参数没有任何作用。
helperDialect:分页插件会自动检测当前的数据库链接,自动选择合适的分页方式。 你可以配置helperDialect属性来指定分页插件使用哪种方言。配置时,可以使用下面的缩写值:oracle,mysql,mariadb,sqlite,hsqldb,postgresql,db2,sqlserver,informix,h2,sqlserver2012,derby特别注意:使用 SqlServer2012 数据库时,需要手动指定为sqlserver2012,否则会使用 SqlServer2005 的方式进行分页。 你也可以实现AbstractHelperDialect,然后配置该属性为实现类的全限定名称即可使用自定义的实现方法。offsetAsPageNum:默认值为false,该参数对使用RowBounds作为分页参数时有效。 当该参数设置为true时,会将RowBounds中的offset参数当成pageNum使用,可以用页码和页面大小两个参数进行分页。rowBoundsWithCount:默认值为false,该参数对使用RowBounds作为分页参数时有效。 当该参数设置为true时,使用RowBounds分页会进行 count 查询。pageSizeZero:默认值为false,当该参数设置为true时,如果pageSize=0或者RowBounds.limit = 0就会查询出全部的结果(相当于没有执行分页查询,但是返回结果仍然是Page类型)。reasonable:分页合理化参数,默认值为false。当该参数设置为true时,pageNum<=0时会查询第一页,pageNum>pages(超过总数时),会查询最后一页。默认false时,直接根据参数进行查询。params:为了支持startPage(Object params)方法,增加了该参数来配置参数映射,用于从对象中根据属性名取值, 可以配置pageNum,pageSize,count,pageSizeZero,reasonable,不配置映射的用默认值, 默认值为pageNum=pageNum;pageSize=pageSize;count=countSql;reasonable=reasonable;pageSizeZero=pageSizeZero。supportMethodsArguments:支持通过 Mapper 接口参数来传递分页参数,默认值false,分页插件会从查询方法的参数值中,自动根据上面params配置的字段中取值,查找到合适的值时就会自动分页。 使用方法可以参考测试代码中的com.github.pagehelper.test.basic包下的ArgumentsMapTest和ArgumentsObjTest。autoRuntimeDialect:默认值为false。设置为true时,允许在运行时根据多数据源自动识别对应方言的分页 (不支持自动选择sqlserver2012,只能使用sqlserver),用法和注意事项参考下面的场景五。closeConn:默认值为true。当使用运行时动态数据源或没有设置helperDialect属性自动获取数据库类型时,会自动获取一个数据库连接, 通过该属性来设置是否关闭获取的这个连接,默认true关闭,设置为false后,不会关闭获取的连接,这个参数的设置要根据自己选择的数据源来决定。aggregateFunctions(5.1.5+):默认为所有常见数据库的聚合函数,允许手动添加聚合函数(影响行数),所有以聚合函数开头的函数,在进行 count 转换时,会套一层。其他函数和列会被替换为 count(0),其中count列可以自己配置。
-
重要提示
PageHelper.startPage方法重要提示只有紧跟在
PageHelper.startPage方法后的第一个Mybatis的查询(Select)方法会被分页。请不要配置多个分页插件
请不要在系统中配置多个分页插件(使用Spring时,
mybatis-config.xml和Spring<bean>配置方式,请选择其中一种,不要同时配置多个分页插件)!分页插件不支持带有
for update语句的分页对于带有
for update的sql,会抛出运行时异常,对于这样的sql建议手动分页,毕竟这样的sql需要重视。分页插件不支持嵌套结果映射
由于嵌套结果方式会导致结果集被折叠,因此分页查询的结果在折叠后总数会减少,所以无法保证分页结果数量正确。
-
在代码中使用
//第一种,RowBounds方式的调用 List<User> list = sqlSession.selectList("x.y.selectIf", null, new RowBounds(0, 10)); //第二种,Mapper接口方式的调用,推荐这种使用方式。 PageHelper.startPage(1, 10); List<User> list = userMapper.selectIf(1); //第三种,Mapper接口方式的调用,推荐这种使用方式。 PageHelper.offsetPage(1, 10); List<User> list = userMapper.selectIf(1); //第四种,参数方法调用 //存在以下 Mapper 接口方法,你不需要在 xml 处理后两个参数 public interface CountryMapper { List<User> selectByPageNumSize( @Param("user") User user, @Param("pageNum") int pageNum, @Param("pageSize") int pageSize); } //配置supportMethodsArguments=true //在代码中直接调用: List<User> list = userMapper.selectByPageNumSize(user, 1, 10); //第五种,参数对象 //如果 pageNum 和 pageSize 存在于 User 对象中,只要参数有值,也会被分页 //有如下 User 对象 public class User { //其他fields //下面两个参数名和 params 配置的名字一致 private Integer pageNum; private Integer pageSize; } //存在以下 Mapper 接口方法,你不需要在 xml 处理后两个参数 public interface CountryMapper { List<User> selectByPageNumSize(User user); } //当 user 中的 pageNum!= null && pageSize!= null 时,会自动分页 List<User> list = userMapper.selectByPageNumSize(user); //第六种,ISelect 接口方式 //jdk6,7用法,创建接口 Page<User> page = PageHelper.startPage(1, 10).doSelectPage(new ISelect() { @Override public void doSelect() { userMapper.selectGroupBy(); } }); //jdk8 lambda用法 Page<User> page = PageHelper.startPage(1, 10).doSelectPage(()-> userMapper.selectGroupBy()); //也可以直接返回PageInfo,注意doSelectPageInfo方法和doSelectPage pageInfo = PageHelper.startPage(1, 10).doSelectPageInfo(new ISelect() { @Override public void doSelect() { userMapper.selectGroupBy(); } }); //对应的lambda用法 pageInfo = PageHelper.startPage(1, 10).doSelectPageInfo(() -> userMapper.selectGroupBy()); //count查询,返回一个查询语句的count数 long total = PageHelper.count(new ISelect() { @Override public void doSelect() { userMapper.selectLike(user); } }); //lambda total = PageHelper.count(()->userMapper.selectLike(user));PageInfo说明:
pageNum当前页 pageSize每页的数量 size当前页的数量 orderBy排序 startRow当前页面第一个元素在数据库中的行号 endRow当前页面最后一个元素在数据库中的行号 total总记录数(在这里也就是查询到的用户总数) pages总页数 (这个页数也很好算,每页5条,总共有11条,需要3页才可以显示完) list结果集 prePage前一页 nextPage下一页 isFirstPage是否为第一页 isLastPage是否为最后一页 hasPreviousPage是否有前一页 hasNextPage是否有下一页 navigatePages导航页码数 navigatepageNums所有导航页号 navigateFirstPage导航第一页 navigateLastPage导航最后一页 firstPage第一页 lastPage最后一页 -
实际例子,github示例
// 相关配置 mybatis: type-aliases-package: tk.mybatis.springboot.model mapper-locations: classpath:mapper/*.xml mapper: mappers: - tk.mybatis.springboot.util.MyMapper not-empty: false identity: MYSQL pagehelper: helperDialect: mysql reasonable: true supportMethodsArguments: true params: count=countSql **/ // 关键代码如下,包括 controller,service,mapper // controller @RestController @RequestMapping("/users") public class UserInfoController { @Autowired private UserInfoService userInfoService; @RequestMapping public PageInfo<UserInfo> getAll(UserInfo userInfo) { List<UserInfo> userInfoList = userInfoService.getAll(userInfo); return new PageInfo<UserInfo>(userInfoList); } @RequestMapping(value = "/add") public UserInfo add() { return new UserInfo(); } @RequestMapping(value = "/view/{id}") public UserInfo view(@PathVariable Integer id) { ModelAndView result = new ModelAndView(); UserInfo userInfo = userInfoService.getById(id); return userInfo; } @RequestMapping(value = "/delete/{id}") public ModelMap delete(@PathVariable Integer id) { ModelMap result = new ModelMap(); userInfoService.deleteById(id); result.put("msg", "删除成功!"); return result; } @RequestMapping(value = "/save", method = RequestMethod.POST) public ModelMap save(UserInfo userInfo) { ModelMap result = new ModelMap(); String msg = userInfo.getId() == null ? "新增成功!" : "更新成功!"; userInfoService.save(userInfo); result.put("userInfo", userInfo); result.put("msg", msg); return result; } } /** * service */ @Service public class UserInfoService { @Autowired private UserInfoMapper userInfoMapper; public List<UserInfo> getAll(UserInfo UserInfo) { if (UserInfo.getPage() != null && UserInfo.getRows() != null) { PageHelper.startPage(UserInfo.getPage(), UserInfo.getRows()); } return userInfoMapper.selectAll(); } public UserInfo getById(Integer id) { return userInfoMapper.selectByPrimaryKey(id); } public void deleteById(Integer id) { userInfoMapper.deleteByPrimaryKey(id); } public void save(UserInfo country) { if (country.getId() != null) { userInfoMapper.updateByPrimaryKey(country); } else { userInfoMapper.insert(country); } } } /** * mapper user tk.mybatis */ public interface UserInfoMapper extends MyMapper<UserInfo> { }
通用Mapper
TK通用Mapper和Mybatis-Plus使用对比:TK通用Mapper和Mybatis-Plus使用对比
mybatisPlus
MyBatis-Plus (opens new window)(简称 MP)是一个 MyBatis (opens new window)的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
tkmybatis
tkmybatis 是对底层 sql 进行了抽象封装,不需要考虑 sql 怎么写,只需要按照逻辑思维,遵循 tkmybatis 的语法即可实现数据库操作。