一般在项目开发过程中,使用比较多的就是先建好表,再利用hibernate反向工程生成*.hbm.xml文件跟POJO类,个人认为由于目前所使用的数据库都是关系数据库,而hibernate作为一个ORM,把对数据库的操作都对象化了,更应当从对象出发,生成数据库里面相关表,这样更加符合人认知事物的习惯。
由于hibernate3提供了自带的工具hbm2ddl,建立根据你的对象建立数据库是一件非常简单的事情。
SchemaExport工具:Hibernate的hbm2dll提供SchemaExport工具,给定一个连接字符串和映射文件,不需输入其他东西就可以按照持久化类和映射文件自动生成数据库架构,现在SchemaExport工具还不是很强大,但是一般应用足够了,它还是一个相当原始的API还在不断改进。SchemaExport工具就是把DDL脚本输出到标准输出,同时/或者执行DDL语句。SchemaExport工具提供了三个方法,分别是Drop()、Create()、Execute(),前两个方法实质是调用Execute()方法。通常使用Execute()方法来生成数据库架构的。
SchemaUpdate工具:在Hibernate2.0中新添加SchemaUpdate工具,可以用来更新数据库架构。但是我觉得没有什么作用,因为它不能Drop现有的表或列,也不能更新现有的列,只能添加新的表和列。如果我需要删除表或者列或者修改其中列,SchemaUpdate工具就显得无能为力了。
SchemaValidator工具:SchemaValidator工具,可以用来检查数据库架构。通过映射文件中配置的相关数据库表及各自的字段属性来检查数据库中对应表结构是否存在或正确,如果不存在表或字段不一致,则抛出异常。
对于单纯的Hibernate,配置有hibernate.cfg.xml数据库配置文件,或是其它SSH整合版本中也配置有相关.cfg.xml文件的工程来说,这种类型的情况下使用Hibernate的SchemaExport实现正向工程比较简单。如下例:
public boolean createTableByBean(String mappingFile) {
Configuration cfg = new Configuration().configure(cfgFile);
cfg.addFile(mappingFile);
boolean flag = true;
SchemaExport dbExport = new SchemaExport(cfg);
try {
dbExport.create(true, true);
} catch (Exception e) {
flag = false;
}
return flag;
}
而我所做的数据迁移工具中使用的是Spring+Hibernate整合框架,而且在数据库配置中没有使用hibernate.properties和hibernate.cfg.xml文件来配置,
因为在使用Hibernate的SchemaExport/SchemaUpdate/SchemaValidator工具时,构建对象时需要Hibernate的Configuration对象实例作为参数。如:
var export = new SchemaExport(cfg); 其中cfg参数由
Configuration cfg = new Configuration().configure(cfgFile);建立,configure默认读取hibernate.cfg.xml配置文件(configure无参函数),
也可以通过传递参数指定自己定义的.cfg.xml文件。我的SessionFactory是借助于Spring提供的
org.springframework.orm.hibernate3.LocalSessionFactoryBean来实现的:
<bean id="targetSessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
……
</bean>
在没有配置.cfg.xml文件的情况下,可以通过配置的数据源的SessionFactory中获取,如下:
public class DaoUtil extends HibernateDaoSupport {
private Configuration cfg;
private Settings settings;
public void init() {
String webRootPath = CommonMethod.getWebRootPath();
ApplicationContext dataSource_ctx = new FileSystemXmlApplicationContext(webRootPath + "/WEB-INF/datatransferConf/applicationContext-targetDataSource.xml");
SessionFactoryImplementor sessionFactoryImpl = (SessionFactoryImplementor) dataSource_ctx.getBean("targetSessionFactory");
LocalSessionFactoryBean localSessionFactory = (LocalSessionFactoryBean) dataSource_ctx.getBean("&targetSessionFactory");
SessionFactory sessionFactory = (SessionFactory) dataSource_ctx.getBean("targetSessionFactory");
this.cfg = localSessionFactory.getConfiguration();
this.settings = sessionFactoryImpl.getSettings();
super.setSessionFactory(sessionFactory);
}
public void createTableFromCfg() {
if (settings.isAutoCreateSchema()) {
new SchemaExport(cfg, settings).create(true, true);
} else if (settings.isAutoUpdateSchema()) {
new SchemaUpdate(cfg, settings).execute(true, true);
} else if (settings.isAutoDropSchema()) {
new SchemaExport(cfg, settings).drop(true, true);
} else if (settings.isAutoValidateSchema()) {
new SchemaValidator(cfg).validate();
}
}
public void createTableFromMapFile(String mappingFile) {
Resource mappingLocation = new ClassPathResource(mappingFile);
try {
cfg.addInputStream(mappingLocation.getInputStream());
} catch (MappingException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
createTableFromCfg();
}
}
SchemaExport 的create(script,export)方法根据持久类和映射文件先删除架构后创建删除数据库架构。有两个参数,第一个为True就是把DDL语句输出到控制台,第二个为True就是根据持久类和映射文件先执行删除再执行创建操作,经过调试可以发现这个方法其实质是执行execute(script,export, false, true)方法。execute(script, export, justDrop, format)方法根据持久类和映射文件先删除架构后创建删除数据库架构。有四个参数,第一个为True就是把DDL语句输出到控制台;第二个为True就是根据持久类和映射文件在数据库中先执行删除再执行创建操作;第三个为false表示不是仅仅执行Drop语句还执行创建操作,这个参数的不同就扩展了上面两个方法;第四个参数为false表示不是格式化输出DDL语句到控制台,是在一行输出的。
Spring配置文件中所定义的LocalSessionFactoryBean实现了org.springframework.beans.factory.FactoryBean接口,在使用ApplicationContext对象读取的时候可以自动转型为多种不同类型的SessionFactory,spring在装配的时候, 如果发现实现了org.springframework.beans.factory.FactoryBean接口,就会使用
FactoryBean#getObject() 方法返回的对象装配,具体的可以看下文档。如果你想拿到LocalSessionFactoryBean实例, 在id前面加个'&'就可以了,在你的配置文件中BeanFactory.getBean('&sessionFactory')拿到的就是LocalSessionFactoryBean的实例。