栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > Web开发 > Html/CSS > Bootstrap教程

自己动手打造专属代码生成工具(完结篇)

自己动手打造专属代码生成工具(完结篇)


神兽坐镇!!
...
...
OK,进入主题,上篇说到了代码生成工具,只是演示了一下简单的操作流程。那么,说好了,这篇是贴码文,在贴码之前先大体说下原理吧(大神止步吧...)......

说到需要生成文件,不得不说说在项目开发中那些让码农们头疼的事:在项目开发中最让人头疼的就是把数据库表字段对应成java实体属性,一个数据库如果有几十个表,单单靠手写java实体的话,等项目上线了,估计实体刚建完...
再一个就是对数据库进行操作的mapper文件,一般的业务上都包括增删改查(批/单),以及对应实体的resultMap定义。此项工作如果没有工具的帮助,就相当于重复造轮子。因为增删改查(批/单)区别就在于表名不同、resultMap区别就在于字段不同
......
以上只是简单的举证了一下(不要嫌俺啰嗦,俺只是深恶痛绝...),说回俺这个代码生成工具,原理莫过于获取系统中的数据库列表,根据数据库获取单个数据库下的所有数据表,最后一步是最重要也是最麻烦的,要获取数据表中的字段、字段类型、字段注释等等,因为要根据字段类型生成对应的java类型变量。
(神马~~!!这TM就是所谓的原理?酱简单?你TM是不是唬我?)
没错,就是这么简单,天地良心

下面到重点部分了,贴码!!

  • 获取所有数据库
    public List getDbNameList(TableForm mybatisSqlForm) {
 List list = new ArrayList();
 ResultSet rs = null;
 Connection conn = null;
 Statement statement = null;
 try {
     String sql = "show databases";
     rs = getResultSet(conn, statement, mybatisSqlForm.getDbAddress(), mybatisSqlForm.getDbLoginName(),
      mybatisSqlForm.getDbPassword(), sql.toString());
     while (rs.next()) {
  list.add(rs.getString(1));
     }
 } catch (SQLException e) {
     e.printStackTrace();
 } finally {
     try {
  if (rs != null) {
      rs.close();
  }
     } catch (SQLException e) {
  e.printStackTrace();
     }
     try {
  if (statement != null)
      statement.close();
     } catch (SQLException e) {
  e.printStackTrace();
     }
     try {
  if (conn != null)
      conn.close();
     } catch (SQLException e) {
  e.printStackTrace();
     }
 }
 return list;
    }

获取数据库也是用的最基本的sql语句:show databases;

  • 获取数据库表列表
    public List getTableNameList(TableForm mybatisSqlForm) {
 List list = new ArrayList();
 ResultSet rs = null;
 Connection conn = null;
 Statement statement = null;
 try {
     String sql = "SELECt TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERe TABLE_SCHEMA = '"
      + mybatisSqlForm.getSelectedDbNames() + "'";
     rs = getResultSet(conn, statement, mybatisSqlForm.getDbAddress(), mybatisSqlForm.getDbLoginName(),
      mybatisSqlForm.getDbPassword(), sql.toString());
     while (rs.next()) {
  list.add(rs.getString(1));
     }
 } catch (SQLException e) {
     e.printStackTrace();
 } finally {
     try {
  if (rs != null) {
      rs.close();
  }
     } catch (SQLException e) {
  e.printStackTrace();
     }
     try {
  if (statement != null)
      statement.close();
     } catch (SQLException e) {
  e.printStackTrace();
     }
     try {
  if (conn != null)
      conn.close();
     } catch (SQLException e) {
  e.printStackTrace();
     }
 }
 return list;
    }
  • 获取字段名 列表
    public List getColumnNameList(TableForm mybatisSqlForm) {
 List columnNames = new ArrayList();
 ResultSet rs = null;
 Connection conn = null;
 Statement statement = null;
 try {
     StringBuffer sql = new StringBuffer();
     sql.append(
      "SELECT DISTINCT column_name cloumnName,data_type type,column_comment comment,column_key FROM Information_schema.COLUMNS ");
     sql.append("WHERe TABLE_NAME = '" + mybatisSqlForm.getSelectedTableNames() + "' and TABLE_SCHEMA = '"
      + mybatisSqlForm.getSelectedDbNames() + "'");
     rs = getResultSet(conn, statement, mybatisSqlForm.getDbAddress(), mybatisSqlForm.getDbLoginName(),
      mybatisSqlForm.getDbPassword(), sql.toString());
     while (rs.next()) {
  columnNames.add(rs.getString(1));
     }
 } catch (SQLException e) {
     e.printStackTrace();
 } finally {
     try {
  if (rs != null) {
      rs.close();
  }
     } catch (SQLException e) {
  e.printStackTrace();
     }
     try {
  if (statement != null)
      statement.close();
     } catch (SQLException e) {
  e.printStackTrace();
     }
     try {
  if (conn != null)
      conn.close();
     } catch (SQLException e) {
  e.printStackTrace();
     }
 }
 return columnNames;
    }
  • 获取数据表详情(字段类型、注释等)
    public List getTableInfo(TableForm mybatisSqlForm) {
 List tableInfo = new ArrayList();
 Connection conn = null;
 Statement statement = null;
 ResultSet rs = null;
 try {
     StringBuffer sql = new StringBuffer();
     sql.append(
      "SELECT DISTINCT column_name cloumnName,data_type type,column_comment comment,column_key FROM Information_schema.COLUMNS ");
     sql.append("WHERe TABLE_NAME = '" + mybatisSqlForm.getSelectedTableNames() + "' and TABLE_SCHEMA = '"
      + mybatisSqlForm.getSelectedDbNames() + "'");
     rs = getResultSet(conn, statement, mybatisSqlForm.getDbAddress(), mybatisSqlForm.getDbLoginName(),
      mybatisSqlForm.getDbPassword(), sql.toString());
     while (rs.next()) {
  Variable variable = new Variable();
  variable.setColumnName(rs.getString("cloumnName"));
  variable.setType(rs.getString("type"));
  variable.setComment(rs.getString("comment"));
  variable.setColumnKey(rs.getString("column_key"));
  tableInfo.add(variable);
     }
 } catch (SQLException e) {
     e.printStackTrace();
 } finally {
     try {
  if (rs != null) {
      rs.close();
  }
     } catch (SQLException e) {
  e.printStackTrace();
     }
     try {
  if (statement != null)
      statement.close();
     } catch (SQLException e) {
  e.printStackTrace();
     }
     try {
  if (conn != null)
      conn.close();
     } catch (SQLException e) {
  e.printStackTrace();
     }
 }
 return tableInfo;
    }
  • 以下这一段代码是以上三段代码需要用到的公共方法
    public ResultSet getResultSet(Connection conn, Statement statement, String dbAddress, String userName,
     String passWord, String sql) {
 ResultSet rs = null;
 try {
     conn = DriverManager.getConnection(getDbUrl(dbAddress), userName, passWord);
     statement = conn.createStatement();
     rs = statement.executeQuery(sql.toString());
 } catch (SQLException e) {
     e.printStackTrace();
 }
 return rs;
    }

    public String getDbUrl(String dbAddress) {
 return "jdbc:mysql://" + dbAddress + "?useUnicode=true&characterEncoding=utf-8";
    }
  • 生成java文件相关业务实现
package com.maven.web.service.generation.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.maven.web.dao.generation.GenerationMapperDao;
import com.maven.web.entity.generation.TableForm;
import com.maven.web.entity.generation.Variable;
import com.maven.web.service.generation.IGenerationClassService;
import com.maven.web.utils.FileUtil;
import com.maven.web.utils.StringUtil;
import com.maven.web.utils.memcache.MemcachedUtil;


@Service
public class GenerationClassServiceImpl implements IGenerationClassService {

    @Autowired
    private GenerationMapperDao generationMapperDao;

    // 数据库数据类型、java数据类型映射map
    private static Map dataTypeMapping = new HashMap();

    // 初始化数据库类型与java类型转换
    static {
 dataTypeMapping.put("int", "int");
 dataTypeMapping.put("tinyint", "int");
 dataTypeMapping.put("smallint", "int");
 dataTypeMapping.put("mediumint", "int");
 dataTypeMapping.put("integer", "int");
 dataTypeMapping.put("bigint", "long");
 dataTypeMapping.put("bit", "boolean");
 dataTypeMapping.put("real", "float");
 dataTypeMapping.put("double", "double");
 dataTypeMapping.put("float", "float");
 dataTypeMapping.put("float", "float");
 dataTypeMapping.put("decimal", "BigDecimal");
 dataTypeMapping.put("numeric", "BigDecimal");
 dataTypeMapping.put("char", "String");
 dataTypeMapping.put("varchar", "String");
 dataTypeMapping.put("date", "java.util.Date");
 dataTypeMapping.put("time", "java.util.Time");
 dataTypeMapping.put("year", "java.util.Date");
 dataTypeMapping.put("timestamp", "java.util.Timestamp");
 dataTypeMapping.put("datetime", "java.util.Date");
 dataTypeMapping.put("tinyblob", "byte[]");
 dataTypeMapping.put("blob", "byte[]");
 dataTypeMapping.put("mediumblob", "byte[]");
 dataTypeMapping.put("longblob", "byte[]");
 dataTypeMapping.put("tinytext", "String");
 dataTypeMapping.put("text", "String");
 dataTypeMapping.put("mediumtext", "String");
 dataTypeMapping.put("longtext", "String");
 dataTypeMapping.put("binary", "byte[]");
    }

    
    @Override
    public Map getJava(TableForm tableForm) {
 List tableInfo = generationMapperDao.getTableInfo(tableForm);
 Map sqlMap = new HashMap();
 String sqlString = createJava(tableInfo, tableForm);
 sqlMap.put("list", sqlString);
 return sqlMap;
    }

    
    @Override
    public String createJava(List tableInfo, TableForm tableForm) {
 StringBuilder sb = new StringBuilder();
 // 包名
 String packageString = createPackage(tableForm.getEntityPackage());
 sb.append(packageString);
 // class
 String classString = createClass(tableForm.getSelectedTableNames());
 sb.append(classString);
 // 变量
 String variablesString = createVariables(tableInfo);
 sb.append(variablesString);
 // SetAndGet
 String SetAndGetString = createSetAndGet(tableInfo);
 sb.append(SetAndGetString);
 // 尾部
 String tailString = createTail();
 sb.append(tailString);
 return sb.toString();
    }

    
    @Override
    public String createPackage(String packagePath) {
 StringBuilder sb = new StringBuilder();
 sb.append("package " + packagePath + ";

"); return sb.toString(); } @Override public String createimport() { StringBuilder sb = new StringBuilder(); sb.append("
"); return sb.toString(); } @Override public String createClass(String tableName) { StringBuilder sb = new StringBuilder(); String[] temps = tableName.split("_"); tableName = temps[0]; for (int i = 1; i < temps.length; i++) { tableName += StringUtil.initialtoUpper(temps[i]); } sb.append("public class " + StringUtil.initialtoUpper(tableName) + " {
"); return sb.toString(); } @Override public String createVariables(List tableInfo) { StringBuilder sb = new StringBuilder(); for (Variable variable : tableInfo) { if (StringUtil.isNotEmpty(variable.getComment())) { sb.append(" //" + variable.getComment() + "
"); } sb.append(" private " + dataTypeMapping.get(variable.getType()) + " " + variable.getPropertyNames() + ";
"); } sb.append("
"); return sb.toString(); } @Override public String createSetAndGet(List tableInfo) { StringBuilder sb = new StringBuilder(); for (Variable variable : tableInfo) { sb.append(" public void set" + StringUtil.initialtoUpper(variable.getPropertyNames()) + "(" + dataTypeMapping.get(variable.getType()) + " " + variable.getPropertyNames() + "){
"); sb.append(" this." + variable.getPropertyNames() + " = " + variable.getPropertyNames() + ";
"); sb.append(" }

"); sb.append(" public " + dataTypeMapping.get(variable.getType()) + " get" + StringUtil.initialtoUpper(variable.getPropertyNames()) + "(){
"); sb.append(" return this." + variable.getPropertyNames() + ";
"); sb.append(" }

"); } return sb.toString(); } @Override public String createTail() { return "}"; } }
  • 关于文件导出
    @RequestMapping(value = "/getJava", produces = "application/json; charset=utf-8")
    @ResponseBody
    public String getJava(TableForm sqlForm) {
 try {
     String filename = StringUtil.splitAndtoUpper(sqlForm.getSelectedTableNames(), "_") + ".java";
     String path = generationClassService.getSaveFilePath(filename, sqlForm);
     MemcachedUtil.set("java_path", path);
     MemcachedUtil.set("java_name", filename);
 } catch (Exception e) {
     e.printStackTrace();
 }
 Map map = generationClassService.getJava(sqlForm);
 // 页面用,保证队形
 String sql = (String) map.get("list");
 map.put("list", sql.replace("   ", " "));
 JSonObject jsonObject = JSONObject.fromObject(map);
 return jsonObject.toString();
    }
    @Override
    public String getSaveFilePath(String filename, TableForm mybatisSqlForm) {
 filename = StringUtil.initialtoUpper(filename);
 Map map = this.getJava(mybatisSqlForm);
 String sql = (String) map.get("list");
 sql = sql.replace("
", "n"); String path = FileUtil.getGenerationJavaFilePath() + filename; FileUtil.saveFile(path, sql.replace("
", "n")); MemcachedUtil.set("java_path", path); return path; }

说明:因为我设计的是在点击生成java代码后才会显示导出按钮,因此,在生成java代码时就要把内容保存到文件中,供下载导出。同时,因为我没有用到数据库表记录生成的文件路径和名字,我用的是Memcache缓存,此处无强求,根据个人爱好,爱咋整咋整。

  • 将字符串保存到新文件中
    public static boolean saveFile(String filePath, String content) {
 return saveFile(filePath, content, "UTF-8");
    }

    
    public static boolean saveFile(String path, String content, String encodeingType) {
 boolean flag = false;
 DataOutputStream dos = null;
 try {
     File file = new File(path);
     if (content != null && content.length() >= 0) {
  byte abyte[] = content.getBytes(encodeingType);
  dos = new DataOutputStream(new FileOutputStream(file));
  dos.write(abyte, 0, abyte.length);
  dos.flush();

  flag = true;
     }
 } catch (FileNotFoundException e) {
     e.printStackTrace();
 } catch (IOException e) {
     e.printStackTrace();
 } finally {
     if (dos != null) {
  close(dos);
     }
 }
 return flag;
    }

OK,到这儿就算到量了,基本的流程和逻辑以及核心代码,就是以上所示。如果感兴趣,可以根据这个思路自己弄一个。如果以上有看不明白的,或者我写的有不明确的地方,请随时call我,或者本文留言也行。

......
恭迎各位大神指点......

github:servlet版项目代码

注:源代码是在SSM框架中的,没另外提。因为有慕友让我提出来一份简单的,所以我就提成了一个servlet版的。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/243706.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号