前言
写博客是为了记录和分享自己的学习,所分享内容是网上的资源,由于非原创项目,主要分享学习思路,只展示贴图部分代码(本人不分享本项目源码,支持项目付费)
一、创建mapper文件以及生成导入语句
//创建Mapper包
File folder = new File(Constants.PATH_MAPPER);
if(!folder.exists()){
folder.mkdirs();
}
String className= tableInfo.getBeanName()+Constants.SUFFIX_BEAN_MAPPER;
//创建Mapper文件
File file = new File(folder,className+".java");
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("package "+Constants.PACKAGE_MAPPER+";");
bw.newLine();
bw.newLine();
bw.write("import org.apache.ibatis.annotations.Param;");
bw.newLine();
bw.newLine();
这段代码的主要功能是动态创建一个 mapper 接口文件。它首先确定了 mapper 文件的存储路径(通过检查并创建指定的文件夹),然后根据给定的表信息生成接口的类名,并创建文件输出流,最后在文件中写入包名、导入必要的库以及接口的声明和注释。
1.创建文件夹:
- File folder = new File(Constants.PATH_MAPPER);:通过一个常量指定 Mapper 文件所在的文件夹路径,并创建一个File对象表示该文件夹。
- if(!folder.exists()){ folder.mkdirs(); }:如果该文件夹不存在,则创建它,确保 Mapper 文件有正确的存储位置。
2.生成类名和创建文件:
- String className = tableInfo.getBeanName()+Constants.SUFFIX_BEAN_MAPPER;:根据表信息和一个常量后缀生成 Mapper 接口的类名。
- File file = new File(folder,className+".java");:创建一个表示 Mapper 文件的File对象,确定了文件的存储路径和名称。
3.创建输出流:
- OutputStream out = null;、OutputStreamWriter writer = null;、BufferedWriter bw = null;:声明输出流相关的变量,用于后续写入文件内容。
- out = new FileOutputStream(file);、writer = new OutputStreamWriter(out,"UTF-8");、bw = new BufferedWriter(writer);:依次创建文件输出流、将输出流转换为字符输出流并使用指定的字符编码,最后创建缓冲字符输出流,提高写入文件的效率。
4.写入文件内容:
- bw.write("package "+Constants.PACKAGE_MAPPER+";");:写入包名,通过常量指定包名,方便在不同的项目环境中进行配置。
- bw.newLine();:写入换行符,使代码格式更加清晰。
- bw.write("import org.apache.ibatis.annotations.Param;");:导入 MyBatis 中用于参数注解的类,为后续生成的方法做准备。
二、写入mapper需要生成的内容
//生成包名
bw.write("package "+Constants.PACKAGE_MAPPER+";");
bw.newLine();
bw.newLine();
bw.write("import org.apache.ibatis.annotations.Param;");
bw.newLine();
bw.newLine();
//生成类名
bw.newLine();
BuildComment.createClassComment(bw, tableInfo.getComment()+" Mapper");
bw.write("public interface "+className+"<T, P> extends BaseMapper {");
bw.newLine();
Map<String, List<FieldInfo>> keyIndexMap = tableInfo.getKeyIndexMap();
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()));
if(index<fieldInfoList.size()){
methodName.append("And");
}
methodParamName.append("@Param(\""+fieldInfo.getPropertyName() +"\") "+fieldInfo.getJavaType()+" "+fieldInfo.getPropertyName());
if(index<fieldInfoList.size()){
methodParamName.append(",");
}
}
BuildComment.createFieldComment(bw,"根据"+methodName+"查询");
bw.write("\t T selectBy"+ methodName+"("+methodParamName+");");
bw.newLine();
bw.newLine();
BuildComment.createFieldComment(bw,"根据"+methodName+"更新");
bw.write("\t Integer updateBy"+ methodName+"(@Param(\"bean\")T t,"+methodParamName+");");
bw.newLine();
bw.newLine();
BuildComment.createFieldComment(bw,"根据"+methodName+"删除");
bw.write("\t Integer deleteBy"+ methodName+"("+methodParamName+");");
bw.newLine();
bw.newLine();
在已创建的 Mapper 文件中继续写入内容。首先生成包名和导入语句,然后生成接口的类名和声明。接着,根据表信息中的键索引映射生成一系列的查询、更新和删除方法。
1.生成包名和导入语句:
- bw.write("package "+Constants.PACKAGE_MAPPER+";");:写入指定的包名,通过常量Constants.PACKAGE_MAPPER获取包名,方便项目中统一管理包结构。
- bw.write("import org.apache.ibatis.annotations.Param;");:导入 MyBatis 的@Param注解,用于在方法参数中标识参数名称。
2.生成类名和接口声明:
- BuildComment.createClassComment(bw, tableInfo.getComment()+" Mapper");:调用自定义的方法生成类的注释,根据表的注释信息为接口添加注释。
- bw.write("public interface "+className+"<T, P> extends BaseMapper {");:写入接口的声明,包括接口名称(根据表信息生成)、泛型参数<T, P>以及继承自BaseMapper接口。
3.生成方法:
- Map<String, List> keyIndexMap = tableInfo.getKeyIndexMap();:获取表的键索引映射,其中键是索引名称,值是包含字段信息的列表,通过遍历键索引映射,为每个索引生成查询、更新和删除方法:
- 生成方法注释:BuildComment.createFieldComment(bw,"根据"+methodName+"查询");,根据构建的方法名生成注释,说明方法的功能。
- 生成查询方法:bw.write("\t T selectBy"+ methodName+"("+methodParamName+");");,写入查询方法,返回类型为泛型T,参数列表为构建的方法参数。
- 生成更新方法:bw.write("\t Integer updateBy"+ methodName+"(@Param("bean")T t,"+methodParamName+");");,写入更新方法,返回类型为整数,表示受影响的行数,参数包括泛型对象t和方法参数。
- 生成删除方法:bw.write("\t Integer deleteBy"+ methodName+"("+methodParamName+");");,写入删除方法,返回类型为整数,表示受影响的行数,参数为方法参数。
三、创建query文件以及生成导入语句
//创建Query包
File folder = new File(Constants.PATH_VO);
if(!folder.exists()){
folder.mkdirs();
}
String className= tableInfo.getBeanName()+Constants.SUFFIX_BEAN_Query;
//创建Query文件
File file = new File(folder,className+".java");
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("package "+Constants.PACKAGE_Query+";");
bw.newLine();
bw.newLine();
//生成导入包
if(tableInfo.getHaveBigDecimal()){
bw.write("import java.math.BigDecimal;");
bw.newLine();
}
if(tableInfo.getHaveDate()||tableInfo.getHaveDateTime()){
bw.write("import java.util.Date;");
bw.newLine();
}
创建一个Query的Java 类文件所在的包目录,如果目录不存在则创建。然后根据表信息生成类名,并创建文件输出流。接着,在文件中写入包名和可能需要的导入语句,具体导入的包取决于表信息中是否包含特定的数据类型(如BigDecimal、Date等)。
1.创建包目录:
- File folder = new File(Constants.PATH_Query);:通过常量指定 Query 文件所在的包路径,并创建一个File对象表示该目录。
- if(!folder.exists()){ folder.mkdirs(); }:如果目录不存在,则创建该目录,确保 Query 文件有正确的存储位置。
2.生成类名和创建文件:
- String className = tableInfo.getBeanName()+Constants.SUFFIX_BEAN_Query;:根据表信息和一个常量后缀生成 Query 类的类名。
- File file = new File(folder,className+".java");:创建一个表示 Query 文件的File对象,确定了文件的存储路径和名称。
3.创建输出流:
- OutputStream out = null;、OutputStreamWriter writer = null;、BufferedWriter bw = null;:声明输出流相关的变量,用于后续写入文件内容。
- out = new FileOutputStream(file);、writer = new OutputStreamWriter(out,"UTF-8");、bw = new BufferedWriter(writer);:依次创建文件输出流、将输出流转换为字符输出流并使用指定的字符编码,最后创建缓冲字符输出流,提高写入文件的效率。
4.写入文件内容:
- bw.write("package "+Constants.PACKAGE_Query+";");:写入包名,通过常量指定包名,方便在不同的项目环境中进行配置。
- 根据表信息判断是否需要导入特定的包:
- if(tableInfo.getHaveBigDecimal()){ bw.write("import java.math.BigDecimal;"); bw.newLine(); }:如果表中包含BigDecimal类型的数据,则导入java.math.BigDecimal包。
- if(tableInfo.getHaveDate()||tableInfo.getHaveDateTime()){ bw.write("import java.util.Date;"); bw.newLine(); }:如果表中包含Date或DateTime类型的数据,则导入java.util.Date包。
四、生成的query基本字段、注释以及对应的 getter 和 setter 方法
//生成基本字段和注解
for(FieldInfo fieldInfo:tableInfo.getFieldIofoList()){
BuildComment.createFieldComment(bw, fieldInfo.getComment()+"查询对象");
bw.write("\tprivate "+fieldInfo.getJavaType()+" "+fieldInfo.getPropertyName()+";");
bw.newLine();
if(ArrayUtils.contains(Constants.SQL_STRING_TYPES,fieldInfo.getSqlType())){
String propertyName=fieldInfo.getPropertyName()+Constants.SUFFIX_BEAN_VO_LIKE;
bw.write("\tprivate "+fieldInfo.getJavaType()+" "+propertyName+";");
bw.newLine();
bw.newLine();
}
if(ArrayUtils.contains(Constants.SQL_DATE_TIME_TYPES,fieldInfo.getSqlType())||ArrayUtils.contains(Constants.SQL_DATE_TYPE,fieldInfo.getSqlType())){
bw.write("\tprivate String"+" "+fieldInfo.getPropertyName()+Constants.SUFFIX_BEAN_VO_DATE_START+";");
bw.newLine();
bw.newLine();
bw.write("\tprivate String"+" "+fieldInfo.getPropertyName()+Constants.SUFFIX_BEAN_VO_DATE_END+";");
bw.newLine();
bw.newLine();
}
}
buildGetSet(tableInfo.getFieldIofoList(),bw);
buildGetSet(tableInfo.getFieldExtendInfoList(),bw);
bw.write("}");
bw.flush();
生成的Query类添加基本字段、注释以及对应的 getter 和 setter 方法。它遍历表的字段信息列表,根据字段的类型生成不同的额外字段,并在最后为所有字段生成 getter 和 setter 方法。
1.遍历字段信息列表:
- for(FieldInfo fieldInfo:tableInfo.getFieldIofoList()){...}:遍历表信息中的字段信息列表。对于每个字段信息,执行以下操作。
- BuildComment.createFieldComment(bw, fieldInfo.getComment()+"查询对象");:调用自定义的方法生成字段的注释,描述字段的用途。
- bw.write("\tprivate "+fieldInfo.getJavaType()+" "+fieldInfo.getPropertyName()+";");:写入字段的声明,包括访问修饰符private、字段类型和字段名称。
- 根据字段类型生成额外字段:
2.生成 getter 和 setter 方法:
- buildGetSet(tableInfo.getFieldIofoList(),bw);:调用自定义的方法为字段信息列表中的字段生成 getter 和 setter 方法。
- buildGetSet(tableInfo.getFieldExtendInfoList(),bw);:如果存在扩展字段信息列表,也为其生成 getter 和 setter 方法。
3.结束类的定义:
- bw.flush();:刷新缓冲输出流,确保数据被写入文件
如果我的内容对你有帮助,请点赞,评论,收藏。创作不易,大家的支持就是我坚持下去的动力!