Hibernate动态建表

[color=red]blog迁移至[/color]:[url=http://www.micmiu.com]http://www.micmiu.com[/url]

[color=blue][b]背景:[/b][/color]由于项目特殊的应用场景,需要实现一个动态创建表的功能。
[color=blue][b]基本思路:[/b][/color]
查了一些资料同时结合到项目里用到了hibernate,就想到利用hibernate的SchemaExport 来实现动态建表
[list]
[*]设计两个javabean:FormTable(表的基本属性)、ColumnAttribute(列的基本属性),实现一对多的关系
[*]Freemaker 可以根据定义好的模板生成 hibernate配置文件[/list]
[color=red][b]提供完整的源代码下载见附件:[/b][/color][url=http://dl.iteye.com/topics/download/0e62b99a-a6f4-3b71-9114-116b1ef9d77b]dynamic_db_table[/url]

lib文件比较多,就不提供了下载了,提供一个lib文件的截图如下:
[img]http://dl.iteye.com/upload/attachment/365766/6a984a56-1183-3fa9-a98c-5404093ae015.jpg[/img]
[color=blue]下面是本人测试的主要代码的片段:[/color]
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;
}

}

[color=blue]TableGenerator.java[/color]
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();
}
}

}

[color=blue]Hibernate配置模板template.hb.ftl[/color]
<?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>

[color=blue]运行的log信息如下:[/color]
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
信息: [color=red]Mapping class: testTable -> TB_GEN[/color]
2010-12-12 13:57:29 org.hibernate.dialect.Dialect <init>
信息: Using dialect: org.hibernate.dialect.MySQL5Dialect
[color=red]2010-12-12 13:57:29 org.hibernate.tool.hbm2ddl.SchemaExport execute[/color]
信息: Running hbm2ddl schema export
2010-12-12 13:57:29 org.hibernate.tool.hbm2ddl.SchemaExport execute
信息: [color=red]writing generated schema to file: d:/test/table.sql[/color]
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=****}
[color=red]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[/color]
信息: schema export complete
2010-12-12 13:57:30 org.hibernate.connection.DriverManagerConnectionProvider close
信息: cleaning up connection pool: jdbc:mysql://localhost/jsnmp

[color=blue][b]生成的脚本文件d:/test/table.sql:[/b][/color]
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上测试的:

[img]http://dl.iteye.com/upload/attachment/365768/dc27f22b-6258-3021-b7cc-3beb6e5a0b60.jpg[/img]
运行测试代码后查看表情况:
[img]http://dl.iteye.com/upload/attachment/365770/f0c7085b-bfa3-3ca3-959a-076247dda878.jpg[/img]
从上面截图比较可见已经成功创建好表: tb_gen.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值