基于springboot+bootstrap+mysql+redis搭建一套完整的权限架构【五】【编写基础代码快速生成工具】

通过第四章我们编写了基础开发工具,但是大家会发现我们每开发一个新的模块都要重写一次从dao到xml层的代码,很明显很多都是重复的开发工作,那我们是否可以直接编写一个工具快速生成我们的代码呢?很明显这完全是没有问题的本章我们将实现使用快速生成工具一秒生成我们的所有的代码,该工具是基于从数据库读取表来实现动态生成我们的代码。

        首先我们在我们的com.csdn包底下我们新建一个codeUtil包如下所示:

基于springboot+bootstrap+mysql+redis搭建一套完整的权限架构【五】【编写基础代码快速生成工具】

首先我们新建一个我们的列的模型(ColumnModel.java)如下:

 

 
  1. /**

  2. * 列模型

  3. */

  4. public class ColumnModel {

  5. private boolean isPrimaryKey;

  6. private boolean isAutoIncrement;

  7. private String columnName;

  8. private String dataType;

  9. private String typeName;

  10. private String columnClassName;

  11. private String fieldName;

  12. private String fieldType;

  13. private int columnSize;

  14. private String columnDef;

  15. private String remarks;

  16.  
  17. public boolean isPrimaryKey() {

  18. return isPrimaryKey;

  19. }

  20.  
  21. public void setPrimaryKey(boolean isPrimaryKey) {

  22. this.isPrimaryKey = isPrimaryKey;

  23. }

  24.  
  25. public boolean isAutoIncrement() {

  26. return isAutoIncrement;

  27. }

  28.  
  29. public void setAutoIncrement(boolean isAutoIncrement) {

  30. this.isAutoIncrement = isAutoIncrement;

  31. }

  32.  
  33. public String getColumnName() {

  34. return columnName;

  35. }

  36.  
  37. public void setColumnName(String columnName) {

  38. this.columnName = columnName;

  39. }

  40.  
  41. public String getDataType() {

  42. return dataType;

  43. }

  44.  
  45. public void setDataType(String dataType) {

  46. this.dataType = dataType;

  47. }

  48.  
  49. public String getTypeName() {

  50. return typeName;

  51. }

  52.  
  53. public void setTypeName(String typeName) {

  54. this.typeName = typeName;

  55. }

  56.  
  57. public int getColumnSize() {

  58. return columnSize;

  59. }

  60.  
  61. public void setColumnSize(int columnSize) {

  62. this.columnSize = columnSize;

  63. }

  64.  
  65. public String getRemarks() {

  66. return remarks;

  67. }

  68.  
  69. public void setRemarks(String remarks) {

  70. this.remarks = remarks;

  71. }

  72.  
  73. @Override

  74. public String toString() {

  75. return "ColumnModel [columnName=" + columnName + ", dataType="

  76. + dataType + ", typeName=" + typeName + ", columnClassName="

  77. + columnClassName + ", fieldName=" + fieldName + ", fieldType="

  78. + fieldType + ", columnSize=" + columnSize + ", columnDef="

  79. + columnDef + ", remarks=" + remarks + "]";

  80. }

  81.  
  82. public String getColumnDef() {

  83. return columnDef;

  84. }

  85.  
  86. public void setColumnDef(String columnDef) {

  87. this.columnDef = columnDef;

  88. }

  89.  
  90. public String getColumnClassName() {

  91. return columnClassName;

  92. }

  93.  
  94. public void setColumnClassName(String columnClassName) {

  95. this.columnClassName = columnClassName;

  96. }

  97.  
  98. public String getFieldName() {

  99. return fieldName;

  100. }

  101.  
  102. public void setFieldName(String fieldName) {

  103. this.fieldName = fieldName;

  104. }

  105.  
  106. public String getFieldType() {

  107. return fieldType;

  108. }

  109.  
  110. public void setFieldType(String fieldType) {

  111. this.fieldType = fieldType;

  112. }

  113.  
  114. }


接着我们创建我们的表结构的模型(TableModel.java)如下:

 

 

 
  1. /**

  2. * 表结构封装

  3. * */

  4. public class TableModel {

  5. //表名

  6. private String tableName;

  7. //主键列

  8. private List<ColumnModel> primaryKeyColumns;

  9. //列

  10. private List<ColumnModel> columns;

  11. //需要引入包

  12. private Set<String> imports;

  13.  
  14. public String getTableName() {

  15. return tableName;

  16. }

  17. public void setTableName(String tableName) {

  18. this.tableName = tableName;

  19. }

  20. public List<ColumnModel> getPrimaryKeyColumns() {

  21. return primaryKeyColumns;

  22. }

  23. public void setPrimaryKeyColumns(List<ColumnModel> primaryKeyColumns) {

  24. this.primaryKeyColumns = primaryKeyColumns;

  25. }

  26. public List<ColumnModel> getColumns() {

  27. return columns;

  28. }

  29. public void setColumns(List<ColumnModel> columns) {

  30. this.columns = columns;

  31. }

  32. public Set<String> getImports() {

  33. return imports;

  34. }

  35. public void setImports(Set<String> imports) {

  36. this.imports = imports;

  37. }

  38. }

在我们新建JdbcUtil.java数据库连接操作类的时候我们首先新建一个(GenCodeUtil.java)我们的操作主类,JdbcUtil的代码如下:

 

 

 
  1. public class JdbcUtil {

  2. private static String properties_file_uri = null;

  3. public static Properties configs;

  4.  
  5. public static void setPropertiesURL(String uri){

  6. properties_file_uri = uri;

  7. }

  8.  
  9. /**

  10. * 获取连接

  11. * @return

  12. */

  13. public static Connection getConnection(){

  14. try {

  15. configs = new Properties();

  16. if(StringUtils.isEmpty(properties_file_uri)){

  17. properties_file_uri = "/genericCoder.properties";

  18. }

  19. String path = GenCodeUtil.class.getResource("/").getPath();

  20. InputStream in = new FileInputStream(new File(path+properties_file_uri));

  21. configs.load(in);

  22. Class.forName(configs.getProperty("spring.datasource.driverClassName"));

  23. Properties properties = new Properties();

  24. properties.put("user", configs.getProperty("spring.datasource.username"));

  25. properties.put("password", configs.getProperty("spring.datasource.password"));

  26. properties.put("remarksReporting","true");//想要获取数据库结构中的注释,这个值是重点

  27. return DriverManager.getConnection(configs.getProperty("spring.datasource.url"), properties);

  28. } catch (Exception e) {

  29. e.printStackTrace();

  30. }

  31. return null;

  32. }

  33.  
  34. /**

  35. * 获取表结构

  36. * @param tableName

  37. * @return

  38. */

  39. public static TableModel getTableStructure(String tableName){

  40. List<ColumnModel> columnModelList = new ArrayList<ColumnModel>();

  41. List<ColumnModel> primaryKeyColumns = new ArrayList<ColumnModel>();

  42. Set<String> imports = new HashSet<String>();

  43. try {

  44. //TODO 表相关

  45. //ResultSet tableSet = metaData.getTables(null, "%",tableName,new String[]{"TABLE"});

  46. //TODO 字段相关

  47. DatabaseMetaData dbMeta = getConnection().getMetaData();

  48. List<String> primaryKeys = getPrimaryKeys(dbMeta, tableName);

  49. ResultSet columnSet = dbMeta.getColumns(null,"%",tableName,"%");

  50. ColumnModel columnModel = null;

  51. while(columnSet.next()){

  52. columnModel = new ColumnModel();

  53. columnModel.setColumnName(columnSet.getString("COLUMN_NAME"));

  54. columnModel.setColumnSize(columnSet.getInt("COLUMN_SIZE"));

  55. columnModel.setDataType(columnSet.getString("DATA_TYPE"));

  56. columnModel.setRemarks(columnSet.getString("REMARKS"));

  57. columnModel.setTypeName(columnSet.getString("TYPE_NAME"));

  58. columnModel.setAutoIncrement(columnSet.getBoolean("IS_AUTOINCREMENT"));

  59. columnModel.setPrimaryKey(justicPrimaryKey(columnModel.getColumnName(), primaryKeys));

  60. //String columnClassName = ColumnTypeEnum.getColumnTypeEnumByDBType(columnModel.getTypeName());

  61. String columnClassName = sqlType2JavaType(columnModel.getTypeName());

  62. String imp = getImportByJavaType(columnClassName);

  63. if(StringUtils.isNotEmpty(imp))

  64. imports.add(imp);

  65. String fieldName = getFieldName(columnModel.getColumnName());

  66. String fieldType = null;

  67. try{

  68. if(StringUtils.isNotEmpty(columnClassName))

  69. fieldType = Class.forName(columnClassName).getSimpleName();

  70. else

  71. throw new RuntimeException();

  72. }

  73. catch(ClassNotFoundException e){

  74. fieldType = columnClassName;

  75. }

  76. columnModel.setFieldName(fieldName);

  77. columnModel.setColumnClassName(columnClassName);

  78. columnModel.setFieldType(fieldType);

  79. columnModelList.add(columnModel);

  80. if(columnModel.isPrimaryKey())

  81. primaryKeyColumns.add(columnModel);

  82. //System.out.println(columnModel.toString());

  83. }

  84. } catch (Exception e) {

  85. e.printStackTrace();

  86. }

  87. TableModel table = new TableModel();

  88. table.setColumns(columnModelList);

  89. table.setPrimaryKeyColumns(primaryKeyColumns);

  90. table.setImports(imports);

  91. table.setTableName(tableName);

  92. return table;

  93. }

  94. /**

  95. * 将数据库字段转换成bean属性

  96. * @param columnName

  97. * @return

  98. */

  99. private static String getFieldName(String columnName) {

  100. char[] columnCharArr = columnName.toCharArray();

  101. StringBuffer sb = new StringBuffer();

  102. int ad = -1;

  103. for (int i = 0; i < columnCharArr.length; i++) {

  104. char cur = columnCharArr[i];

  105. if(cur=='_'){

  106. ad = i;

  107. }else{

  108. if((ad+1)==i&&ad!=-1){

  109. sb.append(Character.toUpperCase(cur));

  110. }else{

  111. sb.append(cur);

  112. }

  113. ad=-1;

  114. }

  115. }

  116. return sb.toString();

  117. }

  118. /**

  119. * 获取表主键

  120. * @throws SQLException

  121. * */

  122. private static List<String> getPrimaryKeys(DatabaseMetaData dbMeta, String tableName) throws SQLException{

  123. ResultSet pkRSet = dbMeta.getPrimaryKeys(null, null, tableName);

  124. List<String> primaryKyes = new ArrayList<String>();

  125. while(pkRSet.next()){

  126. primaryKyes.add(pkRSet.getObject("COLUMN_NAME").toString());

  127. }

  128. return primaryKyes;

  129. }

  130. /**

  131. * 判断列是否为主键列

  132. * */

  133. private static boolean justicPrimaryKey(String columnName, List<String> primaryKyes){

  134. for(String key : primaryKyes)

  135. if(key.equals(columnName))

  136. return true;

  137. return false;

  138. }

  139. /**

  140. * 功能:获得列的数据类型

  141. * @param sqlType

  142. * @return

  143. */

  144. private static String sqlType2JavaType(String sqlType) {

  145. if(sqlType.equalsIgnoreCase("bit")){

  146. return "boolean";

  147. }else if(sqlType.equalsIgnoreCase("tinyint")){

  148. return "byte";

  149. }else if(sqlType.equalsIgnoreCase("smallint")){

  150. return "short";

  151. }else if(sqlType.equalsIgnoreCase("int")){

  152. return "int";

  153. }else if(sqlType.equalsIgnoreCase("bigint")){

  154. return "long";

  155. }else if(sqlType.equalsIgnoreCase("float")){

  156. return "float";

  157. }else if(sqlType.equalsIgnoreCase("decimal") || sqlType.equalsIgnoreCase("numeric")

  158. || sqlType.equalsIgnoreCase("real") || sqlType.equalsIgnoreCase("money")

  159. || sqlType.equalsIgnoreCase("smallmoney")){

  160. return "double";

  161. }else if(sqlType.equalsIgnoreCase("varchar") || sqlType.equalsIgnoreCase("char")

  162. || sqlType.equalsIgnoreCase("nvarchar") || sqlType.equalsIgnoreCase("nchar")

  163. || sqlType.equalsIgnoreCase("text")){

  164. return "String";

  165. }else if(sqlType.equalsIgnoreCase("datetime") || sqlType.equalsIgnoreCase("date")){

  166. return "Date";

  167. }else if(sqlType.equalsIgnoreCase("image")){

  168. return "Blod";

  169. }else if(sqlType.equalsIgnoreCase("timestamp")){

  170. return "Timestamp";

  171. }

  172. return "String";

  173. }

  174. /**

  175. * 根据数据类型获取需要引入的类

  176. * */

  177. private static String getImportByJavaType(String javaType){

  178. switch(javaType){

  179. case "Date": return "java.util.Date";

  180. case "Timestamp": return "java.sql.Timestamp";

  181. case "Blod": return "java.sql.Blod";

  182. }

  183. return null;

  184. }

  185. }

接着我们在生成我们的各层代码的工具类(MyBatisUtil.java)如下:

 

 

 
  1. /**

  2. * mybatis配置文件生成功能

  3. * */

  4. public class MyBatisUtil {

  5. /**

  6. * 从表结构中去生成mybatis配置

  7. * @param table

  8. * @param namespace

  9. * @param beanName

  10. * @param queryModelName

  11. * @return

  12. */

  13. public static String genMapperConfig(TableModel table,String namespace, String beanName, String queryModelName){

  14. StringBuffer sb = new StringBuffer();

  15. sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");

  16. sb.append("<!DOCTYPE mapper PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\" \"http://mybatis.org/dtd/mybatis-3-mapper.dtd\">\n");

  17. sb.append("<mapper namespace=\""+namespace+"\">\n");

  18. //生成resultMap

  19. String resultMap = beanName.split("\\.")[(beanName.split("\\.").length-1)]+"Map";

  20. sb.append(genResultMap(beanName, resultMap, table));

  21. //生成Get SQL

  22. sb.append(genGETSQL(beanName, resultMap, table));

  23. //生成插入SQL

  24. String dbType = "oracle";

  25. String driver = JdbcUtil.configs.getProperty("spring.datasource.driverClassName");

  26. if(driver.toLowerCase().indexOf("mysql")>0){

  27. dbType = "";

  28. }

  29. if(dbType.equalsIgnoreCase("oracle")){

  30. sb.append(genSAVESQLOfORCL(beanName, table));

  31. }

  32. else{

  33. sb.append(genSAVESQL(beanName, table));

  34. }

  35. //生成修改SQL

  36. sb.append(genUPDATESQL(beanName, table));

  37. //生成删除SQL

  38. sb.append(genDELETESQL(beanName, table));

  39. if(StringUtils.isNotEmpty(queryModelName)){

  40. //生成分页查询

  41. if(dbType.equalsIgnoreCase("oracle")){

  42. sb.append(genFINDBYPAGESQLOfORCL(queryModelName, resultMap, table));

  43. }

  44. else{

  45. sb.append(genFINDBYPAGESQL(queryModelName, resultMap, table));

  46. }

  47. //统计

  48. sb.append(genCOUNTSQL(queryModelName, table));

  49. //查询

  50. sb.append(genQUERYSQL(queryModelName, resultMap, table));

  51. }

  52. sb.append("</mapper>");

  53. return sb.toString();

  54. }

  55.  
  56. private static String genResultMap(String beanName, String resultMap, TableModel table){

  57. List<ColumnModel> columnModelList = table.getColumns();

  58. List<ColumnModel> primaryKeys = table.getPrimaryKeyColumns();

  59. StringBuffer sb = new StringBuffer();

  60. sb.append("\t<resultMap type=\""+beanName+"\" id=\""+resultMap+"\">\n");

  61. if(primaryKeys.size()==1){

  62. ColumnModel primaryKey = primaryKeys.get(0);

  63. sb.append("\t\t<id property=\""+primaryKey.getFieldName()+"\" column=\""+primaryKey.getColumnName()+"\"/>\n");

  64. for(ColumnModel cm : columnModelList){

  65. if(!cm.isPrimaryKey())

  66. sb.append("\t\t<result property=\""+cm.getFieldName()+"\" column=\""+cm.getColumnName()+"\"/>\n");

  67. }

  68. }

  69. else

  70. for(ColumnModel cm : columnModelList){

  71. sb.append("\t\t<result property=\""+cm.getFieldName()+"\" column=\""+cm.getColumnName()+"\"/>\n");

  72. }

  73. sb.append("\t</resultMap>\n\n");

  74. return sb.toString();

  75. }

  76.  
  77. private static String genGETSQL(String beanName, String resultMap, TableModel table){

  78. List<ColumnModel> columnModelList = table.getColumns();

  79. List<ColumnModel> primaryKeys = table.getPrimaryKeyColumns();

  80. StringBuffer sb = new StringBuffer();

  81. sb.append("\t<!--根据主键获取对象-->\n");

  82. sb.append("\t<select id=\"get\" parameterType=\""+beanName+"\" resultMap=\""+resultMap+"\">\n\t\tSELECT ");

  83. sb.append(getSelectFields(columnModelList));

  84. sb.append(" FROM "+table.getTableName() +" \n\t\tWHERE ");

  85. for(int i=0; i<primaryKeys.size(); i++){

  86. ColumnModel pk = primaryKeys.get(i);

  87. sb.append(pk.getColumnName()+"=#{"+pk.getFieldName()+"}");

  88. if(i<primaryKeys.size()-1){

  89. sb.append(" and ");

  90. }

  91. }

  92. sb.append("\n\t</select>\n\n");

  93. return sb.toString();

  94. }

  95.  
  96. private static String genSAVESQL(String beanName, TableModel table){

  97. List<ColumnModel> columnModelList = table.getColumns();

  98. List<ColumnModel> primaryKeys = table.getPrimaryKeyColumns();

  99. StringBuffer sb = new StringBuffer();

  100. sb.append("\t<!--保存-->\n");

  101. if(primaryKeys.size()==1 && primaryKeys.get(0).isAutoIncrement()){

  102. //自增主键,并返回主键值

  103. sb.append("\t<insert id=\"save\" parameterType=\""+beanName+"\" useGeneratedKeys=\"true\" keyProperty=\""+primaryKeys.get(0).getFieldName()+"\">\n");

  104. sb.append("\t\tINSERT INTO "+table.getTableName()+"(");

  105. for(ColumnModel cm : columnModelList){

  106. if(!cm.isPrimaryKey()|| !cm.isAutoIncrement()){

  107. sb.append(cm.getColumnName());

  108. sb.append(",");

  109. }

  110. }

  111. sb.deleteCharAt(sb.length()-1);

  112. sb.append(")\n\t\tVALUES(");

  113. for(ColumnModel cm : columnModelList){

  114. if(!cm.isPrimaryKey()|| !cm.isAutoIncrement()){

  115. sb.append("#{"+cm.getFieldName()+"}");

  116. sb.append(",");

  117. }

  118. }

  119. sb.deleteCharAt(sb.length()-1);

  120. sb.append(")\n");

  121. sb.append("\t</insert>\n\n");

  122. }

  123. else{

  124. sb.append("\t<insert id=\"save\" parameterType=\""+beanName+"\">\n");

  125. sb.append("\t\tINSERT INTO "+table.getTableName()+"(");

  126. for(ColumnModel cm : columnModelList){

  127. if(!cm.isAutoIncrement()){

  128. sb.append(cm.getColumnName());

  129. sb.append(",");

  130. }

  131. }

  132. sb.deleteCharAt(sb.length()-1);

  133. sb.append(")\n\t\tVALUES(");

  134. for(ColumnModel cm : columnModelList){

  135. if(!cm.isAutoIncrement()){

  136. sb.append("#{"+cm.getFieldName()+"}");

  137. sb.append(",");

  138. }

  139. }

  140. sb.deleteCharAt(sb.length()-1);

  141. sb.append(")\n");

  142. sb.append("\t</insert>\n\n");

  143. }

  144. return sb.toString();

  145. }

  146.  
  147. private static String genSAVESQLOfORCL(String beanName, TableModel table){

  148. List<ColumnModel> columnModelList = table.getColumns();

  149. List<ColumnModel> primaryKeys = table.getPrimaryKeyColumns();

  150. StringBuffer sb = new StringBuffer();

  151. sb.append("\t<!--保存-->\n");

  152. sb.append("\t<insert id=\"save\" parameterType=\""+beanName+"\">\n");

  153. if(primaryKeys.size()==1 && primaryKeys.get(0).isAutoIncrement()){

  154. String sequence = null;

  155. if(table.getTableName().toLowerCase().indexOf("t_")==0){

  156. sequence = table.getTableName().toLowerCase().replace("t_", "s_");

  157. }

  158. else{

  159. sequence = "s_"+table.getTableName().toLowerCase();

  160. }

  161. //自增主键,并返回主键值

  162. sb.append("\t\t<selectKey keyProperty=\""+primaryKeys.get(0).getFieldName()+"\" resultType=\"int\" order=\"BEFORE\">select "+sequence+".nextval from dual</selectKey>\n");

  163. }

  164. sb.append("\t\tINSERT INTO "+table.getTableName()+"(");

  165. for(ColumnModel cm : columnModelList){

  166. sb.append(cm.getColumnName());

  167. sb.append(",");

  168. }

  169. sb.deleteCharAt(sb.length()-1);

  170. sb.append(")\n\t\tVALUES(");

  171. for(ColumnModel cm : columnModelList){

  172. sb.append("#{"+cm.getFieldName()+"}");

  173. sb.append(",");

  174. }

  175. sb.deleteCharAt(sb.length()-1);

  176. sb.append(")\n");

  177. sb.append("\t</insert>\n\n");

  178. return sb.toString();

  179. }

  180.  
  181. private static String genUPDATESQL(String beanName, TableModel table){

  182. List<ColumnModel> columnModelList = table.getColumns();

  183. List<ColumnModel> primaryKeys = table.getPrimaryKeyColumns();

  184. StringBuffer sb = new StringBuffer();

  185. sb.append("\t<!--修改-->\n");

  186. sb.append("\t<update id=\"update\" parameterType=\""+beanName+"\">\n");

  187. sb.append("\t\tUPDATE "+table.getTableName()+" SET ");

  188. for(ColumnModel cm : columnModelList){

  189. if(!cm.isPrimaryKey()){

  190. sb.append(cm.getColumnName()+"=#{"+cm.getFieldName()+"}");

  191. sb.append(",");

  192. }

  193. }

  194. sb.deleteCharAt(sb.length()-1);

  195. sb.append("\n\t\tWHERE ");

  196. for(int i=0; i<primaryKeys.size(); i++){

  197. ColumnModel pk = primaryKeys.get(i);

  198. sb.append(pk.getColumnName()+"=#{"+pk.getFieldName()+"}");

  199. if(i<primaryKeys.size()-1){

  200. sb.append(" and ");

  201. }

  202. }

  203. sb.append("\n\t</update>\n\n");

  204. return sb.toString();

  205. }

  206.  
  207. private static String genDELETESQL(String beanName, TableModel table){

  208. List<ColumnModel> primaryKeys = table.getPrimaryKeyColumns();

  209. StringBuffer sb = new StringBuffer();

  210. sb.append("\t<!--删除-->\n");

  211. sb.append("\t<delete id=\"delete\" parameterType=\""+beanName+"\">\n");

  212. sb.append("\t\t DELETE FROM "+table.getTableName()+" WHERE ");

  213. for(int i=0; i<primaryKeys.size(); i++){

  214. ColumnModel pk = primaryKeys.get(i);

  215. sb.append(pk.getColumnName()+"=#{"+pk.getFieldName()+"}");

  216. if(i<primaryKeys.size()-1){

  217. sb.append(" and ");

  218. }

  219. }

  220. sb.append("\n\t</delete>\n\n");

  221. return sb.toString();

  222. }

  223.  
  224. private static String genFINDBYPAGESQL(String queryModelName, String resultMap, TableModel table){

  225. List<ColumnModel> columnModelList = table.getColumns();

  226. StringBuffer sb = new StringBuffer();

  227. sb.append("\t<!--分页查询-->\n");

  228. sb.append("\t<select id=\"findByPage\" parameterType=\""+queryModelName+"\" resultMap=\""+resultMap+"\">");

  229. sb.append("\n\t\tSELECT ");

  230. for(ColumnModel cm : columnModelList){

  231. sb.append(cm.getColumnName());

  232. sb.append(",");

  233. }

  234. sb.deleteCharAt(sb.length()-1);

  235. sb.append(" FROM "+table.getTableName());

  236. sb.append("\n\t\tWHERE 1=1");

  237. for(ColumnModel cm :getQueryFields(table)){

  238. sb.append("\n\t\t<if test=\""+cm.getFieldName()+"!=null and "+cm.getFieldName()+"!='' \" >");

  239. sb.append("\n\t\tAND "+cm.getColumnName()+"=#{"+cm.getFieldName()+"}");

  240. sb.append("\n\t\t</if>");

  241. }

  242. sb.append("\n\t\t<if test=\"sort!= null\">\n\t\torder by ${sort} ${order}\n\t\t</if>");

  243. sb.append("\n\t\tlimit #{offset},#{limit}");

  244. sb.append("\n\t</select>\n\n");

  245. return sb.toString();

  246. }

  247.  
  248. private static String genFINDBYPAGESQLOfORCL(String queryModelName, String resultMap, TableModel table){

  249. List<ColumnModel> columnModelList = table.getColumns();

  250. StringBuffer sb = new StringBuffer();

  251. sb.append("\t<!--分页查询-->\n");

  252. sb.append("\t<select id=\"findByPage\" parameterType=\""+queryModelName+"\" resultMap=\""+resultMap+"\">");

  253. sb.append("\n\t\tSELECT * FROM (SELECT t.*, ROWNUM rn FROM (");

  254. sb.append("\n\t\tSELECT ");

  255. for(ColumnModel cm : columnModelList){

  256. sb.append(cm.getColumnName());

  257. sb.append(",");

  258. }

  259. sb.deleteCharAt(sb.length()-1);

  260. sb.append(" FROM "+table.getTableName());

  261. sb.append("\n\t\tWHERE 1=1");

  262. for(ColumnModel cm :getQueryFields(table)){

  263. sb.append("\n\t\t<if test=\""+cm.getFieldName()+"!=null and "+cm.getFieldName()+"!='' \">");

  264. sb.append("\n\t\tAND "+cm.getColumnName()+"=#{"+cm.getFieldName()+"}");

  265. sb.append("\n\t\t</if>");

  266. }

  267. sb.append("\n\t\t<if test=\"sort!= null\">\n\t\torder by ${sort} ${order}\n\t\t</if>");

  268. sb.append("\n\t\t)t) WHERE rn>#{offset} AND (#{offset}+#{limit})>=rn");

  269. sb.append("\n\t</select>\n\n");

  270. return sb.toString();

  271. }

  272.  
  273. private static String genCOUNTSQL(String queryModelName, TableModel table){

  274. StringBuffer sb = new StringBuffer();

  275. sb.append("\t<!--统计-->\n");

  276. sb.append("\t<select id=\"count\" parameterType=\""+queryModelName+"\" resultType=\"int\">");

  277. sb.append("\n\t\tSELECT count(*) FROM "+table.getTableName());

  278. sb.append("\n\t\tWHERE 1=1");

  279. for(ColumnModel cm : getQueryFields(table)){

  280. sb.append("\n\t\t<if test=\""+cm.getFieldName()+"!=null and "+cm.getFieldName()+"!='' \">");

  281. sb.append("\n\t\tAND "+cm.getColumnName()+"=#{"+cm.getFieldName()+"}");

  282. sb.append("\n\t\t</if>");

  283. }

  284. sb.append("\n\t</select>\n\n");

  285. return sb.toString();

  286. }

  287.  
  288. private static String genQUERYSQL(String queryModelName, String resultMap, TableModel table){

  289. List<ColumnModel> columnModelList = table.getColumns();

  290. StringBuffer sb = new StringBuffer();

  291. sb.append("\t<!--查询-->\n");

  292. sb.append("\t<select id=\"query\" parameterType=\""+queryModelName+"\" resultMap=\""+resultMap+"\">\n");

  293. sb.append("\t\tSELECT ");

  294. for(ColumnModel cm : columnModelList){

  295. sb.append(cm.getColumnName());

  296. sb.append(",");

  297. }

  298. sb.deleteCharAt(sb.length()-1);

  299. sb.append(" FROM "+table.getTableName());

  300. sb.append("\n\t\tWHERE 1=1");

  301. for(ColumnModel cm : getQueryFields(table)){

  302. sb.append("\n\t\t<if test=\""+cm.getFieldName()+"!=null and "+cm.getFieldName()+"!='' \">");

  303. sb.append("\n\t\tAND "+cm.getColumnName()+"=#{"+cm.getFieldName()+"}");

  304. sb.append("\n\t\t</if>");

  305. }

  306. sb.append("\n\t\t<if test=\"sort!= null\">\n\t\torder by ${sort} ${order}\n\t\t</if>");

  307. sb.append("\n\t</select>\n");

  308. return sb.toString();

  309. }

  310.  
  311. public static String getSelectFields(List<ColumnModel> columnModelList){

  312. StringBuffer sb = new StringBuffer();

  313. for(ColumnModel cm : columnModelList){

  314. sb.append(cm.getColumnName());

  315. sb.append(",");

  316. }

  317. sb.deleteCharAt(sb.length()-1);

  318. return sb.toString();

  319. }

  320.  
  321. /**

  322. * 获取查询字段

  323. * */

  324. public static List<ColumnModel> getQueryFields(TableModel table){

  325. if(table.getPrimaryKeyColumns().size()==1 && table.getPrimaryKeyColumns().get(0).isAutoIncrement()){

  326. List<ColumnModel> columns = new ArrayList<ColumnModel>();

  327. for(ColumnModel cm : table.getColumns()){

  328. if(!cm.isPrimaryKey())

  329. columns.add(cm);

  330. }

  331. return columns;

  332. }

  333. return table.getColumns();

  334. }

  335. }

最后我们编写我们主入口生成工具类(GenCodeUtil.java)如下所示:

 

 

 
  1. /*

  2. * 类描述:

  3. * @auther linzf

  4. * @create 2017/12/8 0008

  5. */

  6. public class GenCodeUtil {

  7.  
  8. /**

  9. * 从表结构中去生成javabean

  10. * @param author

  11. * @param table

  12. * @param beanName

  13. * @param packagePath

  14. * @return

  15. */

  16. private static String genJavaBeanFromTableStructure(String author, TableModel table,String beanName, String packagePath){

  17. StringBuffer sb = new StringBuffer();

  18. if(StringUtils.isNotEmpty(packagePath)){

  19. sb.append("package "+packagePath+";\n");

  20. }

  21. for(String imp : table.getImports()){

  22. sb.append("import "+imp+";\n");

  23. }

  24. sb.append("\n");

  25. sb.append("/**\n *@author "+author+"\n **/\n");

  26. List<ColumnModel> columnModelList = table.getColumns();

  27. try {

  28. sb.append("public class "+toFirstCharUpCase(beanName)+" {\r\n");

  29. for (ColumnModel columnModel : columnModelList) {

  30. if(StringUtils.isNotBlank(columnModel.getRemarks())){

  31. sb.append(" //"+columnModel.getRemarks()+" \r\n");

  32. }

  33. sb.append(" private "+columnModel.getFieldType()+" "+columnModel.getFieldName()+";\r\n");

  34. }

  35. sb.append("\r\n");

  36. //get set

  37. for (ColumnModel columnModel : columnModelList) {

  38. sb.append(

  39. "\tpublic "+columnModel.getColumnClassName()+" get"+toFirstCharUpCase((String) columnModel.getFieldName())+"() {\r\n" +

  40. "\t\treturn "+columnModel.getFieldName()+";\r\n" +

  41. "\t}\r\n" +

  42. "\r\n" +

  43. "\tpublic void set"+toFirstCharUpCase((String) columnModel.getFieldName())+"("+columnModel.getColumnClassName()+" "+columnModel.getFieldName()+") {\r\n" +

  44. "\t\tthis."+columnModel.getFieldName()+" = "+columnModel.getFieldName()+";\r\n" +

  45. "\t}\r\n\r\n");

  46. }

  47. sb.append("}\r\n");

  48. } catch (Exception e) {

  49. e.printStackTrace();

  50. }

  51. return sb.toString();

  52. }

  53.  
  54. /**

  55. * 从表结构中去生成查询实体类

  56. * @param author

  57. * @param table

  58. * @param beanName

  59. * @param extendsBasePackage

  60. * @param packagePath

  61. * @return

  62. */

  63. private static String genQueryModelFromTableStructure(String author, TableModel table,String beanName, String extendsBasePackage, String packagePath){

  64. StringBuffer sb = new StringBuffer();

  65. if(StringUtils.isNotEmpty(packagePath)){

  66. sb.append("package "+packagePath+";\n\n");

  67. }

  68. sb.append("import "+extendsBasePackage+".entity.QueryBase;\n\n");

  69. sb.append("/**\n *@author "+author+"\n **/\n");

  70. try {

  71. sb.append("public class "+toFirstCharUpCase(beanName)+" extends QueryBase {\r\n");

  72. List<ColumnModel> columns = getQueryFields(table);

  73. for (ColumnModel columnModel : columns) {

  74. if(StringUtils.isNotBlank(columnModel.getRemarks())){

  75. sb.append(" //"+columnModel.getRemarks()+" \r\n");

  76. }

  77. String qFieldType = getQueryModelFieldType(columnModel.getFieldType());

  78. sb.append(" private "+qFieldType+" "+columnModel.getFieldName()+";\r\n");

  79. }

  80. sb.append("\r\n");

  81. //get set

  82. for (ColumnModel columnModel : columns) {

  83. String qFieldType = getQueryModelFieldType(columnModel.getFieldType());

  84. sb.append(

  85. "\tpublic "+qFieldType+" get"+toFirstCharUpCase((String) columnModel.getFieldName())+"() {\r\n" +

  86. "\t\treturn "+columnModel.getFieldName()+";\r\n" +

  87. "\t}\r\n" +

  88. "\r\n" +

  89. "\tpublic void set"+toFirstCharUpCase((String) columnModel.getFieldName())+"("+qFieldType+" "+columnModel.getFieldName()+") {\r\n" +

  90. "\t\tthis."+columnModel.getFieldName()+" = "+columnModel.getFieldName()+";\r\n" +

  91. "\t}\r\n\r\n");

  92. }

  93. sb.append("}\r\n");

  94. } catch (Exception e) {

  95. e.printStackTrace();

  96. }

  97. return sb.toString();

  98. }

  99. /**

  100. * 生成Dao

  101. * */

  102. private static String genDao(String author, String packagePath, String beanName, String queryModelName,String extendsBasePackage){

  103. StringBuffer sb = new StringBuffer();

  104. if(StringUtils.isNotEmpty(packagePath)){

  105. sb.append("package "+packagePath+";\n\n");

  106. }

  107. String businessPackage = packagePath.substring(0, packagePath.lastIndexOf("."));

  108. String basePackage = businessPackage.substring(0, businessPackage.lastIndexOf("."));

  109. sb.append("import "+extendsBasePackage+".dao.GenericDao;\n\n");

  110. sb.append("import "+businessPackage+".entity."+beanName+";\n");

  111. sb.append("import "+businessPackage+".entity."+queryModelName+";\n\n");

  112. sb.append("/**\n *@author "+author+"\n **/\n");

  113. sb.append("public interface "+beanName+"Dao extends GenericDao<"+beanName+", "+queryModelName+"> {\r\n");

  114. sb.append("\n\t\n}");

  115. return sb.toString();

  116. }

  117. /**

  118. * 生成Service

  119. * */

  120. private static String genService(String author, String packagePath, String beanName, String queryModelName,String extendsBasePackage){

  121. StringBuffer sb = new StringBuffer();

  122. if(StringUtils.isNotEmpty(packagePath)){

  123. sb.append("package "+packagePath+";\n\n");

  124. }

  125. String businessPackage = packagePath.substring(0, packagePath.lastIndexOf("."));

  126. String basePackage = businessPackage.substring(0, businessPackage.lastIndexOf("."));

  127. sb.append("import org.springframework.beans.factory.annotation.Autowired;\n");

  128. sb.append("import org.springframework.stereotype.Service;\n\n");

  129. sb.append("import org.springframework.transaction.annotation.Transactional;\n\n");

  130. sb.append("import "+extendsBasePackage+".service.GenericService;\n");

  131. sb.append("import "+basePackage+".common.base.dao.GenericDao;\n\n");

  132. sb.append("import "+businessPackage+".entity."+beanName+";\n");

  133. sb.append("import "+businessPackage+".entity."+queryModelName+";\n");

  134. sb.append("import "+businessPackage+".dao."+beanName+"Dao;\n\n");

  135. sb.append("/**\n *@author "+author+"\n **/\n");

  136. sb.append("@Service(\""+toFirstCharLowerCase(beanName)+"Service\")\n");

  137. sb.append("@Transactional(rollbackFor={IllegalArgumentException.class})\n");

  138. sb.append("public class "+beanName+"Service extends GenericService<"+beanName+", "+queryModelName+"> {\r\n");

  139. sb.append("\[email protected]\n");

  140. sb.append("\[email protected](\"SpringJavaAutowiringInspection\")\n");

  141. sb.append("\tprivate "+beanName+"Dao "+toFirstCharLowerCase(beanName)+"Dao;\n");

  142. sb.append("\[email protected]\n\tprotected GenericDao<"+beanName+", "+queryModelName+"> getDao() {\n");

  143. sb.append("\t\treturn "+toFirstCharLowerCase(beanName)+"Dao;\n");

  144. sb.append("\t}\n");

  145. sb.append("}");

  146. return sb.toString();

  147. }

  148.  
  149. /**

  150. * 生成controller

  151. * */

  152. private static String genController(String author, String packagePath, String beanName, String queryModelName,String extendsBasePackage){

  153. StringBuffer sb = new StringBuffer();

  154. if(StringUtils.isNotEmpty(packagePath)){

  155. sb.append("package "+packagePath+";\n\n");

  156. }

  157. String businessPackage = packagePath.substring(0, packagePath.lastIndexOf("."));

  158. String basePackage = businessPackage.substring(0, businessPackage.lastIndexOf("."));

  159. sb.append("import javax.inject.Inject;\n\n");

  160. sb.append("import org.springframework.web.bind.annotation.RequestMapping;\n");

  161. sb.append("import org.springframework.stereotype.Controller;\n");

  162. sb.append("import "+extendsBasePackage+".controller.GenericController;\n");

  163. sb.append("import "+basePackage+".common.base.service.GenericService;\n\n");

  164. sb.append("import "+businessPackage+".entity."+beanName+";\n");

  165. sb.append("import "+businessPackage+".entity."+queryModelName+";\n");

  166. sb.append("import "+businessPackage+".service."+beanName+"Service;\n\n");

  167. sb.append("/**\n *@author "+author+"\n **/\n");

  168. sb.append("@Controller\n");

  169. sb.append("@RequestMapping(\"/"+toFirstCharLowerCase(beanName)+"\")\n");

  170. sb.append("public class "+beanName+"Controller extends GenericController<"+beanName+", "+queryModelName+"> {\r\n");

  171. sb.append("\[email protected]\n");

  172. sb.append("\tprivate "+beanName+"Service "+toFirstCharLowerCase(beanName)+"Service;\n");

  173. sb.append("\[email protected]\n\tprotected GenericService<"+beanName+", "+queryModelName+"> getService() {\n");

  174. sb.append("\t\treturn "+toFirstCharLowerCase(beanName)+"Service;\n");

  175. sb.append("\t}\n");

  176. sb.append("}");

  177. return sb.toString();

  178. }

  179.  
  180. /**

  181. * 将首字母变大写

  182. * @param str

  183. * @return

  184. */

  185. private static String toFirstCharUpCase(String str){

  186. char[] columnCharArr = str.toCharArray();

  187. StringBuffer sb = new StringBuffer();

  188. for (int i = 0; i < columnCharArr.length; i++) {

  189. char cur = columnCharArr[i];

  190. if(i==0){

  191. sb.append(Character.toUpperCase(cur));

  192. }else{

  193. sb.append(cur);

  194. }

  195. }

  196. return sb.toString();

  197. }

  198. /**

  199. * 将首字母变小写

  200. * @param str

  201. * @return

  202. */

  203. public static String toFirstCharLowerCase(String str){

  204. char[] columnCharArr = str.toCharArray();

  205. StringBuffer sb = new StringBuffer();

  206. for (int i = 0; i < columnCharArr.length; i++) {

  207. char cur = columnCharArr[i];

  208. if(i==0){

  209. sb.append(Character.toLowerCase(cur));

  210. }else{

  211. sb.append(cur);

  212. }

  213. }

  214. return sb.toString();

  215. }

  216. /**

  217. * 获取查询实体类的字段类型

  218. * */

  219. private static String getQueryModelFieldType(String javaType){

  220. switch(javaType){

  221. case "byte": return "Byte";

  222. case "short": return "Short";

  223. case "int": return "Integer";

  224. case "float": return "Float";

  225. case "double": return "Double";

  226. case "long": return "Long";

  227. }

  228. return "String";

  229. }

  230. /**

  231. * 获取查询字段

  232. * */

  233. public static List<ColumnModel> getQueryFields(TableModel table){

  234. if(table.getPrimaryKeyColumns().size()==1 && table.getPrimaryKeyColumns().get(0).isAutoIncrement()){

  235. List<ColumnModel> columns = new ArrayList<ColumnModel>();

  236. for(ColumnModel cm : table.getColumns()){

  237. if(!cm.isPrimaryKey())

  238. columns.add(cm);

  239. }

  240. return columns;

  241. }

  242. return table.getColumns();

  243. }

  244.  
  245. /**

  246. * 创建文件夹,防止文件路径不存在

  247. * */

  248. private static String createFloder(String src, String packagePath) throws IOException{

  249. String path = GenCodeUtil.class.getResource("/").getPath();

  250. File pf = new File(path);

  251. pf = pf.getParentFile().getParentFile();

  252. pf = new File(pf.getAbsolutePath()+"/"+src);

  253. String[] subF = packagePath.split("/");

  254. for(String sf : subF){

  255. pf = new File(pf.getPath()+"/"+sf);

  256. if(!pf.exists()){

  257. pf.mkdirs();

  258. }

  259. }

  260. return pf.getAbsolutePath();

  261. }

  262. /**

  263. * 创建文件夹,防止文件路径不存在

  264. * */

  265. private static String createFloder(String basePath) throws IOException{

  266. String path = GenCodeUtil.class.getResource("/").getPath();

  267. File pf = new File(path);

  268. pf = pf.getParentFile().getParentFile();

  269. String[] subF = basePath.split("/");

  270. for(String sf : subF){

  271. if(StringUtils.isNotEmpty(sf)){

  272. pf = new File(pf.getPath()+"/"+sf);

  273. if(!pf.exists()){

  274. pf.mkdirs();

  275. }

  276. }

  277. }

  278. return pf.getAbsolutePath();

  279. }

  280.  
  281. /**

  282. * @param author 作者

  283. * @param tableName 表名

  284. * @param extendsBasePackage 继承框架类包的基础路径

  285. * @param basePackage 生成文件的包的基础路径

  286. * @param mybatisBasePath mybatis配置文件夹路径

  287. * @param beanName 实体类名称

  288. * @param queryModelName 查询类名称

  289. * @since properties keys include 'db.driver'、'db.username'、'db.password' and 'db.url'

  290. * */

  291. public static void genFiles(String author, String tableName, String extendsBasePackage, String basePackage, String mybatisBasePath, String beanName, String queryModelName, String properitesUri) throws IOException {

  292. String packagePath = basePackage.replaceAll("\\.", "/");

  293. JdbcUtil.setPropertiesURL(properitesUri);

  294. TableModel table = JdbcUtil.getTableStructure(tableName);

  295. String entityPath = createFloder("src/main/java", packagePath+"/entity");

  296. //生成实体类文件

  297. File fEntity = new File(entityPath+"/"+beanName+".java");

  298. if(fEntity.exists()){

  299. fEntity.delete();

  300. }

  301. FileOutputStream fos = new FileOutputStream(fEntity);

  302. fos.write(genJavaBeanFromTableStructure(author, table, beanName, basePackage+".entity").getBytes());

  303. fos.close();

  304. //生成查询实体类文件

  305. if(StringUtils.isNotEmpty(queryModelName)){

  306. File fQEntity = new File(entityPath+"/"+queryModelName+".java");

  307. if(fQEntity.exists()){

  308. fQEntity.delete();

  309. }

  310. fos = new FileOutputStream(fQEntity);

  311. fos.write(genQueryModelFromTableStructure(author, table, queryModelName, extendsBasePackage, basePackage+".entity").getBytes());

  312. fos.close();

  313. }

  314. //生成mybatis配置文件

  315. String mybatisPath = createFloder("/src/main"+mybatisBasePath);

  316. fos = new FileOutputStream(mybatisPath+"/mybatis_"+toFirstCharLowerCase(beanName)+".xml");

  317. fos.write(MyBatisUtil.genMapperConfig(table, basePackage+".dao."+beanName+"Dao", basePackage+".entity."+beanName, basePackage+".entity."+queryModelName).getBytes());

  318. fos.close();

  319. //生成Dao

  320. String daoPath = createFloder("src/main/java", packagePath+"/dao");

  321. File fDao = new File(daoPath+"/"+beanName+"Dao.java");

  322. fos = new FileOutputStream(fDao);

  323. fos.write(genDao(author, basePackage+".dao", beanName, queryModelName,extendsBasePackage).getBytes());

  324. fos.close();

  325. //生成Service

  326. String servicePath = createFloder("src/main/java", packagePath+"/service");

  327. File fService = new File(servicePath+"/"+beanName+"Service.java");

  328. fos = new FileOutputStream(fService);

  329. fos.write(genService(author, basePackage+".service", beanName, queryModelName,extendsBasePackage).getBytes());

  330. fos.close();

  331. // 生成controller

  332. String controllerPath = createFloder("src/main/java", packagePath+"/controller");

  333. File fController = new File(controllerPath+"/"+beanName+"Controller.java");

  334. fos = new FileOutputStream(fController);

  335. fos.write(genController(author, basePackage+".controller", beanName, queryModelName,extendsBasePackage).getBytes());

  336. fos.close();

  337. }

  338.  
  339. /**

  340. * @param args

  341. * @throws IOException

  342. */

  343. public static void main(String[] args) throws IOException {

  344. genFiles("linzf", "t_dining_table", "com.dinner.snqjf.common.base","com.dinner.snqjf.back", "/resources/mybatis/mapper","DiningTable", "QueryDiningTable", "application-dev.properties");

  345. }

  346.  
  347. }


到此我们已经开发完成了我们的代码快速生成工具类,接着大家在GenCodeUtil.java中我们直接执行我们的genFiles("作者","数据库表名","基础工具包路径【com.csdn.demo.common.base】",”java代码生成的路径“,"mybatis代码生成的路径","实体名","查询实体名","读取的配置文件的名字");我们此处则开始试着快速生成一份我们的代码,首先我们在PDM中设计一张字典表如下所示:

 

基于springboot+bootstrap+mysql+redis搭建一套完整的权限架构【五】【编写基础代码快速生成工具】

接着我们在数据执行生成我们的dict表的数据库字典脚本,然后我们在GenCodeUtil的main方法中执行我们的快速生成代码如下:

基于springboot+bootstrap+mysql+redis搭建一套完整的权限架构【五】【编写基础代码快速生成工具】

执行好该代码我们会发现我们的工程中已经多出来了以下的代码:

基于springboot+bootstrap+mysql+redis搭建一套完整的权限架构【五】【编写基础代码快速生成工具】

通过上图我们可以很明显的看到我们的代码已经生成成功了,那么接下来我们重新加载下我们的项目我们访问下我们的swagger2接口我们会发现我们的生成的代码已经生效了:

基于springboot+bootstrap+mysql+redis搭建一套完整的权限架构【五】【编写基础代码快速生成工具】

       到此处我们很明显的发现我们生成的代码已经生效了,那么以后我们每当有一个新的模块的开发那么我们只要设计好数据库,后续我们就可以快速的生成代码,大大简化我们的开发工作,下一章将讲解如何集成bootsrap。

       本章的代码GitHub地址:https://github.com/185594-5-27/csdndemo/tree/base-druid-swagger-tool-two

 

上一篇文章地址:基于springboot+bootstrap+mysql+redis搭建一套完整的权限架构【四】【编写基础开发工具】

 

 

下一篇文章地址:基于springboot+bootstrap+mysql+redis搭建一套完整的权限架构【六】【引入bootstrap前端框架】