@SelectProvider(method=”xxx”,type=xxx.class)
MyBatis3提供的这个注解可以让程序员用自定义的类构造SQL语句(method属性为类中要执行获取sql语句的方法,type属性为获取sql语句的指定类)
实现
可以写一个通用的简单CRUD的接口,让mapper类去继承,这样就不用每个mapper都去写这些简单的CRUD的SQL了(类似MyBatis-Plus)
接口:
基本覆盖了所有简单的CRUD
public interface BaseMapper<T> {
@SelectProvider(method = "selectById", type = BaseSelectMapperProvider.class)
T selectById(Long id);
@SelectProvider(method = "selectByIds", type = BaseSelectMapperProvider.class)
List<T> selectByIds(@Param("ids") List<Long> ids);
@SelectProvider(method = "count", type = BaseSelectMapperProvider.class)
Long count(T entity);
@SelectProvider(method = "select", type = BaseSelectMapperProvider.class)
List<T> select(T entity);
@SelectProvider(method = "selectPage", type = BaseSelectMapperProvider.class)
List<T> selectPage(T entity, Long pageStart, Long pageSize);
@InsertProvider(method = "save", type = BaseInsertMapperProvider.class)
@Options(useGeneratedKeys = true)
int save(T entity);
@InsertProvider(method = "batchSave", type = BaseInsertMapperProvider.class)
int batchSave(@Param("entityList") List<T> entityList);
@UpdateProvider(method = "updateById", type = BaseUpdateMapperProvider.class)
int updateById(T entity);
@DeleteProvider(method = "deleteById", type = BaseDeleteMapperProvider.class)
int deleteById(Long id);
@DeleteProvider(method = "delete", type = BaseDeleteMapperProvider.class)
int delete(T entity);
}
Provider实现类:
public class BaseSelectMapperProvider<T> {
// 封装了通用的获取表名、泛型类型等的helper类
private final BaseMapperHandler handler = new BaseMapperHandler();
public String selectById(ProviderContext context){
Class<?> clazz = handler.getEntityClass(context);
String tableName = handler.getTableName(clazz);
SQL sql = new SQL();
sql.SELECT(handler.generateSelectColumnString(clazz));
sql.FROM(tableName);
sql.WHERE("id = #{id}");
return sql.toString();
}
@SuppressWarnings({"unused", "unchecked"})
public String selectByIds(Map<String, Object> map, ProviderContext context) {
Class<?> clazz = handler.getEntityClass(context);
List<String> list = new ArrayList<>();
List<Long> ids = (List<Long>) map.get("ids");
ids.forEach(id -> list.add(String.valueOf(id)));
String tableName = handler.getTableName(clazz);
SQL sql = new SQL();
sql.SELECT(handler.generateSelectColumnString(clazz));
sql.FROM(tableName);
sql.WHERE("id in (" + String.join(",", list) + ")");
return sql.toString();
}
public String select(T entity, ProviderContext context){
Class<?> clazz = handler.getEntityClass(context);
String tableName = handler.getTableName(clazz);
SQL sql = new SQL();
sql.SELECT(handler.generateSelectColumnString(clazz));
sql.FROM(tableName);
String whereSql = generateWhereSql(entity, clazz);
if (null != whereSql) {
sql.WHERE(whereSql);
}
return sql.toString();
}
public String count(T entity, ProviderContext context) {
Class<?> clazz = handler.getEntityClass(context);
String tableName = handler.getTableName(clazz);
SQL sql = new SQL();
sql.SELECT("count(id)");
sql.FROM(tableName);
String whereSql = generateWhereSql(entity, clazz);
if (null != whereSql) {
sql.WHERE(whereSql);
}
return sql.toString();
}
public String selectPage(T entity, Long pageStart, Long pageSize,ProviderContext context) {
return select(entity, context) + " limit " + pageStart + ", " + pageSize;
}
private String generateWhereSql(T entity, Class<?> clazz){
StringBuilder sql = new StringBuilder();
Field[] fields = handler.getAllFields(clazz);
int whereNum = 0;
for (Field field : fields) {
ColumnName columnNameAnnotation = field.getAnnotation(ColumnName.class);
String fieldName;
if (null != columnNameAnnotation) {
fieldName = columnNameAnnotation.value();
} else {
fieldName = field.getName();
}
if (ObjectUtil.isNotNull(handler.getFieldValue(entity, field.getName()))) {
sql.append(fieldName).append(" = #{").append(field.getName()).append("} and ");
whereNum++;
}
}
if (whereNum == 0) {
return null;
} else {
return sql.substring(0, sql.length() - 5);
}
}
}
使用:
只要继承这个接口,传递实体类,就可以简单使用了。
@Mapper
public interface customerInfoMapper extends BaseMapper<customerInfo> {
}