上一篇博客中Springboot整合MyBatis-Plus入门中已经介绍了MyBatis-Plus的基本入门使用,现在我来介绍一下MP的一些核心查询方法
1.根据主键查询
@Test //根据一个id进行查询
public void selectById() {
User user= userMapper.selectById(1094590409767661570L);
System.out.println(user);
}
@Test //传入主键集合进行批量查询
public void selectByIds() {
List<Long> idList = Arrays.asList(1094590409767661570L, 1234808736028094465L);
List<User> userList = userMapper.selectBatchIds(idList);
userList.forEach(System.out::println);
}
2.根据表中其他字段进行查询
@Test
public void SelectByMap() {
Map<String, Object> map = new HashMap<>();
//增加查询条件,字段需要与数据库表中的字段一致
map.put("age", 25);
map.put("manager_id", 1087982257332887553L);
List<User> userList = userMapper.selectByMap(map);
userList.forEach(System.out::println);
}
- 可以通过创建一个map,对其中设置查询条件,需要注意的是,map中的key必须和数据表中的字段完全相同,而不是和实体类中的属性相同。
3.根据条件构造器进行查询
//1.查找姓王或者年龄大于等于25的用户,通过年龄升序排列,id降序排列
@Test
public void selectByWrapper1() {
QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
userQueryWrapper.likeRight("name", "王").or().ge("age", "25")
.orderByAsc("age").orderByDesc("id");
List<User> userList = userMapper.selectList(userQueryWrapper);
userList.forEach(System.out::println);
}
- 创建一个QueryWrapper对象,其中提供了很多的查询方法,用其设置查询条件,然后使用userMapper调用selectList方法即可以完成基本的条件查询
下面再举两个例子来说明
//2.创建日期为2019年2月14日并且直属上级为名字为王姓
//date_format(create_time,'%Y-%m-%d')='2019-02-14' and manager_id in (select id from user where name like '王%')
@Test
public void selectByWrapper2() {
QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
userQueryWrapper.apply("date_format(create_time,'%Y-%m-%d')={0}", "2019-02-14")
.inSql("manager_id", "select id from user where name like '王%'");
List<User> userList = userMapper.selectList(userQueryWrapper);
userList.forEach(System.out::println);
}
//3、名字为王姓并且(年龄小于40或邮箱不为空)
// name like '王%' and (age<40 or email is not null)
@Test
public void selectByWrapper3() {
QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
userQueryWrapper.likeRight("name", "王").and(qw -> qw.lt("age", "40").or().isNotNull("email"));
List<User> userList = userMapper.selectList(userQueryWrapper);
userList.forEach(System.out::println);
}
- MP中支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
4.排除表中字段的查询方法
有时候我们查询的时候不需要查询表中所有字段,所以我们再查询的时候可以排除表中某些字段进行查询
//4.排除表中字段的查询方法
@Test
public void selectByWrapper4() {
QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
userQueryWrapper.select(User.class, i -> !i.getColumn().equals("create_time") && !i.getColumn().equals("name"));
List<User> userList = userMapper.selectList(userQueryWrapper);
userList.forEach(System.out::println);
}
5.动态条件查询
//5.动态条件查询
@Test
public void selectByWrapperCondition() {
QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
String name = "王";
String email = null;
//先判断属性是否为空,如果condition为false则不会将条件添加到sql中
userQueryWrapper.like(StringUtils.isNotBlank(name), "name", name).eq(StringUtils.isNotBlank(email), "email", email);
List<User> userList = userMapper.selectList(userQueryWrapper);
userList.forEach(System.out::println);
}
- 调用queryWrapper中带有condition参数的方法,就可以先设置条件,如果返回true,则将该条件插入到sql中,反之则不会,这里我判断了是否为空,为空则不会将该条件添加到sql中。
6.实体作为条件构造器的参数进行查询
//6.实体作为条件构造器的参数进行查询
@Test
public void selectByWrapperEntity() {
User user = new User();
user.setName("王");
user.setAge(40);
QueryWrapper<User> userQueryWrapper = new QueryWrapper<>(user);
List<User> userList = userMapper.selectList(userQueryWrapper);
userList.forEach(System.out::println);
}
- 我们可以先创建一个实体,在实体中设置属性,再将该实体作为参数传入到QueryWrapper的构造方法中,MP就会根据实体中有的属性作为查询条件进行查询,默认是全equal的方式进行匹配查询。
- 我们还可以再实体类中设置查询的条件,如下
@TableField(condition = "%s<#{%s}")
private int age;
@TableField(condition = SqlCondition.LIKE_RIGHT)
private String name;
通过@TableField注解中的condition属性可以设置匹配的条件,查看SqlCondition源码可以知道MP提供了一些条件的设置,我在例子中是设置了name作为开头匹配进行查询,也就是like name%这样的形式。我们也可以根据源码的匹配格式自定义条件,如age,定义了小于条件。
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package com.baomidou.mybatisplus.annotation;
public class SqlCondition {
public static final String EQUAL = "%s=#{%s}";
public static final String NOT_EQUAL = "%s<>#{%s}";
public static final String LIKE = "%s LIKE CONCAT('%%',#{%s},'%%')";
public static final String LIKE_LEFT = "%s LIKE CONCAT('%%',#{%s})";
public static final String LIKE_RIGHT = "%s LIKE CONCAT(#{%s},'%%')";
public SqlCondition() {
}
}
7.返回泛型为map的查询
@Test
public void selectByWrapperMaps() {
QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
userQueryWrapper.le("age", "40").select("id", "name");
List<Map<String, Object>> userList = userMapper.selectMaps(userQueryWrapper);
userList.forEach(System.out::println);
}
- 使用selectMaps就可以返回一个泛型为map的集合,这样就避免了我们有时会查询到null的属性,上面的查询都是返回一个泛型为User实体的集合,我们可以根据自己实际需求,来确定你需要使用的查询方法。
8.查询记录数
@Test
public void selectByWrapperCount() {
QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
userQueryWrapper.le("age", "40");
Integer count = userMapper.selectCount(userQueryWrapper);
System.out.println(count);
}
这个就不需要多说了,就是统计查询到的数据的条数,可以看一下打印出来的sql语句
Preparing: SELECT COUNT( 1 ) FROM user WHERE (age <= ?)
//9.自定义sql查询
package com.czc.MP.mapper;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.czc.MP.Entity.User;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.util.List;
public interface UserMapper extends BaseMapper<User> {
@Select("select * from user ${ew.customSqlSegment}")
List<User> getList(@Param(Constants.WRAPPER) Wrapper wrapper);
}
//9.自定义sql查询
@Test
public void selectByWrapperCustomer() {
QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
userQueryWrapper.le("age", "40");
List<User> userList = userMapper.getList(userQueryWrapper);
userList.forEach(System.out::println);
}
- 我们已经知道,MP并没有改变mybatis的通过编写sql语句进行查询的方式,所以我们也可以通过自定义sql进行查询,有两种方式,一种是通过在userMapper接口中注解的方式,还有一种是通过xml的方式,我这里是通过注解的方式,我们需要在sql语句后加入${ew.customSqlSegment},并且在方法参数上加上@Param(Constants.WRAPPER) Wrapper wrapper这么一个注解,这样就可以实现sql加MP的结合使用。*
9.分页查询
- MP中内置了分页插件,首先我们需要向容器中注入一个分页拦截器,可以直接在启动类下注入,可以进行一些初始化操作。
@Bean
public PaginationInterceptor paginationInterceptor() {
PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
// 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求 默认false
// paginationInterceptor.setOverflow(false);
// 设置最大单页限制数量,默认 500 条,-1 不受限制
// paginationInterceptor.setLimit(500);
// 开启 count 的 join 优化,只针对部分 left join
paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true));
return paginationInterceptor;
}
//9.分页查询
@Test
public void selectByWrapperPage() {
QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
userQueryWrapper.le("age", "40");
//创建一个page对象,传入当前页数和一页查询的记录数
Page<User> page = new Page<>(1,3);
//返回一个Ipage对象,里面封装了很多的分页方法
IPage<User> pages = userMapper.selectPage(page, userQueryWrapper);
//获取总页数
System.out.println(pages.getPages());
//获取当前页的记录集合
List<User> userList = pages.getRecords();
userList.forEach(System.out::println);
}
- 代码注释中已经解释很清楚了,这里我就不再进行阐述了。
MP中主要的查询方法就差不多这么多了,对于其他的新增,删除,修改等方法,都比较简单,如果有兴趣想详细了解学习的朋友,我推荐可以去参考MyBatis-Plus的官方文档,里面有非常详细的介绍。MyBatis-Plus官方中文文档