这是我参与8月更文挑战的第16天,活动详情查看:8月更文挑战
全新的
MyBatis-Plus
3.0 版本基于 JDK8,提供了lambda
形式的调用,使用了lambda
表达式可以通过方法引用
的方式来使用实体字段名的操作,避免直接写数据库表字段名时的错写名字。注意事项:
在使用的时候一定要注意,设计的字段名是否标准。不允许字段名出现以
is
get
为开头,负责MyBatis-Plus
在编译lambda表达式会出错
1.创建Lambda表达式的方式
1.1 基本操作
-
LambdaQueryWrapper<T>
方式 -
QueryWrapper<实体>().lambda()
方式 -
Wrappers.<实体>lambdaQuery()
方式
/**
* lambda 条件构造器
* 生成的sql语句
* SELECT id,name,age,email,manager_id,create_time FROM user WHERE name LIKE ? AND age < ?
*/
@Test
public void selectLambda01() {
/* 创建lambda 条件构造器 的三种方法 */
// LambdaQueryWrapper<User> lambda1 = new LambdaQueryWrapper<>();
// LambdaQueryWrapper<User> lambda2 = new QueryWrapper<User>().lambda();
LambdaQueryWrapper<User> lambda3 = Wrappers.<User>lambdaQuery();
lambda3.like(User::getName, "雨").lt(User::getAge, 40);
List<User> users = userMapper.selectList(lambda3);
users.forEach(System.out::println);
}
复制代码
/**
* 名字为王姓并且(年龄小于40并且邮箱不为空)
* name like '王%' and (age <40 or email in not null)
* 生成的sql语句 SELECT id,name,age,email,manager_id,create_time FROM user WHERE name LIKE ? AND age < ?
*/
@Test
public void selectLambda02() {
LambdaQueryWrapper<User> lambda3 = Wrappers.<User>lambdaQuery();
lambda3.likeRight(User::getName, "王").and(qw -> qw.lt(User::getAge, 40).or().isNotNull(User::getEmail));
List<User> users = userMapper.selectList(lambda3);
users.forEach(System.out::println);
}
复制代码
1.2 自定义SQL语句
注解方式(个人不推荐使用)
/**
* 自定义SQL语句使用
* Dao(Mapper)层代码:
* @Select("select * from ${ew.customSqlSegment}")
* List<User> selectAll(@Param(Constants.WRAPPER)Wrapper<User> wrapper);
*/
@Test
public void selectLambda03() {
LambdaQueryWrapper<User> lambda3 = Wrappers.<User>lambdaQuery();
lambda3.likeRight(User::getName, "王").and(qw -> qw.lt(User::getAge, 40).or().isNotNull(User::getEmail));
List<User> users = userMapper.selectAll(lambda3);
users.forEach(System.out::println);
}
复制代码
自定义SQL语句:XML方式,xml方式自定义sql 这里只是个单表演示application.yml 添加
mybatis-plus:
mapper-locations:
- com/mp/mapper/*
复制代码
持久化层接口代码,UserMapper接口添加方法
List<User> selectAll(@Param(Constants.WRAPPER) Wrapper<User> wrapper);
复制代码
映射文件UserMpper.xml代码
<?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.mp.dao.UserMapper">
<select id="selectAll" resultType="com.mp.entity.User">
select * from user ${ew.customSqlSegment}
</select>
</mapper>
复制代码
2.LambdaQueryChainWrapper<实体>(xxxxMapper)
方式
/**
* lambda 条件构造器第四种创建方式 MP 3.0.7 新增的方式
* 生成的sql语句 SELECT id,name,age,email,manager_id,create_time FROM user WHERE name LIKE ? AND age >= ?
* 这个例子可以看出 代码更简洁了
* 生成的sql语句 SELECT id,name,age,email,manager_id,create_time FROM user WHERE name LIKE ? AND age >= ?
*/
@Test
public void selectLambda04() {
List<User> users = new LambdaQueryChainWrapper<User>(userMapper)
.like(User::getName, "雨").ge(User::getAge, 20).list();
users.forEach(System.out::println);
}
复制代码
3.lambda在分页中的应用
3.1 MP的分页操作
BaseMapper
接口提供两种分页方法来实现物理分页(注:导包时导MP的包)
第一个返回实体对象允许null
第二个人返回map对象多用于在指定放回字段时使用,避免为指定字段null值出现
IPage<T> selectPage(IPage<T> page, @Param("ew") Wrapper<T> queryWrapper);
IPage<Map<String, Object>> selectMapsPage(IPage<T> page, @Param("ew") Wrapper<T> queryWrapper);
复制代码
3.2 分页需要配置拦截器
@Configuration
public class MybatisPlusConfig {
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
}
复制代码
3.3 测试代码
/**
* 分页MP 分页插件
*/
@Test
public void selectPage() {
QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
queryWrapper.ge("age", 26);
//后面参数false 表示不查询总记录数
Page<User> userPage = new Page<>(1, 2, false);
/* IPage<User> iPage = userMapper.selectPage(userPage, queryWrapper);
System.out.println("总页数"+iPage.getPages());
System.out.println("总记录数"+iPage.getTotal());
List<User> records = iPage.getRecords();
records.forEach(System.out::println);
*/
IPage<Map<String, Object>> iPage = userMapper.selectMapsPage(userPage, queryWrapper);
System.out.println("总页数" + iPage.getPages());
System.out.println("总记录数" + iPage.getTotal());
List<Map<String, Object>> records = iPage.getRecords();
records.forEach(System.out::println);
}
复制代码
3.4 lambda的分页测试
- 定义UserMapper接口
IPage<User> selectUserPage(Page<User> page,@Param(Constants.WRAPPER)Wrapper<User> wrapper);
IPage<Map<String, Object>> selectUserMapperPage(Page<Map<String, Object>> page,@Param(Constants.WRAPPER)Wrapper<User> wrapper);
复制代码
- 定义UserMpper.xml文件
<select id="selectUserPage" resultType="com.mp.entity.User">
select * from user ${ew.customSqlSegment}
</select>
<select id="selectUserMapperPage" resultType="map">
select * from user ${ew.customSqlSegment}
</select>
复制代码
- 代码测试
/**
* 自定义分页方法
*/
@Test
public void selectPage01() {
LambdaQueryWrapper<User> qw = Wrappers.<User>lambdaQuery();
qw.ge(User::getAge, 18);
Page<User> page = new Page<>(1, 2);
Page<User> iPage = userMapper.selectUserPage(page, qw);
System.out.println("总页数:" + iPage.getPages());
System.out.println("总数:" + iPage.getTotal());
System.out.println("页数:" + iPage.getSize());
System.out.println("页码:" + iPage.getCurrent());
List<User> records = iPage.getRecords();
records.forEach(System.out::println);
System.out.println("---------------------");
Page page1 = new Page(1, 2);
IPage<Map<String, Object>> iPage1 = userMapper.selectUserMapperPage(page1, qw);
System.out.println("总页数:" + iPage1.getPages());
System.out.println("总数:" + iPage1.getTotal());
System.out.println("页数:" + iPage1.getSize());
System.out.println("页码:" + iPage1.getCurrent());
}
/**
* 分页不查询总数
*/
@Test
public void selectPage02() {
LambdaQueryWrapper<User> qw = Wrappers.<User>lambdaQuery();
qw.ge(User::getAge, 20);
Page<User> page = new Page<>(1, 2, false);
Page<User> iPage = userMapper.selectUserPage(page, qw);
List<User> users = iPage.getRecords();
users.forEach(System.out::println);
}
复制代码