java 从数据库生成表的实体类(PostgreSQL版)

前面写了生成表的实体类的MySQL数据库版,这里再贴上PostgreSQL数据库版。

注:pgsql字段类型所对应的Java类型只写了常见的部分类型,如有需要请自行修改完善sqlType2JavaType方法。

package generator;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

 /**
  * 从数据库生成表的实体类 
  * PostgreSQL版
  */
public class PgSQlGenerateEntityUtil {
	
	public static void main(String[] args) {
    	PgSQlGenerateEntityUtil pgGen = new PgSQlGenerateEntityUtil();
    	//PgSQlGenerateEntityUtil.basePath=""; //指定生成的位置,默认是当前工程
    	//pgGen.needEntityHelper=true;
    	//生成的包名
    	PgSQlGenerateEntityUtil.packageOutPath = "net.hlinfo.entity";
    	pgGen.generate();
       System.out.println("generate Entity to classes successful!");
        
    }
	
     //表名
    private String tableName;
    //表注释
    private String tableComment;
     //列名数组
    private String[] colNames;
     //列名类型数组
    private String[] colTypes; 
    //列名大小数组
    private int[] colSizes; 
    //列名注释
    private Map colNamesComment = new HashMap(); 
     //是否需要导入包java.util.*
    private boolean needUtil = false;
     //是否需要导入包java.sql.*
    private boolean needSql = false; 
    //是否需要导入包java.math.BigDecimal
    private boolean needBigDecimal = false; 
     //是否创建EntityHelper
    private boolean needEntityHelper = false;
    private static final SimpleDateFormat SDF = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
     
    // 数据库配置信息
    private static final String JDBC_URL = "jdbc:postgresql://127.0.0.1:5432/test";
    public static final String jdbc_user = "postgres";
    public static final String jdbc_pwd = "123456";
    private static final String DRIVER = "org.postgresql.Driver";
    
    //指定实体生成所在包的路径
    private static String basePath = new File("").getAbsolutePath();
    //指定包名
    private static String packageOutPath = "com.cy.entity";
    //作者名字
    private static final String authorName = "呐喊";
    //指定需要生成的表的表名,全部生成设置为null
    private String[] generateTables = null;
     //主键
    private static String pk;

    private PgSQlGenerateEntityUtil() {
    }
    /**
      * 功能:查询表信息的sql
     * @param tableName
     * @return comment 表的注释,type字段类型,name字段名字,notnull是否为空
     */
    private static String SQL(String tableName) {
    	if(tableName==null || "".equals(tableName)) {return null;}
    	String sql = "SELECT col_description(a.attrelid,a.attnum) as comment,"
        		+ "format_type(a.atttypid,a.atttypmod) as type,a.attname as name, a.attnotnull as notnull,a.atttypmod-4 as fields_length "
        		+ "FROM pg_class as c,pg_attribute as a where c.relname = '"+tableName+"' "
        		+ "and a.attrelid = c.oid and a.attnum>0";
    	return sql;
    	
    }
    /**
      * 功能:获取主键的sql
     * @param tableName
     * @return pk_name:主键名  | colname:主键对应字段名 | typename:主键类型
     */
    private static String PK_SQL(String tableName) {
    	if(tableName==null || "".equals(tableName)) {return null;}
    	String pksql = "select pg_constraint.conname as pk_name,pg_attribute.attname as colname,pg_type.typname as typename from pg_constraint  inner join pg_class on pg_constraint.conrelid = pg_class.oid inner join pg_attribute on pg_attribute.attrelid = pg_class.oid and  pg_attribute.attnum = pg_constraint.conkey[1] inner join pg_type on pg_type.oid = pg_attribute.atttypid where pg_class.relname = '"+tableName+"' and pg_constraint.contype='p'";
    	return pksql;
    }
    /**
     * 功能:解析字段数据,生成实体类的所有内容
     * @return
     */
    private String parse() {
        StringBuffer sb = new StringBuffer();
        sb.append("package " + packageOutPath + ";\r\n");
        sb.append("\r\n");
        // 判断是否导入工具包
        if (needUtil) {
            sb.append("import java.util.Date;\r\n");
         }
        if (needSql) {
            sb.append("import java.sql.*;\r\n");
         }
         
       for (int i = 0; i < colNames.length; i++) {
    	   String hasbd = sqlType2JavaType(colTypes[i]);
    	   if(hasbd =="BigDecimal" || "BigDecimal".equals(hasbd)) {needBigDecimal=true;}
        }
       if(needBigDecimal) {
    	   sb.append("import java.math.BigDecimal;\r\n");
        }
         // 注释部分
        sb.append("/**\r\n");
        sb.append(" * 
    \r\n"); sb.append(" *
  • table name: " + tableName + "
  • \r\n"); sb.append(" *
  • table comment: " + (tableComment==null?"":tableComment) + "
  • \r\n"); sb.append(" *
  • author name: " + authorName + "
  • \r\n"); sb.append(" *
  • create time: " + SDF.format(new Date()) + "
  • \r\n"); sb.append(" *
\r\n"); sb.append(" */ \r\n"); // 实体部分 String classExtends = ""; if(needEntityHelper) { classExtends=" extends EntityHelper"; } sb.append("public class " + under2camel(tableName, true) + classExtends + "{\r\n\r\n"); //实体属性 processAllAttrs(sb); sb.append("\r\n"); // 构造函数 processConstructor(sb);// //get set方法 processAllMethod(sb); processToString(sb); if(needEntityHelper) { processEntityHelper(sb,pk); } sb.append("}\r\n"); return sb.toString(); } /** * @param sb * @description 生成所有成员变量及注释 */ private void processAllAttrs(StringBuffer sb) { for (int i = 0; i < colNames.length; i++) { if(colNamesComment.get(colNames[i])!=null &&!"".equals(colNamesComment.get(colNames[i]))) { sb.append("\t/*"+colNamesComment.get(colNames[i])+"*/\r\n"); } sb.append("\tprivate " + sqlType2JavaType(colTypes[i]) + " " + colNames[i] + ";\r\n"); } } /** * EntityHelper * @param sb * @param pk */ private void processEntityHelper(StringBuffer sb,String pk) { sb.append("\t@Override\r\n"); sb.append("\tpublic String getPrimaryKey() {\r\n"); sb.append("\t\treturn \""+pk+"\";\r\n"); sb.append("\t}\r\n"); } /** * 重写toString()方法 * @param sb */ private void processToString(StringBuffer sb) { sb.append("\t@Override\r\n\tpublic String toString() {\r\n"); sb.append("\t\treturn \"" +tableName + "[\" + \r\n"); for (int i = 0; i < colNames.length; i++) { if (i != 0) sb.append("\t\t\t\", "); if (i == 0) sb.append("\t\t\t\""); sb.append(colNames[i] + "=\" + " + colNames[i]).append(" + \r\n"); if (i == colNames.length - 1) { sb.append("\t\t\t\"]\";\r\n"); } } sb.append("\t}\r\n"); } /** * 构造函数 * @param sb */ private void processConstructor(StringBuffer sb) { StringBuffer p = new StringBuffer(); StringBuffer v = new StringBuffer(); for(int i = 0; i < colNames.length; i++) { p.append(sqlType2JavaType(colTypes[i])+" "+colNames[i]); if(i!=colNames.length-1) { p.append(","); } v.append("\t\tthis."+colNames[i]+"="+colNames[i]+";\r\n"); } //无参数构造函数 sb.append("\tpublic "+under2camel(tableName,true)+"() {\r\n"); sb.append("\t\tsuper();\r\n"); sb.append("\t}\r\n"); //带参构造函数 sb.append("\tpublic "+under2camel(tableName,true)+"("+p.toString()+") {\r\n"); sb.append(v.toString()); sb.append("\t}\r\n"); } /** * @param sb * @description 生成所有get/set方法 */ private void processAllMethod(StringBuffer sb) { for (int i = 0; i < colNames.length; i++) { sb.append("\tpublic void set" + initCap(colNames[i]) + "(" + sqlType2JavaType(colTypes[i]) + " " + colNames[i] + "){\r\n"); sb.append("\t\tthis." + colNames[i] + "=" + colNames[i] + ";\r\n"); sb.append("\t}\r\n"); sb.append("\tpublic " + sqlType2JavaType(colTypes[i]) + " get" + initCap(colNames[i]) + "(){\r\n"); sb.append("\t\treturn " + colNames[i] + ";\r\n"); sb.append("\t}\r\n"); } } /** * 功能:将传入字符串的首字母转成大写 * @param str 传入字符串 * @return */ private String initCap(String str) { char[] ch = str.toCharArray(); if (ch[0] >= 'a' && ch[0] <= 'z') ch[0] = (char) (ch[0] - 32); return new String(ch); } /** * 功能:下划线命名转驼峰命名 * @param s * @param fistCharToUpperCase 首字母是否大写 * @author 呐喊 * @return */ private String under2camel(String s,boolean fistCharToUpperCase) { String separator = "_"; String under=""; s = s.toLowerCase().replace(separator, " "); String sarr[]=s.split(" "); for(int i=0;i0) { sqlType = sqlType.substring(0, sqlType.indexOf("(")); } String returnType=null; switch (sqlType) { case "boolean": case "bit": returnType = "boolean"; break; case "bytea": returnType = "byte"; break; case "bigint": case "int8": case "bigserial": returnType = "Long"; break; case "integer": case "int2": case "int4": case "smallint": case "serial": returnType = "Integer"; break; case "real": case "double precision": returnType = "double"; break; case "text": case "character varying": case "character": case "varchar": case "char": case "uuid": case "json": case "xml": case "money": case "timestamp without time zone": case "timestamp with time zone": case "time without time zone": case "time with time zone": returnType = "String"; break; case "inet": case "cidr": case "macaddr": case "macaddr8": case "box": case "circle": case "interval": case "line": case "lseg": case "path": case "point": case "polygon": case "varbit": returnType = "Object"; break; case "numeric": case "decimal": returnType = "BigDecimal"; break; default: break; } return returnType; } /** * 功能:获取并创建实体所在的路径目录 * @return */ private static String pkgDirName() { String dirName = basePath + "/src/" + packageOutPath.replace(".", "/"); File dir = new File(dirName); if (!dir.exists()) {dir.mkdirs();System.out.println("mkdirs dir 【" + dirName + "】");} return dirName; } /** * 功能:生成EntityHelper */ private void EntityHelper() { String dirName = PgSQlGenerateEntityUtil.pkgDirName(); String javaPath = dirName + "/EntityHelper.java"; try { StringBuffer sb = new StringBuffer(); sb.append("package " + packageOutPath + ";\r\n"); sb.append("\r\n"); sb.append("public abstract class EntityHelper{\r\n\r\n"); sb.append("\tpublic abstract String getPrimaryKey();\r\n"); sb.append("\r\n"); sb.append("}\r\n"); FileWriter fw = new FileWriter(javaPath); PrintWriter pw = new PrintWriter(fw); pw.println(sb.toString()); pw.flush(); if (pw != null){pw.close();} System.out.println("create class 【EntityHelper】"); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * 功能: 生成实体类的主方法 */ private void generate(){ Connection conn=null; try { //数据库的连接 PreparedStatement pStemt = null; Class.forName(DRIVER); conn = DriverManager.getConnection(JDBC_URL, jdbc_user, jdbc_pwd); if(conn!=null) { System.out.println("connect database success..."+conn); }else { System.out.println("connect database failed^_^"); return; } //获取数据库的元数据 DatabaseMetaData db = conn.getMetaData(); //是否有指定生成表,有指定则直接用指定表,没有则全表生成 List tableNames = new ArrayList<>(); List tableComments = new ArrayList<>(); if (generateTables == null) { //从元数据中获取到所有的表名 ResultSet rs = db.getTables(null, null, null, new String[] { "TABLE" }); while (rs.next()) { tableNames.add(rs.getString(3));//表名 tableComments.add(rs.getString(5));//表注释 } } else { for (String tableName : generateTables) tableNames.add(tableName); } if(needEntityHelper) { EntityHelper(); } String tableSql; PrintWriter out = null; for (int j = 0; j < tableNames.size(); j++) { tableName = tableNames.get(j); tableComment = tableComments.get(j); tableSql = SQL(tableName); pStemt = conn.prepareStatement(tableSql,ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY); ResultSet rstb = pStemt.executeQuery(); rstb.last(); int rowCount = rstb.getRow(); rstb.beforeFirst(); colNames = new String[rowCount]; colTypes = new String[rowCount]; colSizes = new int[rowCount]; int idx = 0; while(rstb.next()) { colNames[idx] = rstb.getString("name"); colTypes[idx] = rstb.getString("type"); colSizes[idx] = rstb.getInt("fields_length"); colNamesComment.put(rstb.getString("name"), rstb.getString("comment")); idx++; } //获取主键 pStemt = conn.prepareStatement(PK_SQL(tableName)); ResultSet rspk = pStemt.executeQuery(); while(rspk.next()) { pk=rspk.getString("colname"); } //解析生成实体java文件的所有内容 String content = parse(); //输出生成文件 String dirName = PgSQlGenerateEntityUtil.pkgDirName(); String javaPath = dirName + "/" + under2camel(tableName, true) + ".java"; FileWriter fw = new FileWriter(javaPath); out = new PrintWriter(fw); out.println(content); out.flush(); System.out.println("create class 【" + tableName + "】"); } if (out != null) { out.close(); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); }finally { if(conn!=null) { try { conn.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } }

 

你可能感兴趣的:(项目开发)