mysql自动生成实体类_Panda ORM源码-数据库表自动生成Java实体类

2023-11-01 06:50

本文主要是介绍mysql自动生成实体类_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.add(meta.getColumnName(i+1));

}

}catch (Exception ex) {

new SqlExcuteException(ex.getMessage(),this.getClass().getName(),"sql执行异常",sql);

}finally{

hand.sayGoodbye();

}

return columns;

}

//转换tables信息为实体类代码对应的字符串,并写入文件

public void write(){

Iterator iter = tables.entrySet().iterator();

while (iter.hasNext()) {

Map.Entry entry = (Map.Entry) iter.next();

String tableName = (String)entry.getKey();

Set 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+";\r\n");

sb.append("/**\r\n");

sb.append("* " + new Date() + "\r\n");

sb.append("* Panda ORM atuo generate: " + tableName + " \r\n");

sb.append("*/ \r\n");

//类定义

sb.append("public class " + turnFirstUp(tableName) + "{\r\n");

//属性

for(String colName:columns){

sb.append("\tprivate String "+colName+";\r\n");

}

//方法

for(String colName:columns){

sb.append("\tpublic String get"+turnFirstUp(colName)

+"(){\r\n");

sb.append("\t\treturn "+colName+";\r\n");

sb.append("\t}\r\n");

sb.append("\tpublic void set"+turnFirstUp(colName)

+ "(String "+colName+"){\r\n");

sb.append("\t\tthis."+colName+"="+colName+";\r\n");

sb.append("\t}\r\n");

}

sb.append("}");

return sb.toString();

}

//首字母大写

private String turnFirstUp(String str) {

char[] ch = str.toCharArray();

if(ch[0]>='a'&&ch[0]<='z'){

ch[0]=(char)(ch[0]-32);

}

return new String(ch);

}

}

四,测试,以马上要开始讲解的银行业绩系统数据库为例,表结构如下图(具体含义先不解释,只是演示由数据库生成实体代码):

AAffA0nNPuCLAAAAAElFTkSuQmCC

然后运行,注意配置文件就按开头说的配置的。

public static void main(String[] args) {

EntityGenerater.generateClasses();

}

运行后,控制台提示:Panda ORM generate success!,表示成功,根据配置文件在目录下发现:

AAffA0nNPuCLAAAAAElFTkSuQmCC

打开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的思路和源码。

这篇关于mysql自动生成实体类_Panda ORM源码-数据库表自动生成Java实体类的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/321236

相关文章

Java中流式并行操作parallelStream的原理和使用方法

《Java中流式并行操作parallelStream的原理和使用方法》本文详细介绍了Java中的并行流(parallelStream)的原理、正确使用方法以及在实际业务中的应用案例,并指出在使用并行流... 目录Java中流式并行操作parallelStream0. 问题的产生1. 什么是parallelS

MySQL数据库双机热备的配置方法详解

《MySQL数据库双机热备的配置方法详解》在企业级应用中,数据库的高可用性和数据的安全性是至关重要的,MySQL作为最流行的开源关系型数据库管理系统之一,提供了多种方式来实现高可用性,其中双机热备(M... 目录1. 环境准备1.1 安装mysql1.2 配置MySQL1.2.1 主服务器配置1.2.2 从

Java中Redisson 的原理深度解析

《Java中Redisson的原理深度解析》Redisson是一个高性能的Redis客户端,它通过将Redis数据结构映射为Java对象和分布式对象,实现了在Java应用中方便地使用Redis,本文... 目录前言一、核心设计理念二、核心架构与通信层1. 基于 Netty 的异步非阻塞通信2. 编解码器三、

SpringBoot基于注解实现数据库字段回填的完整方案

《SpringBoot基于注解实现数据库字段回填的完整方案》这篇文章主要为大家详细介绍了SpringBoot如何基于注解实现数据库字段回填的相关方法,文中的示例代码讲解详细,感兴趣的小伙伴可以了解... 目录数据库表pom.XMLRelationFieldRelationFieldMapping基础的一些代

一篇文章彻底搞懂macOS如何决定java环境

《一篇文章彻底搞懂macOS如何决定java环境》MacOS作为一个功能强大的操作系统,为开发者提供了丰富的开发工具和框架,下面:本文主要介绍macOS如何决定java环境的相关资料,文中通过代码... 目录方法一:使用 which命令方法二:使用 Java_home工具(Apple 官方推荐)那问题来了,

Java HashMap的底层实现原理深度解析

《JavaHashMap的底层实现原理深度解析》HashMap基于数组+链表+红黑树结构,通过哈希算法和扩容机制优化性能,负载因子与树化阈值平衡效率,是Java开发必备的高效数据结构,本文给大家介绍... 目录一、概述:HashMap的宏观结构二、核心数据结构解析1. 数组(桶数组)2. 链表节点(Node

Java AOP面向切面编程的概念和实现方式

《JavaAOP面向切面编程的概念和实现方式》AOP是面向切面编程,通过动态代理将横切关注点(如日志、事务)与核心业务逻辑分离,提升代码复用性和可维护性,本文给大家介绍JavaAOP面向切面编程的概... 目录一、AOP 是什么?二、AOP 的核心概念与实现方式核心概念实现方式三、Spring AOP 的关

详解SpringBoot+Ehcache使用示例

《详解SpringBoot+Ehcache使用示例》本文介绍了SpringBoot中配置Ehcache、自定义get/set方式,并实际使用缓存的过程,文中通过示例代码介绍的非常详细,对大家的学习或者... 目录摘要概念内存与磁盘持久化存储:配置灵活性:编码示例引入依赖:配置ehcache.XML文件:配置

Java 虚拟线程的创建与使用深度解析

《Java虚拟线程的创建与使用深度解析》虚拟线程是Java19中以预览特性形式引入,Java21起正式发布的轻量级线程,本文给大家介绍Java虚拟线程的创建与使用,感兴趣的朋友一起看看吧... 目录一、虚拟线程简介1.1 什么是虚拟线程?1.2 为什么需要虚拟线程?二、虚拟线程与平台线程对比代码对比示例:三

Java中的.close()举例详解

《Java中的.close()举例详解》.close()方法只适用于通过window.open()打开的弹出窗口,对于浏览器的主窗口,如果没有得到用户允许是不能关闭的,:本文主要介绍Java中的.... 目录当你遇到以下三种情况时,一定要记得使用 .close():用法作用举例如何判断代码中的 input