使用Mybatis SqlProvider类相关注解生成通用Mapper接口
1. 使用Mybatis @SelectProvider @InsertProvider @UpdateProvider @DeleteProvider注解封装BaseMapper<E, I>通用接口, 普通实体类Mapper接口只需要继承该接口, 即可实现基础常用的CRUD功能.
BaseMapper<E, I> : E为实体类型, I为主键类型. 默认认为主键为实体类Entity的第一个字段.
import org.apache.ibatis.annotations.*;
import java.util.Collection;
import java.util.List;
public interface BaseMapper<E, I> {
@SelectProvider(type = BaseSqlProvider.class, method = "getById")
E getById(I id);
@SelectProvider(type = BaseSqlProvider.class, method = "listByIds")
List<E> listByIds(Collection<I> collection);
@SelectProvider(type = BaseSqlProvider.class, method = "listByEntity")
List<E> listByEntity(E e);
@InsertProvider(type = BaseSqlProvider.class, method = "insert")
@Options(keyProperty = "id", useGeneratedKeys = true)
int insert(E e);
@InsertProvider(type = BaseSqlProvider.class, method = "insertBatch")
@Options(keyProperty = "id", useGeneratedKeys = true)
int insertBatch(Collection<E> list);
@UpdateProvider(type = BaseSqlProvider.class, method = "updateById")
int updateById(E e);
@DeleteProvider(type = BaseSqlProvider.class, method = "deleteById")
int deleteById(I id);
@DeleteProvider(type = BaseSqlProvider.class, method = "deleteByIds")
int deleteByIds(Collection<I> list);
@SelectProvider(type = BaseSqlProvider.class, method = "countAll")
int countAll();
@SelectProvider(type = BaseSqlProvider.class, method = "countByEntity")
int countByEntity(E e);
}
2. BaseSqlProvider实现如下:
import com.aylvn.bn.common.utils.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.builder.annotation.ProviderContext;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.util.Arrays;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* 用于缓存和返回通用SQL语句
*
* @author Aylvn
* @date 2021-01-24
*/
@Slf4j
public class BaseSqlProvider {
private static final Map<String, String> BASE_SQL_CACHE_MAP = new ConcurrentHashMap<>();
public String getById(ProviderContext context) {
return BASE_SQL_CACHE_MAP.computeIfAbsent(getCacheKey(context), value -> {
Sql sql = new Sql();
sql.select(fields(context));
sql.from(tableName(context));
sql.where(id(context));
log.debug("getById:\n{}", sql.build());
return sql.build();
});
}
public String listByIds(ProviderContext context) {
return BASE_SQL_CACHE_MAP.computeIfAbsent(getCacheKey(context), value -> {
Sql sql = new Sql();
sql.select(fields(context));
sql.from(tableName(context));
sql.whereIn(id(context));
log.debug("listByIds:\n{}", sql.build());
return sql.build();
});
}
public String listByEntity(ProviderContext context) {
return BASE_SQL_CACHE_MAP.computeIfAbsent(getCacheKey(context), value -> {
Sql sql = new Sql();
sql.select(fields(context));
sql.from(tableName(context));
sql.where(fields(context));
log.debug("listByEntity:\n{}", sql.build());
return sql.build();
});
}
public String insert(ProviderContext context) {
return BASE_SQL_CACHE_MAP.computeIfAbsent(getCacheKey(context), value -> {
Sql sql = new Sql();
sql.insertInto(tableName(context), fields(context));
sql.values(fields(context));
log.debug("insert:\n{}", sql.build());
return sql.build();
});
}
public String insertBatch(ProviderContext context) {
return BASE_SQL_CACHE_MAP.computeIfAbsent(getCacheKey(context), value -> {
Sql sql = new Sql();
sql.insertIntoBatch(tableName(context), fields(context));
sql.valuesBatch(fields(context));
log.debug("insertBatch:\n{}", sql.build());
return sql.build();
});
}
public String updateById(ProviderContext context) {
return BASE_SQL_CACHE_MAP.computeIfAbsent(getCacheKey(context), value -> {
Sql sql = new Sql();
sql.update(tableName(context));
String[] fieldsExceptId = Arrays.stream(fields(context)).filter(field -> !field.equals(id(context))).toArray(String