使用HibernateTools+Ant全自动生成实体类和数据库

     Hibernate映射文件、实体类和表三个有其就可以生成另外两个,在讨论到底用谁生谁更好之前,首先列出配置步骤,以Java Web项目为例:


项目整体结构图:



1. 所需Jar包:



2. 编写两个测试用的Hibernate映射文件:


<?xml version = "1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="courseChoosing">
    <class name="Student" table="student">
        <id name="id" column="id" type="long">
            <generator class="native" />
        </id>
        <property name="stuNo" type="string" length="10" />
        <property name="name" type="string" length="20" />
        <property name="gender" type="character" />
        <set name="courses" table="courseChoosing" inverse="false">
            <key column="studentId" />
            <many-to-many class="Course" column="courseId" />
        </set>
    </class>
</hibernate-mapping>

<?xml version = "1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="courseChoosing">
    <class name="Course" table="course">
        <id name="id" column="id" type="long">
            <generator class="native" />
        </id>
        <property name="name" type="string" length="50" />
        <property name="credit" type="integer" />
        <property name="totalClasses" type="integer" />
        <set name="students" table="courseChoosing" inverse="true">
            <key column="courseId" />
            <many-to-many class="Student" column="studentId" />
        </set>
    </class>
</hibernate-mapping>

3. 配置hibernate.cfg.xml文件:

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
<session-factory>
	<property name="connection.username">sa</property>
	<property name="connection.password">pailuo</property><!--Your DB password here. -->
	<property name="connection.url">
		jdbc:sqlserver://192.168.1.4:1433;DatabaseName=andy_db_for_test
	</property>
	<property name="connection.driver_class">
		com.microsoft.sqlserver.jdbc.SQLServerDriver
	</property>
	<property name="dialect">
		org.hibernate.dialect.SQLServerDialect
	</property>
	<mapping resource="com/pilelot/member1/entity/xml/Course.hbm.xml" />
	<mapping resource="com/pilelot/member1/entity/xml/Student.hbm.xml" />
</session-factory>
</hibernate-configuration>

4. 配置log4j.properties文件:

log4j.rootCategory=INFO, stdout , R

log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=[Pilelot] %p [%t] %C.%M(%L) | %m%n

log4j.appender.R=org.apache.log4j.DailyRollingFileAppender
log4j.appender.R.File=d:/ant.log
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%d-[TS] %p %t %c - %m%n

5. 在项目根目录下,注意不是src下,新建build.xml和build.properties两个文件:

build.xml:

<?xml version="1.0"?>
<project name="test" basedir="." default="dbschema">
    <!--定义文件夹-->
    <property file="build.properties"></property>
	<!--初始化 定义jar包路径 -->
	<target name="init">
		<path id="lib.path">
			<pathelement id="src" location="src" />
			<pathelement id="WEB\-INF" location="WEB\-INF" />
			<fileset dir="${WEB-INF}\${lib}">
				<include name="**/*.jar"/>
			</fileset>
		</path>
	</target>
	
	<taskdef name="hibernatetools" classname="org.hibernate.tool.ant.HibernateToolTask" 
			classpathref="lib.path"></taskdef>
	<target name="dbschema">
		<hibernatetools>
			<configuration configurationfile="${src}/hibernate.cfg.xml" />
			<hbm2ddl destdir="${WEB-INF}\${dbschema}" export="true"  console="true" 
						create="true" update="true" drop="true"   outputfilename="dbschema.sql" />
			<hbm2java jdk5="true" destdir="${src}" />
		</hibernatetools>
	</target>
	

</project>

build.properties:

src=src
WEB-INF=WebRoot/WEB-INF/
dbschema=dbschema
lib=lib

6. 运行build.xml:输出结果如下,大功告成:

Buildfile: D:\AndyChan\HibernateToolsAntWebTest\build.xml
Warning: Reference lib.path has not been set at runtime, but was found during
build file parsing, attempting to resolve. Future versions of Ant may support
 referencing ids defined in non-executed targets.
dbschema:
[hibernatetools] Executing Hibernate Tool with a Standard Configuration
[hibernatetools] 1. task: hbm2ddl (Generates database schema)
[hibernatetools] [Pilelot] INFO [main] org.hibernate.cfg.Environment.<clinit>(560) | Hibernate 3.3.2.GA
[hibernatetools] [Pilelot] INFO [main] org.hibernate.cfg.Environment.<clinit>(593) | hibernate.properties not found
[hibernatetools] [Pilelot] INFO [main] org.hibernate.cfg.Environment.buildBytecodeProvider(771) | Bytecode provider name : javassist
[hibernatetools] [Pilelot] INFO [main] org.hibernate.cfg.Environment.<clinit>(652) | using JDK 1.4 java.sql.Timestamp handling
[hibernatetools] [Pilelot] INFO [main] org.hibernate.cfg.Configuration.configure(1508) | configuring from file: hibernate.cfg.xml
[hibernatetools] [Pilelot] INFO [main] org.hibernate.cfg.Configuration.addResource(600) | Reading mappings from resource : com/pilelot/member1/entity/xml/Course.hbm.xml
[hibernatetools] [Pilelot] INFO [main] org.hibernate.cfg.HbmBinder.bindRootPersistentClassCommonValues(322) | Mapping class: courseChoosing.Course -> course
[hibernatetools] [Pilelot] INFO [main] org.hibernate.cfg.HbmBinder.bindCollection(1441) | Mapping collection: courseChoosing.Course.students -> courseChoosing
[hibernatetools] [Pilelot] INFO [main] org.hibernate.cfg.Configuration.addResource(600) | Reading mappings from resource : com/pilelot/member1/entity/xml/Student.hbm.xml
[hibernatetools] [Pilelot] INFO [main] org.hibernate.cfg.HbmBinder.bindRootPersistentClassCommonValues(322) | Mapping class: courseChoosing.Student -> student
[hibernatetools] [Pilelot] INFO [main] org.hibernate.cfg.HbmBinder.bindCollection(1441) | Mapping collection: courseChoosing.Student.courses -> courseChoosing
[hibernatetools] [Pilelot] INFO [main] org.hibernate.cfg.Configuration.doConfigure(1589) | Configured SessionFactory: null
[hibernatetools] [Pilelot] INFO [main] org.hibernate.tool.Version.<clinit>(15) | Hibernate Tools 3.3.0.GA
[hibernatetools] [Pilelot] INFO [main] org.hibernate.dialect.Dialect.<init>(175) | Using dialect: org.hibernate.dialect.SQLServerDialect
[hibernatetools] [Pilelot] INFO [main] org.hibernate.tool.hbm2ddl.SchemaUpdate.execute(155) | Running hbm2ddl schema update
[hibernatetools] [Pilelot] INFO [main] org.hibernate.tool.hbm2ddl.SchemaUpdate.execute(167) | fetching database metadata
[hibernatetools] [Pilelot] INFO [main] org.hibernate.connection.DriverManagerConnectionProvider.configure(64) | Using Hibernate built-in connection pool (not for production use!)
[hibernatetools] [Pilelot] INFO [main] org.hibernate.connection.DriverManagerConnectionProvider.configure(65) | Hibernate connection pool size: 20
[hibernatetools] [Pilelot] INFO [main] org.hibernate.connection.DriverManagerConnectionProvider.configure(68) | autocommit mode: false
[hibernatetools] [Pilelot] INFO [main] org.hibernate.connection.DriverManagerConnectionProvider.configure(103) | using driver: com.microsoft.sqlserver.jdbc.SQLServerDriver at URL: jdbc:sqlserver://192.168.1.4:1433;DatabaseName=test
[hibernatetools] [Pilelot] INFO [main] org.hibernate.connection.DriverManagerConnectionProvider.configure(109) | connection properties: {user=sa, password=****}
[hibernatetools] [Pilelot] INFO [main] org.hibernate.tool.hbm2ddl.SchemaUpdate.execute(179) | updating schema
[hibernatetools] [Pilelot] INFO [main] org.hibernate.tool.hbm2ddl.SchemaUpdate.execute(183) | writing generated schema to file: D:\AndyChan\HibernateToolsAntWebTest\WebRoot\WEB-INF\dbschema\dbschema.sql
[hibernatetools] [Pilelot] INFO [main] org.hibernate.tool.hbm2ddl.DatabaseMetadata.getTableMetadata(119) | table not found: course
[hibernatetools] [Pilelot] INFO [main] org.hibernate.tool.hbm2ddl.DatabaseMetadata.getTableMetadata(119) | table not found: courseChoosing
[hibernatetools] [Pilelot] INFO [main] org.hibernate.tool.hbm2ddl.DatabaseMetadata.getTableMetadata(119) | table not found: student
[hibernatetools] [Pilelot] INFO [main] org.hibernate.tool.hbm2ddl.DatabaseMetadata.getTableMetadata(119) | table not found: course
[hibernatetools] [Pilelot] INFO [main] org.hibernate.tool.hbm2ddl.DatabaseMetadata.getTableMetadata(119) | table not found: courseChoosing
[hibernatetools] [Pilelot] INFO [main] org.hibernate.tool.hbm2ddl.DatabaseMetadata.getTableMetadata(119) | table not found: student
[hibernatetools] create table course (id numeric(19,0) identity not null, name varchar(50) null, credit int null, totalClasses int null, primary key (id));
[hibernatetools] create table courseChoosing (courseId numeric(19,0) not null, studentId numeric(19,0) not null, primary key (studentId, courseId));
[hibernatetools] create table student (id numeric(19,0) identity not null, stuNo varchar(10) null, name varchar(20) null, gender char(1) null, primary key (id));
[hibernatetools] alter table courseChoosing add constraint FK42CD624F924EFB30 foreign key (courseId) references course;
[hibernatetools] alter table courseChoosing add constraint FK42CD624F417DBA12 foreign key (studentId) references student;
[hibernatetools] [Pilelot] INFO [main] org.hibernate.tool.hbm2ddl.SchemaUpdate.execute(217) | schema update complete
[hibernatetools] [Pilelot] INFO [main] org.hibernate.connection.DriverManagerConnectionProvider.close(170) | cleaning up connection pool: jdbc:sqlserver://192.168.1.4:1433;DatabaseName=test
[hibernatetools] 2. task: hbm2java (Generates a set of .java files)
BUILD SUCCESSFUL
Total time: 2 seconds

《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《
以上是我测试通过的例子,请修改相关参数,如数据库连接相关的,项目完整代码下载地址:
http://download.csdn.net/detail/king87130/4599922




开头要讨论的那个至关重要的问题,我想引用网上一位大牛的精彩讲述:

不过,我想在这里讨论的是那种从无到有,从想法到实现的那种建立全新应用的情况。那么,自然而然就会有一个问题:“从哪里开始?”。实体类pojo、hbm映射文件和数据库表?先应该建立哪一个,再通过它生成其它两个?这个问题我觉得应该从Hibernate框架的产生的初忠来考虑:为了解决“面向对象模型”与“关系模型”之间的“阻抗不匹配”。简而言之,就是说在我们的类图和E-R关系图中各元素的对应关系很难把握,而且容易让人产生概念的混淆,如“每一个数据库表对应一个实体类”等错误想法,很容易让人在设计实体时不知不觉扔掉很多面向对象模型的优秀思想。其实并不能说哪一个模型是错,只是因为他们描述问题的方向不同。那么,Hibernate框架就是把这两个模型“映射”了起来,让程序员可以在面向对象的世界里完成对数据库的查询,而不必关心底层的数据库表的结构。
【说了那么多,直接了当地讲,我不赞成“先建立数据表,再通过这个数据表生成POJO和hbm文件”这种方案。道理很简单:如果先就去考虑数据库,那么我们随后的设计势必会受到这个数据库的影响,不利于精确地描述我们的应用,Hibernate框架的好处也就体现不出来了(先就把数据库搞定了还要Hibernate来干什么),生成的POJO不用说——内容多半很别扭——因为你企图从一个非面向对象的框框里硬抽象出面向对象模型来(也许你会认为这是可以通过经验来避免的,是的,确实是,不过你不觉得这样一来工作复杂化了吗?要考虑的东西增多了)。
面向对象模型是用来精确而自然地描述问题的,这是我的看法,它提供了包含、继承等等机制,几乎能把这个世界上的所有事物之间的关系精确地描述出来——它好比一门语言——怎么方便你就怎么说。那么,先数据库再POJO的做法就好比是先规定了你只能用哪些词语之后让你说话,而先POJO再数据库就好比是让你随便说随便发挥了,自然后者要好得多。
从软件工程的角度讲,需求——用例——实体这样一趟走下来,POJO出现在数据库前面是很自然的,在OOA阶段就考虑数据库是很不可取的做法(绝对一点讲——是错误的)。
OK,剩下的POJO和hbm文件之间应该先生成哪个呢?我觉得先生成谁都无所谓,都不会对我们的工程产生不利影响了。
hbm文件作为POJO和数据库之间的桥梁,从它入手的话会有一举两得的感觉,全是干净的XML文件。当然,貌似利用xDoclet标签在我们写POJO代码的时候自动生成hbm也是很不错的感觉。。。






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值