如何通過java反射將數據庫表生成實體類?


首先有幾點聲明:

1、代碼是在別人的基礎進行改寫的;

2、大家有什么改進的意見可以告訴我,也可以自己改好共享給其他人;

3、剛剛畢業,水平有限,肯定有許多不足之處;

4、希望剛剛學習java的同學能有所啟發。

 

//這個是做轉換的類,里面的DB只是封裝了數據庫的連接,大家可以用自己的,隨意

package com.tt.util.gen.entity.tool;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
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.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Properties;

import com.tt.util.DB;

public class GenEntityMysql {

    private String packageOutPath;// 指定實體生成所在包的路徑
    private String authorName;// 作者名字
    private String tablename;// 表名
    private String databasename;// 數據庫名
    private List<String> tablenames;// 拿到對應數據庫中所有的實體類(實體類需要與其他表明做區分)
    private List<String> colnames; // 列名集合
    private List<String> colTypes; // 列名類型集合
    private boolean f_util = false; // 是否需要導入包java.util.*
    private boolean f_sql = false; // 是否需要導入包java.sql.*

    /*
     * 構造函數
     */
    public GenEntityMysql() {

        // 使用properties讀取配置文件
        Properties prop = new Properties();
        try {
            InputStream genentity = getClass().getResourceAsStream(
                    "/genentity.properties");
            prop.load(genentity);

            if (genentity != null) {
                genentity.close();
            }
        } catch (Exception e) {
            System.out.println("file " + "catalogPath.properties"
                    + " not found!\n" + e);
        }
        this.databasename = prop.getProperty("databasename").toString();
        this.tablename = prop.getProperty("tablename").toString();
        this.packageOutPath = prop.getProperty("packageOutPath").toString();
        this.authorName = prop.getProperty("authorName").toString();
    }

    // 創建多個實體類
    private void genEntity(List<String> tablenames, Connection conn) {
        // 使用第歸生成文件
        for (String tablename : tablenames) {
            this.genEntity(tablename, conn);
        }
    }

    // 創建單個實體類
    private void genEntity(String tablename, Connection conn) {
        String sql = "select * from " + tablename;
        PreparedStatement pstmt = null;
        ResultSetMetaData rsmd = null;
        try {
            pstmt = DB.getPStmt(conn, sql);
            rsmd = pstmt.getMetaData();
            int size = rsmd.getColumnCount(); // 統計列
            colnames = new ArrayList<String>();
            colTypes = new ArrayList<String>();

            for (int i = 0; i < size; i++) {
                colnames.add(rsmd.getColumnName(i + 1));
                colTypes.add(rsmd.getColumnTypeName(i + 1));

                if (colTypes.get(i).equalsIgnoreCase("datetime")) {
                    f_util = true;
                }
                if (colTypes.get(i).equalsIgnoreCase("image")
                        || colTypes.get(i).equalsIgnoreCase("text")) {
                    f_sql = true;
                }
            }
            System.out.println(colnames);
            System.out.println(colTypes);
        } catch (SQLException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        } finally {
            DB.close(pstmt);
        }
        // 在內存中生成代碼
        String content = parse(tablename);

        // 寫入到文件中
        try {
            File directory = new File("");
            String outputPath = directory.getAbsolutePath() + "/src/"
                    + this.packageOutPath.replace(".", "/") + "/";
            System.out.println("寫出的路徑:" + outputPath);
            // 檢測路徑是否存在,不存在就創建路徑
            File path = new File(outputPath);
            if (!path.exists() && !path.isDirectory()) {
                path.mkdir();
                System.out.println(path.exists());
            }
            // 創建文件
            outputPath += initcap(tablename) + ".java";
            File file = new File(outputPath);
            if (!file.exists()) {
                file.createNewFile();
            }
            // 寫出到硬盤
            FileWriter fw = new FileWriter(file);
            PrintWriter pw = new PrintWriter(fw);
            pw.println(content);
            pw.flush();
            pw.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void getAllEntityTable(Connection conn, List<String> tablenames) {
        ResultSet rs = null;
        try {
            DatabaseMetaData dmd = (DatabaseMetaData) conn.getMetaData();
            /*
             * TABLE_CAT String => 表類別(可為 null)
             * TABLE_SCHEM String => 表模式(可為null)
             * TABLE_NAME String => 表名稱
             * TABLE_TYPE String => 表類型
             */
            rs = dmd.getTables(null, null, "%", null);
            while (rs.next()) {
                tablenames.add(rs.getString("TABLE_NAME"));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     *
     * @param tablename
     * @return
     */
    private String parse(String tablename) {
        StringBuffer sb = new StringBuffer();

        // 判斷是否導入工具包
        if (f_util) {
            sb.append("import java.util.Date;\r\n");
        }
        if (f_sql) {
            sb.append("import java.sql.*;\r\n");
        }
        sb.append("package " + this.packageOutPath + ";\r\n");
        sb.append("\r\n");
        // 注釋部分
        sb.append("   /**\r\n");
        sb.append("    * " + tablename + " 實體類\r\n");
        sb.append("    * " + new Date() + " " + this.authorName + "\r\n");
        sb.append("    */ \r\n");
        // 實體部分
        sb.append("\r\n\r\npublic class " + initcap(tablename) + "{\r\n");
        processAllAttrs(sb);// 屬性
        processAllMethod(sb);// get set方法
        sb.append("}\r\n");

        return sb.toString();
    }

    /**
     * 功能:生成所有屬性
     *
     * @param sb
     */
    private void processAllAttrs(StringBuffer sb) {

        for (int i = 0; i < colnames.size(); i++) {
            sb.append("\tprivate " + sqlType2JavaType(colTypes.get(i)) + " "
                    + colnames.get(i) + ";\r\n");
        }

    }

    /**
     * 功能:生成所有方法
     *
     * @param sb
     */
    private void processAllMethod(StringBuffer sb) {

        for (int i = 0; i < colnames.size(); i++) {
            sb.append("\tpublic void set" + initcap(colnames.get(i)) + "("
                    + sqlType2JavaType(colTypes.get(i)) + " " + colnames.get(i)
                    + "){\r\n");
            sb.append("\t\tthis." + colnames.get(i) + "=" + colnames.get(i)
                    + ";\r\n");
            sb.append("\t}\r\n");
            sb.append("\tpublic " + sqlType2JavaType(colTypes.get(i)) + " get"
                    + initcap(colnames.get(i)) + "(){\r\n");
            sb.append("\t\treturn " + colnames.get(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 sqlType
     * @return
     */
    private String sqlType2JavaType(String sqlType) {

        if (sqlType.equalsIgnoreCase("bit")) {
            return "boolean";
        } else if (sqlType.equalsIgnoreCase("tinyint")) {
            return "byte";
        } else if (sqlType.equalsIgnoreCase("smallint")) {
            return "short";
        } else if (sqlType.equalsIgnoreCase("int")) {
            return "int";
        } else if (sqlType.equalsIgnoreCase("bigint")) {
            return "long";
        } else if (sqlType.equalsIgnoreCase("float")) {
            return "float";
        } else if (sqlType.equalsIgnoreCase("decimal")
                || sqlType.equalsIgnoreCase("numeric")
                || sqlType.equalsIgnoreCase("real")
                || sqlType.equalsIgnoreCase("money")
                || sqlType.equalsIgnoreCase("smallmoney")) {
            return "double";
        } else if (sqlType.equalsIgnoreCase("varchar")
                || sqlType.equalsIgnoreCase("char")
                || sqlType.equalsIgnoreCase("nvarchar")
                || sqlType.equalsIgnoreCase("nchar")
                || sqlType.equalsIgnoreCase("text")) {
            return "String";
        } else if (sqlType.equalsIgnoreCase("datetime")) {
            return "Date";
        } else if (sqlType.equalsIgnoreCase("image")) {
            return "Blod";
        }

        return null;
    }

    /**
     * 出口 TODO
     *
     * @param args
     */
    public static void main(String[] args) {

        new GenEntityMysql().start();

    }

    private void start() {
        // 創建連接
        Connection conn = DB.getConn();

        if (databasename != null && !databasename.equals("")
                && tablename != null && !tablename.equals("")) {
            System.out.println("databasename 和 tablename 不能同時存在");
        } else {
            // 如果配置文件中有數據庫名字,則可以拿到其中所有的實體類
            if (databasename != null && !databasename.equals("")) {
                // 獲取所有實體表名字
                tablenames = new ArrayList<String>();
                getAllEntityTable(conn, tablenames);
                System.out.println(tablenames);
                // 為每個實體表生成實體類
                genEntity(tablenames, conn);
            } else {
                // 為指定實體表生成實體類
                genEntity(tablename, conn);
            }

            // 關閉數據庫連接
            if (conn != null) {
                DB.close(conn);
            }
        }

    }

}

 

需要一個配置文件,位置隨意(你可能需要對代碼中路徑進行改動),我的放到根目錄下 genentity.properties

內容:

packageOutPath=com.tt.model
authorName=\u8D75\u5FD7\u4F1F
tablename=
databasename=test

 

注意:DB的那個我會再發一份(如果大家需要看的話),因為放到一起太多了,看着會吐,第一次發博客!謝謝大家!

有小伙伴需要的 DB 工具類補充, 這個東東就是個玩具大家要使用更先進工具

import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

/**
* 數據庫連接操作工具類
*/
public class DBUtil {
private static String jdbcUrl = "";
private static String driverClass = "";
private static String username = "";
private static String password = "";

/*
讀取數據庫配置文件信息
*/
static {
// 使用properties讀取配置文件
Properties prop = new Properties();
try {
InputStream genentity = DBUtil.class.getResourceAsStream(
"/jdbc.properties");
prop.load(genentity);

if (genentity != null) {
genentity.close();
}
} catch (Exception e) {
System.out.println("file " + "jdbc.properties"
+ " not found!\n" + e);
}
jdbcUrl = prop.getProperty("jdbcUrl");
driverClass = prop.getProperty("driverClass");
username = prop.getProperty("username");
password = prop.getProperty("password");
}

/**
* 加載數據庫驅動
*/
static {
try {
Class.forName(driverClass);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}

/**
* 拿到數據庫連接
* @return
*/
public static Connection getConn() {
Connection conn = null;
try {
// conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/?user=root&password=root");
conn = DriverManager.getConnection(jdbcUrl, username, password);
} catch (SQLException e) {
e.printStackTrace();
}
return conn;
}

/**
*
* @param conn
* @return
*/
public static Statement getStmt(Connection conn) {
Statement stmt = null;
try {
stmt = conn.createStatement();
} catch (SQLException e) {
e.printStackTrace();
}
return stmt;
}

/**
*
* @param conn
* @param sql
* @return
*/
public static PreparedStatement getPStmt(Connection conn, String sql) {
PreparedStatement pstmt = null;
try {
pstmt = conn.prepareStatement(sql);
} catch (SQLException e) {
e.printStackTrace();
}
return pstmt;
}

/**
*
* @param stmt
* @param sql
* @return
*/
public static ResultSet getRs(Statement stmt, String sql) {
try {
stmt.executeQuery(sql);
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}

/**
*
* @param stmt
* @param sql
*/
private static void executeUpdate(Statement stmt, String sql) {
try {
stmt.executeUpdate(sql);
} catch (SQLException e) {
e.printStackTrace();
}
}

/**
*
* @param conn
* @param sql
*/
public static void executeUpdate(Connection conn, String sql) {
Statement stmt = null;
try {
stmt = conn.createStatement();
} catch (SQLException e) {
e.printStackTrace();
}
executeUpdate(stmt, sql);
}

/**
*
* @param conn
* @param sql
* @return
*/
public static ResultSet executeQuery(Connection conn, String sql) {
ResultSet rs = null;
try {
rs = conn.prepareStatement(sql).executeQuery();
} catch (SQLException e) {
e.printStackTrace();
}
return rs;
}

/**
*
* @param conn
*/
public static void close(Connection conn) {
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}

/**
*
* @param stmt
*/
public static void close(Statement stmt) {
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}

/**
*
* @param rs
*/
private static void close(ResultSet rs) {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM