`
sjsky
  • 浏览: 921715 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Hibernate动态建表

阅读更多
    blog迁移至:http://www.micmiu.com

背景:由于项目特殊的应用场景,需要实现一个动态创建表的功能。
基本思路:
    查了一些资料同时结合到项目里用到了hibernate,就想到利用hibernate的SchemaExport 来实现动态建表
  • 设计两个javabean:FormTable(表的基本属性)、ColumnAttribute(列的基本属性),实现一对多的关系
  • Freemaker 可以根据定义好的模板生成 hibernate配置文件
提供完整的源代码下载见附件:dynamic_db_table

lib文件比较多,就不提供了下载了,提供一个lib文件的截图如下:

下面是本人测试的主要代码的片段:
package com.michael;

import java.util.ArrayList;
import java.util.List;

import com.michael.vo.ColumnAttribute;
import com.michael.vo.FormTable;

/**
 * @author Michael
 * 
 */
public class TestMain {
    /**
     * @param args
     * @throws Exception
     */
    public static void main(String[] args) throws Exception {
        TestMain test = new TestMain();
        FormTable fromTable = test.initData();

        TableGenerator tg = new TableGenerator(fromTable);
        tg.generatorTable();

    }

    /**
     * 初始化数据
     * @return
     */
    private FormTable initData() {
        FormTable form = new FormTable();
        form.setName("testTable");
        form.setTableName("TB_GEN");

        List<ColumnAttribute> list = new ArrayList<ColumnAttribute>();
        ColumnAttribute attr = new ColumnAttribute();
        attr.setName("collectKey");
        attr.setColumnType("string");
        attr.setColumnName("COLLECTKEY");
        attr.setLength(100);
        list.add(attr);
        ColumnAttribute attr1 = new ColumnAttribute();
        attr1.setName("mibVal");
        attr1.setColumnType("string");
        attr1.setColumnName("MIBVAL");
        attr1.setLength(100);
        list.add(attr1);
        ColumnAttribute attr2 = new ColumnAttribute();
        attr2.setName("dsname");
        attr2.setColumnType("string");
        attr2.setColumnName("DSNAME");
        attr2.setLength(100);
        list.add(attr2);
        ColumnAttribute attr3 = new ColumnAttribute();
        attr3.setName("timestamp");
        attr3.setColumnType("long");
        attr3.setColumnName("TIMESTAMP");
        list.add(attr3);
        form.setFormAttributeList(list);
        return form;
    }

}

TableGenerator.java
package com.michael;

import java.io.StringWriter;
import java.io.Writer;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import javax.sql.DataSource;

import org.hibernate.cfg.Configuration;
import org.hibernate.tool.hbm2ddl.SchemaExport;

import com.michael.vo.FormTable;

import freemarker.template.Template;

/**
 * @author Michael
 * 
 */
public class TableGenerator {

    /**
     * tableVo
     */
    private FormTable tableVo;

    /**
     * 脚本文件
     */
    private String scriptFileName = "d:/test/table.sql";

    /**
     * 构造函数
     * @param tableVo
     */
    public TableGenerator(FormTable tableVo) {
        this.tableVo = tableVo;
    }

    /**
     * 构造函数
     * @param tableVo
     * @param scriptFileName
     */
    public TableGenerator(FormTable tableVo, String scriptFileName) {
        this.tableVo = tableVo;
        if (null != scriptFileName && !"".equals(scriptFileName)) {
            this.scriptFileName = scriptFileName;
        }
    }

    /**
     * 
     */
    public void generatorTable() {
        if (tableVo.getColumnAttrList().isEmpty()) {
            System.out.println(" column attr list size==0 ");
            return;
        }

        Template tl;
        try {
            Map<String, Object> paramMap = new HashMap<String, Object>();
            paramMap.put("entity", tableVo);

            tl = getTemplateConfig("/com/michael/ftl").getTemplate(
                    "template.hb.ftl");
            Writer out = new StringWriter();
            tl.process(paramMap, out);
            String hbxml = out.toString();
            System.out.println(hbxml);
            Configuration hbcfg = this.getHibernateCfg(hbxml);

            // Properties pp = CommonUtil
            // .getPropertiesByResource(Constant.PPFILENAME);
            // DataSource ds = BasicDataSourceFactory.createDataSource(pp);

            createDbTableByCfg(hbcfg);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取freemarker的cfg
     * @param resource
     * @return Configuration
     */
    protected freemarker.template.Configuration getTemplateConfig(
            String resource) {

        freemarker.template.Configuration cfg = new freemarker.template.Configuration();
        cfg.setDefaultEncoding("UTF-8");
        cfg.setClassForTemplateLoading(this.getClass(), resource);
        return cfg;
    }

    /**
     * 处理hibernate的配置文件
     * @param resource
     */
    protected Configuration getHibernateCfg(String hbxml) {
        org.hibernate.cfg.Configuration hbcfg = new org.hibernate.cfg.Configuration();
        hbcfg.configure("/hibernate.cfg.xml");
        Properties extraProp = new Properties();
        extraProp.put("hibernate.hbm2ddl.auto", "update");
        hbcfg.addProperties(extraProp);
        hbcfg.addXML(hbxml);
        return hbcfg;
    }

    /**
     * 根据hibernate cfg配置文件动态建表
     * @param hbcfg
     */
    public void createDbTableByCfg(Configuration hbcfg) {
        SchemaExport schemaExport;
        try {
            schemaExport = new SchemaExport(hbcfg);
            // 设置脚本文件
            schemaExport.setOutputFile(scriptFileName);
            schemaExport.create(true, true);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 根据配置文件、Connection 来动态建表
     * @param conf
     * @param ds
     */
    public void createDbTableByConn(Configuration conf, DataSource ds) {
        SchemaExport schemaExport;
        try {

            schemaExport = new SchemaExport(conf, ds.getConnection());
            schemaExport.setOutputFile(scriptFileName);
            schemaExport.create(true, true);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

Hibernate配置模板template.hb.ftl
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping 
  PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
         "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
    <class
        name="${entity.name}"
        table="${entity.tableName}"
        dynamic-update="false"
        dynamic-insert="false"
        select-before-update="false"
        optimistic-lock="version">
        <id
            name="id"
            column="ID"
            type="long"
            unsaved-value="null">
            <generator class="native" />
        </id>
        <#if entity.columnAttrList?exists>
            <#list entity.columnAttrList as attr>
                <#if attr.name == "id">                
                <#elseif attr.columnType=="string">
        <property
            name="${attr.name}"
            type="java.lang.String"
            update="true"
            insert="true"
            access="property"
            column="${attr.columnName}"
            length="${attr.length}"
            not-null="false"
            unique="false"
        />
        <#else>
        <property
            name="${attr.name}"
            type="${attr.columnType}"
            update="true"
            insert="true"
            access="property"
            column="`${attr.columnName}`"
            not-null="false"
            unique="false"
        />
        
                </#if>
            </#list>
        </#if>
    </class>
</hibernate-mapping>

运行的log信息如下:
2010-12-12 13:57:28 org.hibernate.cfg.Environment <clinit>
信息: Hibernate 3.2.5
2010-12-12 13:57:28 org.hibernate.cfg.Environment <clinit>
信息: hibernate.properties not found
2010-12-12 13:57:28 org.hibernate.cfg.Environment buildBytecodeProvider
信息: Bytecode provider name : cglib
2010-12-12 13:57:28 org.hibernate.cfg.Environment <clinit>
信息: using JDK 1.4 java.sql.Timestamp handling
2010-12-12 13:57:28 org.hibernate.cfg.Configuration configure
信息: configuring from resource: /hibernate.cfg.xml
2010-12-12 13:57:28 org.hibernate.cfg.Configuration getConfigurationInputStream
信息: Configuration resource: /hibernate.cfg.xml
2010-12-12 13:57:29 org.hibernate.cfg.Configuration doConfigure
信息: Configured SessionFactory: null
2010-12-12 13:57:29 org.hibernate.cfg.HbmBinder bindRootPersistentClassCommonValues
信息: Mapping class: testTable -> TB_GEN
2010-12-12 13:57:29 org.hibernate.dialect.Dialect <init>
信息: Using dialect: org.hibernate.dialect.MySQL5Dialect
2010-12-12 13:57:29 org.hibernate.tool.hbm2ddl.SchemaExport execute
信息: Running hbm2ddl schema export
2010-12-12 13:57:29 org.hibernate.tool.hbm2ddl.SchemaExport execute
信息: writing generated schema to file: d:/test/table.sql
2010-12-12 13:57:29 org.hibernate.tool.hbm2ddl.SchemaExport execute
信息: exporting generated schema to database
2010-12-12 13:57:29 org.hibernate.connection.DriverManagerConnectionProvider configure
信息: Using Hibernate built-in connection pool (not for production use!)
2010-12-12 13:57:29 org.hibernate.connection.DriverManagerConnectionProvider configure
信息: Hibernate connection pool size: 20
2010-12-12 13:57:29 org.hibernate.connection.DriverManagerConnectionProvider configure
信息: autocommit mode: false
2010-12-12 13:57:29 org.hibernate.connection.DriverManagerConnectionProvider configure
信息: using driver: com.mysql.jdbc.Driver at URL: jdbc:mysql://localhost/jsnmp
2010-12-12 13:57:29 org.hibernate.connection.DriverManagerConnectionProvider configure
信息: connection properties: {user=root, password=****}
drop table if exists TB_GEN
create table TB_GEN (ID bigint not null auto_increment, COLLECTKEY varchar(100), MIBVAL varchar(100), DSNAME varchar(100), `TIMESTAMP` bigint, primary key (ID))
2010-12-12 13:57:30 org.hibernate.tool.hbm2ddl.SchemaExport execute

信息: schema export complete
2010-12-12 13:57:30 org.hibernate.connection.DriverManagerConnectionProvider close
信息: cleaning up connection pool: jdbc:mysql://localhost/jsnmp

生成的脚本文件d:/test/table.sql:
drop table if exists TB_GEN
create table TB_GEN (ID bigint not null auto_increment, COLLECTKEY varchar(100), 
MIBVAL varchar(100), DSNAME varchar(100), `TIMESTAMP` bigint, primary key (ID))


本程序是在mysql5上测试的:


运行测试代码后查看表情况:

从上面截图比较可见已经成功创建好表: tb_gen.
  • 大小: 57.1 KB
  • 大小: 10.7 KB
  • 大小: 13.2 KB
2
3
分享到:
评论
6 楼 bigboy 2012-03-27  
为什么我的那个脚本文件没有生成呢?
5 楼 junying280efun 2012-01-31  
博主,我想问下,你这样动态生成表后,在不重启tomcat的情况下,能用hibernate对新建的表进行操作吗?会不会有org.hibernate.MappingException: Unknown entity:的exception?
4 楼 sjsky 2011-09-19  
promzaid 写道
楼主,我用你的程序把所有表的内容都清空了,怎么回事?

你是指映射的表被清空了 还是没有映射的表也被清空了???
3 楼 promzaid 2011-09-19  
楼主,我用你的程序把所有表的内容都清空了,怎么回事?
2 楼 sjsky 2011-09-03  
zeyonq 写道
非常感谢您的资料!


1 楼 zeyonq 2011-09-03  
非常感谢您的资料!

相关推荐

    hibernate动态生成表结构

    本文将深入探讨如何利用Hibernate的特性来实现动态生成表结构,以及如何处理表与表之间的关系。 一、Hibernate概述 Hibernate是一个开源的Java库,它的主要功能是将Java类与数据库表进行映射,使得程序员可以使用...

    java动态增加页面元素和动态建表

    在Java编程中,动态增加页面元素和动态建表是两个重要的技术点,它们通常涉及到Web开发中的前端交互和后端数据库操作。以下是对这两个概念的详细解析。 首先,让我们谈谈“Java动态增加页面元素”。在Java Web应用...

    JPA注解 和hibernate 建表

    JPA注解和Hibernate建表 一、JPA概述 Java Persistence API(JPA)是Sun官方提出的Java持久化规范,它只是一个规范不是一个产品。JPA的主要目标是提供一种简洁、易用的方式来访问、操作和管理Java应用程序中的数据...

    Hibernate建表用到的jar包

    下面将详细介绍这些jar包及其在Hibernate建表中的作用。 1. **hibernate-core.jar**:这是Hibernate的核心库,包含了Hibernate的API和实现,如Session、SessionFactory等核心接口以及实体管理、查询语言(HQL)、事件...

    hibernate增删改查代码

    在IT行业中,Hibernate是一个非常重要的Java持久化框架,它简化了数据库操作,使得开发者可以更加专注于业务逻辑,而不是底层的数据访问细节。本篇文章将详细解析标题"hibernate增删改查代码"所涵盖的知识点,并结合...

    自动在数据库中建成表(Hibernate)

    4. **配置自动建表**:在Hibernate的配置文件中,启用`hbm2ddl.auto`属性,如设置为`create`或`create-drop`,Hibernate将在启动时创建表(或每次启动时删除并重新创建)。如果希望更新已有表结构,可以设置为`...

    Spring Data JPA/Hibernate 运行期动态模型、动态实体建表、动态字段查询的方式

    涉及到动态生成表结构,动态生成模型实体类动态查询表字段等等,经过调研发现hibernate在这方面是很方便的,调用内置API就能完成系列操作,下面贴出核心代码: /** * @author cjbi */ public class DynamicDdlTest...

    hibernate3.5多对多自动建表

    用hibernate3.5 xml文件映射,junit实现多对多自动建表,下载后解压用myeclipse导入,这里要注意:需要junit的包。这个是学hibernate的关键,建议新手作为重点,大虾就请多多指教了

    hibernate建表例子

    标题"hibernate建表例子"表明我们要探讨的是关于使用Hibernate框架进行数据库表创建的示例。Hibernate是一个强大的Java持久层框架,它简化了数据库操作,通过对象关系映射(ORM)将Java类与数据库表对应起来。 描述...

    HIBERNATE:Hibernate 学习一--注解方式自动建表

    这篇博客"Hibernate学习一--注解方式自动建表"主要探讨了如何使用Hibernate的注解来实现数据库表的自动化创建。 在Java编程中,注解(Annotation)是一种元数据,它提供了在代码中插入信息的方式,这些信息可以被...

    学生宿舍管理系统(struts2和hibernate)

    struts2和hibernate整合的,hibernate使用的注解方式,数据库是mysql。数据库的配置在hibernate.cfg.xml中修改一下,直接新建一个数据库就可以了,hibernate自动建表,自己手动在程序中添加数据信息。

    struts2+hibernate整合增删改查加注册登录Demo包含数据库自动建表语句

    3. **数据库自动建表语句**:在Hibernate中,可以通过配置使其自动根据映射文件创建数据库表,这对于快速原型开发或测试非常有用。这通常在hibernate.cfg.xml的`hibernate.hbm2ddl.auto`属性中设置,如设为"create...

    springMVC4+hibernate4+mysql全注解自动建表

    注释齐全,'零'配置文件 (1)在config中找到db.properties:连接自己的mysql (2)在连接到的mysql中建一个数据库(database):(defaultName:mvcdemo) (3)运行本项目 (4)页面输入 ...

    SpringMVC实现动态加表及字段并显示数据

    例如,Hibernate提供了@Entity动态调整和@JoinColumn等注解,可以在运行时动态修改实体类,从而影响数据库表结构。 接下来,我们需要设计一个动态表单,这通常涉及到HTML、JavaScript和CSS的配合。使用SpringMVC的...

    hibernate的相关jar包

    在开发过程中,有时我们需要查看Hibernate根据实体类自动生成的建表语句,这通常是为了调试或确认数据库结构。可以通过以下步骤实现: 1. 在Hibernate的配置文件(`hibernate.cfg.xml`)中启用SQL日志输出: ```...

    hibernate简单的入门案例

    3. **自动建表策略** Hibernate 提供了自动创建、更新、验证数据库表的策略。在配置文件中,你可以通过以下属性来控制这个行为: ```xml &lt;property name="hibernate.hbm2ddl.auto"&gt;create ``` 上述配置中的`...

    hibernate根据类生成表

    "hibernate根据类生成表"这一主题主要涉及Hibernate的自动建表功能,即Hibernate能够基于我们的Java实体类自动生成对应的数据库表结构。下面我们将详细探讨这一功能。 1. Hibernate自动建表原理 Hibernate的核心是...

    毕设-B2B 在线招标系统

    2.sql 见 src 目录下 sql 文件 , 默认 hibernate 自动建表 3.配置文件见 src/resources 目录 1.springMvc 以 location="classpath:*-gourderwa.properties" 装载配置,若修改配置文件名称对应修改此处 2.指定 ...

    SSH高质量整合.Spring注解标签,项目启动自动建表.

    综上所述,SSH高质量整合利用Spring的注解简化配置,通过Hibernate的注解实现ORM映射,同时利用Hibernate的自动建表功能,极大地提高了开发效率。项目中的标签注入则优化了视图层的开发,使得整个Web应用的开发流程...

Global site tag (gtag.js) - Google Analytics