`

数据库反向生成实体类 (转)

 
阅读更多
数据库反向生成实体类是dbdesigner的一个功能,现在很多开发工具也带有这样的功能。实现原理也很简单:先通过SQL语句获取所有数据库表,再通过SQL语句获取表的结构,最后根据表的字段信息生成相应的hibernate实体类。
本文的初步实现代码只考虑mysql 5.1版本,其它版本数据库暂不考虑。

获取所有表的SQl:
show tables

获取表字段信息的SQL有两种:
(1) SELECT COLUMN_NAME, DATA_TYPE, COLUMN_COMMENT FROM information_schema.columns WHERE table_name = 表名
(2) describe 表名

主要的实现代码如下
DBDao主要提供获取数据库表和表字段信息的方法

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.commons.dbutils.DbUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.ResultSetHandler;
import org.apache.commons.dbutils.handlers.ArrayListHandler;
import org.apache.commons.dbutils.handlers.MapListHandler;
import org.dbdesigner.ui.component.ConnectDbDialog;
import org.dbdesigner.ui.util.NodeProperty;

public class DBDao {
    private NodeProperty conConfig;

    public DBDao(NodeProperty con) {
        this.conConfig = con;
    }

    private Connection getConnect() throws InstantiationException,
            IllegalAccessException, ClassNotFoundException, SQLException {
        String strDriver = conConfig.getProperty(ConnectDbDialog.PRO_DRIVER);
        String strUrl = "jdbc:mysql://"
                + conConfig.getProperty(ConnectDbDialog.PRO_SERVER) + ":"
                + conConfig.getProperty(ConnectDbDialog.PRO_PORT) + "/"
                + conConfig.getProperty(ConnectDbDialog.PRO_DATABASE);
        String strUser = conConfig.getProperty(ConnectDbDialog.PRO_USER);
        String strPass = conConfig.getProperty(ConnectDbDialog.PRO_PSW);
        Class.forName(strDriver).newInstance();
        return DriverManager.getConnection(strUrl, strUser, strPass);
    }

    
        /** *//**
     * 获取所有数据表
     */
    public ArrayList getAllTable() {
        ArrayList result = null;
        Connection con = null;
        try {
            con = getConnect();
            QueryRunner qr = new QueryRunner();
            ResultSetHandler rsh = new ArrayListHandler();
            String strsql = "show tables";   //show tables为mysql获取所有表的方法
            result = qr.query(con, strsql, rsh);
//            for (int i = 0; i < result.size(); i++) {
//                System.out.println(((Object[]) result.get(i))[0]);
//            }
        } catch (Exception ex) {
            ex.printStackTrace(System.out);
        } finally {
            try {
                DbUtils.close(con);
            } catch (Exception ex) {
            }
        }
        return result;
    }

        /** *//**
     * 获取指定表的字段信息
     * @param t 表名
     */
    public NodeProperty getTableDescribe(String t) {
        Connection con = null;
        NodeProperty table = NodeProperty.getInstance(NodeProperty.NODE_TABLE);
        table.addProperty(NodeProperty.PROPERTY_NAME, t);
        try {
            con = getConnect();
            QueryRunner qr = new QueryRunner();
            String strsql = "describe " + t;
            List results = qr.query(con, strsql, new MapListHandler());
            NodeProperty columns = NodeProperty
                    .getInstance(NodeProperty.NODE_COLUMNS);
            table.addChild(columns);
            for (int i = 0; i < results.size(); i++) {
                NodeProperty column = NodeProperty
                        .getInstance(NodeProperty.NODE_COLUMN);
                Map map = (Map) results.get(i);
                String name = map.get("COLUMN_NAME").toString();
                String key = map.get("COLUMN_KEY").toString();
                String isKey = key.equals("PRI") ? "true" : "false";
                String nullable = map.get("IS_NULLABLE").toString();
                boolean isNullable = nullable.equals("YES") ? true : false;
                String type = map.get("COLUMN_TYPE").toString();
                String unsigned = "false";
                int index = type.indexOf("unsigned");
                if(index > 0){
                    unsigned = "true";
                    type = type.substring(0, index - 1);
                }
                column.addProperty(NodeProperty.PROPERTY_NAME, name);
                column.addProperty(NodeProperty.PROPERTY_COMMENT, name);
                column.addProperty(NodeProperty.PROPERTY_PRIMARYKEY, isKey);
                column.addProperty(NodeProperty.PROPERTY_UNSIGNED, unsigned);
                column.addProperty(NodeProperty.PROPERTY_DATATYPE, type);
                columns.addChild(column);
            }
        } catch (Exception ex) {
            ex.printStackTrace(System.out);
        } finally {
            try {
                DbUtils.close(con);
            } catch (Exception ex) {
            }
        }
        return table;
    }
}

GenerateEntity主要是根据NodeProperty的内容,生成实体类。

import java.util.List;
import org.dbdesigner.db.MySqlDataType;
import org.dbdesigner.ui.component.DBGraphComponent;
import org.dbdesigner.ui.util.NodeProperty;
import org.dbdesigner.utils.FileUtil;
import org.dbdesigner.utils.StringUtil;

public class GenerateEntity {
    private String filePath = null;
    private String packageName = null;
    public GenerateEntity(String filePath, String packageName, DBGraphComponent graphComponent){
        this.filePath = filePath;
        this.packageName = packageName;
    }
    
    //根据DBDao.getTableDescribe(String t)方法返回的NodeProperty内容,生成相应的实体类
    public void NodeToEntity(NodeProperty node){
        StringBuilder sr = new StringBuilder();
        StringBuilder declareSr = new StringBuilder();
        StringBuilder methodSr = new StringBuilder();
        String tableName = node.getProperty(NodeProperty.PROPERTY_NAME);
        String uTableName = StringUtil.upperFirst(tableName);
        if(StringUtil.isEmpty(packageName) == false){
            sr.append("package ").append(packageName).append("\n");
        }
        //添加引用包
        sr.append("import java.io.Serializable;\n");
        sr.append("import javax.persistence.*;\n");
        NodeProperty columns = node.getChildByType(NodeProperty.NODE_COLUMNS);
        if(columns != null){
            List<NodeProperty> list = columns.getChild();
            if(list.size() > 0){
                for(NodeProperty column:list){
                    String dataType =column.getProperty(NodeProperty.PROPERTY_DATATYPE);
                    if(dataType != null){
                         String type = dataType.toLowerCase();
                         if(type.equals("date") || type.equals("datetime")){
                             sr.append("import java.util.Date;\n");
                         }
                    }
                    //声明
                    generateDeclare(declareSr, column, dataType);
                    //方法
                    generateMethod(methodSr, column, dataType);
                }
            }
        }
        
        /**//*输出类名*/
        sr.append("\n");
        sr.append("@Entity\n");
        sr.append("@Table(name =\"").append(tableName)
        .append("\")\n");
        sr.append("public class ").append(uTableName).append(
                " implements Serializable {\n");
        sr.append("\tprivate static final long serialVersionUID = 1L;\n");
        sr.append("\n");
        
        /**//*输出声明*/
        sr.append(declareSr.toString());
        /**//*输出方法*/
        sr.append(methodSr.toString());
        
        sr.append("}\n");
        sr.append("\n");
        try{
            FileUtil.save(filePath + FileUtil.sp + uTableName + ".java", sr.toString().getBytes());
        }
        catch(Exception e){
            System.out.println("生成实体类出错!");
            e.printStackTrace();
        }
    }
    
    //生成字段声明内容
    public void generateDeclare(StringBuilder deSr, NodeProperty column, String dataType){
        int start = dataType.indexOf("(");
        int end = dataType.indexOf(")");
        String type = dataType;
        String lenght = "";
        if(start > 0 && end > 0){
            type = dataType.substring(0, start);
            lenght = dataType.substring(start + 1, dataType.length() - 1);
        }
        String primaryKey = column.getProperty(NodeProperty.PROPERTY_PRIMARYKEY);
        if(primaryKey != null && primaryKey.equals("true")){
            deSr.append("\t@Id\n");
        }
        deSr.append("\t@Column(name =\"").append(column.getProperty(NodeProperty.PROPERTY_NAME)).append("\"");
        if (type.equals("varchar") || type.equals("char")) {
            deSr.append(", length=").append(lenght);
        } 

        deSr.append(")\n");
        if (type.equals("date") || type.equals("datetime")) {
            deSr.append("\t@Temporal(TemporalType.TIMESTAMP)\n");
        }
        
        deSr.append("\tprivate ").append(MySqlDataType.get(type)).append(" ").append(column.getProperty(NodeProperty.PROPERTY_NAME)).append(";\n");
        deSr.append("\n");
    }
    
    //生成字段的setter、getter方法
    public void generateMethod(StringBuilder deSr, NodeProperty column, String dataType){
        String name = column.getProperty(NodeProperty.PROPERTY_NAME);
        String upperName = StringUtil.upperFirst(name);
        int start = dataType.indexOf("(");
        if(start > 0){
            dataType = dataType.substring(0, start);
        }
        String type = MySqlDataType.get(dataType) != null ? MySqlDataType.get(dataType) : dataType;
        deSr.append("\tpublic ").append(type).append(" ").append(
                "boolean".equals(dataType) ? "is" : "get").append(upperName)
                .append("() {\n");
        deSr.append("\t\treturn ").append(name).append(";\n");
        deSr.append("\t}\n");
        deSr.append("\n");
        deSr.append("\tpublic void set").append(upperName).append("(").append(type)
                .append(" ").append(name).append(") {\n");
        deSr.append("\t\tthis.").append(name).append(" = ").append(name)
                .append(";\n");
        deSr.append("\t}\n");
        deSr.append("\n");
    }
}

NodeProperty记录xml节点的内容

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Hashtable;

/** *//**
 * 记录xml内容的java类
 */
public class NodeProperty implements Serializable {

    public static final String NODE_TABLE = "Table";
    public static final String NODE_COLUMNS = "Columns";
    public static final String NODE_COLUMN = "Column";
    
    public static final String PROPERTY_NAME = "Name";
    public static final String PROPERTY_ID = "Id";
    public static final String PROPERTY_DESCRIPT = "Descript";
    public static final String PROPERTY_G = "G";
    public static final String PROPERTY_P = "P";
    public static final String PROPERTY_COMMENT = "Comment";
    public static final String PROPERTY_DATATYPE = "DataType";
    public static final String PROPERTY_MANDATORY = "Mandatory";
    public static final String PROPERTY_UNSIGNED = "Unsigned";
    public static final String PROPERTY_PRIMARYKEY = "isPrimaryKey";
    public static final String PROPERTY_LENGTH = "Length";
    
    private String type = null;
    private List<NodeProperty> child = null;
    private Map<String, String> property = null;
    private String value = null;

    private NodeProperty() {
        this.child = new ArrayList<NodeProperty>();
        this.property = new Hashtable<String, String>();
    }

    public void addChild(NodeProperty fp) {
        child.add(fp);
    }

    public List<NodeProperty> getChild() {
        return child;
    }

    public void addProperty(String key, String value) {
        property.put(key, value);
    }

    public String getProperty(String key) {
        return property.get(key);
    }

    public static NodeProperty getInstance(String type) {
        NodeProperty xml = new NodeProperty();
        xml.setType(type);
        return xml;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String toXML() {
        StringBuilder sb = new StringBuilder();
        sb.append("<").append(type);
        Iterator<Entry<String, String>> it = property.entrySet().iterator();
        while (it.hasNext()) {
            sb.append(" ");
            Entry<String, String> e = it.next();
            sb.append(e.getKey()).append("=\"").append(e.getValue())
                    .append("\"");
        }
        if (child.size() > 0) {
            sb.append(">\n");
            for (NodeProperty node : child) {
                sb.append(node.toXML());
            }
            sb.append("\n</").append(type).append(">");
        } else {
            sb.append(" />");
        }
        return sb.toString();
    }

    /** *//**
     * 获取当前节点中指定类型的子节点
     * @param type
     * @return
     */
    public NodeProperty getChildByType(String type) {
        NodeProperty result = null;
        if (this.child.size() > 0) {
            for (NodeProperty np : child) {
                if (np.getType().equals(type)) {
                    result = np;
                }
            }
        }
        return result;
    }

    public void removeChild() {
        if (child.size() > 0) {
            int size = child.size();
            for (int i = 0; i < size; i++) {
                child.remove(0);
            }
        }
    }

    public String toString() {
        return this.getProperty(PROPERTY_NAME) == null ? "" : getProperty(PROPERTY_NAME);
    }
}

下面看一下在dbdesigner的运行效果:





添加数据库连接











//生成的实体类效果

package com.penngo.model;

import java.io.Serializable;
import javax.persistence.*;
import java.math.BigInteger;

@Entity
@Table(name ="jbpm4_deployment")
public class Jbpm4_deployment implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @Column(name ="DBID_")
    private BigInteger dbid_;

    @Column(name ="NAME_")
    private String name_;

    @Column(name ="TIMESTAMP_")
    private BigInteger timestamp_;

    @Column(name ="STATE_", length=255)
    private String state_;

    public BigInteger getDbid_() {
        return dbid_;
    }

    public void setDbid_(BigInteger dbid_) {
        this.dbid_ = dbid_;
    }

    public String getName_() {
        return name_;
    }

    public void setName_(String name_) {
        this.name_ = name_;
    }

    public BigInteger getTimestamp_() {
        return timestamp_;
    }

    public void setTimestamp_(BigInteger timestamp_) {
        this.timestamp_ = timestamp_;
    }

    public String getState_() {
        return state_;
    }

    public void setState_(String state_) {
        this.state_ = state_;
    }
}
分享到:
评论

相关推荐

    idea配置数据库,反向生成实体类demo,支持lombok,swagger2注解

    idea配置数据库,反向生成实体类demo,支持lombok,swagger2注解

    eclipse由数据库反向生成hibernate实体类(图解).doc

    - **第三个选项**:如果要反向生成实体类,则需要勾选此选项。同时还可以指定实体类保存的具体文件夹路径。此外,还需要配置Reveng.xml文件。通过点击“Setup...”按钮,可以选择“新建”或“使用已存在的”Reveng....

    数据库反向生成实体类

    数据库反向生成实体类是软件开发中的一个常见实践,特别是在使用ORM(对象关系映射)框架如Hibernate时。这个过程主要是将数据库结构转化为代码,自动创建对应的Java实体类,这样可以减少手动编写这些类的工作量,...

    逆向生成工具,有数据库表生成java bean实体类

    这个XML文件包含了工具所需的参数,如数据库连接信息(包括数据库URL、用户名和密码)、需要逆向生成的数据库表名以及生成实体类的相关设置。例如,你可以指定实体类的包名、类名前缀、是否生成getter和setter方法、...

    C# .net数据库表实体类生成,一键生成数据库所有表的实体类

    然而,在.NET Core中,虽然EF Core提供了模型构建工具,但并不支持一键生成数据库的所有表对应的实体类。为了解决这个问题,开发者需要自定义解决方案,例如创建一个数据库实体类代码生成器。 本文将详细介绍如何...

    myeclipse与hibernate―反向生成实体类和DAO

    MyEclipse与Hibernate反向生成实体类和DAO MyEclipse是一个基于Eclipse平台的集成开发环境(IDE),它提供了很多实用的功能和插件来帮助开发者快速开发Java应用程序。Hibernate是一个流行的对象关系映射(ORM)框架...

    mybatis逆向从数据库生成实体类

    MyBatis逆向工程是MyBatis框架的一个实用特性,它允许开发者从现有的数据库结构自动生成Java实体类、Mapper接口和XML配置文件,极大地简化了数据访问层的开发工作。这个过程通常包括以下步骤: 1. **安装和配置...

    反向生成实体类

    ### 反向生成实体类:从数据库表结构到JavaBean 在软件开发过程中,特别是基于数据库的应用程序开发中,我们经常需要将数据库中的表映射为面向对象编程语言(如Java)中的实体类(通常称为JavaBean)。这种过程称为...

    mybatis反向生成实体类

    本文将详细介绍如何使用MyBatis Generator反向生成实体类、DAO和Mapper文件,并提供操作步骤。 1. **MyBatis Generator简介** MyBatis Generator (MBG) 是MyBatis的一个插件,它能够根据数据库表的信息自动生成...

    Eclipse数据库hibernate反向生成数据库类

    在本篇文章中,我们将详细介绍如何使用Eclipse中的Hibernate插件反向生成数据库实体类。首先,我们需要安装Hibernate Tools,下载地址为http://www.jboss.org/tools/download/archive/3_1_GA.html,我们只需要下载...

    eclipse从数据库逆向生成Hibernate实体类

    eclipse从数据库逆向生成Hibernate实体类

    实体类模型构建(根据数据库自动生成实体类)

    在本主题中,我们将聚焦于如何使用Eclipse集成开发环境和JDK1.7来根据数据库自动生成实体类,这可以显著提高开发效率并减少手动编码的工作量。 首先,让我们了解一下Eclipse。Eclipse是一款广泛使用的开源Java IDE...

    数据库反向生成基础代码

    数据库反向生成基础代码是指通过特定工具或技术从已有的数据库结构中自动生成相应的应用程序代码,这大大减少了开发人员手动编写数据访问层的工作量。在软件开发过程中,尤其是在大型项目中,这种自动化过程能提高...

    java反向生成实体工具

    有了这种反向生成实体工具,开发者可以快速、准确地自动生成与数据库表结构对应的实体类,极大地提高了开发效率。 该工具的核心功能在于它能够通过连接数据库,读取表结构信息,包括字段名、数据类型、主键等,然后...

    mybatis实体类反向生成

    `mybatis-generator`是MyBatis官方提供的一个工具,它可以自动根据数据库表生成实体类、Mapper接口和映射XML文件。用户需要在配置文件中指定数据库连接信息、表名以及生成规则,然后运行工具即可生成代码。这个过程...

    eclipse中,由数据库反向生成hibernate实体类.pdf

    在Eclipse中,使用Hibernate工具反向工程生成实体类是一个高效的方法,可以帮助开发者快速地将数据库结构转换为Java对象,从而简化开发流程。以下详细解释了如何在Eclipse中进行这个过程,特别是针对SQL Server 2000...

    generatorSqlmapCustom反向生成实体类的一个小项目

    本项目名为“generatorSqlmapCustom”,它的主要目标是反向生成实体类,这是一个方便快捷的方式,可以帮助开发者省去手动编写这些类的繁琐工作。 项目描述中提到,用户只需将这个小项目导入Eclipse IDE,就可以进行...

    实体类转换成数据库表

    4. **反向工程(Reverse Engineering)**: Hibernate支持从现有数据库生成实体类和映射文件,这是一个称为反向工程的过程。在描述中提到的"sqlserver数据库中的表通过Hibernate反射生成的的实体类",就是指的这个...

    hibernate反向生成实体类及CRUD操作教学视频

    【hibernate反向生成实体类及CRUD操作教学视频】是针对Java开发中的一个重要框架——Hibernate进行深入学习的资源。Hibernate是一个强大的对象关系映射(ORM)框架,它简化了Java应用程序对数据库的操作,通过将Java...

Global site tag (gtag.js) - Google Analytics