如何通过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的那个我会再发一份(如果大家需要看的话),因为放到一起太多了,看着会吐,第一次发博客!谢谢大家!
如何通过java反射将数据库表生成实体类?的更多相关文章
- symfony 数据库表生成实体、迁移数据库
从数据库表生成实体 1. 由数据库生成模型: php bin/console doctrine:mapping:convert --from-database yml D:\db\ D:\test_b ...
- django根据已有数据库表生成model类
django根据已有数据库表生成model类 创建一个Django项目 django-admin startproject 'xxxx' 修改setting文件,在setting里面设置你要连接的数据 ...
- MyEclipse从数据库反向生成实体类之Hibernate方式 反向工程
前文: hibernate带给我们的O/RMapping思想是很正确的,即从面相对象的角度来设计工程中的实体对象,建立pojo,然后在编写hbm.xml映射文件来生成数据表.但是在实际开发中,往往我们 ...
- MyEclipse数据库反向生成实体类
MyEclipse数据库反向生成实体类 “计应134(实验班) 凌豪” 当我们在开发项目涉及到的表太多时,一个一个的写JAVA实体类很是费事.然而强大的MyEclipse为我们提供简便的方法:数据库反 ...
- J2EE进阶(十五)MyEclipse反向工程实现从数据库反向生成实体类之Hibernate方式
J2EE进阶(十五)MyEclipse反向工程实现从数据库反向生成实体类之Hibernate方式 反向工程又称逆向工程. 开发项目涉及到的表太多,一个一个的写JAVA实体类很是费事.MyEcl ...
- 使用T4为数据库自动生成实体类
T4 (Text Template Transformation Toolkit) 是一个基于模板的代码生成器.使用T4你可以通过写一些ASP.NET-like模板,来生成C#, T-SQL, XML ...
- 自定义tt文本模板实现MySql指数据库中生成实体类
自定义tt文本模板实现MySql指数据库中生成实体类 1.在项目中依次点击“添加”/“新建项”,选择“文本模板”,输入名称后点击添加. 2.在Base.tt中添加如下代码. <#@ templa ...
- IDEA快速生成数据库表的实体类
IDEA连接数据库 IDEA右边侧栏有个DataSource,可以通过这个来连接数据库,我们先成功连接数据库 点击进入后填写数据库进行连接,注意记得一定要去Test Connection 确保正常连接 ...
- 使用hibernate利用实体类生成表和利用表生成实体类
1,配置数据库,这里以oracle数据库为例.点击右侧Database图标:
随机推荐
- Python 标识符
Python 标识符 在python里,标识符有字母.数字.下划线组成. 在python中,所有标识符可以包括英文.数字以及下划线(_),但不能以数字开头. python中的标识符是区分大小写的. 以 ...
- DX9三角形顶点绕序的判断
今天亲自实践了下,终于搞清楚了. 多边形都有2个侧面,观察坐标系中正面朝向摄像机的为多边形为正面朝向多边形,正面偏离摄像机的为多边形为背面朝向多边形,d3d会把背面朝向多边形剔除,即背面消隐. 使用 ...
- Linux 网络编程基础(1)--网络相关的数据结构及转化函数
在Linux下进行网络编程,使用的语言一般为C.就个人感受而言,在Linux下进行网络程序的编写,重要的不是代码能力要多强,而是对Linux的网络编程思想的理解和对Linux网络数据结构的掌握.如果想 ...
- 转:批处理for命令详解
批处理for命令详解FOR这条命令基本上都被用来处理文本,但还有其他一些好用的功能!看看他的基本格式(这里我引用的是批处理中的格式,直接在命令行只需要一个%号)FOR 参数 %%变量名 IN (相关文 ...
- xsoup,Jsoup
Xsoup 0.2.0 Xsoup 的详细介绍:请点这里 Xsoup 的下载地址:请点这里 https://github.com/code4craft/xsoup http://www.oschina ...
- android 关于多任务下载问题
关于多任务下载问题 近期项目中,遇到一个问题,列表数据中的图片地址是一个需要下载JS再解析的字段,之前的图片下载是一个异步的过程,由一个队列处理. Android系统以不同寻常的方式处理多个应用 ...
- HDU 5274 Dylans loves tree(树链剖分)
[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5274 [题目大意] 给出一棵树,每个点有一个权值,权值可修改,且大于等于0,询问链上出现次数为奇数 ...
- POJ 1222 EXTENDED LIGHTS OUT(高斯消元)
[题目链接] http://poj.org/problem?id=1222 [题目大意] 给出一个6*5的矩阵,由0和1构成,要求将其全部变成0,每个格子和周围的四个格子联动,就是说,如果一个格子变了 ...
- js 计算两个时间差
/* * 计算两个日期的间隔天数* BeginDate:起始日期的文本框,格式為:2012-01-01* EndDate:結束日期的文本框,格式為:2012-01-02* 返回兩個日期所差的天數* 調 ...
- zoj 1409 Communication System
/*如果要一个物体的多种属性,最好用结构体,不要用二维数组或者多维数组.用多维数组进行关键字排序很不稳定 */ /*给每个设备的所有价格排序,每个设备选取恰好比已知带宽大的价格(这个时候的比例最大) ...