Panda ORM原始碼-資料庫表自動生成Java實體類
一,整體思路
1,首先明確目標,需要透過指定資料庫名,自動生成該資料庫中所有表對應的Java實體類。
2,資料庫名及其他一些引數(跟資料庫url、使用者、密碼、實體類儲存路徑)透過配置檔案設定。
3,連線資料庫後,透過資料庫名獲取該資料庫中所有的表。對於MySQL來說,可以透過select table_name from information_schema.tables where table_schema='XXX'
,來獲取XXX資料庫中所有的表名。PS:對於information_schema資料庫不瞭解的可以開啟看下,information_schema.tables儲存了執行在MySQL上表的資訊。
4,透過Java程式碼讀取表結構資訊,生成對應的Java類字串,將字串寫入檔案。
二,引數設定
引數儲存在src目錄下config.properties檔案下,透過Constants的static方法獲取配置檔案資訊,具體程式碼如下:
config.properties程式碼如下,注意前五個引數為資料庫連線需要的引數,table_schema表示資料庫名,entity_package_name表示生成實體類的包名,兩個path分別表示實體類檔案及日誌儲存路徑。
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/bank_performance?useUnicode=true&characterEncoding=utf-8
user=root
password=Pass1234
table_schema=bank_performance
entity_package_name=panda.bank.entity
file_save_path=D:\Java\AutoEntity\
file_log_path=D:\Java\AutoEntity\
讀取配置檔案是透過Constants 中的static方法實現:
package panda.orm.util;
public class Constants {
//Property類程式碼在下面
public static Property CONFIG_PROPERTY;
public static String getFormatDateTime(){
SimpleDateFormat formater = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return formater.format(new Date());
}
public static String getLogFormatDateTime(){
SimpleDateFormat formater = new SimpleDateFormat("yyyyMMddhhmmss");
return formater.format(new Date());
}
static{
Properties fileProperties = new Properties();
InputStream inputStream = fileProperties.getClass().getResourceAsStream("/config.properties");
CONFIG_PROPERTY=new Property();
try{
fileProperties.load(inputStream);
CONFIG_PROPERTY.setDriver(fileProperties.getProperty("driver"));
CONFIG_PROPERTY.setUrl(fileProperties.getProperty("url"));
CONFIG_PROPERTY.setUser(fileProperties.getProperty("user"));
CONFIG_PROPERTY.setPassword(fileProperties.getProperty("password"));
CONFIG_PROPERTY.setTable_schema(fileProperties.getProperty("table_schema"));
CONFIG_PROPERTY.setFile_save_path(fileProperties.getProperty("file_save_path"));
CONFIG_PROPERTY.setFile_log_path(fileProperties.getProperty("file_log_path"));
CONFIG_PROPERTY.setEntity_package_name(fileProperties.getProperty("entity_package_name"));
}catch (IOException ex){
ex.printStackTrace();
}finally{
try {
inputStream.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
package panda.orm.util;
public class Property{
private String driver;
private String url;
private String user;
private String password;
private String table_schema;
private String file_save_path;
private String file_log_path;
private String entity_package_name;
//省略get set
三,EntityGenerater.generateClasses()方法直接生成資料庫中所有表對應實體類,直接上程式碼看註釋部分即可:
package panda.orm.util;
import java.io.File;
import java.io.FileOutputStream;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import panda.orm.database.MySQLHandler;
import panda.orm.exception.SqlExcuteException;
/**
* 由MySQL資料庫自動生成Java實體類
* @author 貓哥
* @date 2017.3.23
*/
public class EntityGenerater {
//在配置完config.properties之後,直接呼叫EntityGenerater類的靜態方法generateClasses即可生成對應Java實體類
public static void main(String[] args) {
EntityGenerater.generateClasses();
}
//generateClasses方法做了三件事
//1,構造方法獲取需要的引數
//2,init方法生成資料庫對應的表-類結構
//3,write方法負責將類結構轉換為實體類程式碼字串並寫入檔案
public static void generateClasses(){
EntityGenerater eg=new EntityGenerater(Constants.CONFIG_PROPERTY.getTable_schema(),
Constants.CONFIG_PROPERTY.getEntity_package_name(),Constants.CONFIG_PROPERTY.getFile_save_path());
eg.init();
eg.write();
System.out.println("Panda ORM generate success!");
}
//tables儲存了資料庫的結構,tables的key表示表名,key對應的結合表示該表的所有列名集合
private Map> tables=new HashMap>();
private String table_schema;
private String entity_package_name;
private String entity_save_path;
public EntityGenerater(String table_schema,String entity_package_name,String entity_save_path){
this.table_schema=table_schema;
this.entity_package_name=entity_package_name;
this.entity_save_path=entity_save_path;
}
public void init(){
MySQLHandler hand=new MySQLHandler();
ResultSet rs=null;
//資料庫名
String table_schema =Constants.CONFIG_PROPERTY.getTable_schema();
//獲取資料庫下所有表的sql語句
String sql="select table_name from information_schema.tables where table_schema='"+table_schema+"'";
tables.clear();
try {
rs=hand.query(sql);
while(rs.next()){
String tableName=rs.getString("table_name");
//getColumns方法獲取表對應的列
Set columns=getColumns(tableName);
//將表和對應列結合放入tables
tables.put(tableName, columns);
}
} catch (Exception ex) {
new SqlExcuteException(ex.getMessage(),this.getClass().getName(),"sql執行異常",sql);
}finally{
hand.sayGoodbye();
}
}
//獲取表對應的列名集合
private Set getColumns(String tableName){
MySQLHandler hand=new MySQLHandler();
ResultSet rs=null;
String sql="select * from "+tableName;
Set columns=new HashSet();
try {
rs=hand.query(sql);
ResultSetMetaData meta=rs.getMetaData();
int count=meta.getColumnCount();
for(int i=0;i columns = (Set)entry.getValue();
//核心方法,將表明和對應列資訊轉換為實體類程式碼
String entityString=getEntityString(tableName,columns);
//寫檔案
try{
String path=entity_save_path+turnFirstUp(tableName)+".java";
File file=new File(path);
if(!file.exists())
file.createNewFile();
FileOutputStream out=new FileOutputStream(file,true);
out.write(entityString.getBytes("utf-8"));
out.close();
}
catch(Exception ex){
ex.printStackTrace();
}
}
}
//核心方法,將表明和對應列資訊轉換為實體類程式碼
private String getEntityString(String tableName,Set columns){
StringBuilder sb=new StringBuilder();
//包名及類註釋
sb.append("package "+entity_package_name+";rn");
sb.append("/**rn");
sb.append("* " + new Date() + "rn");
sb.append("* Panda ORM atuo generate: " + tableName + " rn");
sb.append("*/ rn");
//類定義
sb.append("public class " + turnFirstUp(tableName) + "{rn");
//屬性
for(String colName:columns){
sb.append("tprivate String "+colName+";rn");
}
//方法
for(String colName:columns){
sb.append("tpublic String get"+turnFirstUp(colName)
+"(){rn");
sb.append("ttreturn "+colName+";rn");
sb.append("t}rn");
sb.append("tpublic void set"+turnFirstUp(colName)
+ "(String "+colName+"){rn");
sb.append("ttthis."+colName+"="+colName+";rn");
sb.append("t}rn");
}
sb.append("}");
return sb.toString();
}
//首字母大寫
private String turnFirstUp(String str) {
char[] ch = str.toCharArray();
if(ch[0]>='a'&&ch[0]
四,測試,以馬上要開始講解的銀行業績系統資料庫為例,表結構如下圖(具體含義先不解釋,只是演示由資料庫生成實體程式碼):
然後執行,注意配置檔案就按開頭說的配置的。
public static void main(String[] args) {
EntityGenerater.generateClasses();
}
執行後,控制檯提示:Panda ORM generate success!
,表示成功,根據配置檔案在目錄下發現:
開啟User.java,成功。
package panda.bank.entity;
/**
* Thu Mar 23 11:30:12 CST 2017
* Panda ORM atuo generate: user
*/
public class User{
private String user_name;
private String user_role;
private String user_job;
private String user_password;
private String user_id;
private String user_department;
public String getUser_name(){
return user_name;
}
public void setUser_name(String user_name){
this.user_name=user_name;
}
public String getUser_role(){
return user_role;
}
public void setUser_role(String user_role){
this.user_role=user_role;
}
public String getUser_job(){
return user_job;
}
public void setUser_job(String user_job){
this.user_job=user_job;
}
public String getUser_password(){
return user_password;
}
public void setUser_password(String user_password){
this.user_password=user_password;
}
public String getUser_id(){
return user_id;
}
public void setUser_id(String user_id){
this.user_id=user_id;
}
public String getUser_department(){
return user_department;
}
public void setUser_department(String user_department){
this.user_department=user_department;
}
}
五,補充說明
根據Panda ORM整體的設計,所有類屬性都是String型別,其實可以根據表中的資料型別轉換屬性型別,此處不再加以演示。
有了實體類程式碼後,需要新增主鍵、外來鍵註釋,並需要將外來鍵對應屬性型別改為外來鍵指向表實體型別,然後就可以直接利用Panda ORM生成常用的增、刪、改、查方法。
增、刪、改沒有問題,查的話只提供了最基本的查數量、分頁查、查全部、按主鍵查的功能。更加複雜的查詢還是要寫原生的sql程式碼,有點遺憾。但是想想MyBatis每個都要單獨寫sql和Hibernate複雜的配置,心裡又好受了很多,哈哈。下篇演示透過註解實現ORM的思路和原始碼。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/2730/viewspace-2798541/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 利用FreeSql.Generator自動根據資料庫表動態生成實體類SQL資料庫
- MyBatis 根據資料表反向生成 java 實體類等MyBatisJava
- IDEA自動生成實體類Idea
- Django中的ORM如何通過資料庫中的表格資訊自動化生成Model 模型類?DjangoORM資料庫模型
- C#連線Oracle資料庫,通過EF自動生成與資料庫表相關的實體類C#Oracle資料庫
- 寫一個工具生成資料庫實體類資料庫
- SpringBoot使用JPA根據實體類自動生成相應表-mysqlSpring BootMySql
- java使用jaxb解析XML(含根據xml自動生成實體類)JavaXML
- mysql資料庫語句自動生成MySql資料庫
- abp框架寫實體類並生成對應的資料庫框架資料庫
- J2SE - Lombok自動生成實體方法的工具類庫的使用Lombok
- 一個根據資料庫自動生成model類的擴充套件資料庫套件
- generatorConfig自動生成實體類以及自定義生成註釋的方法
- PHP根據資料表自動生成CURD操作PHP
- [xmlbeans]自動生成讀寫xml的java類XMLBeanJava
- 帶你實現一個簡單的MYSQL資料庫生成實體類工具MySql資料庫
- java自動生成實體類(帶註釋)和controller層,service層 dao層 xml層JavaControllerXML
- ORM實操之資料庫遷移ORM資料庫
- 無需手寫,自動生成Flutter/Dart實體類檔案FlutterDart
- 直播app原始碼,資料庫多資料來源自動選擇實現APP原始碼資料庫
- lavavel 自動生成資料字典
- idea自動建立實體類Idea
- .NETCore使用EntityFrameworkCore連線資料庫生成實體NetCoreFramework資料庫
- 程式碼生成器,自適應mysql、oracle資料庫MySqlOracle資料庫
- 使用Wesky.Net.Opentools庫,一行程式碼實現自動解析實體類summary註釋資訊(可用於資料實體文件的快速實現)行程
- Laravel 資料表按月份水平分表,表不存在,自動建立生成Laravel
- 如何實現資料庫資料到Abp vnext實體物件的同步?以及程式碼生成工具資料庫物件
- 基於Dapper的開源Lambda擴充套件,且支援分庫分表自動生成實體APP套件
- [shell]shell指令碼實現每天自動抽取資料插入hive表指令碼Hive
- 當資料庫表無主鍵ID時,ORM這樣更新資料資料庫ORM
- mybatise外掛反向生成資料庫表相關Java程式碼MyBatis資料庫Java
- 從Python原始碼註釋,自動生成API文件Python原始碼API
- 基於AbstractProcessor擴充套件MapStruct自動生成實體對映工具類套件Struct
- mybatis根據表逆向自動化生成程式碼MyBatis
- 資料庫中介軟體 MyCAT原始碼分析:【單庫單表】查詢【推薦閱讀】資料庫原始碼
- Panda資料處理
- 測試資料之自動生成
- 小技巧 EntityFrameworkCore 實現 CodeFirst 透過模型生成資料庫表時自動攜帶模型及欄位註釋資訊Framework模型資料庫