前言
写博客是为了记录和分享自己的学习,所分享内容是网上的资源,由于非原创项目,主要分享学习思路,只展示贴图部分代码(本人不分享本项目源码,支持项目付费)
一、创建mapper.xml文件以及生成XML 头部信息
//创建MapperXml包
File folder = new File(Constants.PATH_MAPPER_XML);
if(!folder.exists()){
folder.mkdirs();
}
String className= tableInfo.getBeanName()+Constants.SUFFIX_BEAN_MAPPER;
//创建MapperXml文件
File file = new File(folder,className+".xml");
OutputStream out=null;
OutputStreamWriter writer=null;
BufferedWriter bw=null;
out=new FileOutputStream(file);
writer=new OutputStreamWriter(out,"UTF-8");
bw=new BufferedWriter(writer);
bw.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
"<!DOCTYPE mapper PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\" \"http://mybatis.org/dtd/mybatis-3-mapper.dtd\">");
bw.newLine();
bw.write("<mapper namespace=\""+Constants.PACKAGE_MAPPER+"."+className+"\">");
bw.newLine();
bw.newLine();
- 创建MapperXml包
- File folder = new File(Constants.PATH_MAPPER_XML);:通过一个常量路径创建一个表示MapperXml包的File对象。
- if(!folder.exists()){ folder.mkdirs(); }:如果该包对应的文件路径不存在,则创建这个目录。
- 创建 MapperXml 文件
- String className = tableInfo.getBeanName()+Constants.SUFFIX_BEAN_MAPPER;:获取表信息中的 bean 名称,并加上特定后缀组成文件名。
- File file = new File(folder,className+".xml");:在已创建的MapperXml包中创建一个以特定名称命名的 XML 文件。
- 准备写入文件
- OutputStream out = null;、OutputStreamWriter writer = null;、BufferedWriter bw = null;:声明输出流、输出流写入器和缓冲写入器,用于向文件写入内容。
- out = new FileOutputStream(file);:创建一个文件输出流,指向要创建的 XML 文件。
- writer = new OutputStreamWriter(out,"UTF-8");:使用指定的字符编码创建一个输出流写入器,包裹文件输出流。
- bw = new BufferedWriter(writer);:创建一个缓冲写入器,包裹输出流写入器,以提高写入效率。
- 写入内容
- bw.write("\n" + "");:向 XML 文件写入 XML 声明和 DTD 定义。
- bw.newLine();:写入一个换行符。
- bw.write("<mapper namespace=""+Constants.PACKAGE_MAPPER+"."+className+"">");:写入标签的开头部分,并设置命名空间为特定的包名和类名。
二、生成实体映射
//生成实体映射
bw.write("\t<!--实体映射-->");
bw.newLine();
String dtoClassName=Constants.PACKAGE_PO+"."+tableInfo.getBeanName()+Constants.SUFFIX_BEAN_PO;
bw.write("\t<resultMap id=\""+tableInfo.getBeanName()+"ResultMap\" type=\""+dtoClassName+"\">");
bw.newLine();
FieldInfo isField=null;
Map<String, List<FieldInfo>> keyIndexMap = tableInfo.getKeyIndexMap();
for(Map.Entry<String,List<FieldInfo>> entry:keyIndexMap.entrySet()){
if("PRIMARY".equals(entry.getKey())){
List<FieldInfo> fieldInfoList = entry.getValue();
if(fieldInfoList.size()==1){
isField=fieldInfoList.get(0);
break;
}
}
}
for(FieldInfo fieldInfo:tableInfo.getFieldIofoList()){
bw.write("\t\t<!-- "+fieldInfo.getComment()+" -->");
bw.newLine();
String key="";
if(isField!=null && fieldInfo.getPropertyName().equals(isField.getFieldName())){
key="id";
}else {
key="result";
}
bw.write("\t\t<"+key+" column=\""+fieldInfo.getFieldName()+"\" property=\""+fieldInfo.getPropertyName()+"\"/>");
bw.newLine();
}
bw.write("\t</resultMap>");
bw.newLine();
bw.newLine();
这段代码在之前创建的 MyBatis Mapper XML 文件中生成实体映射部分。具体来说,它创建了一个名为tableInfo.getBeanName() + "ResultMap"的结果映射,用于将数据库查询结果映射到指定的实体类。
- 创建结果映射
- String dtoClassName = Constants.PACKAGE_PO + "." + tableInfo.getBeanName() + Constants.SUFFIX_BEAN_PO;:构建实体类的全限定名。
- bw.write("\t<resultMap id="" + tableInfo.getBeanName() + "ResultMap" type="" + dtoClassName + "">");:开始定义一个结果映射,指定其 ID 和对应的实体类类型。
- 确定主键字段 通过遍历tableInfo.getKeyIndexMap(),查找键为"PRIMARY"的条目,获取主键字段信息。如果主键只有一个字段,将其存储在isField变量中。
- 生成字段映射 遍历tableInfo.getFieldIofoList(),对于每个字段: 根据字段是否为主键确定映射的标签类型:如果是主键字段,使用id标签;否则,使用result标签。然后写入字段映射信息,包括数据库列名和实体类属性名。
三、生成通用sql片段
//通用查询列表
bw.write("\t<!--通用查询列表-->");
bw.newLine();
bw.write("\t<sql id=\""+BASE_COLUMN_LIST+"\">");
bw.newLine();
StringBuilder sb=new StringBuilder();
for(FieldInfo fieldInfo:tableInfo.getFieldIofoList()){
sb.append(fieldInfo.getFieldName()).append(",");
}
String sbStr=sb.substring(0,sb.lastIndexOf(","));
bw.write("\t\t"+sbStr);
bw.newLine();
bw.write("\t</sql>");
bw.newLine();
bw.newLine();
//基础查询条件
bw.write("\t<!--基础查询条件-->");
bw.newLine();
bw.write("\t<sql id=\""+BASE_QUERY_CONDITION+"\">");
bw.newLine();
for(FieldInfo fieldInfo:tableInfo.getFieldIofoList()){
String stringQuery="";
if(ArrayUtils.contains(Constants.SQL_STRING_TYPES,fieldInfo.getSqlType())){
stringQuery="and query."+fieldInfo.getPropertyName()+" !=''";
}
bw.write("\t\t<if test=\"query."+fieldInfo.getPropertyName()+" != null "+stringQuery+"\">");
bw.newLine();
bw.write("\t\t\tand "+fieldInfo.getFieldName()+" = #{query."+fieldInfo.getPropertyName()+"}");
bw.newLine();
bw.write("\t\t</if>");
bw.newLine();
}
bw.write("\t</sql>");
bw.newLine();
bw.newLine();
//拓展查询条件
bw.write("\t<!--拓展查询条件-->");
bw.newLine();
bw.write("\t<sql id=\""+BASE_QUERY_CONDITION_EXTEND+"\">");
bw.newLine();
for(FieldInfo fieldInfo:tableInfo.getFieldExtendInfoList()){
String andWhere="";
if(ArrayUtils.contains(Constants.SQL_STRING_TYPES,fieldInfo.getSqlType())){
andWhere="and "+fieldInfo.getFieldName()+" like concat('%',#{query."+fieldInfo.getPropertyName()+"},'%')";
}else if(ArrayUtils.contains(Constants.SQL_DATE_TIME_TYPES,fieldInfo.getSqlType())||ArrayUtils.contains(Constants.SQL_DATE_TYPE,
fieldInfo.getSqlType())){
if(fieldInfo.getPropertyName().endsWith(Constants.SUFFIX_BEAN_QUREY_DATE_START)){
andWhere="<![CDATA[ and "+fieldInfo.getFieldName()+">=str_to_date(#{query."+fieldInfo.getPropertyName()+"}, '%Y-%m-%d') ]]>";
} else if (fieldInfo.getPropertyName().endsWith(Constants.SUFFIX_BEAN_QUREY_DATE_END)) {
andWhere="<![CDATA[ and "+fieldInfo.getFieldName()+"< date_sub(str_to_date(#{query."+fieldInfo.getPropertyName()+"}, '%Y-%m-%d'),"+
"interval -1 day) ]]>";
}
}
bw.write("\t\t<if test=\"query."+fieldInfo.getPropertyName()+" != null and query."+fieldInfo.getPropertyName()+" !=''\">");
bw.newLine();
// bw.write("\t\t\tand id = #{query."+fieldInfo.getPropertyName()+" }");
bw.write("\t\t\t"+andWhere);
bw.newLine();
bw.write("\t\t</if>");
bw.newLine();
}
bw.write("\t</sql>");
bw.newLine();
bw.newLine();
//通用查询条件
bw.write("\t<!--通用查询条件-->");
bw.newLine();
bw.write("\t<sql id=\""+QUERY_CONDITION+"\">");
bw.newLine();
bw.write("\t\t<where>");
bw.newLine();
bw.write("\t\t\t<include refid=\""+BASE_QUERY_CONDITION+"\"/>");
bw.newLine();
bw.write("\t\t\t<include refid=\""+BASE_QUERY_CONDITION_EXTEND+"\"/>");
bw.newLine();
bw.write("\t\t</where>");
bw.newLine();
bw.write("\t</sql>");
bw.newLine();
bw.newLine();
这段代码在Mapper XML 文件中继续添加了通用查询列表和不同类型的查询条件相关的内容,方便我们在之后的片段调用。
- 通用查询列表
- 定义 SQL 片段:bw.write("\t<sql id=""+BASE_COLUMN_LIST+"">");开始定义一个名为BASE_COLUMN_LIST的 SQL 片段。
- 遍历字段列表构建查询列:遍历tableInfo.getFieldIofoList(),将每个字段的名称拼接起来,最后写入 SQL 片段中。
- 基础查询条件
- 定义 SQL 片段:bw.write("\t<sql id=""+BASE_QUERY_CONDITION+"">");开始定义一个名为BASE_QUERY_CONDITION的 SQL 片段。
- 遍历字段列表生成条件判断:对于每个字段,根据字段类型判断是否为字符串类型,如果是,则生成相应的查询条件。使用标签进行条件判断,如果查询参数不为空且不是空字符串,则添加查询条件。
- 拓展查询条件
- 定义 SQL 片段:bw.write("\t<sql id=""+BASE_QUERY_CONDITION_EXTEND+"">");开始定义一个名为BASE_QUERY_CONDITION_EXTEND的 SQL 片段。
- 遍历扩展字段列表生成条件判断:对于每个扩展字段,根据字段类型生成不同的查询条件。如果是字符串类型,则进行模糊查询;如果是日期类型,则根据特定的后缀判断是开始日期还是结束日期,并生成相应的日期范围查询条件。
- 通用查询条件
- 定义 SQL 片段:bw.write("\t<sql id=""+QUERY_CONDITION+"">");开始定义一个名为QUERY_CONDITION的 SQL 片段。
- 使用where标签包裹查询条件:在这个 SQL 片段中,引入了之前定义的基础查询条件和拓展查询条件。
四、生成查询方法
根据参数查询集合
//根据参数查询集合
bw.write("\t<!--根据参数查询集合-->");
bw.newLine();
bw.write("\t<select id=\"selectList\" resultMap=\""+tableInfo.getBeanName()+"ResultMap\">");
bw.newLine();
bw.write("\t\tSELECT <include refid=\""+BASE_COLUMN_LIST+"\" /> FROM "+tableInfo.getTableName()+
" <include refid=\"" +QUERY_CONDITION+"\" />");
bw.newLine();
bw.write("\t\t<if test=\"query.orderBy!=null\">order by ${query.orderBy} </if>");
bw.newLine();
bw.write("\t\t<if test=\"query.SimplePage!=null\">limit #{query.SimplePage.start}, #{query.SimplePage.end} </if>");
bw.newLine();
bw.write("\t</select>");
bw.newLine();
bw.newLine();
- bw.write("\t<select id="selectList" resultMap=""+tableInfo.getBeanName()+"ResultMap">");开始定义一个名为selectList的查询方法,并指定结果映射为前面生成的结果映射。
- 构建查询语句: bw.write("\t\tSELECT <include refid=""+BASE_COLUMN_LIST+"" /> FROM "+tableInfo.getTableName()+ " <include refid="" +QUERY_CONDITION+"" />");使用标签引入通用查询列和通用查询条件,构建查询语句从指定的表中查询数据。
- 处理排序: bw.write("\t\t<if test="query.orderBy!=null">order by ${query.orderBy} ")如果查询参数中包含排序字段,则使用动态 SQL 添加排序条件。这里使用了{}语法,需要注意防止 SQL 注入。
- 处理分页: bw.write("\t\t<if test="query.SimplePage!=null">limit #{query.SimplePage.start}, #{query.SimplePage.end} ");如果查询参数中包含分页信息,则使用动态 SQL 添加分页条件,通过#{}语法传入分页的起始位置和结束位置。
根据参数查询数量
//根据参数查询数量
bw.write("\t<!--根据参数查询数量-->");
bw.newLine();
bw.write("\t<select id=\"selectCount\" resultType=\"java.lang.Integer\">");
bw.newLine();
bw.write("\t\tSELECT count(1) FROM "+tableInfo.getTableName()+ " <include refid=\"" +QUERY_CONDITION+"\" />");
bw.newLine();
bw.write("\t</select>");
bw.newLine();
bw.newLine();
- bw.write("\t<select id="selectCount" resultType="java.lang.Integer">");开始定义一个名为selectCount的查询方法,并指定结果类型为java.lang.Integer,表示返回一个整数结果,即数据记录的数量。
- 构建查询语句: bw.write("\t\tSELECT count(1) FROM "+tableInfo.getTableName()+ " <include refid="" +QUERY_CONDITION+"" />");使用SELECT count(1)语句从指定的表中查询数据记录数量,并通过标签引入通用查询条件,以确保只统计满足特定条件的数据记录。
单条插入
//单条插入
bw.write("\t<!--插入-匹配有值的字段-->");
bw.newLine();
bw.write("\t<insert id=\"insert\" parameterType=\""+dtoClassName+"\">");
bw.newLine();
FieldInfo autoIncrementField=null;
for(FieldInfo fieldInfo:tableInfo.getFieldIofoList()){
if(fieldInfo.getAutoIncrement()!=null&&fieldInfo.getAutoIncrement()){
autoIncrementField=fieldInfo;
break;
}
}
if(autoIncrementField!=null){
bw.write("\t\t<selectKey keyProperty=\"bean."+autoIncrementField.getPropertyName()+"\" resultType=\""+autoIncrementField.getJavaType()
+"\" order=\"AFTER\">");
bw.newLine();
bw.write("\t\t\tSELECT 0");
bw.newLine();
bw.write("\t\t</selectKey>");
bw.newLine();
}
bw.write("\t\tinsert into "+tableInfo.getTableName());
bw.newLine();
bw.write("\t\t<trim prefix=\"(\" suffix=\")\" suffixOverrides=\",\">");
bw.newLine();
for(FieldInfo fieldInfo:tableInfo.getFieldIofoList()){
bw.write("\t\t\t<if test=\"bean."+fieldInfo.getPropertyName()+" != null\">");
bw.newLine();
bw.write("\t\t\t\t"+fieldInfo.getFieldName()+", ");
bw.newLine();
bw.write("\t\t\t</if>");
bw.newLine();
}
bw.write("\t\t</trim>");
bw.newLine();
bw.write("\t\t<trim prefix=\"values (\" suffix=\")\" suffixOverrides=\",\">");
bw.newLine();
for(FieldInfo fieldInfo:tableInfo.getFieldIofoList()){
bw.write("\t\t\t<if test=\"bean."+fieldInfo.getPropertyName()+" != null\">");
bw.newLine();
bw.write("\t\t\t\t#{bean."+fieldInfo.getPropertyName()+"}, ");
bw.newLine();
bw.write("\t\t\t</if>");
bw.newLine();
}
bw.write("\t\t</trim>");
bw.newLine();
bw.write("\t</insert>");
bw.newLine();
bw.newLine();
- 定义插入方法: bw.write("\t<insert id="insert" parameterType=""+dtoClassName+"">");开始定义一个名为insert的插入方法,并指定参数类型为实体类的全限定名。
- 处理自增字段: 遍历字段列表查找自增字段:通过遍历tableInfo.getFieldIofoList(),查找标记为自增的字段,并将其存储在autoIncrementField变量中。
- 构建插入语句: bw.write("\t\tinsert into "+tableInfo.getTableName());指定要插入数据的表名。 使用trim标签处理字段列表和值列表: 第一个trim标签用于构建字段列表,遍历实体类的字段,如果字段值不为空,则将字段名添加到列表中。 第二个trim标签用于构建值列表,同样遍历实体类的字段,如果字段值不为空,则将#{bean.属性名}形式的占位符添加到列表中。
插入或更新
//插入或更新
bw.write("\t<!--插入或更新 -->");
bw.newLine();
bw.write("\t<insert id=\"insertOrUpdate\" parameterType=\""+dtoClassName+"\">");
bw.newLine();
bw.write("\t\tinsert into "+tableInfo.getTableName());
bw.newLine();
bw.write("\t\t<trim prefix=\"(\" suffix=\")\" suffixOverrides=\",\">");
bw.newLine();
for(FieldInfo fieldInfo:tableInfo.getFieldIofoList()){
bw.write("\t\t\t<if test=\"bean."+fieldInfo.getPropertyName()+" != null\">");
bw.newLine();
bw.write("\t\t\t\t"+fieldInfo.getFieldName()+", ");
bw.newLine();
bw.write("\t\t\t</if>");
bw.newLine();
}
bw.write("\t\t</trim>");
bw.newLine();
bw.write("\t\t<trim prefix=\"values (\" suffix=\")\" suffixOverrides=\",\">");
bw.newLine();
for(FieldInfo fieldInfo:tableInfo.getFieldIofoList()){
bw.write("\t\t\t<if test=\"bean."+fieldInfo.getPropertyName()+" != null\">");
bw.newLine();
bw.write("\t\t\t\t#{bean."+fieldInfo.getPropertyName()+"}, ");
bw.newLine();
bw.write("\t\t\t</if>");
bw.newLine();
}
bw.write("\t\t</trim>");
bw.newLine();
bw.write("\t\tON DUPLICATE KEY UPDATE ");
bw.newLine();
Map<String,String> keyTempMap=new HashMap<>();
for(Map.Entry<String,List<FieldInfo>> entry:keyIndexMap.entrySet()){
List<FieldInfo> fieldInfoList = entry.getValue();
for(FieldInfo fieldInfo:fieldInfoList) {
keyTempMap.put(fieldInfo.getFieldName(),fieldInfo.getFieldName());
}
}
bw.write("\t\t<trim prefix=\"\" suffix=\"\" suffixOverrides=\",\">");
bw.newLine();
for(FieldInfo fieldInfo:tableInfo.getFieldIofoList()){
if(keyTempMap.get(fieldInfo.getFieldName())!=null){
continue;
}
bw.write("\t\t\t<if test=\"bean."+fieldInfo.getPropertyName()+" != null\">");
bw.newLine();
bw.write("\t\t\t\t"+fieldInfo.getFieldName()+" = VALUES("+fieldInfo.getFieldName()+"),");
bw.newLine();
bw.write("\t\t\t</if>");
bw.newLine();
}
bw.write("\t\t</trim>");
bw.newLine();
bw.write("\t</insert>");
bw.newLine();
bw.newLine();
- 定义插入或更新方法: bw.write("\t<insert id="insertOrUpdate" parameterType=""+dtoClassName+"">");开始定义一个名为insertOrUpdate的方法,并指定参数类型为实体类的全限定名。
- 构建插入语句部分: 与单条插入方法类似,构建插入语句,包括指定表名、使用标签处理字段列表和值列表。遍历实体类的字段,如果字段值不为空,则将字段名和对应的值占位符添加到插入语句中。
- 处理重复键冲突: bw.write("\t\tON DUPLICATE KEY UPDATE ");指定当发生重复键冲突时执行更新操作。
- 构建更新语句: 首先,遍历表的键索引信息,将所有键字段存储在keyTempMap中。 然后,再次遍历实体类的字段列表,对于非键字段,如果字段值不为空,则生成更新语句,形式为字段名 = VALUES(字段名)。使用标签去除多余的逗号后缀。
批量插入
//批量插入
bw.write("\t<!--批量插入-->");
bw.newLine();
bw.write("\t<insert id=\"insertBatch\" parameterType=\""+dtoClassName+"\" >");
bw.newLine();
StringBuffer insertFieldBuffer=new StringBuffer();
StringBuffer insertPropertyBuffer=new StringBuffer();
for(FieldInfo fieldInfo:tableInfo.getFieldIofoList()){
if(fieldInfo.getAutoIncrement()){
continue;
}
insertFieldBuffer.append(fieldInfo.getFieldName()).append(",");
insertPropertyBuffer.append("#{item.").append(fieldInfo.getPropertyName()).append("},");
}
String insertFieldBuddefStr=insertFieldBuffer.substring(0,insertFieldBuffer.lastIndexOf(","));
bw.write("\t\tinsert into "+tableInfo.getTableName()+"("+insertFieldBuddefStr+")values");
bw.newLine();
bw.write("\t\t<foreach collection=\"list\" item=\"item\" separator=\",\">");
bw.newLine();
String insertPropertyBuddefStr=insertPropertyBuffer.substring(0,insertPropertyBuffer.lastIndexOf(","));
bw.write("\t\t\t("+insertPropertyBuddefStr+")");
bw.newLine();
bw.write("\t\t</foreach>");
bw.newLine();
bw.write("\t</insert>");
bw.newLine();
bw.newLine();
- 定义批量插入方法: bw.write("\t<insert id="insertBatch" parameterType=""+dtoClassName+"" >");开始定义一个名为insertBatch的方法,并指定参数类型为实体类的全限定名。
- 构建插入字段和属性列表: 遍历表的字段信息列表:对于每个字段,如果不是自增字段,则将字段名添加到insertFieldBuffer中,将#{item.属性名}形式的占位符添加到insertPropertyBuffer中。 提取字段和属性列表字符串:去除最后一个逗号,得到用于插入语句的字段列表字符串和属性列表字符串。
- 构建批量插入语句: bw.write("\t\tinsert into "+tableInfo.getTableName()+"("+insertFieldBuddefStr+")values");指定要插入数据的表名和字段列表。
- 使用标签进行循环插入: bw.write("\t\t<foreach collection="list" item="item" separator=",">");表示遍历参数中的列表,每个元素称为item,元素之间用逗号分隔。 bw.write("\t\t\t("+insertPropertyBuddefStr+")");构建每个元素的插入值列表。 bw.write("\t\t/foreach");结束foreach标签。
for(Map.Entry<String,List<FieldInfo>> entry:keyIndexMap.entrySet()){
List<FieldInfo> fieldInfoList = entry.getValue();
Integer index=0;
StringBuilder methodName = new StringBuilder();
StringBuilder methodParamName = new StringBuilder();
for(FieldInfo fieldInfo:fieldInfoList){
index++;
methodName.append(StringUtils.uperCaseFirstLetter(fieldInfo.getPropertyName()));
methodParamName.append(fieldInfo.getFieldName()+"=#{"+fieldInfo.getPropertyName()+"}");
if(index<fieldInfoList.size()){
methodName.append("And");
methodParamName.append("and");
}
}
//查询
bw.write("\t<!-- 根据"+methodName+"查询 -->");
bw.newLine();
bw.write("\t<select id=\"selectBy"+ methodName+"\" resultMap=\""+tableInfo.getBeanName()+"ResultMap\">");
bw.newLine();
bw.write("\t\tselect <include refid=\""+BASE_COLUMN_LIST+"\"/> from "+tableInfo.getTableName()+" where "+methodParamName);
bw.newLine();
bw.write("\t</select>");
bw.newLine();
bw.newLine();
//更新
bw.write("\t<!-- 根据"+methodName+"更新 -->");
bw.newLine();
bw.write("\t<update id=\"updateBy"+ methodName+"\" parameterType=\""+dtoClassName+"\">");
bw.newLine();
bw.write("\t\t update "+tableInfo.getTableName());
bw.newLine();
bw.write("\t\t <set>");
bw.newLine();
for(FieldInfo fieldInfo:tableInfo.getFieldIofoList()){
bw.write("\t\t\t<if test=\"bean."+fieldInfo.getPropertyName()+"!=null\">");
bw.newLine();
bw.write("\t\t\t\t"+fieldInfo.getFieldName()+" = #{bean."+fieldInfo.getPropertyName()+"},");
bw.newLine();
bw.write("\t\t\t</if>");
bw.newLine();
}
bw.write("\t\t </set>");
bw.newLine();
bw.write("\t\t where "+methodParamName);
bw.newLine();
bw.write("\t</update>");
bw.newLine();
bw.newLine();
//删除
bw.write("\t<!-- 根据"+methodName+"删除 -->");
bw.newLine();
bw.write("\t<delete id=\"deleteBy"+ methodName+"\">");
bw.newLine();
bw.write("\t\t delete from "+tableInfo.getTableName()+" where "+methodParamName);
bw.newLine();
bw.write("\t</delete>");
bw.newLine();
bw.newLine();
}
这段代码遍历一个键索引映射(keyIndexMap),对于每个键对应的字段列表,生成了根据这些字段组合进行查询、更新和删除的 MyBatis Mapper XML 方法定义。
- 遍历键索引映射 for(Map.Entry<String,List> entry:keyIndexMap.entrySet()){...}:遍历键索引映射,其中每个键对应一个字段信息列表。
- 生成方法名和参数名
- 对于每个字段信息列表,遍历其中的字段信息: Integer index=0; StringBuilder methodName = new StringBuilder(); StringBuilder methodParamName = new StringBuilder();:初始化索引、方法名和方法参数名的字符串构建器。
- 在循环中,拼接方法名和方法参数名,将属性名首字母大写后添加到方法名中,同时构建参数名形式为 “字段名 =#{属性名}”,如果不是最后一个字段,则在方法名和方法参数名中添加 “And” 或 “and” 进行连接。
- 查询方法定义
- 添加注释:bw.write("\t");。
- 定义查询方法:bw.write("\t<select id="selectBy"+ methodName+"" resultMap=""+tableInfo.getBeanName()+"ResultMap">");,指定结果映射为之前生成的结果映射。
- 构建查询语句:bw.write("\t\tselect <include refid=""+BASE_COLUMN_LIST+""/> from "+tableInfo.getTableName()+" where "+methodParamName);,使用通用查询列和根据方法参数名构建的查询条件。
- 更新方法定义
- 添加注释:bw.write("\t");。
- 定义更新方法:bw.write("\t<update id="updateBy"+ methodName+"" parameterType=""+dtoClassName+"">");,指定参数类型为实体类全限定名。
- 构建更新语句: bw.write("\t\t update "+tableInfo.getTableName());:指定要更新的表名。 bw.write("\t\t set");开始设置更新的字段。 遍历实体类的字段信息列表,根据字段值是否为空生成更新语句:bw.write("\t\t\t<if test="bean."+fieldInfo.getPropertyName()+"!=null">");...。 bw.write("\t\t set");结束标签。 bw.write("\t\t where "+methodParamName);:添加查询条件。
- 删除方法定义
- 添加注释:bw.write("\t");。
- 定义删除方法:bw.write("\t<delete id="deleteBy"+ methodName+"">");。
- 构建删除语句:bw.write("\t\t delete from "+tableInfo.getTableName()+" where "+methodParamName);。
如果我的内容对你有帮助,请点赞,评论,收藏。创作不易,大家的支持就是我坚持下去的动力!