文章目录
MyBatis高级操作— — Wrapper接口
1)Wrapper接口
1 根据多个条件查询用户
/**
* 查询姓名包含fa 年龄大于20 同时email不为空
*/
@Test
void testQueryAllUser(){
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.like("name","fa")
.gt("age",20)
.isNotNull("email");
List<User> users = userMapper.selectList(wrapper);
users.forEach(System.out::println);
}
2 根据条件排序
/**
* 根据年龄升序排序,年龄相同的情况下根据id降序排列
*/
@Test
void queryAllUserByOrder(){
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.orderByAsc("age")
.orderByDesc("id");
List<User> users = userMapper.selectList(wrapper);
System.out.println(users);
}
3 根据条件删除
/**
* 删除年龄小于18的记录
*/
@Test
void deleteUser(){
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.lt("age", 16);
int i = userMapper.delete(wrapper);
System.out.println(i);
}
4 组合查询
/**
* 组合查询
*
* 查询姓名中包含fa且年龄大于20 或邮箱地址为空的记录
*/
@Test
void queryAllUser1(){
QueryWrapper<User> wrapper = new QueryWrapper<>();
// wrapper.like("name", "fa")
// .gt("age", 20)
// .or()
// .isNull("email");
// List<User> users = userMapper.selectList(wrapper);
// System.out.println(users);
wrapper.and((item) -> {
item.like("name", "fa")
.gt("age", 20);
}).or((item) -> {
item.isNull("email");
});
List<User> users = userMapper.selectList(wrapper);
System.out.println(users);
}
5 查询指定列
/**
* 查询指定列
*
* 查询年龄大于20的用户姓名与年龄
*/
@Test
void queryAllUser2(){
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.gt("age", 20).select("age", "name");
List<Map<String, Object>> mapList = userMapper.selectMaps(wrapper);
System.out.println(mapList);
}
6 子查询(inSql)
/**
* 子查询
* select * from t_user where id in (select id from t_user where id < 6)
*/
@Test
void queryAllUser3(){
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.inSql("id", "select id from user where id < 6");
List<User> users = userMapper.selectList(wrapper);
System.out.println(users);
}
7 更新操作
/**
* 更新操作
*/
@Test
void updateUser(){
UpdateWrapper<User> wrapper = new UpdateWrapper<>();
wrapper.set("age", 25)
.set("email", "xx@qq.com")
.eq("name", "curry");
int update = userMapper.update(null, wrapper);
System.out.println(update);
}
8 动态SQL
/**
* 动态sql
*/
@Test
void queryAllUser4(){
String name = "curry";
Integer age = null;
String email = null;
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq(StringUtils.isNotBlank(name), "name", name)
.eq(age != null && age > 0, "age", age)
.eq(StringUtils.isNotBlank(email), "email", email);
List<User> users = userMapper.selectList(wrapper);
users.forEach(System.out::println);
}
2)分页插件的使用
①创建配置类
MyBatisPlus内部集成了分页插件,我们不需要单独引入,只需要添加对应的配置类即可
@Configuration
@MapperScan("com.zi.mpdemo01.mapper")
public class MyBatisPlusConfig {
/**
* 新的分页插件,一缓和二缓遵循mybatis的规则,
* 需要设置 MybatisConfiguration#useDeprecatedExecutor = false 避免缓存出现问题(该属性会在旧插件移除后一同移除)
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}
②在测试类中直接创建Page对象并使用
/**
* 测试分页
*/
@Test
void queryAllUserPage(){
Page<User> page = new Page<>(1, 5);
Page<User> userPage = userMapper.selectPage(page, null);
List<User> records = userPage.getRecords();
records.forEach(System.out::println);
System.out.println("userPage.getPages() = " + userPage.getPages());
System.out.println("userPage.getTotal() = " + userPage.getTotal());
System.out.println("userPage.getPages() = " + userPage.getPages());
System.out.println("userPage.hasPrevious() = " + userPage.hasPrevious());
System.out.println("userPage.hasNext() = " + userPage.hasNext());
}
3)代码生成器
①pom中导入freemark依赖(后面要使用该模板)和代码生成器依赖
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.5.2</version>
</dependency>
②创建代码生成器类
package com.zi.mpdemo01.config;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import java.util.Collections;
/**
* 代码生成器
*/
public class MyFastAutoGenerator {
public static void main(String[] args) {
FastAutoGenerator.create("jdbc:mysql://localhost:3306/mp?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true"
, "root", "123456")
.globalConfig(builder -> {
builder.author("zi") // 设置作者
//.enableSwagger() // 开启 swagger 模式
.fileOverride() // 覆盖已生成文件
.outputDir("D://MyBatisPlus"); // 指定输出目录
})
.packageConfig(builder -> {
builder.parent("com.zi.mp") // 设置父包名
.moduleName("system") // 设置父包模块名
.pathInfo(Collections.singletonMap(OutputFile.xml, "D://")); // 设置mapperXml生成路径
})
.strategyConfig(builder -> {
builder.addInclude("t_user") // 设置需要生成的表名
.addTablePrefix("t_", "c_"); // 设置过滤表前缀
})
.templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板,默认的是Velocity引擎模板
.execute();
}
}
③最终运行结果:
帮助我们生成了部分包和部分类
- 此处推荐工作中必不可少的一个Idea插件MyBatisX,它可以帮我们快速生成domain类,mapper映射文件,service层等
MyBatisPlus相关bug:
①Error querying database. Cause: java.lang.UnsupportedOperationException
我的查询结果是list,因此想直接将mapper文件中的resultType写为java.util.List;结果发现执行之后报如上错误。
- resultType字段类型映射错了,如果我们想返回list,应该在resultType上写成查询结果集中list对应的类型,如:返回结果是List<Integer>,那么我们应该写为:resultType=java.lang.Integer
- 参数名没映射上,例如:接口中的参数字段名为songId,但是xml中的SQL写成了数据库中的song_id
推荐这个时候开启SQL打印,方便我们排查问题
基本类型 :resultType=基本类型
List类型: resultType=List中元素的类型