对mybatis-plus提供的ServiceImpl进行拓展和补充,写的一般,多多海涵,都是工作中自己总结的!
说明
继承
定义一个抽象类继承ServiceImpl,如BaseRepository(也可以不是抽象类,我主要是为了方便根据表去继承)
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.ListUtils;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import java.io.Serializable;
import java.util.*;
import java.util.stream.Collectors;
public abstract class BaseRepository<M extends BaseMapper<T>, T> extends ServiceImpl<M, T> {
// 默认批量获取结果集大小
protected static final int DEFAULT_LIST_BATCH_SIZE = 500;
}
判断结果是否存在
根据id判断
// 根据id判断结果是否存在
public boolean existById(Serializable id) {
return Objects.nonNull(getById(id));
}
// 根据id判断结果是否不存在
public boolean notExistById(Serializable id) {
return Objects.isNull(getById(id));
}
根据列名和值判断
这里使用了mybatis-plus提供的函数接口,实现lambda形式字段名称传入
public <V> boolean existByColumn(SFunction<T, V> column, @Nullable V value) {
// 断言列名是否为空
Assert.notNull(column, "column 不可为空");
if (Objects.isNull(value)) {
return lambdaQuery()
.isNull(column)
.exists();
}
return lambdaQuery()
.eq(column, value)
.exists();
}
public <V> boolean notExistByColumn(SFunction<T, V> column, @Nullable V value) {
// 断言列名是否为空
Assert.notNull(column, "column 不可为空");
if (Objects.isNull(value)) {
return lambdaQuery()
.isNotNull(column)
.exists();
}
return !lambdaQuery()
.eq(column, value)
.exists();
}
使用案例:
existByColumn(AppSecretDO::getAppId, appId)
获取某一列的全部结果
这里使用了mybatis-plus提供的函数接口,实现lambda形式字段名称传入
// 根据列名获取某一列的全部结果,结果可能包含重复项,不包含为null的项
public <V> List<?> listColumnValue(SFunction<T, V> column) {
return listColumnValue(column, false, true);
}
// 根据列名获取某一列的全部结果,结果不包含重复项,不包含为null的项
public <V> List<?> listUniqueColumnValue(SFunction<T, V> column) {
return listColumnValue(column, true, true);
}
// 根据列名获取某一列的全部结果,根据入参决定是否包含重复项和为null的项
public <V> List<?> listColumnValue(SFunction<T, V> column, boolean unique, boolean nonNull) {
// 断言列名是否为空
Assert.notNull(column, "column 不可为空");
// 这里为了方便,我直接用var自动推导类型了
var queryWrapper = lambdaQuery().select(column);
if (nonNull) {
queryWrapper = queryWrapper.isNotNull(column);
}
var stream = queryWrapper.list()
.stream()
.map(column);
if (unique) {
stream = stream.distinct();
}
return stream.collect(Collectors.toList());
}
使用案例:
// result: {"123","123","1312312"}
listColumnValue(AppSecretDO::getAppId)
// result: {"123","1312312"}
listUniqueColumnValue(AppSecretDO::getAppId)
// result: {"123","1312312"}
listUniqueColumnValue(AppSecretDO::getAppId, true, true)
// result: {"123","123","1312312", null}
listUniqueColumnValue(AppSecretDO::getAppId, false, false)
// result: {"123","1312312"}
listUniqueColumnValue(AppSecretDO::getAppId, true, true)
// result: {"123","1312312", null}
listUniqueColumnValue(AppSecretDO::getAppId, true, false)
// result: {"123","123","1312312"}
listUniqueColumnValue(AppSecretDO::getAppId, false, true)
根据某一列查询结果
根据id查询结果(对mybatis-plus原生方法进行继承并拓展)
// 根据默认结果集大小进行分片
@Override
public List<T> listByIds(Collection<? extends Serializable> ids) {
return listByIds(ids, DEFAULT_LIST_BATCH_SIZE);
}
// 根据传入的结果集大小对id集合进行分片,执行多次查询,防止sql执行速度过慢
public List<T> listByIds(Collection<? extends Serializable> ids, int batchSize) {
// 判断id集合是否为空,为空则返回空集合,避免查询报错
if (CollectionUtils.isEmpty(ids)) {
return Collections.emptyList();
}
// 去除集合中为null的id(StreamUtils是我自己实现的,这里可以去掉,也可以自己实现类似的功能)
List<? extends Serializable> validIdList = StreamUtils.toNonNullList(ids);
// 判断id集合大小是否达到单次结果集上限
if (validIdList.size() <= batchSize) {
return super.listByIds(validIdList);
}
// id集合分片,执行查询,合并结果集
return ListUtils.partition(new ArrayList<>(validIdList), batchSize)
.stream()
.map(super::listByIds)
.flatMap(List::stream)
.toList();
}
根据列名和值查询单条结果
这里使用了mybatis-plus提供的函数接口,实现lambda形式字段名称传入
如果列不具备唯一索引,查询可能报错
// 根据列名和值查询单条结果(值可以为null)
public <V> T getByColumnValue(SFunction<T, V> column, @Nullable V value) {
// 断言列名是否为空
Assert.notNull(column, "column 不可为空");
// 判断值是否为null,为nul则使用is null作为条件查询
if (Objects.isNull(value)) {
return lambdaQuery()
.isNull(column)
.one();
}
return lambdaQuery()
.eq(column, value)
.one();
}
使用案例:
getByColumnValue(AppSecretDO::getAppId, "adsad")
根据列名和列值查询多条结果
// 根据列名和值查询单条结果(值可以为null)
public <V> List<T> listByColumnValue(SFunction<T, V> column, @Nullable V value) {
// 断言列名是否为空
Assert.notNull(column, "column 不可为空");
// 判断值是否为null,为nul则使用is null作为条件查询
if (Objects.isNull(value)) {
return lambdaQuery()
.isNull(column)
.list();
}
return lambdaQuery()
.eq(column, value)
.list();
}
使用案例:
listByColumnValue(AppSecretDO::getAppId, "adsad")
根据列名和列值集合查询多条结果
public <V> List<T> listByColumnValues(SFunction<T, V> column, Collection<V> values) {
return listByColumnValues(column, values, DEFAULT_LIST_BATCH_SIZE);
}
public <V> List<T> listByColumnValues(SFunction<T, V> column, Collection<V> values, int batchSize) {
// 断言列名是否为空
Assert.notNull(column, "column 不可为空");
// 判断id集合是否为空,为空则返回空集合,避免查询报错
if (CollectionUtils.isEmpty(values)) {
return Collections.emptyList();
}
// 去除集合中为null的值(StreamUtils是我自己实现的,这里可以去掉,也可以自己实现类似的功能)
List<?> validList = StreamUtils.toNonNullList(values);
// 判断集合大小是否达到单次结果集上限
if (validList.size() <= batchSize) {
return lambdaQuery()
.in(column, validList)
.list();
}
// 集合分片,执行查询,合并结果集
return ListUtils.partition(new ArrayList<>(validList), batchSize)
.stream()
.map(part -> lambdaQuery()
.in(column, part)
.list())
.flatMap(List::stream)
.toList();
}
使用案例:
listByColumnValue(AppSecretDO::getAppId, Collections.singletonList("adsad"))
完整代码
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.ListUtils;
import org.springframework.lang.Nullable;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import java.io.Serializable;
import java.util.*;
import java.util.stream.Collectors;
public abstract class BaseRepository<M extends BaseMapper<T>, T> extends ServiceImpl<M, T> {
protected static final int DEFAULT_LIST_BATCH_SIZE = 500;
public boolean existById(Serializable id) {
return Objects.nonNull(getById(id));
}
public boolean notExistById(Serializable id) {
return Objects.isNull(getById(id));
}
public <V> boolean existByColumn(SFunction<T, V> column, @Nullable V value) {
Assert.notNull(column, "column 不可为空");
if (Objects.isNull(value)) {
return lambdaQuery()
.isNull(column)
.exists();
}
return lambdaQuery()
.eq(column, value)
.exists();
}
public <V> boolean notExistByColumn(SFunction<T, V> column, @Nullable V value) {
Assert.notNull(column, "column 不可为空");
if (Objects.isNull(value)) {
return lambdaQuery()
.isNotNull(column)
.exists();
}
return !lambdaQuery()
.eq(column, value)
.exists();
}
public <V> List<?> listColumnValue(SFunction<T, V> column) {
return listColumnValue(column, false, true);
}
public <V> List<?> listUniqueColumnValue(SFunction<T, V> column) {
return listColumnValue(column, true, true);
}
public <V> List<?> listColumnValue(SFunction<T, V> column, boolean unique, boolean nonNull) {
Assert.notNull(column, "column 不可为空");
var queryWrapper = lambdaQuery().select(column);
if (nonNull) {
queryWrapper = queryWrapper.isNotNull(column);
}
var stream = queryWrapper.list()
.stream()
.map(column);
if (unique) {
stream = stream.distinct();
}
return stream.collect(Collectors.toList());
}
@Override
public List<T> listByIds(Collection<? extends Serializable> ids) {
return listByIds(ids, DEFAULT_LIST_BATCH_SIZE);
}
public List<T> listByIds(Collection<? extends Serializable> ids, int batchSize) {
if (CollectionUtils.isEmpty(ids)) {
return Collections.emptyList();
}
List<? extends Serializable> validIdList = StreamUtils.toNonNullList(ids);
if (validIdList.size() <= batchSize) {
return super.listByIds(validIdList);
}
return ListUtils.partition(new ArrayList<>(validIdList), batchSize)
.stream()
.map(super::listByIds)
.flatMap(List::stream)
.toList();
}
public <V> T getByColumnValue(SFunction<T, V> column, @Nullable V value) {
Assert.notNull(column, "column 不可为空");
if (Objects.isNull(value)) {
return lambdaQuery()
.isNull(column)
.one();
}
return lambdaQuery()
.eq(column, value)
.one();
}
public <V> List<T> listByColumnValue(SFunction<T, V> column, @Nullable V value) {
Assert.notNull(column, "column 不可为空");
if (Objects.isNull(value)) {
return lambdaQuery()
.isNull(column)
.list();
}
return lambdaQuery()
.eq(column, value)
.list();
}
public <V> List<T> listByColumnValues(SFunction<T, V> column, Collection<V> values) {
return listByColumnValues(column, values, DEFAULT_LIST_BATCH_SIZE);
}
public <V> List<T> listByColumnValues(SFunction<T, V> column, Collection<V> values, int batchSize) {
Assert.notNull(column, "column 不可为空");
if (CollectionUtils.isEmpty(values)) {
return Collections.emptyList();
}
List<?> validList = StreamUtils.toNonNullList(values);
if (validList.size() <= batchSize) {
return lambdaQuery()
.in(column, validList)
.list();
}
return ListUtils.partition(new ArrayList<>(validList), batchSize)
.stream()
.map(part -> lambdaQuery()
.in(column, part)
.list())
.flatMap(List::stream)
.toList();
}
@Transactional(rollbackFor = Exception.class)
@Override
public boolean saveBatch(Collection<T> entityList) {
if (CollectionUtils.isEmpty(entityList)) {
return false;
}
List<T> validEntityList = StreamUtils.toNonNullList(entityList);
return super.saveBatch(validEntityList, DEFAULT_BATCH_SIZE);
}
@Transactional(rollbackFor = Exception.class)
@Override
public boolean saveBatch(Collection<T> entityList, int batchSize) {
if (CollectionUtils.isEmpty(entityList)) {
return false;
}
List<T> validEntityList = StreamUtils.toNonNullList(entityList);
return super.saveBatch(validEntityList, batchSize);
}
@Transactional(rollbackFor = Exception.class)
@Override
public boolean updateBatchById(Collection<T> entityList) {
if (CollectionUtils.isEmpty(entityList)) {
return false;
}
List<T> validEntityList = StreamUtils.toNonNullList(entityList);
return super.updateBatchById(validEntityList, DEFAULT_BATCH_SIZE);
}
@Transactional(rollbackFor = Exception.class)
@Override
public boolean updateBatchById(Collection<T> entityList, int batchSize) {
if (CollectionUtils.isEmpty(entityList)) {
return false;
}
List<T> validEntityList = StreamUtils.toNonNullList(entityList);
return super.updateBatchById(validEntityList, batchSize);
}
@Transactional(rollbackFor = Exception.class)
@Override
public boolean saveOrUpdateBatch(Collection<T> entityList) {
if (CollectionUtils.isEmpty(entityList)) {
return false;
}
List<T> validEntityList = StreamUtils.toNonNullList(entityList);
return super.saveOrUpdateBatch(validEntityList, DEFAULT_BATCH_SIZE);
}
@Transactional(rollbackFor = Exception.class)
@Override
public boolean saveOrUpdateBatch(Collection<T> entityList, int batchSize) {
if (CollectionUtils.isEmpty(entityList)) {
return false;
}
List<T> validEntityList = StreamUtils.toNonNullList(entityList);
return super.saveOrUpdateBatch(validEntityList, batchSize);
}
@Transactional(rollbackFor = Exception.class)
@Override
public boolean removeByIds(Collection<?> list) {
if (CollectionUtils.isEmpty(list)) {
return false;
}
List<?> validList = StreamUtils.toNonNullList(list);
return super.removeByIds(validList);
}
@Transactional(rollbackFor = Exception.class)
@Override
public boolean removeBatchByIds(Collection<?> list) {
if (CollectionUtils.isEmpty(list)) {
return false;
}
List<?> validList = StreamUtils.toNonNullList(list);
return super.removeBatchByIds(validList, DEFAULT_BATCH_SIZE);
}
@Transactional(rollbackFor = Exception.class)
@Override
public boolean removeBatchByIds(Collection<?> list, int batchSize) {
if (CollectionUtils.isEmpty(list)) {
return false;
}
List<?> validList = StreamUtils.toNonNullList(list);
return super.removeBatchByIds(validList, batchSize);
}
public <V> boolean removeByColumnValue(SFunction<T, V> column, @Nullable V value) {
Assert.notNull(column, "column 不可为空");
if (Objects.isNull(value)) {
return lambdaUpdate()
.isNull(column)
.remove();
}
return lambdaUpdate()
.eq(column, value)
.remove();
}
@Transactional(rollbackFor = Exception.class)
public <V> boolean removeBatchByColumns(SFunction<T, V> column, Collection<V> values) {
return removeBatchByColumns(column, values, DEFAULT_BATCH_SIZE);
}
@Transactional(rollbackFor = Exception.class)
public <V> boolean removeBatchByColumns(SFunction<T, V> column, Collection<V> values, int batchSize) {
Assert.notNull(column, "column 不可为空");
if (CollectionUtils.isEmpty(values)) {
return false;
}
List<V> validList = StreamUtils.toNonNullList(values);
if (validList.size() <= batchSize) {
return lambdaUpdate()
.in(column, validList)
.remove();
}
return ListUtils.partition(new ArrayList<>(validList), batchSize)
.stream()
.allMatch(part -> lambdaUpdate()
.in(column, part)
.remove());
}
}