您的位置:首页 > 编程语言 > Java开发

Spring Boot + Mybatis-Plus 集成与使用(五)

2020-01-14 13:27 1301 查看

首言:

我们已经学习了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脚本。这里有两点需要注意下:

  1. 定义的参数变量使用$而不是#
  2. 参数变量名必须为“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提供的代码生成功能。

扫描下方二维码,关注微信公众号,掌握最新动态。与关注的同伴们一起学习,一起编程!

 

  • 点赞
  • 收藏
  • 分享
  • 文章举报
伴学编程 发布了9 篇原创文章 · 获赞 3 · 访问量 1256 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: