Spring Boot + Mybatis-Plus 集成与使用(五)
首言:
我们已经学习了MyBatis-Plus核心功能之一的条件构造器,讲解了条件构造器各个方法的使用。本章节将讲解配置mapper接口映射的mapper.xml文件,编写、执行动态SQL操作。以及讲解MyBatis-Plus分页插件进行分页查询。
一、映射文件XML
我们在类资源目录下新建mappers目录,在该目录下新建SysLogMapper.xml文件,在文件中添加头部声明和命名空间
[code]<?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.banxun.demo.mapper.SysLogMapper"> </mapper>
在application.properties配置文件中Mapper所对应的 XML文件位置
[code]mybatis-plus.mapper-locations=classpath:/mappers/*.xml
Maven 多模块项目的扫描路径需以
classpath*:开头 (即加载多个 jar 包下的 XML 文件)
配置完成后,我们在SysLogMapper接口中定义一个方法
[code]public interface SysLogMapper extends BaseMapper<SysLog> { List<SysLog> queryLog(String personName); }
在SysLogMapper.xml文件中定义方法映射的sql
[code]<select id="queryLog" resultType="com.banxun.demo.entity.SysLog"> select * from t_sys_log where f_option_person = #{personName} </select>
我们在junit方法测试调用下此方法
[code]@Test public void contextLoads() { List<SysLog> logList = sysLogMapper.queryLog("admin"); for (SysLog sysLog : logList) { System.out.println(sysLog.getOptionPerson()); } }
我们可以执行结果失败,报空指针异常。我们打断点看下logList的情况
通过断点可以看到,logList不为空,大小为20,但集全元素 All elements are null。这是因为我们这表张的字段名都有一个前缀"f_",无法自动映射SysLog对象的属性。在自定义的sql脚本里,将*改为字段名并加上同属性名的别名。这里我们只给f_option_person加上别名optionPerson。
[code]<select id="queryLog" resultType="com.banxun.demo.entity.SysLog.SysLog"> select f_option_person optionPerson from t_sys_log where f_option_person = #{personName} </select>
打上断点再来看下结果。可以看到logList集合有元素了,元素SysLog对象除了optionPerson有属性值,其他属性值都为空。
有同伴在学习时也发现在注解@TatableName里有一个属性autoResultMap,官方文档中介绍为是否自动构建 resultMap并使用(如果设置 resultMap 则不会进行 resultMap 的自动构建并注入)(@since 3.1.2)。其实这个是与typeHandle 处理使用,并不是xml里的resultMap开启自动映射。具体使用在后续章节将给各位同伴进行讲解。
而MyBatis-Plus之所以没有通过注解@TableFIeld的字段名自动映射实体属性名,是因为MyBatis-Plus只对提供的相关方法有效,XML文件中的sql需写法遵守原生规则,要么as起别名,要么遵循Mybatis的规范命名。
这里讲解到XML映射文件,再给同伴们讲解一个配置属性typeAliasesPackage的用法。
在application.properties配置typeAliasesPackage属性值,值为实体类的包扫描路径,通过该属性可以给包中的实体类注册别名,注册后在 Mapper对应的XML映射文件中可以直接使用类名,而不用使用全限定的类名。像这样:
[code]#这里直接在resultType里给类名即可 <select id="queryLog" resultType="SysLog"> select f_option_person optionPerson from t_sys_log where f_option_person = #{personName} </select>
二、注解SQL
这里再讲解下使用注解@Select方式如何在使用了mybatis-plus之后,自定义SQL的使用条件构想器的便利。 在mybatis-plus版本版本需要大于或等于3.0.7。
在Mapper接口中定义一个方法,在方法使用@Select定义sql脚本。这里有两点需要注意下:
- 定义的参数变量使用$而不是#
- 参数变量名必须为“ew”或使用MyBatis-Plus提供的常量Constants.WRAPPER
[code]public interface SysLogMapper extends BaseMapper<SysLog> { @Select("select f_option_person optionPerson from t_sys_log ${ew.customSqlSegment}") List<SysLog> queryLog(@Param("ew") Wrapper wrapper); }
我们来看下测试用例与执行结果
[code]@Test public void test() { QueryWrapper<SysLog> query = new QueryWrapper(); query.lambda().eq(SysLog::getOptionPerson, "admin"); List<SysLog> list = sysLogMapper.queryLog(query); }
[code] Time:19 ms - ID:com.banxun.demo.mapper.SysLogMapper.queryLog Execute SQL: select f_option_person optionPerson from t_sys_log WHERE f_option_person = 'admin'
可以看控制台日志打印正常
三、分页查询与分页插件
查询不可缺少分页查询,接下来我们看下MyBatis-Plus是如何进行分页查询操作。
1、分页类型
- 物理分页: 物理分页依赖的是某一物理实体,这个物理实体就是数据库,比如MySQL数据库提供了limit关键字,程序员只需要编写带有limit关键字的SQL语句,数据库返回的就是分页结果。
- 逻辑分页:逻辑分页依赖的是程序员编写的代码。数据库返回的不是分页结果,而是全部数据,然后再由程序员通过代码获取分页数据,常用的操作是一次性从数据库中查询出全部数据并存储到List集合中,因为List集合有序,再根据索引获取指定范围的数据。
2、分页插件
MyBatis-Plus为我们提供了一个非常便捷的分页插件-PaginationInterceptor。
3、分页插件配置
配置分页插件非常简单,在我们之前章节中用到的MyBatisConfig配置类中加入如下代码,Spring Boot启动时实例化插件对象。
[code]@Bean public PaginationInterceptor paginationInterceptor() { PaginationInterceptor paginationInterceptor = new PaginationInterceptor(); return paginationInterceptor; }
4、默认方法分页查询
在BaseMapper接口中已定义两个分页方法。
[code] IPage<T> selectPage(IPage<T> page, @Param("ew") Wrapper<T> queryWrapper); IPage<Map<String, Object>> selectMapsPage(IPage<T> page, @Param("ew") Wrapper<T> queryWrapper);
我们写个junit单元测试来调用下selectPage方法进行分页查询。先实例化一个page对象。page对象用来定义分页参数,以及排序。
[code]@Test public void contextLoads() { //分页对象,构造方法传入当前页数与每页条数 Page<SysLog> page = new Page<>(1, 2); page.addOrder(OrderItem.asc("f_option_time")); page = (Page)sysLogMapper.selectPage(page, null); System.out.println("数据总条数" + page.getTotal()); //数据总条数 System.out.println("每页条数=" + page.getSize()); //每页条数 System.out.println("当前页数=" + page.getCurrent()); //当前页数 System.out.println("总页数=" +page.getPages()); //总页数 System.out.println("结果数据条数=" + page.getRecords().size()); }
控制台日志打印输出如下结果:
[code] Time:19 ms - ID:com.banxun.demo.mapper.SysLogMapper.selectPage Execute SQL: SELECT * FROM t_sys_log ORDER BY f_option_time LIMIT 0, 2 数据总条数21 每页条数=2 当前页数=1 总页数=11 结果数据条数=2
我们来分析下上面的代码与执行结果。
注意:Page内引用了OrderItem定义排序字段。在MyBatis-Plus 3.2.0版本之前,OrderItem未实现Serializable接口类,在使用RPC(如dubbo)不可以在消费端使用page.addOrder(OrderItem.asc("f_option_time")),否则报OrderItem类未序列化异常
上面代码调用selectPage传入page对象,返回IPage接口类。这里需要强转下得到page对象。page对象里封装了分页所需的属性值。可以看控制台输出了相关数据。以及打印的执行sql,sql使用limit 进行分页查询。
5、自定义SQL分页查询
我们再来看下在XML映射文件中如何进行分页查询操作。XML手动编写sql,但不出我们像上面那样在sql结尾编写limit控制分页。
也来个单元测试用例看下,在mapper接口中定义一个分页查询方法。
注意,这里需要传IPage接口实现类,返回可以是IPage对象,也可以集合。如果是集合,需要在调用的地方现在用入参的page对象调用setRecords()方法将集合封装到page对象中。
[code]public interface SysLogMapper extends BaseMapper<SysLog> { IPage<SysLog> queryLogPage(IPage page); }
定义的sql如下,我们未在sql后编写limit
[code]<select id="queryLogPage" resultType="SysLog"> select f_option_person optionPerson from t_sys_log </select>
再来看下测试用例,这里使用IPage接口定义page对象,返回类型一致,不用向下转型。每页条数为5条。
[code]@Test public void contextLoads() { //分页对象,构造方法传入当前页数与每页条数 IPage<SysLog> page = new Page<>(1, 5); page = sysLogMapper.queryLogPage(page); System.out.println("数据总条数" + page.getTotal()); //数据总条数 System.out.println("每页条数=" + page.getSize()); //每页条数 System.out.println("当前页数=" + page.getCurrent()); //当前页数 System.out.println("总页数=" +page.getPages()); //总页数 System.out.println("结果数据条数=" + page.getRecords().size()); }
[code] Time:17 ms - ID:com.banxun.demo.mapper.SysLogMapper.queryLogPage Execute SQL: select f_option_person optionPerson from t_sys_log LIMIT 0, 5 数据总条数21 每页条数=5 当前页数=1 总页数=5 结果数据条数=5
控制台打印输出结结果可以看到对数据进行了分页查询,并且在手动编写的sql后面自动添加了limit语句
6、注解SQL分页查询
我们再看如使用注解方式如何进行分页查询
在Mapper里给之前的queryLog方法,加入IPage接口实现对象入参,这里返回一个集合
[code]public interface SysLogMapper extends BaseMapper<SysLog> { @Select("select f_option_person optionPerson from t_sys_log ${ew.customSqlSegment}") List<SysLog> queryLog(IPage page, @Param(Constants.WRAPPER) Wrapper wrapper); }
junit测试方法中,将mapper接口的方法返回的集合封装到page对象
[code]@Test public void test() { IPage<SysLog> page = new Page<>(1, 5); QueryWrapper<SysLog> query = new QueryWrapper(); query.lambda().eq(SysLog::getOptionPerson, "admin"); List<SysLog> list = sysLogMapper.queryLog(page, query); page.setRecords(list); System.out.println("数据总条数" + page.getTotal()); //数据总条数 System.out.println("每页条数=" + page.getSize()); //每页条数 System.out.println("当前页数=" + page.getCurrent()); //当前页数 System.out.println("总页数=" +page.getPages()); //总页数 System.out.println("结果数据条数=" + page.getRecords().size()); }
控制台打印日志输出结果数据条数,就是上面的集合个数
[code]Time:18 ms - ID:com.banxun.demo.mapper.SysLogMapper.queryLog Execute SQL: select f_option_person optionPerson from t_sys_log WHERE f_option_person = 'admin' LIMIT 0,5 数据总条数20 每页条数=5 当前页数=1 总页数=4 结果数据条数=5
四、小结
本章节中我们讲解如何对XML映射文件以及注解方法的动态sql进行查询以及配置分页插件后如何进行分页查询。后续章节我们将给同伴们分析分页插件的原理以及MyBatis-Plus提供的代码生成功能。
扫描下方二维码,关注微信公众号,掌握最新动态。与关注的同伴们一起学习,一起编程!
- 点赞
- 收藏
- 分享
- 文章举报
- Spring Boot + Mybatis-Plus 集成与使用(六)
- Spring Boot + Mybatis-Plus 集成与使用(七)
- 使用SpringBoot搭建小型项目,集成mybatis,redis,swagger2,并部署在外部容器中。
- 架构实战项目心得(七):使用SpringBoot+Dubbo+Mybatisplus+Oracle搭建后台项目框架(一)
- 在springboot项目中使用mybatis 集成 Sharding-JDBC
- SpringBoot之集成mybatis:使用mybatis xml
- springboot+mybatisplus(使用总结,配置总结!!!干货...)
- spring boot 集成 mybatis 使用redis做二级缓存
- spring-boot-mybatis-plus使用心得
- spring-boot集成mybatis使用Druid监控
- (二十一)SpringBoot之集成mybatis:使用mybatis xml
- Spring Boot 使用Oracle集成Mybatis,驼峰映射(下划线)问题
- SpringBoot实践:集成Mybatis-Plus
- Mybatis-plus集成springboot
- Springboot-2.0.6.RELEASE版本集成Mybatis-plus及Mysql
- springboot2.0.5集成mybatis(PageHelper分页插件、generator插件使用)
- SpringBoot和mybatisplus的入门使用
- (二十)SpringBoot之集成mybatis:使用mybatis注解
- springboot 零xml集成mybatis-plus
- 从零学spring boot--集成mybatis--项目--使用注解方式