目录
(简称 MP)是一个 MyBatis (opens new window)的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
接下来我们来看看一些常用的操作吧。
使用Wrapper(条件构造器)做CRUD操作
QueryWrapper(LambdaQueryWrapper) 和 UpdateWrapper(LambdaUpdateWrapper) 的父类 用于生成 sql 的 where 条件, entity 属性也用于生成 sql 的 where 条件 。
常用的构造条件的属性
eq、inSql、like、likeRight、likeLeft、notLike、gt、ge、lt、le、between、notBetween、in、notIn、groupBy、orderByAsc、orderByDesc、or等。
示例
eq、like:
// name属性中包含"精"的数据,并且为女性
queryWrapper.eq("sex","女").like("name", "%精%");
List<User> userList=userService.list(queryWrapper);
beteewn:
// 查询年龄在18-35之间的女性用户
queryWrapper.between("age", 18, 35);
List<User> users=userService.list(queryWrapper);
orderByDesc、gt:
// 查询年龄大于100岁的,并且按照年龄降序排列,如果年龄相同按照Id降序排列.
queryWrapper.orderByDesc("age","Id");
queryWrapper.gt("age", 100);
List<User> users=userService.list(queryWrapper);
likeLeft、lt
// 查询名称以"乔"结尾的,并且性别为女,并且age小于30岁.按照年龄降序排列.
queryWrapper.orderByDesc("age")
.eq("sex", "女")
.lt("age",30)
.likeLeft("name","乔");
List<User> users=userService.list(queryWrapper);
inSql
// 查询age < 100岁的用户,并且性别与name="孙尚香"的性别相同的的用户数据.
queryWrapper.lt("age",100)
.inSql("sex","select sex from user where name='孙尚香'");
List<User> users=userService.list(queryWrapper);
condition
// * 以name和sex不为null的数据当做where条件.
// * condition作用:
// * 判断参数是否拼接为where条件
// * 结果true,动态拼接参数
// * 结果false,参数不会动态拼接
// * 应用场景:
// * 接收前台的参数时,参数可能为null或者其他的数值类型时
// * 需要添加判断.
// * 业务需求:
// * 如果age>18时,才能查询年龄
int age = 18;
String sex="";
String name="";
queryWrapper.lambda()
.apply(true, "age > {0}", age)
.isNotNull(StringUtils.isNotEmpty(sex), User::getSex)
.isNotNull((StringUtils.isNotEmpty(name)),User::getName);
List<User> users = userService.list(queryWrapper);
当然,使用 Lambda 形式,可以不用手动填写字段名
@Test
void testCondition() {
// 模拟前端传过来的数据
String name = "银氨";
// 年龄大于等于 20 且小于等于 30 的用户
Integer ageStart = 20;
Integer ageEnd = 30;
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(StringUtils.isNotBlank(name), User::getName, name)
.ge(ageStart != null, User::getAge, ageStart)
.le(ageEnd != null, User::getAge, ageEnd);
List<User> users = userMapper.selectList(wrapper);
users.forEach(System.out::println);
}
更多用法请参考官方文档。条件构造器 | MyBatis-Plus
批量操作
批量新增
大致先看一下有哪些方法
// 新增数据 sava(T) : boolean // 伪批量插入,实际上是通过 for 循环一条一条的插入 savaBatch(Collection<T>) : boolean // 伪批量插入,int 表示批量提交数,默认为 1000 savaBatch(Collection<T>, int) : boolean // 新增或更新(单条数据) saveOrUpdate(T) : boolean // 批量新增或更新 saveOrUpdateBatch(Collection<T>) : boolean // 批量新增或更新(可指定批量提交数) saveOrUpdateBatch(Collection<T>, int) : boolean
这里只显示savaBatch和saveOrUpdateBatch的代码
User users=new User();
users.setName("小黄");
users.setAge(12);
users.setSex("男");
User users1=new User();
users1.setName("小王");
users1.setAge(13);
users1.setSex("女");
List<User> userList1 = new ArrayList<>();
userList1.add(users);
userList1.add(users1);
boolean userList=userService.saveBatch (userList1);
System.out.println(userList);
User users=new User();
users.setName("小黄");
users.setAge(12);
users.setSex("男");
User users1=new User();
users1.setName("小王");
users1.setAge(13);
users1.setSex("女");
List<User> userList1 = new ArrayList<>();
userList1.add(users);
userList1.add(users1);
boolean userList=userService.saveOrUpdateBatch(userList1);
System.out.println(userList);
当你需要执行的数据,数据库中已存在时,就执行更新操作。框架是如何判断该记录是否存在呢? 如设置了主键 ID,因为主键 ID 必须是唯一的,Mybatis Plus 会先执行查询操作,判断数据是否存在,存在即执行更新,否则,执行插入操作 。
(批量)删除
// 根据主键 ID 删除 (直接传入 ID) int deleteById(Serializable id); // 根据主键 ID 删除 (传入实体类) int deleteById(T entity); // 根据主键 ID 批量删除 int deleteBatchIds(Collection<?> idList) // 通过 Wrapper 条件构造器删除 int delete(Wrapper<T> queryWrapper); // 通过 Map 设置条件来删除 int deleteByMap(Map<String, Object> columnMap);
//根据主键 ID 批量删除
List<Integer> ids = new ArrayList<>();
ids.add(57);
ids.add(58);
int re=userDao.deleteBatchIds(ids);
System.out.println("删除了"+re+"数据");
// 通过wrapper构造器进行删除
int id=90;
QueryWrapper<User> userQueryWrapper=new QueryWrapper<>();
userQueryWrapper.eq("id", id);
int re1=userDao.delete(userQueryWrapper);
System.out.println("删除了"+re1+"数据");
// Lambda 表达式形式
int id=91;
QueryWrapper<User> userQueryWrapper=new QueryWrapper<>();
userQueryWrapper.lambda()
.eq(User::getId, id);
int re2=userDao.delete(userQueryWrapper);
通过map来进行删除
// 通过 Map 设置条件来删除
Map<String, Object> columnMap = new HashMap<>();
columnMap.put("name", "小黄");
columnMap.put("sex", "女");
int count = userDao.deleteByMap(columnMap);
System.out.println("受影响的行数:" + count);
当然,以上是mapper层的方法,service层还有更多更丰富的方法,这里挑了几个常用的方法
// 根据 entity 条件,删除记录
boolean remove(Wrapper<T> queryWrapper);
// 根据 ID 删除
boolean removeById(Serializable id);
// 根据 columnMap 条件,删除记录
boolean removeByMap(Map<String, Object> columnMap);
// 删除(根据ID 批量删除)
boolean removeByIds(Collection<? extends Serializable> idList);
(批量)更新
mapper层的方法这里不做介绍,以下是service层的方法
// 根据 ID 来更新,entity 用于设置 ID 以及其他更新条件
boolean updateById(T entity);
// wrapper 用于设置更新数据以及条件
boolean update(Wrapper<T> updateWrapper);
// entity 用于设置更新的数据,wrapper 用于组装更新条件
boolean update(T entity, Wrapper<T> updateWrapper);
// 批量更新
boolean updateBatchById(Collection<T> entityList);
// 批量更新,可手动设置批量提交阀值
boolean updateBatchById(Collection<T> entityList, int batchSize);
// 保存或者更新
boolean saveOrUpdate(T entity);
// 批量修改
QueryWrapper<User> userQueryWrapper=new QueryWrapper<>();
List<User> ids = new ArrayList<>();
User user1=new User();
user1.setSex("男");
user1.setName("小乔乔");
user1.setId(11);
user1.setAge(19);
User user2=new User();
user2.setSex("男");
user2.setName("貂蝉1");
user2.setId(12);
user2.setAge(19);
ids.add(user1);
ids.add(user2);
boolean re=userService.updateBatchById(ids);
通过构造器编辑:
// 使用构造器修改
UpdateWrapper<User> userQueryWrapper=new UpdateWrapper<>();
userQueryWrapper.eq("id",2);
userQueryWrapper.set("name", "小游");
boolean re=userService.update(userQueryWrapper);
此处使用UpdateWrapper构造器中的set方法比较方便,当然也可以用QueryWrapper
QueryWrapper<User> userQueryWrapper=new QueryWrapper<>();
User user=new User();
user.setAge(1);
user.setName("银氨");
userQueryWrapper.eq("id",1);
boolean re=userService.update(user, userQueryWrapper);
(批量)查询
mapper层封装:
//通过 Wrapper 组装查询条件,查询一条记录
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
// 仅查询 id, name 字段
queryWrapper.select("id", "name");
// where id = 1
queryWrapper.eq("id", 1L);
// 实际执行 SQL : SELECT id,name,age,gender FROM user WHERE (id = 1)
User user = userDao.selectOne(queryWrapper);
注意: selectOne
方法期望仅返回一条数据,若实际查询到多条数据,会主动抛出异常
//查询(根据ID 批量查询)
// 实际执行 SQL : SELECT id,name,age,gender FROM user WHERE id IN ( 1 , 2 , 3 )
List<User> users = userDao.selectBatchIds(Arrays.asList(1, 2, 3));
//通过 Wrapper 组装查询条件,查询全部记录
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
// 仅查询 id, name 字段
queryWrapper.select("id", "name");
// where age = 30
queryWrapper.eq("age", 30);
// 实际执行 SQL : SELECT id,name FROM user WHERE (age = 30)
List<User> users = userDao.selectList(queryWrapper);
//查询(根据 columnMap 来设置条件)
// 通过 map 来设置查询条件
Map<String, Object> columnMap = new HashMap<>();
columnMap.put("name", "银氨");
columnMap.put("age", 30);
// 实际执行 SQL : SELECT id,name,age,gender FROM user WHERE name = '银氨' AND age = 30
List<User> users = userDao.selectByMap(columnMap);
//根据 Wrapper 组装查询条件,查询全部记录,并以 map 的形式返回
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
// 仅查询 id, name 字段
queryWrapper.select("id", "name");
// where age = 30
queryWrapper.eq("age", 30);
// 实际执行 SQL : SELECT id,name FROM user WHERE (age = 30)
List<Map<String,Object>> users = userDao.selectMaps(queryWrapper);
//根据 Wrapper 条件,查询总记录数
// 组装查询条件
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("name", "银氨").eq("age", 30);
// 实际执行 SQL : SELECT COUNT( * ) FROM user WHERE (name = '银氨' AND age = 30)
long count = userDao.selectCount(queryWrapper);
System.out.println("总记录数:" + count);
Service 层封装的查询方法注意分为 4 块
-
getXXX
: get 开头的方法; -
listXXX
: list 开头的方法,用于查询多条数据; -
pageXXX
: page 开头的方法,用于分页查询; -
count
: 用于查询总记录数;
get 相关方法
get
开头的相关方法用于查询一条记录,方法如下:
// 根据 ID 查询 T getById(Serializable id); // 根据 Wrapper,查询一条记录。如果结果集是多个会抛出异常 T getOne(Wrapper<T> queryWrapper); // 根据 Wrapper,查询一条记录 T getOne(Wrapper<T> queryWrapper, boolean throwEx); // 根据 Wrapper,查询一条记录,以 map 的形式返回数据 Map<String, Object> getMap(Wrapper<T> queryWrapper); // 根据 Wrapper,查询一条记录 <V> V getObj(Wrapper<T> queryWrapper, Function<? super Object, V> mapper);
这里挑两个具有代表性的方法:
-
根据 ID 查询
// 实际执行 SQL : SELECT id,name,age,gender FROM user WHERE id=1
User user = userService.getById(1);
-
根据 Wrapper,查询一条记录。如果结果集是多个会抛出异常:
// 组装查询条件
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("id", 1).eq("name", "银氨");
// 实际执行 SQL : SELECT id,name,age,gender FROM user WHERE (id = 1 AND name = '银氨')
User user = userService.getOne(queryWrapper);
list 相关方法
list
开头的相关方法用于查询多条记录,方法如下:
// 查询所有 List<T> list(); // 查询列表 List<T> list(Wrapper<T> queryWrapper); // 查询(根据ID 批量查询) Collection<T> listByIds(Collection<? extends Serializable> idList); // 查询(根据 columnMap 条件) Collection<T> listByMap(Map<String, Object> columnMap); // 查询所有列表, 以 map 的形式返回 List<Map<String, Object>> listMaps(); // 查询列表 List<Map<String, Object>> listMaps(Wrapper<T> queryWrapper); // 查询全部记录 List<Object> listObjs(); // 查询全部记录 <V> List<V> listObjs(Function<? super Object, V> mapper); // 根据 Wrapper 条件,查询全部记录 List<Object> listObjs(Wrapper<T> queryWrapper); // 根据 Wrapper 条件,查询全部记录 <V> List<V> listObjs(Wrapper<T> queryWrapper, Function<? super Object, V> mapper);
这里挑几个具有代表性的方法:
// 组装查询条件
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
// where name = '犬小哈' and age >= 20
queryWrapper.eq("name", "银氨").ge("age", 1);
// 实际执行 SQL : SELECT id,name,age,gender FROM user WHERE (name = '银氨' AND age >= 20)
List<User> users = userService.list(queryWrapper);
// 实际执行 SQL : SELECT id,name,age,gender FROM user WHERE id IN ( 1 , 2 , 3 )
List<User> users = userService.listByIds(Arrays.asList(1, 2, 3));
Map<String , Object> columnMap = new HashMap<>();
columnMap.put("name", "银氨");
columnMap.put("age", 30);
// 实际执行 SQL : SELECT id,name,age,gender FROM user WHERE name = '银氨' AND age = 30
List<User> users = userService.listByMap(columnMap);
page分页将放到之后博客部分进行说明
count 查询总记录数
查询总记录数 count
相关方法如下:
// 查询总记录数(不带查询条件) count(); // 查询总记录数(可以带查询条件) count(Wrapper<T>)
// 组装查询条件
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
// where age = 30
queryWrapper.eq("age", 30);
// 实际执行 SQL : SELECT COUNT( * ) FROM user WHERE (age = 30)
long count = userService.count(queryWrapper);
System.out.println("总记录数:" + count);