代码自动生成(二)
来源:互联网 发布:剑灵天女捏脸图文数据 编辑:程序博客网 时间:2024/05/16 01:04
在上一篇文章 代码自动生成(一)中废了很多话,下面注解入正题:
首先定义列Col类,积累列中相应的信息,具体如下:
public class Col { private Integer index; private String name; private String fieldName; private String methodName; private String desc; private Type type; private String default_; private String isPK = "no"; private String allowNull = "no"; private Boolean hasNext = true; /** 基本参数的构造 * @author hym * @time 2017年7月20日 下午7:37:27 * @param index * @param fieldName * @param type */public Col(Integer index,String fieldName,Type type){ this.index=index; this.fieldName=fieldName; this.type=type; } /**构造校验 * @author hym * @time 2017年7月22日 下午5:19:20 * @param tab * @param index * @param defs * @param isColMap */public Col(String tab, int index, List<Object> defs, Boolean isColMap) { int size = defs.size(); this.index = index; if (size < 2) { throw new RuntimeException("表'" + tab + "'的第'" + index + "'字段没有定义字段名"); } name = (String) defs.get(1); if (name == null || name.trim().length() == 0) { throw new RuntimeException("表'" + tab + "'的第'" + index + "'字段没有定义字段名"); } desc = (String) defs.get(2); if (size < 4) { throw new RuntimeException("表'" + tab + "'的'" + name + "'字段没有定义类型"); } String typeStr = (String) defs.get(3); if (typeStr == null || typeStr.trim().length() == 0) { throw new RuntimeException("表'" + tab + "'的'" + name + "'字段没有定义字类型"); } typeStr = typeStr.trim().toLowerCase(); type = Type.get(typeStr); if (type == null) { throw new RuntimeException("表'" + tab + "'的'" + name + "'字段类型定义错误"); } fieldName = format(); if (size >= 6) { default_ = defs.get(5).toString().trim(); if (default_.length() == 0) { default_ = null; } } if (size >= 7) { isPK = defs.get(6).toString().trim().toLowerCase(); if (isPK.length() == 0) { isPK = "no"; } } if (size >= 8) { allowNull = defs.get(7).toString().trim().toLowerCase(); if (allowNull.length() == 0) { allowNull = "no"; } } if (isColMap) { name = removeDBKeyword(name); } } public Integer getIndex() { return index; } public void setIndex(Integer index) { this.index = index; } public String getName() { return new StringBuffer(name).toString(); } public String getFieldName() { return fieldName; } public void setFieldName(String fieldName) { this.fieldName = fieldName; } public String getMethodName() { return methodName; } public void setMethodName(String methodName) { this.methodName = methodName; } private String format() { String _name = this.getName(); int idx = -1; while ((idx = _name.indexOf("_")) != -1) { String pre = _name.substring(0, idx); String tmpSuf = _name.substring(idx + 1).trim(); String suf_ = ""; if (tmpSuf.length() > 0) { String suf = tmpSuf.substring(0, 1).toUpperCase(); if (tmpSuf.length() > 1) { suf_ = suf + tmpSuf.substring(1); } else { suf_ = suf; } } _name = pre + suf_; } methodName = _name.substring(0, 1).toUpperCase() + _name.substring(1); return _name.substring(0, 1).toLowerCase() + _name.substring(1); } private String removeDBKeyword(String name) { String result = name; if (DBKeyword.get(name.toUpperCase()) != null) { result = "`" + name + "`"; } return result; } public void setName(String name) { this.name = name; } public String getDesc() { return desc; } public void setDesc(String desc) { this.desc = desc; } public Type getType() { return type; } public void setType(Type type) { this.type = type; } public String getDefault() { return default_; } public void setDefault(String default_) { this.default_ = default_; } public String getIsPK() { return isPK; } public void setPK(String isPK) { this.isPK = isPK; } public String getIsAllowNull() { return allowNull; } public void setAllowNull(String allowNull) { this.allowNull = allowNull; }public Boolean getHasNext() {return hasNext;}public void setHasNext(Boolean hasNext) {this.hasNext = hasNext;}}
Type类是定义mysql列数据类型和java中数据类型的转换,写的比较单一,该项可以再以后进行扩展改变,因为数据库除了mysql还有oracle,sqlserver等;
public class Type { private String sqlType; private String javaType; private static HashMap<String, String> typeMap=new HashMap<>(); static{ //基本的sql数据类型 typeMap.put("VARCHAR", "String"); typeMap.put("CHAR", "String"); typeMap.put("BLOB", "byte[]"); typeMap.put("TEXT", "String"); typeMap.put("INT", "Integer"); typeMap.put("INT UNSIGNED", "Integer"); typeMap.put("INTEGER", "Long"); typeMap.put("INTEGER UNSIGNED", "Long"); typeMap.put("TINYINT", "Integer"); typeMap.put("TINYINT UNSIGNED", "Integer"); typeMap.put("SMALLINT", "Integer"); typeMap.put("SMALLINT UNSIGNED", "Integer"); typeMap.put("MEDIUMINT", "Integer"); typeMap.put("MEDIUMINT UNSIGNED", "Integer"); typeMap.put("FLOAT", "Float"); typeMap.put("FLOAT UNSIGNED", "Float"); typeMap.put("DOUBLE", "Double"); typeMap.put("BIT", "Boolean"); typeMap.put("BIGINT", "java.math.BigInteger"); typeMap.put("DECIMAL", "java.math.BigDecimal"); typeMap.put("BOOLEAN", "Long"); typeMap.put("DATE", "java.sql.Date"); typeMap.put("TIME", "java.sql.Time"); typeMap.put("DATETIME", "java.sql.Timestamp") ; typeMap.put("TIMESTAMP", "java.sql.Timestamp"); typeMap.put("YEAR", "java.sql.Date"); typeMap.put("OTHER", "String"); } /** * @author hym * @time 2017年7月20日 下午5:21:52 * @param sqlType * @param javaType */public Type(String sqlType, String javaType) { this.sqlType = sqlType.toLowerCase(); this.javaType = javaType; } public String getSqlType() { return sqlType; } public void setSqlType(String sqlType) { this.sqlType = sqlType; } public String getJavaType() { return javaType; } public void setJavaType(String javaType) { this.javaType = javaType; } /** * 当返回值找不到的时候,直接返回other-string * @author hym * @time 2017年7月20日下午5:22:09 * @param sqlType * @return */public static Type get(String sqlType) {String javaType=typeMap.get(sqlType.toUpperCase());if (StringUtils.isEmpty(javaType)) {javaType=typeMap.get("OTHER");} Type result = new Type(sqlType, javaType); return result; }}
当我们准备好工具类之后,那么就进入主类了,如下:
public class AutoGenerationJavaCode { private String url; private String name; private String passWord; private String driver; private String sql; private String tableName; private String templateDir; private String autoGeneratedFile; //包的基础路径 比如com.xx等 private String basePath; private static String[][] fileNameArray = new String[6][2]; static { fileNameArray[0][0] = "entityTemplate.ftl"; fileNameArray[0][1] = ".java"; fileNameArray[1][0] = "serviceTemplate.ftl"; fileNameArray[1][1] = "Service.java"; fileNameArray[2][0] = "serviceImplTemplate.ftl"; fileNameArray[2][1] = "ServiceImpl.java"; fileNameArray[3][0] = "daoTemplate.ftl"; fileNameArray[3][1] = "Dao.java"; fileNameArray[4][0] = "daoImplTemplate.ftl"; fileNameArray[4][1] = "DaoImpl.java"; fileNameArray[5][0] = "mapper.ftl"; fileNameArray[5][1] = "Mapper.xml"; } public AutoGenerationJavaCode(String url, String name, String passWord, String driver, String tableName, String autoGeneratedFile,String basePath) { this.url = url; this.name = name; this.passWord = passWord; this.driver = driver; this.sql = "select * from " + tableName; this.tableName = tableName; this.templateDir = this.getClass().getResource("").getPath().replace("target/classes/com/xx/common/code/autocode/", "") +"src/main/java/com/xx/common/code/template"; this.autoGeneratedFile = autoGeneratedFile; this.basePath=basePath; } public void autoGenerationJavaCode() throws IOException, TemplateException, ClassNotFoundException, SQLException { Configuration cfg = new Configuration(); cfg.setDefaultEncoding("utf-8"); String className = dealClassName(dealTableName()); String fileName = className; // Map<String, Object> columnMap = getColumn(); //设置模板文件路径 cfg.setDirectoryForTemplateLoading(new File(templateDir)); Map<String, Object> rootMap = new HashMap<String, Object>(); rootMap.put("className", className); //rootMap.put("columnMap", columnMap); rootMap.put("columns", getColumnList()); rootMap.put("basePath", basePath); for (int i = 0; i < fileNameArray.length; i++) { String packageName=null; String filePath=null; //设定包名 switch(fileNameArray[i][0]){ case "entityTemplate.ftl": packageName=basePath+".entity"; filePath=autoGeneratedFile+"/entity"; break; case "daoTemplate.ftl": packageName=basePath+".dao"; filePath=autoGeneratedFile+"/dao"; break; case "daoImplTemplate.ftl": packageName=basePath+".dao.impl"; filePath=autoGeneratedFile+"/dao/impl"; break; case "serviceTemplate.ftl": packageName=basePath+".service"; filePath=autoGeneratedFile+"/service"; break; case "serviceImplTemplate.ftl": packageName=basePath+".service.impl"; filePath=autoGeneratedFile+"/service/impl"; break; case "mapper.ftl": packageName=basePath; filePath=autoGeneratedFile+"/mapper"; rootMap.put("tableName", tableName); break; } rootMap.put("packageName", packageName); File dir=new File(filePath); //检查目录是否存在,不存在则创建 if (!dir.exists()) { dir.mkdir(); } Template temp = cfg.getTemplate(fileNameArray[i][0]); File docFile = new File(filePath + "//" + fileName + fileNameArray[i][1]); Writer docout = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(docFile))); //输出文件 temp.process(rootMap, docout); } System.out.println("==============所有的文件已成功生成==============="); } public List<Col> getColumnList() throws ClassNotFoundException, SQLException { Connection conn; PreparedStatement pStemt = null; Class.forName(driver); conn = DriverManager.getConnection(url, name, passWord); pStemt = conn.prepareStatement(sql); ResultSetMetaData rsmd = pStemt.getMetaData(); List<Col> listColumn=new ArrayList<Col>(); int size = rsmd.getColumnCount(); for (int i = 0; i < size; i++) { // String columnName = dealColumnName(rsmd, i); Col col=getColumnInfo(rsmd, i); if(i==size-1){ col.setHasNext(false); } listColumn.add(col); } conn.close(); return listColumn; } /** * 获取列信息 需要设置多属性,该处生成mapper.xml的时候需要各种属性 * @author hym * @time 2017年7月20日下午7:48:39 * @param rsmd * @param i * @return * @throws SQLException */ private Col getColumnInfo(ResultSetMetaData rsmd,int i) throws SQLException{ String columnName = rsmd.getColumnName(i + 1).toLowerCase(); String charAfterLine = String.valueOf(columnName.charAt((columnName.indexOf("_") + 1))); String convertedChar = charAfterLine.toUpperCase(); String fieldName = columnName.replace("_" + charAfterLine, convertedChar);//映射到类中的名称 String columntype=rsmd.getColumnTypeName(i+1);//sql的列类型 Type type=new Type(columntype, Type.get(columntype).getJavaType()); Col col=new Col(i, fieldName, type); col.setMethodName(dealClassName(fieldName)); col.setName(columnName);//表中的列名 if (columnName.equalsIgnoreCase("id")) { col.setPK("yes");} return col; } /** * 将表名转换为DMO的字段名,比如 operate_type 转换后为 operateType * @author hym * @time 2017年7月22日下午4:22:14 * @param rsmd * @param i * @return * @throws SQLException */ private String dealColumnName(ResultSetMetaData rsmd, int i) throws SQLException { String columnName = rsmd.getColumnName(i + 1).toLowerCase(); String charAfterLine = String.valueOf(columnName.charAt((columnName.indexOf("_") + 1))); String convertedChar = charAfterLine.toUpperCase(); columnName = columnName.replace("_" + charAfterLine, convertedChar); return columnName; } /** * 将表名转换为类型类名 比如 t_operate_log 转换后为 operateLog ,类名首字母应为大写,这里在freemarker的模板里直接转换 * @author hym * @time 2017年7月22日下午4:22:05 * @return */ private String dealTableName() { String className = tableName.toLowerCase().substring(tableName.indexOf("_") + 1); String charAfterLine = String.valueOf(className.charAt((className.indexOf("_") + 1))); String convertedChar = charAfterLine.toUpperCase(); className = className.replace("_" + charAfterLine, convertedChar); return className; } public static void main(String[] args) { String tableName="t_operate_table_test"; String className = tableName.toLowerCase().substring(tableName.indexOf("_") + 1); String charAfterLine = String.valueOf(className.charAt((className.indexOf("_") + 1))); String convertedChar = charAfterLine.toUpperCase(); className = className.replace("_" + charAfterLine, convertedChar);} /** * 将类名转换为文件名,java公共类名与其文件名应该相同,这里将首字母转换为大写 如operateLog 转换后为 OperateLog * @author hym * @time 2017年7月22日下午4:22:25 * @param className * @return */ private String dealClassName(String className) { String first = className.substring(0, 1).toUpperCase(); String rest = className.substring(1, className.length()); String fileName = new StringBuffer(first).append(rest).toString(); return fileName; }}
Ok,上面的基本完成了生成所需的java类文件;
测试代码如下:
public static void main(String[] args) throws ClassNotFoundException, IOException, TemplateException, SQLException {String url="jdbc:mysql://10.67.18.17:3306/xx";String username="xx";String password="xx";String driver="com.mysql.jdbc.Driver";String tableName="t_test_operate";String basePath="com.xx.test";String templateDir=System.getProperty("user.dir")+"/src/main/java/"+"com/xx/common/code/template";String generateFilePath=System.getProperty("user.dir")+"/src/main/java/"+basePath.replace(".", "/");AutoGenerationJavaCode autoGenerationJavaCode=new AutoGenerationJavaCode(url, username, password, driver, tableName, generateFilePath, "com.xx.test");autoGenerationJavaCode.autoGenerationJavaCode();}
考虑到可能会用到不同类型的数据库,后面会对上面的类进行改造;
阅读全文
0 0
- 代码自动生成(二)
- AOS 自动生成代码(二) Dao生成
- 代码自动生成工具(二)-miniproto介绍
- 代码自动生成工具MyGeneration之二
- 代码自动生成工具MyGeneration之二
- 代码自动生成工具MyGeneration之二
- 代码自动生成(二)数据库表字段生成mybaties 映射配置文件**mapper.xml
- [代码生成器] 二. 动态加载DLL的代码自动生成
- 代码自动生成(一)
- 代码自动生成(三)
- 如何高效地使用XCodeFactory自动生成的数据层代码(二)
- C#分析数据库结构,使用XSL模板自动生成代码(二)
- [goa]golang微服务框架学习(二)-- 代码自动生成
- CXF使用教程(二)——webService自动生成客户端代码
- 代码自动生成工具(二)-miniproto的c++库实现
- 代码自动生成工具(二)-miniproto的c#库实现
- 代码自动生成工具(二)-miniproto的java库实现
- Mybatis-Generator自动生成代码——Mybatis 深入浅出(二)
- JS遍历
- Android系统版本与AspectJ
- 谁获得了最高奖学金
- Java 随机生成50个正整数,存放到数组,求出总和,平均值,最大值,最小值
- Android入门
- 代码自动生成(二)
- leetcode 141. Linked List Cycle
- Android简单绘图
- (poj 2377)Kruskal算法 最大生成树
- 南阳oj 题目115 城市平乱 迪杰斯特拉
- Nginx入门介绍-安装与使用
- mysql中insert into select from的使用
- 不用循环数组求和---京东金融面试
- String与StringBuilder以及StringBuffer的比较