SpringBoot - MyBatis-Plus使用详解4(Mapper的CRUD接口1:基本查询)
MyBatis-Plus 内置通用 Mapper,我们仅需要继承 BaseMapper,通过少量配置即可实现单表大部分 CRUD 操作,同时其更有强大的条件构造器,满足各类使用需求。
四、Mapper 的 CRUD 接口1:基本查询
1,准备工作
(1)假设我们有如下用户信息表 user_info:
(2)首先创建对应的实体类 UserInfo:
@Data public class UserInfo { private Integer id; private String userName; private String passWord; private Integer age; }
(3)接着只需要创建 UserInfoMapper 接口,并继承 BaseMapper 接口,就可以使用各种 CRUD 方法了。
public interface UserInfoMapper extends BaseMapper<UserInfo> { }
2,selectById(根据 id 查询一条记录)
@RestController public class HelloController { @Autowired UserInfoMapper userInfoMapper; @RequestMapping("/test") public void test(){ // 根据id查询数据 UserInfo user = userInfoMapper.selectById(2); System.out.println(user); } }
3,selectOne(使用查询构造器,查询一条记录):
注意:是数据库中符合传入条件的记录有多条,那就不能用这个方法,会报错。
// 查询条件:名字中包含'ha'并且年龄小于40 QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>(); queryWrapper.like("user_name","ha").lt("age",40); // 开始查询 UserInfo user = userInfoMapper.selectOne(queryWrapper); System.out.println(user);
(2)除了使用 QueryWrapper 外,我们还可以 lambda 条件构造器做同样的事。
提示:lambda 条件构造器好处是由于它是通过调用实体类中的方法,如果方法名称写错,会直接报错,从而提前纠错。不像 QueryWrapper 是通过自己写表中相应的属性来构造 where 条件,容易发生拼写错误,等到运行时才发现。
// 查询条件:名字中包含'ha'并且年龄小于40 LambdaQueryWrapper<UserInfo> queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.like(UserInfo::getUserName,"ha").lt(UserInfo::getAge,40); // 开始查询 UserInfo user = userInfoMapper.selectOne(queryWrapper); System.out.println(user);
- MyBatis-Plus 提供了 4 种方式创建 lambda 条件构造器,前三种分别如下:
LambdaQueryWrapper<UserInfo> lqw1 = new QueryWrapper<UserInfo>().lambda(); LambdaQueryWrapper<UserInfo> lqw2= new LambdaQueryWrapper<>(); LambdaQueryWrapper<UserInfo> lqw3 = Wrappers.lambdaQuery();
- 无论是之前的 lambda 构造器还是 queryWrapper,每次编写完条件构造语句后都要将对象传递给 mapper 的 selectOne 方法,比较麻烦,MyBatisPlus 提供了第四种函数式编程方式,不用每次都传。
UserInfo userInfo = new LambdaQueryChainWrapper<>(userInfoMapper) .like(UserInfo::getUserName,"ha") .lt(UserInfo::getAge,40) .one();
(3)我们也可以将对象直接以构造参数的形式传递给 QueryWrapper,MyBatisPlus 会自动根据实体对象中的属性自动构建相应查询的 SQL 语句:
// 查询条件:名字为'hangge'并且年龄为22 UserInfo userInfo = new UserInfo(); userInfo.setUserName("hangge"); userInfo.setAge(22); QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>(userInfo); // 开始查询 UserInfo user = userInfoMapper.selectOne(queryWrapper); System.out.println(user);
- 如果想通过对象中某些属性进行模糊查询,我们可以在跟数据库表对应的实体类中相应的属性标注相应注解即可。比如我们想通过姓名进行模糊查询用户:
@Data public class UserInfo { private Integer id; @TableField(condition = SqlCondition.LIKE) private String userName; private String passWord; private Integer age; }
- 下面我们查询名字包含 ha 的用户,可以发现生成的 sql 语句确实使用 like 进行模糊查询:
// 查询条件:名字包含为'ha' UserInfo userInfo = new UserInfo(); userInfo.setUserName("ha"); QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>(userInfo); // 开始查询 UserInfo user = userInfoMapper.selectOne(queryWrapper);
4,selectBatchIds(根据 ID 批量查询,返回一个 List)
List<Integer> ids = new ArrayList<>(); ids.add(1); ids.add(2); ids.add(3); List<UserInfo> users = userInfoMapper.selectBatchIds(ids); System.out.println(users);
5,selectByMap(通过 Map 封装的条件查询,返回一个 List)
注意:map 写的是数据表中的列名,而非实体类的属性名。比如属性名为 userName,数据表中字段为 user_name,这里应该写的是 user_name。
Map<String,Object> columnMap = new HashMap<>(); columnMap.put("user_name", "hangge"); columnMap.put("age", 22); List<UserInfo> users = userInfoMapper.selectByMap(columnMap); System.out.println(users);
6,selectList(使用查询构造器,返回一个 List):
注意:selectList 使用与 selectOne 类似,不同的是当数据库中符合传入的条件的记录有多条,使用 selectOne 会报错。这时就要使用 selectList。
(1)查询前我们需要先创建相应的 QueryWrapper,通过自己写表中相应的属性来构造 where 条件:
// 查询条件:名字中包含'ha'并且年龄小于40 QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>(); queryWrapper.like("user_name","ha").lt("age",40); // 开始查询 List<UserInfo> users = userInfoMapper.selectList(queryWrapper); System.out.println(user);
(2)除了使用 QueryWrapper 外,我们还可以 lambda 条件构造器做同样的事。
提示:lambda 条件构造器好处是由于它是通过调用实体类中的方法,如果方法名称写错,会直接报错,从而提前纠错。不像 QueryWrapper 是通过自己写表中相应的属性来构造 where 条件,容易发生拼写错误,等到运行时才会发现。
// 查询条件:名字中包含'ha'并且年龄小于40 LambdaQueryWrapper<UserInfo> queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.like(UserInfo::getUserName,"ha").lt(UserInfo::getAge,40); // 开始查询 List<UserInfo> users = userInfoMapper.selectList(queryWrapper); System.out.println(users);
- MyBatis-Plus 提供了 4 种方式创建 lambda 条件构造器,前三种分别如下:
LambdaQueryWrapper<UserInfo> lqw1 = new QueryWrapper<UserInfo>().lambda(); LambdaQueryWrapper<UserInfo> lqw2= new LambdaQueryWrapper<>(); LambdaQueryWrapper<UserInfo> lqw3 = Wrappers.lambdaQuery();
- 无论是之前的 lambda 构造器还是 queryWrapper,每次编写完条件构造语句后都要将对象传递给 mapper 的 selectList 方法,比较麻烦,MyBatisPlus 提供了第四种函数式编程方式,不用每次都传。
List<UserInfo> userInfos = new LambdaQueryChainWrapper<>(userInfoMapper) .like(UserInfo::getUserName,"ha") .lt(UserInfo::getAge,40) .list();
(3)我们也可以将对象直接以构造参数的形式传递给 QueryWrapper,MyBatisPlus 会自动根据实体对象中的属性自动构建相应查询的 SQL 语句:
// 查询条件:名字为'hangge'并且年龄为22 UserInfo userInfo = new UserInfo(); userInfo.setUserName("hangge"); userInfo.setAge(22); QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>(userInfo); // 开始查询 List<UserInfo> users = userInfoMapper.selectList(queryWrapper); System.out.println(users);
- 如果想通过对象中某些属性进行模糊查询,我们可以在跟数据库表对应的实体类中相应的属性标注相应注解即可。比如我们想通过姓名进行模糊查询用户:
@Data public class UserInfo { private Integer id; @TableField(condition = SqlCondition.LIKE) private String userName; private String passWord; private Integer age; }
- 下面我们查询名字包含 ha 的用户,可以发现生成的 sql 语句确实使用 like 进行模糊查询:
// 查询条件:名字包含'ha' UserInfo userInfo = new UserInfo(); userInfo.setUserName("ha"); QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>(userInfo); // 开始查询 List<UserInfo> users = userInfoMapper.selectList(queryWrapper);
7,selectMaps(使用查询构造器,返回一个 List<map>):
selectMaps 的用法和上面的 selectList 很像,都是传入一个查询构造器进行查询,然后返回一个 List。不同在于 selectMaps 返回的 List 里面是 Map:注意:
Map 里的 key 为表字段名,而不是对应实体类的属性名。
UserInfo userInfo = new UserInfo(); userInfo.setUserName("ha"); QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>(userInfo); // 开始查询 List<Map<String, Object>> users = userInfoMapper.selectMaps(queryWrapper); System.out.println(users);
8,selectObjs(使用查询构造器,返回一个 List<object>):
selectObjs 的用法和前面的 selectList 很像,都是传入一个查询构造器进行查询,然后返回一个 List。不同在于 selectObjs 返回的 List 里面只有返回的第一个字段值:UserInfo userInfo = new UserInfo(); userInfo.setAge(22); QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>(userInfo); // 开始查询 List<Object> users = userInfoMapper.selectObjs(queryWrapper); System.out.println(users);
9,selectCount(使用查询构造器,查询总记录数):
selectCount 的用法和前面的 selectList 很像,都是传入一个查询构造器进行查询,不同的是 selectCount 返回的是一个 Integer 值(符合条件的记录数):
UserInfo userInfo = new UserInfo(); userInfo.setAge(22); QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>(userInfo); // 开始查询 Integer count = userInfoMapper.selectCount(queryWrapper); System.out.println(count);
附:添加自己的数据库操作
如果觉得默认提供的 CRUD 接口不能满足需求,我们可以添加自己的 SQL 语句,具体有如下两种方案。
1,注解方式(Mapper.java)
我们可以直接在自定义方法上使用 @Select 设置对应的 sql 语句:public interface UserInfoMapper extends BaseMapper<UserInfo> { @Select("select * from user_info WHERE age > #{age}") List<UserInfo> getAll(Integer age); }
2,XML 形式(Mapper.xml)
(1)首先在 mapper.xml 中添加自定义的 sql 语句:<?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.example.demo.mapper.UserInfoMapper"> <select id="getAll" resultType="com.example.demo.model.UserInfo"> SELECT * FROM user_info WHERE age > #{age} </select> </mapper>
(2)然后在 mapper.java 中添加相应的接口方法即可:
public interface UserInfoMapper extends BaseMapper<UserInfo> { List<UserInfo> getAll(Integer age); }