package cn.iocoder.yudao.framework.mybatis.core.mapper;
|
|
import cn.hutool.core.collection.CollUtil;
|
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.SortablePageParam;
|
import cn.iocoder.yudao.framework.common.pojo.SortingField;
|
import cn.iocoder.yudao.framework.mybatis.core.util.JdbcUtils;
|
import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils;
|
import com.baomidou.mybatisplus.annotation.DbType;
|
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
|
import com.baomidou.mybatisplus.extension.toolkit.Db;
|
import com.github.yulichang.base.MPJBaseMapper;
|
import com.github.yulichang.interfaces.MPJBaseJoin;
|
import com.github.yulichang.wrapper.MPJLambdaWrapper;
|
import org.apache.ibatis.annotations.Param;
|
|
import java.util.Collection;
|
import java.util.List;
|
|
/**
|
* 在 MyBatis Plus 的 BaseMapper 的基础上拓展,提供更多的能力
|
*
|
* 1. {@link BaseMapper} 为 MyBatis Plus 的基础接口,提供基础的 CRUD 能力
|
* 2. {@link MPJBaseMapper} 为 MyBatis Plus Join 的基础接口,提供连表 Join 能力
|
*/
|
public interface BaseMapperX<T> extends MPJBaseMapper<T> {
|
|
default PageResult<T> selectPage(SortablePageParam pageParam, @Param("ew") Wrapper<T> queryWrapper) {
|
return selectPage(pageParam, pageParam.getSortingFields(), queryWrapper);
|
}
|
|
default PageResult<T> selectPage(PageParam pageParam, @Param("ew") Wrapper<T> queryWrapper) {
|
return selectPage(pageParam, null, queryWrapper);
|
}
|
|
default PageResult<T> selectPage(PageParam pageParam, Collection<SortingField> sortingFields, @Param("ew") Wrapper<T> queryWrapper) {
|
// 特殊:不分页,直接查询全部
|
if (PageParam.PAGE_SIZE_NONE.equals(pageParam.getPageSize())) {
|
MyBatisUtils.addOrder(queryWrapper, sortingFields);
|
List<T> list = selectList(queryWrapper);
|
return new PageResult<>(list, (long) list.size());
|
}
|
|
// MyBatis Plus 查询
|
IPage<T> mpPage = MyBatisUtils.buildPage(pageParam, sortingFields);
|
selectPage(mpPage, queryWrapper);
|
// 转换返回
|
return new PageResult<>(mpPage.getRecords(), mpPage.getTotal());
|
}
|
|
default <D> PageResult<D> selectJoinPage(PageParam pageParam, Class<D> clazz, MPJLambdaWrapper<T> lambdaWrapper) {
|
// 特殊:不分页,直接查询全部
|
if (PageParam.PAGE_SIZE_NONE.equals(pageParam.getPageSize())) {
|
List<D> list = selectJoinList(clazz, lambdaWrapper);
|
return new PageResult<>(list, (long) list.size());
|
}
|
|
// MyBatis Plus Join 查询
|
IPage<D> mpPage = MyBatisUtils.buildPage(pageParam);
|
mpPage = selectJoinPage(mpPage, clazz, lambdaWrapper);
|
// 转换返回
|
return new PageResult<>(mpPage.getRecords(), mpPage.getTotal());
|
}
|
|
/**
|
* 执行分页查询并返回结果。
|
*
|
* @param pageParam 分页参数,包含页码、每页条数和排序字段信息。如果 pageSize 为 {@link PageParam#PAGE_SIZE_NONE},则不分页,直接查询所有数据。
|
* @param clazz 结果集的类类型
|
* @param lambdaWrapper MyBatis Plus Join 查询条件包装器
|
* @param <D> 结果集的泛型类型
|
* @return 返回分页查询的结果,包括总记录数和当前页的数据列表
|
*/
|
default <D> PageResult<D> selectJoinPage(SortablePageParam pageParam, Class<D> clazz, MPJLambdaWrapper<T> lambdaWrapper) {
|
// 特殊:不分页,直接查询全部
|
if (PageParam.PAGE_SIZE_NONE.equals(pageParam.getPageSize())) {
|
List<D> list = selectJoinList(clazz, lambdaWrapper);
|
return new PageResult<>(list, (long) list.size());
|
}
|
|
// MyBatis Plus Join 查询
|
IPage<D> mpPage = MyBatisUtils.buildPage(pageParam, pageParam.getSortingFields());
|
mpPage = selectJoinPage(mpPage, clazz, lambdaWrapper);
|
// 转换返回
|
return new PageResult<>(mpPage.getRecords(), mpPage.getTotal());
|
}
|
|
default <DTO> PageResult<DTO> selectJoinPage(PageParam pageParam, Class<DTO> resultTypeClass, MPJBaseJoin<T> joinQueryWrapper) {
|
IPage<DTO> mpPage = MyBatisUtils.buildPage(pageParam);
|
selectJoinPage(mpPage, resultTypeClass, joinQueryWrapper);
|
// 转换返回
|
return new PageResult<>(mpPage.getRecords(), mpPage.getTotal());
|
}
|
|
default T selectOne(String field, Object value) {
|
return selectOne(new QueryWrapper<T>().eq(field, value));
|
}
|
|
default T selectOne(SFunction<T, ?> field, Object value) {
|
return selectOne(new LambdaQueryWrapper<T>().eq(field, value));
|
}
|
|
default T selectOne(String field1, Object value1, String field2, Object value2) {
|
return selectOne(new QueryWrapper<T>().eq(field1, value1).eq(field2, value2));
|
}
|
|
default T selectOne(SFunction<T, ?> field1, Object value1, SFunction<T, ?> field2, Object value2) {
|
return selectOne(new LambdaQueryWrapper<T>().eq(field1, value1).eq(field2, value2));
|
}
|
|
default T selectOne(SFunction<T, ?> field1, Object value1, SFunction<T, ?> field2, Object value2,
|
SFunction<T, ?> field3, Object value3) {
|
return selectOne(new LambdaQueryWrapper<T>().eq(field1, value1).eq(field2, value2).eq(field3, value3));
|
}
|
|
/**
|
* 获得满足条件的一条记录,并使用 FOR UPDATE 锁定。
|
*
|
* 注意:需要在事务中调用,否则锁会立即释放。
|
*
|
* @param queryWrapper 查询条件
|
* @return 实体
|
*/
|
default T selectOneForUpdate(LambdaQueryWrapper<T> queryWrapper) {
|
return selectOne(queryWrapper.last("FOR UPDATE"));
|
}
|
|
default T selectOneForUpdate(SFunction<T, ?> field, Object value) {
|
return selectOneForUpdate(new LambdaQueryWrapper<T>().eq(field, value));
|
}
|
|
default T selectOneForUpdate(SFunction<T, ?> field1, Object value1, SFunction<T, ?> field2, Object value2) {
|
return selectOneForUpdate(new LambdaQueryWrapper<T>().eq(field1, value1).eq(field2, value2));
|
}
|
|
default T selectOneForUpdate(SFunction<T, ?> field1, Object value1, SFunction<T, ?> field2, Object value2,
|
SFunction<T, ?> field3, Object value3) {
|
return selectOneForUpdate(new LambdaQueryWrapper<T>().eq(field1, value1).eq(field2, value2).eq(field3, value3));
|
}
|
|
/**
|
* 获取满足条件的第 1 条记录
|
*
|
* 目的:解决并发场景下,插入多条记录后,使用 selectOne 会报错的问题
|
*
|
* @param field 字段名
|
* @param value 字段值
|
* @return 实体
|
*/
|
default T selectFirstOne(SFunction<T, ?> field, Object value) {
|
// 如果明确使用 MySQL 等场景,可以考虑使用 LIMIT 1 进行优化
|
List<T> list = selectList(new LambdaQueryWrapper<T>().eq(field, value));
|
return CollUtil.getFirst(list);
|
}
|
|
default T selectFirstOne(SFunction<T, ?> field1, Object value1, SFunction<T, ?> field2, Object value2) {
|
List<T> list = selectList(new LambdaQueryWrapper<T>().eq(field1, value1).eq(field2, value2));
|
return CollUtil.getFirst(list);
|
}
|
|
default T selectFirstOne(SFunction<T,?> field1, Object value1, SFunction<T,?> field2, Object value2,
|
SFunction<T,?> field3, Object value3) {
|
List<T> list = selectList(new LambdaQueryWrapper<T>().eq(field1, value1).eq(field2, value2).eq(field3, value3));
|
return CollUtil.getFirst(list);
|
}
|
|
|
default Long selectCount() {
|
return selectCount(new QueryWrapper<>());
|
}
|
|
default Long selectCount(String field, Object value) {
|
return selectCount(new QueryWrapper<T>().eq(field, value));
|
}
|
|
default Long selectCount(SFunction<T, ?> field, Object value) {
|
return selectCount(new LambdaQueryWrapper<T>().eq(field, value));
|
}
|
|
default List<T> selectList() {
|
return selectList(new QueryWrapper<>());
|
}
|
|
default List<T> selectList(String field, Object value) {
|
return selectList(new QueryWrapper<T>().eq(field, value));
|
}
|
|
default List<T> selectList(SFunction<T, ?> field, Object value) {
|
return selectList(new LambdaQueryWrapper<T>().eq(field, value));
|
}
|
|
default List<T> selectList(String field, Collection<?> values) {
|
if (CollUtil.isEmpty(values)) {
|
return CollUtil.newArrayList();
|
}
|
return selectList(new QueryWrapper<T>().in(field, values));
|
}
|
|
default List<T> selectList(SFunction<T, ?> field, Collection<?> values) {
|
if (CollUtil.isEmpty(values)) {
|
return CollUtil.newArrayList();
|
}
|
return selectList(new LambdaQueryWrapper<T>().in(field, values));
|
}
|
|
default List<T> selectList(SFunction<T, ?> field1, Object value1, SFunction<T, ?> field2, Object value2) {
|
return selectList(new LambdaQueryWrapper<T>().eq(field1, value1).eq(field2, value2));
|
}
|
|
/**
|
* 批量插入,适合大量数据插入
|
*
|
* @param entities 实体们
|
*/
|
default Boolean insertBatch(Collection<T> entities) {
|
// 特殊:SQL Server 批量插入后,获取 id 会报错,因此通过循环处理
|
DbType dbType = JdbcUtils.getDbType();
|
if (JdbcUtils.isSQLServer(dbType)) {
|
entities.forEach(this::insert);
|
return CollUtil.isNotEmpty(entities);
|
}
|
return Db.saveBatch(entities);
|
}
|
|
/**
|
* 批量插入,适合大量数据插入
|
*
|
* @param entities 实体们
|
* @param size 插入数量 Db.saveBatch 默认为 1000
|
*/
|
default Boolean insertBatch(Collection<T> entities, int size) {
|
// 特殊:SQL Server 批量插入后,获取 id 会报错,因此通过循环处理
|
DbType dbType = JdbcUtils.getDbType();
|
if (JdbcUtils.isSQLServer(dbType)) {
|
entities.forEach(this::insert);
|
return CollUtil.isNotEmpty(entities);
|
}
|
return Db.saveBatch(entities, size);
|
}
|
|
default int updateBatch(T update) {
|
return update(update, new QueryWrapper<>());
|
}
|
|
default Boolean updateBatch(Collection<T> entities) {
|
return Db.updateBatchById(entities);
|
}
|
|
default Boolean updateBatch(Collection<T> entities, int size) {
|
return Db.updateBatchById(entities, size);
|
}
|
|
default int delete(String field, String value) {
|
return delete(new QueryWrapper<T>().eq(field, value));
|
}
|
|
default int delete(SFunction<T, ?> field, Object value) {
|
return delete(new LambdaQueryWrapper<T>().eq(field, value));
|
}
|
|
default int deleteBatch(SFunction<T, ?> field, Collection<?> values) {
|
if (CollUtil.isEmpty(values)) {
|
return 0;
|
}
|
return delete(new LambdaQueryWrapper<T>().in(field, values));
|
}
|
|
}
|