MyBatisPlus的CRUD接口
半塘 2024/1/14 MyBatisPlus框架
MyBatisPlus提供了很多CRUD接口,可以直接使用这些接口来操作数据库。而不用像MyBatis那样写大量的XML文件及SQL语句。本章将介绍MyBatisPlus的CRUD接口的使用方法。
# 1、Mapper CRUD 接口
我们在入门案例中,用的就是该方式进行CRUD操作。主要关键是继承BaseMapper<T>
,其中T是实体类。
# 1.1、使用案例
- Mapper层继承BaseMapper接口
@Mapper
public interface StudentMapper extends BaseMapper<StudentPO> {
}
1
2
3
4
2
3
4
- 测试使用
@SpringBootTest
@Slf4j
public class TestController {
@Autowired
private StudentMapper studentMapper;
@Test
public void testQueryStudentList(){
List<StudentPO> studentList = studentMapper.selectList(null);
log.info("studentList========>"+studentList);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
BaseMapper接口中定义了足够我们CRUD的操作方法:Insert、Delete、Update、Select。
# 1.2、Insert
// 插入一条记录
int insert(T entity);
1
2
2
案例
@SpringBootTest
public class TestController {
@Autowired
private StudentMapper studentMapper;
@Test
public void testInsert(){
studentMapper.insert(new StudentPO(null,"ls",20,"", SexEnum.WOMAN,1,null));
}
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# 1.3、Delete
// 根据 entity 条件,删除记录
int delete(@Param(Constants.WRAPPER) Wrapper<T> wrapper);
// 删除(根据ID 批量删除)
int deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);
// 根据 ID 删除
int deleteById(Serializable id);
// 根据 columnMap 条件,删除记录
int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
案例
@Test
public void testDelete(){
// 根据 entity 条件,删除记录
Wrapper<StudentPO> wrapper = new QueryWrapper<StudentPO>().eq("name", "ls");
studentMapper.delete(wrapper);
// 删除(根据ID 批量删除)
List<String> ids = new ArrayList<>();
ids.add("1");
ids.add("2");
studentMapper.deleteBatchIds(ids);
// 根据 ID 删除
studentMapper.deleteById("1746460971291541505");
// 根据 columnMap 条件,删除记录
Map<String, Object> map = new HashMap<>();
map.put("name","Tom");
map.put("id",3);
studentMapper.deleteByMap(map);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 1.4、Update
// 根据 whereWrapper 条件,更新记录
int update(@Param(Constants.ENTITY) T updateEntity, @Param(Constants.WRAPPER) Wrapper<T> whereWrapper);
// 根据 ID 修改
int updateById(@Param(Constants.ENTITY) T entity);
1
2
3
4
2
3
4
案例
@Test
public void testUpdate(){
StudentPO studentPO = new StudentPO();
studentPO.setId(3L);
studentPO.setName("sss");
studentMapper.updateById(studentPO);
studentMapper.update(studentPO,new QueryWrapper<StudentPO>().eq("id",4));
}
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# 1.5、Select
// 根据 ID 查询
T selectById(Serializable id);
// 根据 entity 条件,查询一条记录
T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 查询(根据ID 批量查询)
List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);
// 根据 entity 条件,查询全部记录
List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 查询(根据 columnMap 条件)
List<T> selectByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
// 根据 Wrapper 条件,查询全部记录
List<Map<String, Object>> selectMaps(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 根据 Wrapper 条件,查询全部记录。注意: 只返回第一个字段的值
List<Object> selectObjs(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 根据 entity 条件,查询全部记录(并翻页)
IPage<T> selectPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 根据 Wrapper 条件,查询全部记录(并翻页)
IPage<Map<String, Object>> selectMapsPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 根据 Wrapper 条件,查询总记录数
Integer selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 2、Service CRUD 接口
Service CRUD 封装IService (opens new window)接口,进一步封装 CRUD 采用 get 查询单行 remove 删除 list 查询集合 page 分页 前缀命名方式区分 Mapper 层避免混淆。
# 2.1、使用案例
- 新增StudentService接口及实现类
接口继承IService<T>
,泛型为StudentPO
public interface StudentService extends IService<StudentPO> {
}
1
2
2
实现类继承ServiceImpl,并指定Mapper和实体类
@Service
public class StudentServiceImpl extends ServiceImpl<StudentMapper, StudentPO> implements StudentService {
}
1
2
3
4
2
3
4
- 测试使用
注入StudentServiceImpl,并调用Service CRUD 接口中的方法,用法和Mapper CRUD 接口中的差不多。
@SpringBootTest
@Slf4j
public class TestController {
@Autowired
private StudentServiceImpl studentService;
@Test
public void testQuery(){
List<StudentPO> list = studentService.list();
log.info("studentList========>"+list);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# 2.2、Save
// 插入一条记录(选择字段,策略插入)
boolean save(T entity);
// 插入(批量)
boolean saveBatch(Collection<T> entityList);
// 插入(批量)
boolean saveBatch(Collection<T> entityList, int batchSize);
1
2
3
4
5
6
2
3
4
5
6
# 2.3、SaveOrUpdate
// TableId 注解存在更新记录,否插入一条记录
boolean saveOrUpdate(T entity);
// 根据updateWrapper尝试更新,否继续执行saveOrUpdate(T)方法
boolean saveOrUpdate(T entity, Wrapper<T> updateWrapper);
// 批量修改插入
boolean saveOrUpdateBatch(Collection<T> entityList);
// 批量修改插入
boolean saveOrUpdateBatch(Collection<T> entityList, int batchSize);
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 2.4、Remove
// 根据 queryWrapper 设置的条件,删除记录
boolean remove(Wrapper<T> queryWrapper);
// 根据 ID 删除
boolean removeById(Serializable id);
// 根据 columnMap 条件,删除记录
boolean removeByMap(Map<String, Object> columnMap);
// 删除(根据ID 批量删除)
boolean removeByIds(Collection<? extends Serializable> idList);
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 2.5、Update
// 根据 UpdateWrapper 条件,更新记录 需要设置sqlset
boolean update(Wrapper<T> updateWrapper);
// 根据 whereWrapper 条件,更新记录
boolean update(T updateEntity, Wrapper<T> whereWrapper);
// 根据 ID 选择修改
boolean updateById(T entity);
// 根据ID 批量更新
boolean updateBatchById(Collection<T> entityList);
// 根据ID 批量更新
boolean updateBatchById(Collection<T> entityList, int batchSize);
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# 2.6、Get
// 根据 ID 查询
T getById(Serializable id);
// 根据 Wrapper,查询一条记录。结果集,如果是多个会抛出异常,随机取一条加上限制条件 wrapper.last("LIMIT 1")
T getOne(Wrapper<T> queryWrapper);
// 根据 Wrapper,查询一条记录
T getOne(Wrapper<T> queryWrapper, boolean throwEx);
// 根据 Wrapper,查询一条记录
Map<String, Object> getMap(Wrapper<T> queryWrapper);
// 根据 Wrapper,查询一条记录
<V> V getObj(Wrapper<T> queryWrapper, Function<? super Object, V> mapper);
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# 2.7、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);
// 查询所有列表
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);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 2.8、Page
// 无条件分页查询
IPage<T> page(IPage<T> page);
// 条件分页查询
IPage<T> page(IPage<T> page, Wrapper<T> queryWrapper);
// 无条件分页查询
IPage<Map<String, Object>> pageMaps(IPage<T> page);
// 条件分页查询
IPage<Map<String, Object>> pageMaps(IPage<T> page, Wrapper<T> queryWrapper);
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 2.9、Count
// 查询总记录数
int count();
// 根据 Wrapper 条件,查询总记录数
int count(Wrapper<T> queryWrapper);
1
2
3
4
2
3
4
# 2.10、Chain
Chain为链式封装
- query(查询)
// 链式查询 普通
QueryChainWrapper<T> query();
// 链式查询 lambda 式。注意:不支持 Kotlin
LambdaQueryChainWrapper<T> lambdaQuery();
1
2
3
4
5
6
2
3
4
5
6
使用案例
以下四个查询效果相等,只是写法不同。
@Test
public void testQuery2(){
List<StudentPO> list1 = studentService.list(new QueryWrapper<StudentPO>().eq("name", "ls").eq("age", 20));
log.info("studentList========>"+list1);
List<StudentPO> list2 = studentService.list(new LambdaQueryWrapper<StudentPO>().eq(StudentPO::getName, "ls").eq(StudentPO::getAge, 20));
log.info("studentList========>"+list2);
List<StudentPO> list3 = new QueryChainWrapper<>(studentMapper).eq("name", "ls").eq("age", 20).list();
log.info("studentList========>"+list3);
List<StudentPO> list4 = new LambdaQueryChainWrapper<>(studentMapper).eq(StudentPO::getName, "ls").eq(StudentPO::getAge, 20).list();
log.info("studentList========>"+list4);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
- update(更新)
// 链式更改 普通
UpdateChainWrapper<T> update();
// 链式更改 lambda 式。注意:不支持 Kotlin
LambdaUpdateChainWrapper<T> lambdaUpdate();
1
2
3
4
2
3
4
使用案例
以下四个更新效果相等,只是写法不同。
@Test
public void testUpdate2(){
StudentPO studentPO = new StudentPO();
studentPO.setId(3L);
studentPO.setName("sss");
studentService.update(studentPO,new QueryWrapper<StudentPO>().eq("name", "ls").eq("age", 20));
studentService.update(studentPO,new LambdaQueryWrapper<StudentPO>().eq(StudentPO::getName, "ls").eq(StudentPO::getAge, 20));
new UpdateChainWrapper<>(studentMapper).eq("name", "ls").eq("age", 20).update(studentPO);
new LambdaUpdateChainWrapper<>(studentMapper).eq(StudentPO::getName, "ls").eq(StudentPO::getAge, 20).update(studentPO);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
# 3、ActiveRecord 模式
- 实体类只需继承 Model 类即可进行强大的 CRUD 操作
- 需要项目中已注入对应实体的BaseMapper
使用案例
- 继承Model类
@Data
@TableName(value = "student",excludeProperty = {"age"})
public class StudentPO extends Model<StudentPO> {
@OrderBy(sort = 1)
@TableId(value = "id",type = IdType.ASSIGN_ID)
private Long id;
@OrderBy(asc = true,sort = 2)
@TableField(value = "name",condition = SqlCondition.LIKE)
private String name;
private Integer age;
@TableField(exist = false)
private String email;
private SexEnum sex;
@Version
private Integer version;
@TableField("is_delete")
@TableLogic(value = "0",delval = "1")
private Integer isDelete = 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
- 调用CRUD方法
@Test
public void testActiveRecord(){
StudentPO studentPO = new StudentPO(null,"ls",20,"", SexEnum.WOMAN,1,null);
studentPO.insert();
studentPO.insert();
studentPO.selectAll();
studentPO.updateById();
studentPO.deleteById();
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# 4、SimpleQuery 工具类
- 对selectList查询后的结果用Stream流进行了一些封装,使其可以返回一些指定结果,简洁了api的调用
- 需要项目中已注入对应实体的BaseMapper
# 4.1、keyMap
// 查询表内记录,封装返回为Map<属性,实体>
Map<A, E> keyMap(LambdaQueryWrapper<E> wrapper, SFunction<E, A> sFunction, Consumer<E>... peeks);
// 查询表内记录,封装返回为Map<属性,实体>,考虑了并行流的情况
Map<A, E> keyMap(LambdaQueryWrapper<E> wrapper, SFunction<E, A> sFunction, boolean isParallel, Consumer<E>... peeks);
1
2
3
4
2
3
4
使用案例
@Test
public void testQuery3(){
Map<String, StudentPO> map = SimpleQuery.keyMap(new LambdaQueryWrapper<StudentPO>()
.in(StudentPO::getName,"Tom","Sandy"),StudentPO::getName);
log.info("map========>"+map);
}
/**
* 输出结果:map========>
* {
* Tom=StudentPO(id=3, name=Tom, age=null, email=null, sex=null, version=null, isDelete=0),
* Sandy=StudentPO(id=4, name=Sandy, age=null, email=null, sex=null, version=null, isDelete=0)
* }
*/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
# 4.2、map
// 查询表内记录,封装返回为Map<属性,属性>
Map<A, P> map(LambdaQueryWrapper<E> wrapper, SFunction<E, A> keyFunc, SFunction<E, P> valueFunc, Consumer<E>... peeks);
// 查询表内记录,封装返回为Map<属性,属性>,考虑了并行流的情况
Map<A, P> map(LambdaQueryWrapper<E> wrapper, SFunction<E, A> keyFunc, SFunction<E, P> valueFunc, boolean isParallel, Consumer<E>... peeks);
1
2
3
4
2
3
4
使用案例
@Test
public void testQuery4(){
Map<Long, String> map = SimpleQuery.map(new LambdaQueryWrapper<StudentPO>()
.in(StudentPO::getName,"Tom","Sandy"),StudentPO::getId,StudentPO::getName);
log.info("map========>"+map);
}
// 输出结果:map========>{3=Tom, 4=Sandy}
1
2
3
4
5
6
7
2
3
4
5
6
7
# 4.3、group
// 查询表内记录,封装返回为Map<属性,List<实体>>
Map<K, List<T>> group(LambdaQueryWrapper<T> wrapper, SFunction<T, A> sFunction, Consumer<T>... peeks);
// 查询表内记录,封装返回为Map<属性,List<实体>>,考虑了并行流的情况
Map<K, List<T>> group(LambdaQueryWrapper<T> wrapper, SFunction<T, K> sFunction, boolean isParallel, Consumer<T>... peeks);
// 查询表内记录,封装返回为Map<属性,分组后对集合进行的下游收集器>
M group(LambdaQueryWrapper<T> wrapper, SFunction<T, K> sFunction, Collector<? super T, A, D> downstream, Consumer<T>... peeks);
// 查询表内记录,封装返回为Map<属性,分组后对集合进行的下游收集器>,考虑了并行流的情况
M group(LambdaQueryWrapper<T> wrapper, SFunction<T, K> sFunction, Collector<? super T, A, D> downstream, boolean isParallel, Consumer<T>... peeks);
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
使用案例
@Test
public void testQuery5(){
Map<Long, List<StudentPO>> map = SimpleQuery.group(new LambdaQueryWrapper<StudentPO>()
.in(StudentPO::getName,"Tom","Sandy"),StudentPO::getId);
log.info("map========>"+map);
}
/**
* 输出结果:map========>
* {
* 3=[StudentPO(id=3, name=Tom, age=null, email=null, sex=null, version=null, isDelete=0)],
* 4=[StudentPO(id=4, name=Sandy, age=null, email=null, sex=null, version=null, isDelete=0)]
* }
*/
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# 4.4、list
// 查询表内记录,封装返回为List<属性>
List<A> list(LambdaQueryWrapper<E> wrapper, SFunction<E, A> sFunction, Consumer<E>... peeks);
// 查询表内记录,封装返回为List<属性>,考虑了并行流的情况
List<A> list(LambdaQueryWrapper<E> wrapper, SFunction<E, A> sFunction, boolean isParallel, Consumer<E>... peeks);
1
2
3
4
2
3
4
使用案例
@Test
public void testQuery6(){
List<SexEnum> list = SimpleQuery.list(new LambdaQueryWrapper<StudentPO>(),StudentPO::getSex);
log.info("list========>"+list);
}
// 输出结果:list========>[WOMAN, WOMAN, null, null, null, null, WOMAN, MAN]
@Test
public void testQuery7(){
List<SexEnum> list = SimpleQuery.list(new LambdaQueryWrapper<StudentPO>(), StudentPO::getSex, new Consumer<StudentPO>() {
@Override
public void accept(StudentPO studentPO) {
// 如果性别为空,则设置为MAN
studentPO.setSex(Optional.ofNullable(studentPO.getSex()).orElse(SexEnum.MAN));
}
});
log.info("list========>"+list);
}
// 输出结果:list========>[WOMAN, WOMAN, MAN, MAN, MAN, MAN, WOMAN, MAN]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 5、Db类
- 使用静态调用的方式,执行CRUD方法,避免Spring环境下Service循环注入、简洁代码,提升效率
- 需要项目中已注入对应实体的BaseMapper
# 5.1、Db类所有静态方法
Db类所有静态方法
public static <T> boolean save(T entity);
public static <T> boolean saveBatch(Collection<T> entityList);
public static <T> boolean saveBatch(Collection<T> entityList, int batchSize);
public static <T> boolean saveOrUpdateBatch(Collection<T> entityList);
public static <T> boolean saveOrUpdateBatch(Collection<T> entityList, int batchSize);
public static <T> boolean removeById(Serializable id, Class<T> entityClass);
public static <T> boolean removeById(T entity);
public static <T> boolean remove(AbstractWrapper<T, ?, ?> queryWrapper);
public static <T> boolean updateById(T entity);
public static <T> boolean update(AbstractWrapper<T, ?, ?> updateWrapper);
public static <T> boolean update(T entity, AbstractWrapper<T, ?, ?> updateWrapper);
public static <T> boolean updateBatchById(Collection<T> entityList);
public static <T> boolean updateBatchById(Collection<T> entityList, int batchSize);
public static <T> boolean removeByIds(Collection<? extends Serializable> list, Class<T> entityClass);
public static <T> boolean removeByMap(Map<String, Object> columnMap, Class<T> entityClass);
public static <T> boolean saveOrUpdate(T entity);
public static <T> T getById(Serializable id, Class<T> entityClass);
public static <T> T getOne(AbstractWrapper<T, ?, ?> queryWrapper);
public static <T> T getOne(T entity);
public static <T> T getOne(T entity, boolean throwEx);
public static <T> T getOne(AbstractWrapper<T, ?, ?> queryWrapper, boolean throwEx);
public static <T> List<T> listByMap(Map<String, Object> columnMap, Class<T> entityClass);
public static <T> List<T> listByIds(Collection<? extends Serializable> idList, Class<T> entityClass);
public static <T> Map<String, Object> getMap(AbstractWrapper<T, ?, ?> queryWrapper);
public static <T> Map<String, Object> getMap(T entity);
public static <T> long count(Class<T> entityClass);
public static <T> long count(T entity);
public static <T> long count(AbstractWrapper<T, ?, ?> queryWrapper);
public static <T> List<T> list(AbstractWrapper<T, ?, ?> queryWrapper);
public static <T> List<T> list(IPage<T> page, AbstractWrapper<T, ?, ?> queryWrapper);
public static <T> List<T> list(Class<T> entityClass);
public static <T> List<T> list(IPage<T> page, Class<T> entityClass);
public static <T> List<T> list(T entity);
public static <T> List<T> list(IPage<T> page, T entity);
public static <T> List<Map<String, Object>> listMaps(AbstractWrapper<T, ?, ?> queryWrapper);
public static <T> List<Map<String, Object>> listMaps(IPage<? extends Map<String, Object>> page, AbstractWrapper<T, ?, ?> queryWrapper);
public static <T> List<Map<String, Object>> listMaps(Class<T> entityClass);
public static <T> List<Map<String, Object>> listMaps(IPage<? extends Map<String, Object>> page, Class<T> entityClass);
public static <T> List<Map<String, Object>> listMaps(T entity);
public static <T> List<Map<String, Object>> listMaps(IPage<? extends Map<String, Object>> page, T entity);
public static <T> List<T> listObjs(Class<T> entityClass);
public static <E, T> List<E> listObjs(AbstractWrapper<T, ?, ?> queryWrapper);
public static <T, V> List<V> listObjs(AbstractWrapper<T, ?, ?> queryWrapper, SFunction<? super T, V> mapper);
public static <T, V> List<V> listObjs(Class<T> entityClass, SFunction<? super T, V> mapper);
public static <T, E extends IPage<Map<String, Object>>> E pageMaps(E page, Class<T> entityClass);
public static <T, E extends IPage<Map<String, Object>>> E pageMaps(E page, AbstractWrapper<T, ?, ?> queryWrapper);
public static <T> IPage<T> page(IPage<T> page, Class<T> entityClass);
public static <T> IPage<T> page(IPage<T> page, AbstractWrapper<T, ?, ?> queryWrapper);
public static <T> QueryChainWrapper<T> query(Class<T> entityClass);
public static <T> KtQueryChainWrapper<T> ktQuery(Class<T> entityClass);
public static <T> LambdaQueryChainWrapper<T> lambdaQuery(Class<T> entityClass);
public static <T> UpdateChainWrapper<T> update(Class<T> entityClass);
public static <T> KtUpdateChainWrapper<T> ktUpdate(Class<T> entityClass);
public static <T> LambdaUpdateChainWrapper<T> lambdaUpdate(Class<T> entityClass);
public static <T> boolean saveOrUpdate(T entity, AbstractWrapper<T, ?, ?> updateWrapper);
public static <T, V> V getObj(AbstractWrapper<T, ?, ?> queryWrapper, SFunction<? super T, V> mapper);
protected static <T> Class<T> getEntityClass(Collection<T> entityList);
protected static <T> Class<T> getEntityClass(AbstractWrapper<T, ?, ?> queryWrapper);
protected static <T> Class<T> getEntityClass(T entity);
protected static <T> TableInfo getTableInfo(Class<T> entityClass);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# 5.2、使用案例
@Test
public void testQuery8(){
List<StudentPO> list = Db.list(Wrappers.lambdaQuery(StudentPO.class)
.in(StudentPO::getName,"Tom","Sandy"));
log.info("list========>"+list);
StudentPO byId = Db.getById(1, StudentPO.class);
log.info("byId========>"+byId);
}
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# 5.3、Db类所有测试用例
Db类所有测试用例
package com.baomidou.mybatisplus.test.toolkit;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.QueryChainWrapper;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.baomidou.mybatisplus.extension.conditions.update.UpdateChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.toolkit.Db;
import com.baomidou.mybatisplus.test.BaseDbTest;
import com.baomidou.mybatisplus.test.sqlrunner.Entity;
import com.baomidou.mybatisplus.test.sqlrunner.EntityMapper;
import org.apache.ibatis.exceptions.TooManyResultsException;
import org.apache.ibatis.plugin.Interceptor;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import java.util.*;
/**
* 以静态方式调用Service中的函数
*
* @author VampireAchao
* @since 2022-05-03
*/
class DbTest extends BaseDbTest<EntityMapper> {
@Test
void testSave() {
Entity entity = new Entity();
entity.setName("ruben");
boolean isSuccess = Db.save(entity);
Assertions.assertTrue(isSuccess);
Assertions.assertEquals(3L, Db.count(Entity.class));
}
@Test
void testSaveBatch() {
List<Entity> list = Arrays.asList(new Entity(), new Entity());
boolean isSuccess = Db.saveBatch(list);
Assertions.assertTrue(isSuccess);
Assertions.assertEquals(4, Db.count(Entity.class));
}
@Test
void testSaveOrUpdateBatch() {
Entity entity = new Entity();
entity.setId(1L);
entity.setName("cat");
List<Entity> list = Arrays.asList(new Entity(), entity);
boolean isSuccess = Db.saveOrUpdateBatch(list);
Assertions.assertTrue(isSuccess);
Assertions.assertEquals(3, Db.count(Entity.class));
}
@Test
void testRemoveById() {
Entity entity = new Entity();
entity.setId(1L);
boolean isSuccess = Db.removeById(entity);
Assertions.assertTrue(isSuccess);
Assertions.assertEquals(1, Db.count(Entity.class));
isSuccess = Db.removeById(2L, Entity.class);
Assertions.assertTrue(isSuccess);
Assertions.assertEquals(0, Db.count(Entity.class));
}
@Test
void testUpdateById() {
Entity entity = new Entity();
entity.setId(1L);
entity.setName("bee bee I'm a sheep");
boolean isSuccess = Db.updateById(entity);
Assertions.assertTrue(isSuccess);
Assertions.assertEquals("bee bee I'm a sheep", Db.getById(1L, Entity.class).getName());
}
@Test
void testUpdate() {
boolean isSuccess = Db.update(Wrappers.lambdaUpdate(Entity.class).eq(Entity::getId, 1L).set(Entity::getName, "be better"));
Assertions.assertTrue(isSuccess);
Assertions.assertEquals("be better", Db.getById(1L, Entity.class).getName());
Entity entity = new Entity();
entity.setId(1L);
entity.setName("bee bee I'm a sheep");
isSuccess = Db.update(entity, Wrappers.lambdaQuery(Entity.class).eq(Entity::getId, 1L));
Assertions.assertTrue(isSuccess);
Assertions.assertEquals("bee bee I'm a sheep", Db.getById(1L, Entity.class).getName());
}
@Test
void testUpdateBatchById() {
Entity sheep = new Entity();
sheep.setId(1L);
sheep.setName("bee bee I'm a sheep");
Entity ruben = new Entity();
ruben.setId(2L);
ruben.setName("rabbit");
boolean isSuccess = Db.updateBatchById(Arrays.asList(sheep, ruben));
Assertions.assertTrue(isSuccess);
Assertions.assertEquals("bee bee I'm a sheep", Db.getById(1L, Entity.class).getName());
Assertions.assertEquals("rabbit", Db.getById(2L, Entity.class).getName());
}
@Test
void testRemove() {
boolean isSuccess = Db.remove(Wrappers.lambdaQuery(Entity.class).eq(Entity::getId, 1L));
Assertions.assertTrue(isSuccess);
Assertions.assertEquals(1, Db.count(Entity.class));
}
@Test
void testRemoveByIds() {
boolean isSuccess = Db.removeByIds(Arrays.asList(1L, 2L), Entity.class);
Assertions.assertTrue(isSuccess);
Assertions.assertEquals(0, Db.count(Entity.class));
}
@Test
void testRemoveByMap() {
boolean isSuccess = Db.removeByMap(Collections.singletonMap("id", 1L), Entity.class);
Assertions.assertTrue(isSuccess);
Assertions.assertEquals(1, Db.count(Entity.class));
}
@Test
void testSaveOrUpdate() {
Entity entity = new Entity();
entity.setId(null);
entity.setName("bee bee I'm a sheep");
boolean isSuccess = Db.saveOrUpdate(entity);
Assertions.assertTrue(isSuccess);
Assertions.assertEquals("bee bee I'm a sheep", Db.getById(entity.getId(), Entity.class).getName());
entity.setName("be better");
isSuccess = Db.saveOrUpdate(entity, Wrappers.lambdaQuery(Entity.class).eq(Entity::getId, entity.getId()));
Assertions.assertTrue(isSuccess);
Assertions.assertEquals("be better", Db.getById(entity.getId(), Entity.class).getName());
}
@Test
void testGetOne() {
LambdaQueryWrapper<Entity> wrapper = Wrappers.lambdaQuery(Entity.class);
Assertions.assertThrows(TooManyResultsException.class, () -> Db.getOne(wrapper));
Entity one = Db.getOne(wrapper, false);
Assertions.assertNotNull(one);
Entity entity = new Entity();
entity.setId(1L);
one = Db.getOne(entity);
Assertions.assertNotNull(one);
}
@Test
void testListByMap() {
Map<String, Object> map = new HashMap<>();
map.put("id", 1L);
List<Entity> list = Db.listByMap(map, Entity.class);
Assertions.assertEquals(1, list.size());
Assertions.assertEquals("ruben", list.get(0).getName());
}
@Test
void testByIds() {
List<Entity> list = Db.listByIds(Arrays.asList(1L, 2L), Entity.class);
Assertions.assertEquals(2, list.size());
}
@Test
void testGetMap() {
Map<String, Object> map = Db.getMap(Wrappers.lambdaQuery(Entity.class));
Assertions.assertNotNull(map);
Entity entity = new Entity();
entity.setId(1L);
map = Db.getMap(entity);
Assertions.assertNotNull(map);
}
@Test
void testList() {
List<Entity> list = Db.list(Wrappers.lambdaQuery(Entity.class));
Assertions.assertEquals(2, list.size());
list = Db.list(Entity.class);
Assertions.assertEquals(2, list.size());
Entity entity = new Entity();
entity.setId(1L);
list = Db.list(entity);
Assertions.assertEquals(1, list.size());
}
@Test
void testListMaps() {
List<Map<String, Object>> list = Db.listMaps(Wrappers.lambdaQuery(Entity.class));
Assertions.assertEquals(2, list.size());
list = Db.listMaps(Entity.class);
Assertions.assertEquals(2, list.size());
Entity entity = new Entity();
entity.setId(1L);
list = Db.listMaps(entity);
Assertions.assertEquals(1, list.size());
}
@Test
void testListObjs() {
List<Entity> list = Db.listObjs(Entity.class);
Assertions.assertEquals(2, list.size());
List<Long> objectList = Db.listObjs(Wrappers.lambdaQuery(Entity.class), Entity::getId);
Assertions.assertEquals(2, objectList.size());
List<String> names = Db.listObjs(Entity.class, Entity::getName);
Assertions.assertArrayEquals(new String[]{"ruben", "chocolate"}, names.toArray());
}
@Override
protected List<Interceptor> interceptors() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.SQLITE));
return Collections.singletonList(interceptor);
}
@Test
void testPageMaps() {
Page<Map<String, Object>> page = Db.pageMaps(new Page<>(1, 1), Entity.class);
Assertions.assertEquals(2, page.getTotal());
Assertions.assertEquals(Db.listMaps(new Page<>(1, 1, false), Entity.class).size(), page.getRecords().size());
page = Db.pageMaps(new Page<>(1, 1), Wrappers.lambdaQuery(Entity.class));
Assertions.assertEquals(1, page.getRecords().size());
Assertions.assertEquals(Db.listMaps(new Page<>(1, 1, false), Wrappers.lambdaQuery(Entity.class)).size(), page.getRecords().size());
}
@Test
void testPage() {
IPage<Entity> page = Db.page(new Page<>(1, 1), Entity.class);
Assertions.assertEquals(2, page.getTotal());
Assertions.assertEquals(Db.list(new Page<Entity>(1, 1), Entity.class).size(),page.getRecords().size());
page = Db.page(new Page<>(1, 1), Wrappers.lambdaQuery(Entity.class));
Assertions.assertEquals(1, page.getRecords().size());
Assertions.assertEquals(Db.list(new Page<Entity>(1, 1), Wrappers.lambdaQuery(Entity.class)).size(),page.getRecords().size());
}
@Test
void testChain() {
QueryChainWrapper<Entity> query = Db.query(Entity.class);
List<Entity> list = query.eq("id", 1L).list();
Assertions.assertEquals(1, list.size());
LambdaQueryChainWrapper<Entity> lambdaQuery = Db.lambdaQuery(Entity.class);
list = lambdaQuery.eq(Entity::getId, 1L).list();
Assertions.assertEquals(1, list.size());
UpdateChainWrapper<Entity> update = Db.update(Entity.class);
update.eq("id", 1L).set("name", "bee bee I'm a sheep").update();
Assertions.assertEquals("bee bee I'm a sheep", lambdaQuery.eq(Entity::getId, 1L).one().getName());
LambdaUpdateChainWrapper<Entity> lambdaUpdate = Db.lambdaUpdate(Entity.class);
lambdaUpdate.eq(Entity::getId, 1L).set(Entity::getName, "be better").update();
Assertions.assertEquals("be better", lambdaQuery.eq(Entity::getId, 1L).one().getName());
}
@Test
void testGetObj() {
String name = Db.getObj(Wrappers.lambdaQuery(Entity.class).eq(Entity::getId, 1L), Entity::getName);
Assertions.assertEquals("ruben", name);
}
@Override
protected String tableDataSql() {
return "insert into entity(id,name) values(1,'ruben'),(2,'chocolate');";
}
@Override
protected List<String> tableSql() {
return Arrays.asList("drop table if exists entity", "CREATE TABLE IF NOT EXISTS entity (" +
"id BIGINT NOT NULL," +
"name VARCHAR(30) NULL DEFAULT NULL," +
"PRIMARY KEY (id))");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296