前言:使用mybatis自动生成mapper.xml文件,同时自己写的sql放在mapperExt.xml中,随着表的增加,启动越来越慢,为减少加载xml的时间,去掉生成的mapper.xml文件,步骤如下
1.重写AutoSqlInjector的inject(...)方法
/**
* 自定义方法,注入点(子类需重写该方法)
*/
public void inject(Configuration configuration, MapperBuilderAssistant builderAssistant, Class<?> mapperClass,
Class<?> modelClass, TableInfo table) {
// to do nothing
}
重写后如下:
public class CustomAutoSqlInjector {
/**
* 自定义方法,注入点(子类需重写该方法)
*/
@Override
public void inject(Configuration configuration, MapperBuilderAssistant builderAssistant, Class<?> mapperClass, Class<?> modelClass, TableInfo table) {
injectSelectRecordsSql(configuration, builderAssistant, mapperClass, modelClass, table);
injectSelectRecordsByConditionSql(configuration, builderAssistant, mapperClass, modelClass, table);
injectSelectIdPageSql(configuration, builderAssistant, mapperClass, modelClass, table);
}
protected void injectSelectRecordsSql(Configuration configuration, MapperBuilderAssistant builderAssistant, Class<?> mapperClass, Class<?> modelClass, TableInfo table) {
String method = "selectRecords";
String sql = selectRecordsSql(table);
SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
this.addSelectMappedStatement(mapperClass, method, sqlSource, modelClass, table);
}
protected void injectSelectRecordsByConditionSql(Configuration configuration, MapperBuilderAssistant builderAssistant, Class<?> mapperClass, Class<?> modelClass, TableInfo table) {
String method = "selectRecordsByCondition";
String sql = selectRecordsByCondition(table);
SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
this.addSelectMappedStatement(mapperClass, method, sqlSource, modelClass, table);
}
protected void injectSelectIdPageSql(Configuration configuration, MapperBuilderAssistant builderAssistant, Class<?> mapperClass, Class<?> modelClass, TableInfo table) {
String method = "selectIdPage";
String sql = selectIdPageSql(table);
SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
this.addSelectMappedStatement(mapperClass, method, sqlSource, modelClass, table);
}
protected String selectRecordsSql(TableInfo tableInfo) {
StringBuilder sql = new StringBuilder();
sql.append("<script>");
sql.append("select ").append(sqlSelectColumns(tableInfo, false)).append(" from ").append(tableInfo.getTableName());
sql.append("\n<where>del_flg = 1");
tableInfo.getFieldList().forEach(t -> {
sql.append("\n<if test=\"").append(t.getProperty()).append(" != null\">");
sql.append("\nand ").append(t.getColumn()).append(" = #{").append(t.getProperty()).append("}");
sql.append("\n</if>");
});
sql.append("\n<if test=\"keyword != null and keyword != '' and fields.size() > 0 \">");
sql.append("\nand <foreach collection=\"fields\" close=\")\" open=\"(\" index=\"index\" item=\"item\" separator=\"or\">");
sql.append("\n${item} like concat('%',#{keyword},'%')");
sql.append("\n</foreach>");
sql.append("\n</if>");
sql.append("\n</where>");
sql.append("\n<if test=\"orderBy != null and orderBy != ''\">");
sql.append("\norder by ${orderBy}");
sql.append("\n</if>");
sql.append("</script>");
return sql.toString();
}
protected String selectRecordsByCondition(TableInfo tableInfo) {
StringBuilder sql = new StringBuilder();
sql.append("<script>");
sql.append("select ").append(sqlSelectColumns(tableInfo, false)).append(" from ").append(tableInfo.getTableName());
sql.append("\n${cw.sqlSegment}");
sql.append("\nand del_flg = 1");
tableInfo.getFieldList().forEach(t -> {
sql.append("\n<if test=\"em.").append(t.getProperty()).append(" != null\">");
sql.append("\nand ").append(t.getColumn()).append(" = #{em.").append(t.getProperty()).append("}");
sql.append("\n</if>");
});
sql.append("\n<if test=\"em.keyword != null and em.keyword != '' and em.fields.size() > 0 \">");
sql.append("\nand <foreach collection=\"em.fields\" close=\")\" open=\"(\" index=\"index\" item=\"item\" separator=\"or\">");
sql.append("\n${item} like concat('%',#{em.keyword},'%')");
sql.append("\n</foreach>");
sql.append("\n</if>");
sql.append("\n<if test=\"em.orderBy != null and em.orderBy != ''\">");
sql.append("\norder by ${em.orderBy}");
sql.append("\n</if>");
sql.append("</script>");
return sql.toString();
}
protected String selectIdPageSql(TableInfo tableInfo){
StringBuilder sql = new StringBuilder();
sql.append("<script>");
sql.append("select id from ").append(tableInfo.getTableName());
sql.append("\n<where>del_flg = 1");
tableInfo.getFieldList().forEach(t -> {
sql.append("\n<if test=\"cm.").append(t.getProperty()).append(" != null\">");
sql.append("\nand ").append(t.getColumn()).append(" = #{cm.").append(t.getProperty()).append("}");
sql.append("\n</if>");
});
sql.append("\n<if test=\"cm.keyword != null and cm.keyword != ''\">");
sql.append("\nand (");
tableInfo.getFieldList().forEach(t -> {
sql.append("\nor ").append(t.getColumn()).append(" like concat('%',#{cm.keyword},'%')");
});
sql.append("\n)</if>");
sql.append("\n</where>");
sql.append("</script>");
return sql.toString();
}
}
2.修改mybatis-plus配置文件(application.yml)指定刚刚自定义的注入器位置
mybatis-plus:
type-aliases-package: com.xxx.dal.model
mapper-locations: classpath*:com/xxx/dal/mapper/**/*.xml
configuration:
map-underscore-to-camel-case: true
default-fetch-size: 100
default-statement-timeout: 30
global-config:
sql-injector: com.xxx.dal.config.CustomAutoSqlInjector
可以删除自动生产mapper.xml文件,只保留maperExt.xml即可
另:也可以重写update语句中的set部分,支持update空字符串
/**
* SQL 更新 set 语句
*
* @param table 表
* @param prefix 前缀
*/
@Override
protected String sqlSet(TableInfo table, String prefix) {
StringBuilder set = new StringBuilder();
set.append("<trim prefix=\"SET\" suffixOverrides=\",\">");
List<TableFieldInfo> fieldList = table.getFieldList();
for (TableFieldInfo fieldInfo : fieldList) {
set.append(convertIfTagForUpdate(true, fieldInfo, prefix, false));
set.append(fieldInfo.getColumn()).append("=#{");
if (null != prefix) {
set.append(prefix);
}
set.append(fieldInfo.getEl()).append("},");
set.append(convertIfTagForUpdate(true, fieldInfo, null, true));
}
set.append("\n</trim>");
return set.toString();
}
/**
* IF 条件转换方法
*
* @param ignored 允许忽略
* @param fieldInfo 字段信息
* @param prefix 条件前缀
* @param colse 是否闭合标签
*/
protected String convertIfTagForUpdate(boolean ignored, TableFieldInfo fieldInfo, String prefix, boolean colse) {
/* 忽略策略 */
FieldStrategy fieldStrategy = fieldInfo.getFieldStrategy();
if (fieldStrategy == FieldStrategy.IGNORED) {
if (ignored) {
return "";
}
// 查询策略,使用全局策略
GlobalConfiguration.getGlobalConfig(configuration).getFieldStrategy();
}
// 关闭标签
if (colse) {
return "</if>";
}
// 前缀处理
String property = fieldInfo.getProperty();
if (null != prefix) {
property = prefix + property;
}
return String.format("\n\t<if test=\"%s!=null\">", property);
}