共901行
2026-07-08 08:48:14
package com.dpb.yunc.db.mapper.common;
import org.apache.ibatis.annotations.*;
import java.util.List;
import java.util.Map;
public interface BaseMapper<T, ID> {
/**
* 新增一条记录
*
* @param entity 实体
* @return 受影响记录
*/
@InsertProvider(type = BaseSqlProvider.class, method = "insert")
@Options(useGeneratedKeys = true, keyColumn = "id", keyProperty = "id")
int insert(T entity);
/**
* 删除一条记录
*
* @param id id
* @return 受影响记录
*/
@DeleteProvider(type = BaseSqlProvider.class, method = "delete")
int delete(ID id);
/**
* 修改一条记录
*
* @param entity 实体
* @return 受影响记录
*/
@UpdateProvider(type = BaseSqlProvider.class, method = "update")
int update(T entity);
/**
* 根据id查询
*
* @param id id
* @return Entity
*/
@SelectProvider(type = BaseSqlProvider.class, method = "selectById")
T selectById(ID id);
/**
* 查询所有数据
*
* @param entity 实体
* @return 查询结果
*/
@SelectProvider(type = BaseSqlProvider.class, method = "selectByEntity")
List<T> selectByEntity(T entity);
/**
* 查询所有数据
*
* @param criteriaMap - 查询参数Map
* @return 查询结构
*/
@SelectProvider(type = BaseSqlProvider.class, method = "selectByCriteriaMap")
List<T> selectByCriteriaMap(Map<String, Object> criteriaMap);
/**
* 根据id列表查询
*
* @param ids id列表
* @return 查询结果
*/
@SelectProvider(type = BaseSqlProvider.class, method = "selectByIds")
List<T> selectByIds(List<ID> ids);
/**
* 批量删除
* @param ids id列表
* @return 受影响记录
*/
@DeleteProvider(type = BaseSqlProvider.class, method = "deleteAll")
int deleteAll(List<ID> ids);
/**
* 批量保存
*
* @param entities 实体列表
* @return 受影响记录
*/
@InsertProvider(type = BaseSqlProvider.class, method = "insertAll")
@Options(useGeneratedKeys = true, keyColumn = "id", keyProperty = "id")
int insertAll(List<T> entities);
/**
* 逻辑删除
* @param id id列表
* @return 受影响记录
*/
@UpdateProvider(type = BaseSqlProvider.class, method = "smartDelete")
int smartDelete(ID id);
/**
* 批量逻辑删除
* @param ids id列表
* @return 受影响记录
*/
@UpdateProvider(type = BaseSqlProvider.class, method = "smartDeleteAll")
int smartDeleteAll(List<ID> ids);
}文件作用: 泛型基础Mapper接口,提供通用的数据库CRUD操作
核心设计:
<T, ID> - T为实体类型,ID为主键类型@Provider注解动态生成SQL提供的方法:
| 方法 | 功能 | 说明 |
|---|---|---|
insert(T entity) |
新增记录 | 支持主键自动回填 |
delete(ID id) |
物理删除 | 根据ID删除 |
update(T entity) |
更新记录 | 根据ID更新 |
selectById(ID id) |
根据ID查询 | 返回单个实体 |
selectByEntity(T entity) |
按实体查询 | 非空字段作为查询条件 |
selectByCriteriaMap(Map) |
按Map查询 | 支持复杂查询条件 |
selectByIds(List<ID> ids) |
批量ID查询 | 返回实体列表 |
deleteAll(List<ID> ids) |
批量物理删除 | 根据ID列表删除 |
insertAll(List<T> entities) |
批量插入 | 支持主键回填 |
smartDelete(ID id) |
逻辑删除 | 自动判断是否有delFlag字段 |
smartDeleteAll(List<ID> ids) |
批量逻辑删除 | 同smartDelete |
package com.dpb.yunc.db.mapper.common;
import cn.hutool.core.util.StrUtil;
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;
public class BaseSqlProvider {
private static final Map<String, String> BASE_SQL_CACHE_MAP = new ConcurrentHashMap<>();
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));
return sql.build();
});
}
public String delete(ProviderContext context) {
return BASE_SQL_CACHE_MAP.computeIfAbsent(getCacheKey(context), value -> {
Sql sql = new Sql();
sql.deleteFrom(tableName(context));
sql.where(id(context));
return sql.build();
});
}
public String update(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[]::new);
sql.set(fieldsExceptId);
sql.whereId(id(context));
return sql.build();
});
}
public String selectById(ProviderContext context) {
return BASE_SQL_CACHE_MAP.computeIfAbsent(getCacheKey(context), value -> {
Sql sql = new Sql();
sql.select(fields(context));
sql.from(tableName(context));
sql.whereId(id(context));
return sql.build();
});
}
public String selectByIds(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));
return sql.build();
});
}
public String selectByEntity(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));
return sql.build();
});
}
public String selectByCriteriaMap(ProviderContext context, Map<String, Object> criteriaMap) {
return BASE_SQL_CACHE_MAP.computeIfAbsent(getCacheKey(context) + ":" + criteriaMap.keySet(), value -> {
Sql sql = new Sql();
sql.select(fields(context));
sql.from(tableName(context));
sql.whereCriteria(criteriaMap.keySet().toArray(new String[0]));
return sql.build();
});
}
public String deleteAll(ProviderContext context) {
return BASE_SQL_CACHE_MAP.computeIfAbsent(getCacheKey(context), value -> {
Sql sql = new Sql();
sql.deleteFrom(tableName(context));
sql.whereIn(id(context));
return sql.build();
});
}
public String insertAll(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));
return sql.build();
});
}
/**
* 逻辑删除
*/
public String smartDelete(ProviderContext context) {
return BASE_SQL_CACHE_MAP.computeIfAbsent(getCacheKey(context), value -> {
Sql sql = new Sql();
if (hasDelFlag(context)) {
sql.update(tableName(context));
sql.sql(" SET del_flag = 1 ");
sql.where(id(context));
} else {
sql.deleteFrom(tableName(context));
sql.where(id(context));
}
return sql.build();
});
}
public String smartDeleteAll(ProviderContext context) {
return BASE_SQL_CACHE_MAP.computeIfAbsent(getCacheKey(context), value -> {
Sql sql = new Sql();
if (hasDelFlag(context)) {
sql.update(tableName(context));
sql.sql(" SET delFlag = 1 ");
sql.whereIn(id(context));
} else {
sql.deleteFrom(tableName(context));
sql.whereIn(id(context));
}
return sql.build();
});
}
/**
* 主键 默认取实体的第一个字段
*/
public static String id(ProviderContext context) {
return fields(context)[0];
}
/**
* 所有字段名称
*/
public static String[] fields(ProviderContext context) {
Class<?> entityType = entityType(context);
Field[] entityFields = entityType.getDeclaredFields();
Field[] superFields = entityType.getSuperclass().getDeclaredFields();
// 过滤掉序列化版本号字段
entityFields = Arrays.stream(entityFields).filter(field -> !"serialVersionUID".equals(field.getName())).toArray(Field[]::new);
superFields = Arrays.stream(superFields).filter(field -> !"serialVersionUID".equals(field.getName())).toArray(Field[]::new);
Field[] fields = Arrays.copyOf(superFields, entityFields.length + superFields.length);
System.arraycopy(entityFields, 0, fields, superFields.length, entityFields.length);
return Arrays.stream(fields)
.filter(field -> field.getAnnotation(IgnoreField.class) == null)
.map(Field::getName)
.toArray(String[]::new);
}
/**
* 表名称
*/
public static String tableName(ProviderContext context) {
String tableName = StrUtil.toUnderlineCase(entityType(context).getSimpleName());
return tableName.substring(0, tableName.length() - 3);
}
/**
* 获取实体类型
*/
private static Class<?> entityType(ProviderContext context) {
Class<?> clazz = context.getMapperType();
return (Class<?>) ((ParameterizedType) (clazz.getGenericInterfaces()[0])).getActualTypeArguments()[0];
}
/**
* 缓存key
*/
private static String getCacheKey(ProviderContext context) {
return context.getMapperType().getSimpleName() + ":" + context.getMapperMethod().getName();
}
/**
* 判断实体类是否包含 delFlag 字段
*/
private static boolean hasDelFlag(ProviderContext context) {
try {
Class<?> entityType = entityType(context);
Field[] entityFields = entityType.getDeclaredFields();
for (Field field : entityFields) {
if ("delFlag".equals(field.getName())) {
return true;
}
}
Field[] superFields = entityType.getSuperclass().getDeclaredFields();
for (Field field : superFields) {
if ("delFlag".equals(field.getName())) {
return true;
}
}
return false;
} catch (Exception e) {
return false;
}
}
}文件作用: SQL提供者,为BaseMapper生成动态SQL语句
核心机制:
ConcurrentHashMap缓存生成的SQL,避免重复解析UserPO → user)userName → user_name)关键方法:
| 方法 | 功能 |
|---|---|
id(context) |
获取主键字段(默认第一个字段) |
fields(context) |
获取所有字段(过滤serialVersionUID和@IgnoreField标记的字段) |
tableName(context) |
获取表名 |
hasDelFlag(context) |
检查是否有delFlag字段,用于判断逻辑删除 |
智能逻辑删除:
// smartDelete方法会自动判断:
if (hasDelFlag(context)) {
// 有delFlag字段 → 执行 UPDATE table SET del_flag = 1
} else {
// 无delFlag字段 → 执行 DELETE FROM table
}package com.dpb.yunc.db.mapper.common;
import cn.hutool.core.util.StrUtil;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class Sql {
private final Criteria criteria = new Criteria();
private static final String SELECT = "SELECT";
private static final String FROM = "FROM";
private static final String WHERE = "WHERE";
private static final String AND = "AND ";
private static final String IN = " IN ";
private static final String INSERT_INTO = "INSERT INTO";
private static final String VALUES = "VALUES";
private static final String UPDATE = "UPDATE";
private static final String DELETE_FROM = "DELETE FROM";
private static final String COUNT = "COUNT";
private static final String OPEN_BRACKET = "(";
private static final String CLOSE_BRACKET = ")";
private static final String BRACKET_NULL = "(NULL)";
private static final String SCRIPT_HEAD = "<script>";
private static final String SCRIPT_END = "</script>";
private static final String WHERE_HEAD = "<where>";
private static final String WHERE_END = "</where>";
private static final String IF_HEAD_LIST_NOT_BLANK = "<if test = \"list != null and list.size() > 0\">";
private static final String IF_HEAD_LIST_BLANK = "<if test = \"list == null or list.size() == 0\">";
private static final String IF_HEAD_PREFIX = "<if test = \"";
private static final String IF_HEAD_SUFFIX = " != null\">";
private static final String IF_END = "</if>";
private static final String SCRIPT_TYPE = "</";
private static final String TRIM_HEAD_BRACKET = "<trim prefix=\"(\" suffix=\")\" suffixOverrides=\",\">";
private static final String TRIM_END = "</trim>";
private static final String SET_HEAD = "<set>";
private static final String SET_END = "</set>";
/**
* foreach 要做foreach的对象,作为入参时,List对象默认用"list"代替作为键,数组对象有"array"代替作为键
* 在作为入参时可以使用@Param("keyName")来设置键,设置keyName后,list,array将会失效。
* 除了入参这种情况外,还有一种作为参数对象的某个字段的时候。举个例子:如果User有属性List ids。入参是User对象,那么这个collection = "ids"
*/
private static final String FOREACH_HEAD_LIST = "<foreach item = \"item\" collection = \"list\" separator = \",\" index = \"index\">";
private static final String FOREACH_HEAD_BRACKET_LIST = "<foreach item = \"item\" collection = \"list\" separator = \",\" open=\"(\" close=\")\" index = \"index\">";
private static final String FOREACH_ITEM = "#{item}";
private static final String FOREACH_END = "</foreach>";
private static final String EQUALS = " = ";
private static final String COMMA = ",";
private static final String COMMA_CRLF_TAB = ",\n\t";
private static final String COMMA_CRLF_TAB_TAB = ",\n\t\t";
private final StringBuilder sql;
public Sql() {
this.sql = new StringBuilder();
}
public Sql sql() {
return this;
}
public Sql sql(String str) {
sql.append(str);
return this;
}
public Sql crlf() {
return sql("\n");
}
public Sql tab() {
return sql("\t");
}
public Sql select(String... fields) {
List<String> columns = Arrays.stream(fields).map(StrUtil::toUnderlineCase).collect(Collectors.toList());
sql(SELECT).crlf();
tab().sql(String.join(COMMA_CRLF_TAB, columns)).crlf();
return this;
}
public Sql selectCount(String field) {
sql(SELECT).crlf();
tab().sql(COUNT).sql(OPEN_BRACKET).sql(field).sql(CLOSE_BRACKET).crlf();
return this;
}
public Sql from(String tableName) {
sql(FROM).crlf();
tab().sql(tableName).crlf();
return this;
}
public Sql where(String... fields) {
List<String> conditions = Arrays.stream(fields).map(this::ifAndColumnFieldRel).collect(Collectors.toList());
sql(WHERE_HEAD).crlf();
sql(String.join("", conditions));
sql(WHERE_END).crlf();
return this;
}
public Sql whereCriteria(String... criteriaKeys) {
List<String> conditions = Arrays.stream(criteriaKeys).map(criteria::ifAndCriteriaRel).collect(Collectors.toList());
sql(WHERE_HEAD).crlf();
sql(String.join("", conditions));
sql(WHERE_END).crlf();
return this;
}
public Sql whereId(String id){
sql(WHERE_HEAD).crlf();
sql(columnFieldRel(id));
sql(WHERE_END).crlf();
return this;
}
public Sql whereIn(String field) {
sql(WHERE).crlf();
foreachIn(field);
return this;
}
/**
* 插入不为null的字段
*/
public Sql insertInto(String tableName, String... fields) {
String[] ifColumns = Arrays.stream(fields).map(this::ifColumnComma).toArray(String[]::new);
sql(INSERT_INTO).crlf();
tab().sql(tableName).crlf();
tab().trimHeadBracket();
sql(String.join("", ifColumns));
tab().trimEnd();
return this;
}
public Sql insertIntoBatch(String tableName, String... fields) {
String[] columns = Arrays.stream(fields).map(StrUtil::toUnderlineCase).toArray(String[]::new);
sql(INSERT_INTO).crlf();
tab().sql(tableName).sql(OPEN_BRACKET).crlf();
tab().tab().sql(String.join(COMMA_CRLF_TAB_TAB, columns)).crlf();
tab().sql(CLOSE_BRACKET).crlf();
return this;
}
public Sql values(String... fields) {
String[] ifFields = Arrays.stream(fields).map(this::ifHashFieldComma).toArray(String[]::new);
sql(VALUES).crlf();
tab().trimHeadBracket();
sql(String.join("", ifFields));
tab().trimEnd();
return this;
}
public Sql valuesBatch(String... fields) {
String[] hashListFields = Arrays.stream(fields).map(this::hashListField).toArray(String[]::new);
sql(VALUES).crlf();
tab().foreachHeadList();
tab().trimHeadBracket();
tab().tab().sql(String.join(COMMA_CRLF_TAB_TAB, hashListFields)).crlf();
tab().trimEnd();
tab().foreachEnd();
return this;
}
public Sql update(String tableName) {
sql(UPDATE).crlf();
tab().sql(tableName).crlf();
return this;
}
public Sql set(String... fields) {
List<String> conditions = Arrays.stream(fields).map(this::ifColumnFieldRelComma).collect(Collectors.toList());
sql(SET_HEAD).crlf();
sql(String.join("", conditions)).crlf();
sql(SET_END).crlf();
return this;
}
public Sql deleteFrom(String tableName) {
sql(DELETE_FROM).crlf();
tab().sql(tableName).crlf();
return this;
}
public Sql in() {
return sql(IN);
}
public Sql ifHeadListNotBlank() {
return sql(IF_HEAD_LIST_NOT_BLANK).crlf();
}
public Sql ifHeadListBlank() {
return sql(IF_HEAD_LIST_BLANK).crlf();
}
public Sql ifHead(String field) {
return sql(IF_HEAD_PREFIX).sql(field).sql(IF_HEAD_SUFFIX).crlf();
}
public Sql ifEnd() {
return sql(IF_END).crlf();
}
public Sql bracketNull() {
return sql(BRACKET_NULL).crlf();
}
public Sql foreachHeadBracketList() {
return sql(FOREACH_HEAD_BRACKET_LIST).crlf();
}
public Sql foreachHeadList() {
return sql(FOREACH_HEAD_LIST).crlf();
}
public Sql foreachItem() {
return sql(FOREACH_ITEM).crlf();
}
public Sql foreachEnd() {
return sql(FOREACH_END).crlf();
}
public Sql trimHeadBracket() {
return sql(TRIM_HEAD_BRACKET).crlf();
}
public Sql trimEnd() {
return sql(TRIM_END).crlf();
}
public Sql foreachIn(String field) {
tab().sql(StrUtil.toUnderlineCase(field)).in().crlf();
tab().ifHeadListNotBlank();
tab().tab().foreachHeadBracketList();
tab().tab().tab().foreachItem();
tab().tab().foreachEnd();
tab().ifEnd();
tab().ifHeadListBlank();
tab().tab().bracketNull();
tab().ifEnd();
return this;
}
@Override
public String toString() {
return sql.toString();
}
public String build() {
if (sql.toString().contains(SCRIPT_TYPE)) {
return SCRIPT_HEAD + "\n" + sql.toString() + SCRIPT_END;
}
return sql.toString();
}
private String columnFieldRel(String field, String rel) {
return StrUtil.toUnderlineCase(field) + " " + rel + " " + hashField(field);
}
private String columnFieldRel(String field) {
return columnFieldRel(field, EQUALS);
}
private String andColumnFieldRel(String field) {
return andColumnFieldRel(field, EQUALS);
}
private String andColumnFieldRel(String field, String rel) {
return AND + columnFieldRel(field, rel);
}
private String columnFieldRelComma(String field) {
return columnFieldRelComma(field, EQUALS);
}
private String columnFieldRelComma(String field, String rel) {
return columnFieldRel(field, rel) + COMMA;
}
public String ifColumnComma(String field) {
return ifScript(field, StrUtil.toUnderlineCase(field) + COMMA);
}
public String ifHashFieldComma(String field) {
return ifScript(field, hashField(field) + COMMA);
}
public String ifColumnFieldRel(String field) {
return ifScript(field, columnFieldRel(field));
}
public String ifAndColumnFieldRel(String field) {
return ifScriptForQuery(field, andColumnFieldRel(field));
}
private Sql ifHeadNotEmpty(String field) {
return sql(IF_HEAD_PREFIX).sql(field).sql(" != null and ").sql(field).sql(".toString() != '' \">").crlf();
}
public String ifColumnFieldRelComma(String field) {
return ifScript(field, columnFieldRelComma(field));
}
public String ifScript(String field, String express) {
return new Sql()
.tab().ifHead(field)
.tab().tab().sql(express).crlf()
.tab().ifEnd().toString();
}
public String ifScriptForQuery(String field, String express) {
return new Sql()
.tab().ifHeadNotEmpty(field)
.tab().tab().sql(express).crlf()
.tab().ifEnd().toString();
}
public String ifScriptForQueryCriteria(String field, String express) {
return new Sql()
.tab().ifHead(field)
.tab().tab().sql(express).crlf()
.tab().ifEnd().toString();
}
private String hashField(String field) {
return "#{" + field + "}";
}
private String hashListField(String field) {
return "#{item." + field + "}";
}
public class Criteria {
private final static String CRITERIA_LIKE = "_like";
private final static String CRITERIA_LIKE_RIGHT = "_likeRight";
private final static String CRITERIA_LIKE_LEFT = "_likeLeft";
private final static String CRITERIA_LT = "_lt";
private final static String CRITERIA_GT = "_gt";
private final static String CRITERIA_LTE = "_lte";
private final static String CRITERIA_GTE = "_gte";
private final static String CRITERIA_IN = "_in";
private final static String CRITERIA_NOT_EQ = "_ne";
private final static String CRITERIA_IS_NULL = "_isNull";
private final static String CRITERIA_NOT_NULL = "_notNull";
private final static String CRITERIA_BETWEEN = "_between";
private final static String LIKE = " like ";
private final static String CONCAT = " concat";
private final static String PERCENT = "'%'";
private final static String EMPTY = " ";
private final static String LT = " < ";
private final static String LTE = " <= ";
private final static String GT = " > ";
private final static String GTE = " >= ";
private final static String BETWEEN = " between ";
private String concat(String... express) {
return CONCAT.concat(OPEN_BRACKET).concat(String.join(",",express)).concat(CLOSE_BRACKET).concat(EMPTY);
}
private String andColumnCriteriaRel(String criteria) {
if (criteria.endsWith(CRITERIA_LIKE)) {
String field = StrUtil.toUnderlineCase(criteria.substring(0, criteria.length() - CRITERIA_LIKE.length()));
return AND + field + LIKE + concat(PERCENT, hashField(criteria), PERCENT);
} else if (criteria.endsWith(CRITERIA_LIKE_LEFT)) {
String field = StrUtil.toUnderlineCase(criteria.substring(0, criteria.length() - CRITERIA_LIKE_LEFT.length()));
return AND + field + LIKE + concat(PERCENT, hashField(criteria));
} else if (criteria.endsWith(CRITERIA_LIKE_RIGHT)) {
String field = StrUtil.toUnderlineCase(criteria.substring(0, criteria.length() - CRITERIA_LIKE_RIGHT.length()));
return AND + field + LIKE + concat(hashField(criteria), PERCENT);
} else if (criteria.endsWith(CRITERIA_LT)) {
String field = StrUtil.toUnderlineCase(criteria.substring(0, criteria.length() - CRITERIA_LT.length()));
return AND + field + LT + hashField(criteria);
} else if (criteria.endsWith(CRITERIA_GT)) {
String field = StrUtil.toUnderlineCase(criteria.substring(0, criteria.length() - CRITERIA_GT.length()));
return AND + field + GT + hashField(criteria);
} else if (criteria.endsWith(CRITERIA_LTE)) {
String field = StrUtil.toUnderlineCase(criteria.substring(0, criteria.length() - CRITERIA_LTE.length()));
return AND + field + LTE + hashField(criteria);
} else if (criteria.endsWith(CRITERIA_GTE)) {
String field = StrUtil.toUnderlineCase(criteria.substring(0, criteria.length() - CRITERIA_GTE.length()));
return AND + field + GTE + hashField(criteria);
} else if (criteria.endsWith(CRITERIA_IN)) {
String field = StrUtil.toUnderlineCase(criteria.substring(0, criteria.length() - CRITERIA_IN.length()));
return foreachIn(field, criteria);
} else if (criteria.endsWith(CRITERIA_BETWEEN)){
String field = StrUtil.toUnderlineCase(criteria.substring(0, criteria.length() - CRITERIA_BETWEEN.length()));
return AND + field + BETWEEN + hashField(criteria + "[0]") + AND + hashField(criteria + "[1]");
} else if (criteria.endsWith(CRITERIA_NOT_EQ)){
String field = StrUtil.toUnderlineCase(criteria.substring(0, criteria.length() - CRITERIA_NOT_EQ.length()));
return AND + field + " != " + hashField(criteria);
} else if (criteria.endsWith(CRITERIA_IS_NULL)) {
String field = StrUtil.toUnderlineCase(criteria.substring(0, criteria.length() - CRITERIA_IS_NULL.length()));
return AND + field + " is null ";
} else if (criteria.endsWith(CRITERIA_NOT_NULL)){
String field = StrUtil.toUnderlineCase(criteria.substring(0, criteria.length() - CRITERIA_NOT_NULL.length()));
return AND + field + " is not null ";
}else {
return andColumnFieldRel(criteria, EQUALS);
}
}
public String ifAndCriteriaRel(String criteria) {
return ifScriptForQuery(criteria,andColumnCriteriaRel(criteria));
}
private String foreachIn(String field, String listName) {
return String.format(
" <choose> " +
" <when test = '%s.length > 0' > " +
" AND %s in " +
" <foreach item = \"item\" collection = \"%1$s\" separator = \",\" open=\"(\" close=\")\" > " +
" #{item}" +
" </foreach>" +
" </when> " +
" <otherwise> " +
" AND 1 = 2 " +
" </otherwise> " +
" </choose> "
, listName, field);
}
}
}文件作用: SQL构建器,使用Builder模式动态构建MyBatis动态SQL
设计特点:
Sql对象)<script>, <if>, <where>, <set>, <foreach>等)Criteria提供高级查询条件支持支持的查询条件(通过Map参数):
| 后缀 | 含义 | 示例 |
|---|---|---|
_like |
模糊查询(全匹配) | name_like → LIKE '%xxx%' |
_likeLeft |
左模糊 | name_likeLeft → LIKE '%xxx' |
_likeRight |
右模糊 | name_likeRight → LIKE 'xxx%' |
_lt |
小于 | age_lt → < xxx |
_gt |
大于 | age_gt → > xxx |
_lte |
小于等于 | age_lte → ≤ xxx |
_gte |
大于等于 | age_gte → ≥ xxx |
_in |
IN查询 | id_in → IN (x,x,x) |
_ne |
不等于 | status_ne → != xxx |
_isNull |
为空 | field_isNull → IS NULL |
_notNull |
不为空 | field_notNull → IS NOT NULL |
_between |
区间查询 | age_between → BETWEEN x AND y |
生成的SQL示例:
// insert方法生成的SQL:
<script>
INSERT INTO
user
(<trim prefix="(" suffix=")" suffixOverrides=",">
<if test = "id != null">id,</if>
<if test = "name != null">name,</if>
</trim>)
VALUES
(<trim prefix="(" suffix=")" suffixOverrides=",">
<if test = "id != null">#{id},</if>
<if test = "name != null">#{name},</if>
</trim>)
</script>package com.dpb.yunc.db.mapper.common;
import java.lang.annotation.*;
@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface IgnoreField {
}文件作用: 自定义注解,用于标记实体类中需要被忽略的字段
详细说明:
@Retention(RetentionPolicy.RUNTIME))@Target({ElementType.FIELD, ElementType.METHOD}))@Inherited)表示子类可以继承此注解