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

Hibernate 专栏收录该内容
0 篇文章 0 订阅

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


项目整体结构图:



1. 所需Jar包:



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


  1. <?xml version = "1.0"?>
  2. <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
  3. <hibernate-mapping package="courseChoosing">
  4. <class name="Student" table="student">
  5. <id name="id" column="id" type="long">
  6. <generator class="native" />
  7. </id>
  8. <property name="stuNo" type="string" length="10" />
  9. <property name="name" type="string" length="20" />
  10. <property name="gender" type="character" />
  11. <set name="courses" table="courseChoosing" inverse="false">
  12. <key column="studentId" />
  13. <many-to-many class="Course" column="courseId" />
  14. </set>
  15. </class>
  16. </hibernate-mapping>

  1. <?xml version = "1.0"?>
  2. <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
  3. <hibernate-mapping package="courseChoosing">
  4. <class name="Course" table="course">
  5. <id name="id" column="id" type="long">
  6. <generator class="native" />
  7. </id>
  8. <property name="name" type="string" length="50" />
  9. <property name="credit" type="integer" />
  10. <property name="totalClasses" type="integer" />
  11. <set name="students" table="courseChoosing" inverse="true">
  12. <key column="courseId" />
  13. <many-to-many class="Student" column="studentId" />
  14. </set>
  15. </class>
  16. </hibernate-mapping>

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

  1. <?xml version='1.0' encoding='UTF-8'?>
  2. <!DOCTYPE hibernate-configuration PUBLIC
  3. "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
  4. "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
  5. <hibernate-configuration>
  6. <session-factory>
  7. <property name="connection.username">sa</property>
  8. <property name="connection.password">pailuo</property><!--Your DB password here. -->
  9. <property name="connection.url">
  10. jdbc:sqlserver://192.168.1.4:1433;DatabaseName=andy_db_for_test
  11. </property>
  12. <property name="connection.driver_class">
  13. com.microsoft.sqlserver.jdbc.SQLServerDriver
  14. </property>
  15. <property name="dialect">
  16. org.hibernate.dialect.SQLServerDialect
  17. </property>
  18. <mapping resource="com/pilelot/member1/entity/xml/Course.hbm.xml" />
  19. <mapping resource="com/pilelot/member1/entity/xml/Student.hbm.xml" />
  20. </session-factory>
  21. </hibernate-configuration>

4. 配置log4j.properties文件:

  1. log4j.rootCategory=INFO, stdout , R
  2. log4j.appender.stdout=org.apache.log4j.ConsoleAppender
  3. log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
  4. log4j.appender.stdout.layout.ConversionPattern=[Pilelot] %p [%t] %C.%M(%L) | %m%n
  5. log4j.appender.R=org.apache.log4j.DailyRollingFileAppender
  6. log4j.appender.R.File=d:/ant.log
  7. log4j.appender.R.layout=org.apache.log4j.PatternLayout
  8. log4j.appender.R.layout.ConversionPattern=%d-[TS] %p %t %c - %m%n

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

build.xml:

  1. <?xml version="1.0"?>
  2. <project name="test" basedir="." default="dbschema">
  3. <!--定义文件夹-->
  4. <property file="build.properties"></property>
  5. <!--初始化 定义jar包路径 -->
  6. <target name="init">
  7. <path id="lib.path">
  8. <pathelement id="src" location="src" />
  9. <pathelement id="WEB\-INF" location="WEB\-INF" />
  10. <fileset dir="${WEB-INF}\${lib}">
  11. <include name="**/*.jar"/>
  12. </fileset>
  13. </path>
  14. </target>
  15. <taskdef name="hibernatetools" classname="org.hibernate.tool.ant.HibernateToolTask"
  16. classpathref="lib.path"></taskdef>
  17. <target name="dbschema">
  18. <hibernatetools>
  19. <configuration configurationfile="${src}/hibernate.cfg.xml" />
  20. <hbm2ddl destdir="${WEB-INF}\${dbschema}" export="true" console="true"
  21. create="true" update="true" drop="true" outputfilename="dbschema.sql" />
  22. <hbm2java jdk5="true" destdir="${src}" />
  23. </hibernatetools>
  24. </target>
  25. </project>

build.properties:

  1. src=src
  2. WEB-INF=WebRoot/WEB-INF/
  3. dbschema=dbschema
  4. lib=lib

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

  1. Buildfile: D:\AndyChan\HibernateToolsAntWebTest\build.xml
  2. Warning: Reference lib.path has not been set at runtime, but was found during
  3. build file parsing, attempting to resolve. Future versions of Ant may support
  4. referencing ids defined in non-executed targets.
  5. dbschema:
  6. [hibernatetools] Executing Hibernate Tool with a Standard Configuration
  7. [hibernatetools] 1. task: hbm2ddl (Generates database schema)
  8. [hibernatetools] [Pilelot] INFO [main] org.hibernate.cfg.Environment.<clinit>(560) | Hibernate 3.3.2.GA
  9. [hibernatetools] [Pilelot] INFO [main] org.hibernate.cfg.Environment.<clinit>(593) | hibernate.properties not found
  10. [hibernatetools] [Pilelot] INFO [main] org.hibernate.cfg.Environment.buildBytecodeProvider(771) | Bytecode provider name : javassist
  11. [hibernatetools] [Pilelot] INFO [main] org.hibernate.cfg.Environment.<clinit>(652) | using JDK 1.4 java.sql.Timestamp handling
  12. [hibernatetools] [Pilelot] INFO [main] org.hibernate.cfg.Configuration.configure(1508) | configuring from file: hibernate.cfg.xml
  13. [hibernatetools] [Pilelot] INFO [main] org.hibernate.cfg.Configuration.addResource(600) | Reading mappings from resource : com/pilelot/member1/entity/xml/Course.hbm.xml
  14. [hibernatetools] [Pilelot] INFO [main] org.hibernate.cfg.HbmBinder.bindRootPersistentClassCommonValues(322) | Mapping class: courseChoosing.Course -> course
  15. [hibernatetools] [Pilelot] INFO [main] org.hibernate.cfg.HbmBinder.bindCollection(1441) | Mapping collection: courseChoosing.Course.students -> courseChoosing
  16. [hibernatetools] [Pilelot] INFO [main] org.hibernate.cfg.Configuration.addResource(600) | Reading mappings from resource : com/pilelot/member1/entity/xml/Student.hbm.xml
  17. [hibernatetools] [Pilelot] INFO [main] org.hibernate.cfg.HbmBinder.bindRootPersistentClassCommonValues(322) | Mapping class: courseChoosing.Student -> student
  18. [hibernatetools] [Pilelot] INFO [main] org.hibernate.cfg.HbmBinder.bindCollection(1441) | Mapping collection: courseChoosing.Student.courses -> courseChoosing
  19. [hibernatetools] [Pilelot] INFO [main] org.hibernate.cfg.Configuration.doConfigure(1589) | Configured SessionFactory: null
  20. [hibernatetools] [Pilelot] INFO [main] org.hibernate.tool.Version.<clinit>(15) | Hibernate Tools 3.3.0.GA
  21. [hibernatetools] [Pilelot] INFO [main] org.hibernate.dialect.Dialect.<init>(175) | Using dialect: org.hibernate.dialect.SQLServerDialect
  22. [hibernatetools] [Pilelot] INFO [main] org.hibernate.tool.hbm2ddl.SchemaUpdate.execute(155) | Running hbm2ddl schema update
  23. [hibernatetools] [Pilelot] INFO [main] org.hibernate.tool.hbm2ddl.SchemaUpdate.execute(167) | fetching database metadata
  24. [hibernatetools] [Pilelot] INFO [main] org.hibernate.connection.DriverManagerConnectionProvider.configure(64) | Using Hibernate built-in connection pool (not for production use!)
  25. [hibernatetools] [Pilelot] INFO [main] org.hibernate.connection.DriverManagerConnectionProvider.configure(65) | Hibernate connection pool size: 20
  26. [hibernatetools] [Pilelot] INFO [main] org.hibernate.connection.DriverManagerConnectionProvider.configure(68) | autocommit mode: false
  27. [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
  28. [hibernatetools] [Pilelot] INFO [main] org.hibernate.connection.DriverManagerConnectionProvider.configure(109) | connection properties: {user=sa, password=****}
  29. [hibernatetools] [Pilelot] INFO [main] org.hibernate.tool.hbm2ddl.SchemaUpdate.execute(179) | updating schema
  30. [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
  31. [hibernatetools] [Pilelot] INFO [main] org.hibernate.tool.hbm2ddl.DatabaseMetadata.getTableMetadata(119) | table not found: course
  32. [hibernatetools] [Pilelot] INFO [main] org.hibernate.tool.hbm2ddl.DatabaseMetadata.getTableMetadata(119) | table not found: courseChoosing
  33. [hibernatetools] [Pilelot] INFO [main] org.hibernate.tool.hbm2ddl.DatabaseMetadata.getTableMetadata(119) | table not found: student
  34. [hibernatetools] [Pilelot] INFO [main] org.hibernate.tool.hbm2ddl.DatabaseMetadata.getTableMetadata(119) | table not found: course
  35. [hibernatetools] [Pilelot] INFO [main] org.hibernate.tool.hbm2ddl.DatabaseMetadata.getTableMetadata(119) | table not found: courseChoosing
  36. [hibernatetools] [Pilelot] INFO [main] org.hibernate.tool.hbm2ddl.DatabaseMetadata.getTableMetadata(119) | table not found: student
  37. [hibernatetools] create table course (id numeric(19,0) identity not null, name varchar(50) null, credit int null, totalClasses int null, primary key (id));
  38. [hibernatetools] create table courseChoosing (courseId numeric(19,0) not null, studentId numeric(19,0) not null, primary key (studentId, courseId));
  39. [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));
  40. [hibernatetools] alter table courseChoosing add constraint FK42CD624F924EFB30 foreign key (courseId) references course;
  41. [hibernatetools] alter table courseChoosing add constraint FK42CD624F417DBA12 foreign key (studentId) references student;
  42. [hibernatetools] [Pilelot] INFO [main] org.hibernate.tool.hbm2ddl.SchemaUpdate.execute(217) | schema update complete
  43. [hibernatetools] [Pilelot] INFO [main] org.hibernate.connection.DriverManagerConnectionProvider.close(170) | cleaning up connection pool: jdbc:sqlserver://192.168.1.4:1433;DatabaseName=test
  44. [hibernatetools] 2. task: hbm2java (Generates a set of .java files)
  45. BUILD SUCCESSFUL
  46. 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也是很不错的感觉。。。