关于用hibernate映射类时涉及到一个问题:
1.先创建数据表再写JOPO类和映射文件
2.先写POJO类,然后映射文件,最后数据库
3.先映射文件,再同时生成POJO类和数据库
第1种方法有背面向对象原理,而且控制起来不大方便,所以不推荐。第2种我认为思路会比较清楚,符合一般人思维习惯,但必须在POJO类里添加大量Xdoclet注释。第3种很方便,大家都推荐,但对于不习惯写映射文件的人有点小麻烦。但后两种都属于工具代人工生成数据表,因此需要精细控制数据表间关系的应该考虑在数据库生成后适当修改。(关于这个问题,仁者见仁,智者见智。大家有经验不妨说出来一起探讨下)
现结合自身实践对第2种做些介绍,有问题请名位大大指正。
假设工程为myeclipse web工程。现在POJO已经编好,并且Xdoclet注释都正确编写。如下示例类
package org.easyshop.domain; import java.util.HashSet; import java.util.Set; /** * * @hibernate.class * */ public class Category { private Long categoryId; private String categoryName; private String imageURL; private Set<Category> subCategory=new HashSet<Category>(); private Set<Item> items=new HashSet<Item>(); /** * @hibernate.id * column="categoryId" * unsaved-value="null" * generator-class="native" * */ public Long getCategoryId() { return categoryId; } public void setCategoryId(Long categoryId) { this.categoryId = categoryId; } /** * * @hibernate.property length="32" not-null="true" * */ public String getCategoryName() { return categoryName; } public void setCategoryName(String name) { this.categoryName = name; } /** * * @hibernate.property length="64" * */ public String getImageURL() { return imageURL; } public void setImageURL(String imageURL) { this.imageURL = imageURL; } /** * * @hibernate.set cascade="all" * @hibernate.key column="categoryId" * @hibernate.one-to-many class="org.easyshop.domain.Cagegory" * */ public Set<Category> getSubCategory() { return subCategory; } public void setSubCategory(Set<Category> sub) { this.subCategory = sub; } /** * * @hibernate.set table="category_item" cascade="save-update" lazy="true" * @hibernate.key column="categoryId" * @hibernate.many-to-many class="org.easyshop.domain.Item" column="itemId" * */ public Set<Item> getItems() { return items; } public void setItems(Set<Item> items) { this.items = items; } }
ps:这里有个问题,请教各位。hibernate的返身关联问题。如上的private Set<Category> subCategory=new HashSet<Category>();这样能像一对多那样进行映射否,小弟还没有进行试验,只是在<<hibernate高手秘极>>里看到过这么一个名词。
现在要让工具来自动生成hbm,和数据表,将如下ant build文件放在工程根目录。注意需要将工程用到的jar包放到WebRoot/WEB-INF/lib/目录下:(我这里方便为了防出错就将整个包全解压放在该目录下)hibernate 3,xdoclet,hibernate-tools.jar,slf4j(这东东不知是做什么用的,当时提示缺少它就直接放里边了)
<?xml version="1.0" encoding="gbk"?> <project name="newshop" default="schema" basedir="."> <property name="project.src" value="src"/> <property name="po.package" value="org/easyshop/domain"/> <property name="xdoclet.lib" value="WebRoot/WEB-INF/lib/xdoclet"/> <property name="project.lib" value="WebRoot/WEB-INF/lib"/> <property name="class.dir" value="WebRoot/WEB-INF/classes"/> <!--Xdoclet的类路径定义--> <path id="xdoclet.task.classpath"> <fileset dir="${xdoclet.lib}"> <include name="*.jar" /> </fileset> <pathelement location="${xdoclet.lib}/xdoclet-plugin-hibernate-1.0.4.jar" /> </path> <!--Hibernate及自定义类路径定义--> <path id="project.classpath"> <fileset dir="${project.lib}"> <include name="**/*.jar" /> </fileset> <pathelement path="${class.dir}"/><!--这里必须把自已定义的类路路径标志出来--> </path> <!--每次生成新映射文件前将旧的*.hbm.xml文件删除--> <target name="removehbm" > <delete> <fileset dir="${basedir}/src"> <include name="**/*.hbm.xml"/> </fileset> </delete> </target> <target name="removeclass" > <delete> <fileset dir="${basedir}/${class.dir}"> <include name="**/*.class"/> </fileset> </delete> </target> <!--编译源程序生成的类文件放在class目录中,后面的从映射文件生成数据库文件将用到他们--> <target name="compile" depends="removeclass"> <javac srcdir="${project.src}" destdir="${class.dir}" debug="on" optimize="off" deprecation="on"> <classpath refid="project.classpath"/> </javac> </target> <!--定义两个任务 1:POJO->映射文件 2:映射文件->数据库--> <taskdef name="xdoclet" classname="org.xdoclet.ant.XDocletTask" classpathref="xdoclet.task.classpath" /> <taskdef name="schemaexport" classname="org.hibernate.tool.ant.HibernateToolTask" classpathref="project.classpath" /><!--注意这里用到的工具并不是Hibernate里的Hbm2ddl而是hibernate-tool里的--> <!--POJO->映射文件--> <target name="hibernate.mapping.generate" depends="removehbm,compile"> <xdoclet> <fileset dir="${project.src}"> <include name="${po.package}/*.java" /> </fileset> <component classname="org.xdoclet.plugin.hibernate.HibernateMappingPlugin" destdir="${basedir}/${project.src}" version="3.0" /> </xdoclet> </target> <!-- 映射文件->数据库 --> <target name = "schema" depends="hibernate.mapping.generate"> <schemaexport destdir = "${project.src}"> <configuration configurationfile = "${project.src}/hibernate.cfg.xml" /> <hbm2ddl export="true" console="true" create="true" update="true" drop="false" outputfilename="order.sql" /> </schemaexport> </target> </project>
上面的ant编译流程是:先删除POJO .class文件和映射hbm文件,再重新编译POJO和生成hbm文件,再由xdoclet工具生成对应hbm映射文件,最后由hibernate-tools工具的Hbm2ddl类生成数据表。