Atea - Hero's Grave

          面向對象,開源,框架,敏捷,云計算,NoSQL,商業智能,編程思想。

            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
            40 隨筆 :: 0 文章 :: 28 評論 :: 0 Trackbacks
          XDoclet是一款開源的代碼自動生成引擎,支持很多框架的代碼自動生成。
          而XDoclet2作為Maven2的插件,支持Hibernate3的pojo->xml的代碼自動生成。配合ant與Hibernate Tool API,可以實現pojo<->xml<->db schema的相互轉化。具體關系為:
           生成處理  實用工具
           pojo->xml  XDoclet2
           xml->pojo
           Hibernate Tool API
           pojo+xml -> db schema  Hibernate Tool API
           db schema -> pojo+xml
           可用myeclipse,本文不涉及

          下面通過ANT腳本例子,來展示如何完成以上的轉換。
           1 <?xml version="1.0" encoding="utf-8"?>
           2 <project name="xdoclet_example">
           3 
           4     <!--xdoclet的jar包所在目錄-->
           5     <property name="xdoclet.plugin.install.dir" value="./lib/xdoclet" />
           6     <!--待處理項目的src目錄-->
           7     <property name="src.dir" value="./src" />
           8     <!--待處理項目的根目錄-->
           9     <property name="prj.dir" value="./" />
          10 
          11     <!--include進來xdoclet所有jar包-->
          12     <path id="xdoclet.task.classpath" description="xdoclet的所有jar">
          13         <fileset dir="${xdoclet.plugin.install.dir}">
          14             <include name="**/*.jar" />
          15         </fileset>
          16     </path>
          17     <!--include進來待處理項目的所有jar包,意在使用hibernate相關的jar包-->
          18     <path id="prj.jar" description="項目目錄下的所有jar">
          19         <fileset dir="${prj.dir}">
          20             <include name="**/*.jar" />
          21         </fileset>
          22     </path>
          23     <!--
          24         繼承上2個目錄,同時需要把pojo編譯好的class文件包含進來。
          25         這里定義需要留意,很容易掉入到ant的bug陷阱里去。
          26         詳細可參照http://www.aygfsteel.com/boluobn/articles/136197.html
          27     -->
          28     <path id="runtime.path" description="SchemaExport用的jar和class文件">
          29         <path refid="xdoclet.task.classpath" />
          30         <path refid="prj.jar" />
          31         <pathelement location="${prj.dir}/build/classes" />
          32     </path>
          33 
          34     <!--
          35         xdoclet只在判斷未存在hbm.xml的情況下才會生成,已存在的話則不會自動覆蓋。
          36         所以定義一個清空已存在的hbm.xml文件任務。
          37     -->
          38     <target name="clean" description="清空已有的hbm.xml">
          39         <echo message="清空已有的hbm.xml" />
          40         <delete dir="src">
          41             <include name="**/po/*.hbm.xml" />
          42         </delete>
          43     </target>
          44 
          45     <!--根據pojo生成hbm.xml,注意一下pojo的路徑即可-->
          46     <target name="xdoclet2hbm" description="根據pojo生成hbm.xml" depends="clean">
          47         <echo message="根據pojo生成hbm.xml" />
          48         <taskdef name="xdoclet" classname="org.xdoclet.ant.XDocletTask" classpathref="xdoclet.task.classpath" />
          49         <xdoclet encoding="utf-8">
          50             <fileset dir="${src.dir}">
          51                 <include name="**/po/*.java" />
          52             </fileset>
          53             <component classname="org.xdoclet.plugin.hibernate.HibernateMappingPlugin" destdir="${basedir}/${src.dir}" version="3.0" />
          54         </xdoclet>
          55     </target>
          56 
          57     <!--根據hibernate.cfg.xml文件生成pojo-->
          58     <target name="hbm2java" description="根據hbm.xml文件生成pojo">
          59         <echo message="根據hbm.xml文件生成pojo" />
          60         <taskdef name="hbm2java" classname="org.hibernate.tool.ant.HibernateToolTask" classpathref="runtime.path" />
          61         <hbm2java destdir="${src.dir}">
          62             <configuration configurationfile="${src.dir}/hibernate.cfg.xml" />
          63             <hbm2java />
          64         </hbm2java>
          65     </target>
          66 
          67     <!--
          68         生成數據庫環境的任務。
          69         這個可能并不常用,使用org.hibernate.tool.hbm2ddl.SchemaExport編寫一個JUnit test可以更方便的連搭環境帶造數據。
          70     -->
          71     <target name="SchemaExport" description="根據hibernate.cfg.xml生成數據庫環境">
          72         <echo message="根據hibernate.cfg.xml生成數據庫環境" />
          73         <taskdef name="schemaexport" classname="org.hibernate.tool.hbm2ddl.SchemaExportTask" classpathref="runtime.path" />
          74         <schemaexport config="${src.dir}/hibernate.cfg.xml" quiet="false" text="false" drop="false" delimiter=";" output="schema-export.sql" />
          75     </target>
          76 
          77 </project>
          腳本很詳細,看注釋即可。

          在使用xdoclet2hbm前,需要在pojo上設定javadoc注釋,以告訴xdoclet如何進行解析。
          one2one & one2many的例子:
          Child.java
           1 package po;
           2 
           3 /**
           4  * @hibernate.class table="child"
           5  */
           6 @SuppressWarnings("serial")
           7 public class Child implements java.io.Serializable {
           8 
           9     //xdoclet注釋有寫在getter上與寫在field上2種方法。
          10     //寫在field上會自動生成access="field",所以寫在getter上更常用一些。
          11 
          12     private String id;
          13     private String name;
          14     private Father father;
          15 
          16     /**
          17      * @hibernate.id generator-class="uuid.hex" column="id" length="32"
          18      */
          19     public String getId() {
          20         return this.id;
          21     }
          22 
          23     public void setId(String id) {
          24         this.id = id;
          25     }
          26 
          27     //基本支持所有的hibernate 屬性,所以想要啥設置就大膽的寫吧
          28     /**
          29      * @hibernate.property column="name" length="32" not-null="true" type="java.lang.String" lazy="true"
          30      */
          31     public String getName() {
          32         return this.name;
          33     }
          34 
          35     public void setName(String name) {
          36         this.name = name;
          37     }
          38 
          39     /**
          40      * @hibernate.many-to-one column="father_id" not-null="true"
          41      */
          42     public Father getFather() {
          43         return this.father;
          44     }
          45 
          46     public void setFather(Father father) {
          47         this.father = father;
          48     }
          49 
          50 }

          Father.java
           1 package po;
           2 
           3 import java.util.HashSet;
           4 import java.util.Set;
           5 
           6 /**
           7  * @hibernate.class table="father"
           8  */
           9 @SuppressWarnings("serial")
          10 public class Father implements java.io.Serializable {
          11 
          12     private String id;
          13 
          14     private String name;
          15 
          16     private Integer age;
          17 
          18     private Set<Child> children = new HashSet<Child>(0);
          19 
          20     /**
          21      * @hibernate.id generator-class="uuid.hex" column="id" length="32"
          22      */
          23     public String getId() {
          24         return this.id;
          25     }
          26 
          27     public void setId(String id) {
          28         this.id = id;
          29     }
          30 
          31     /**
          32      * @hibernate.property column="name" length="32" not-null="true" type="java.lang.String"
          33      */
          34     public String getName() {
          35         return this.name;
          36     }
          37 
          38     public void setName(String name) {
          39         this.name = name;
          40     }
          41 
          42     /**
          43      * @hibernate.property column="age" length="32" type="java.lang.Integer"
          44      */
          45     public Integer getAge() {
          46         return age;
          47     }
          48 
          49     public void setAge(Integer age) {
          50         this.age = age;
          51     }
          52 
          53     /**
          54      * @hibernate.set table="child"
          55      * @hibernate.key column="father_id"
          56      * @hibernate.one-to-many class="po.Child"
          57      */
          58     public Set<Child> getChildren() {
          59         return children;
          60     }
          61 
          62     public void setChildren(Set<Child> children) {
          63         this.children = children;
          64     }
          65 }

          many2many的例子:
          Student.java
           1 package po;
           2 
           3 import java.util.HashSet;
           4 import java.util.Set;
           5 
           6 /**
           7  * @hibernate.class table="student"
           8  */
           9 @SuppressWarnings("serial")
          10 public class Student implements java.io.Serializable {
          11 
          12     private String id;
          13     private String name;
          14     private Set<Teacher> teachers = new HashSet<Teacher>(0);
          15 
          16     /**
          17      * @hibernate.id generator-class="uuid.hex" column="id" length="32"
          18      */
          19     public String getId() {
          20         return this.id;
          21     }
          22 
          23     public void setId(String id) {
          24         this.id = id;
          25     }
          26 
          27     /**
          28      * @hibernate.property column="name" length="32" not-null="true" type="java.lang.String"
          29      */
          30     public String getName() {
          31         return this.name;
          32     }
          33 
          34     public void setName(String name) {
          35         this.name = name;
          36     }
          37 
          38     /**
          39      * @hibernate.set table="student_teacher_relation"
          40      * @hibernate.key column="student_id"
          41      * @hibernate.many-to-many class="po.Teacher" column="teacher_id"
          42      */
          43     public Set<Teacher> getTeachers() {
          44         return teachers;
          45     }
          46 
          47     public void setTeachers(Set<Teacher> teachers) {
          48         this.teachers = teachers;
          49     }
          50 }

          Teacher.java
           1 package po;
           2 
           3 import java.util.HashSet;
           4 import java.util.Set;
           5 
           6 /**
           7  * @hibernate.class table="teacher"
           8  */
           9 @SuppressWarnings("serial")
          10 public class Teacher implements java.io.Serializable {
          11 
          12     private String id;
          13     private String name;
          14     private Set<Student> students = new HashSet<Student>(0);
          15 
          16     /**
          17      * @hibernate.id generator-class="uuid.hex" column="id" length="32"
          18      */
          19     public String getId() {
          20         return this.id;
          21     }
          22 
          23     public void setId(String id) {
          24         this.id = id;
          25     }
          26 
          27     /**
          28      * @hibernate.property column="name" length="32" not-null="true" type="java.lang.String"
          29      */
          30     public String getName() {
          31         return this.name;
          32     }
          33 
          34     public void setName(String name) {
          35         this.name = name;
          36     }
          37 
          38     /**
          39      * @hibernate.set table="student_teacher_relation"
          40      * @hibernate.key column="teacher_id"
          41      * @hibernate.many-to-many class="po.Student" column="student_id"
          42      */
          43     public Set<Student> getStudents() {
          44         return students;
          45     }
          46 
          47     public void setStudents(Set<Student> students) {
          48         this.students = students;
          49     }
          50 
          51 }

          總結:
          1.本文沒有涉及hibernate annnotation模式,需要者請自行查閱相關資料。
          2.XDoclet2沒有XDoclet1代好找,推薦一個網址 Jar Search Engine
          3.本文未能涉及在開發中,程序運轉時遇到DB schema結構變化而進行的動態自動轉換技術。如有高人知曉,請不吝賜教。
          posted on 2009-08-01 22:35 Atea 閱讀(1115) 評論(2)  編輯  收藏 所屬分類: HibernateAnt

          評論

          # re: 使用XDoclet2+Ant實現Hibernate3的pojo-xml-db代碼相互轉換[未登錄] 2010-08-11 23:38 lixl
          請問 pojo轉換.hbm.xml 的腳本如何執行呢?請指教 詳解  回復  更多評論
            

          # re: 使用XDoclet2+Ant實現Hibernate3的pojo-xml-db代碼相互轉換[未登錄] 2010-08-17 20:27 Atea
          @lixl
          1、注意一下pojo的路徑
          把這句話改成你自己的:
          <include name="**/po/*.java" />
          2、在po里寫javadoc
          3、執行ant xdoclet2hbm

          PS:
          一年之后,反觀xml配置方式已不如annotation來得方便
          只在一些有特殊要求的項目中用

            回復  更多評論
            

          主站蜘蛛池模板: 沿河| 余姚市| 潞城市| 新宾| 崇左市| 武隆县| 宁化县| 屯昌县| 镇安县| 剑河县| 彝良县| 韩城市| 六盘水市| 岑巩县| 宝鸡市| 江安县| 唐河县| 建湖县| 垣曲县| 沐川县| 锡林浩特市| 鄂托克前旗| 保德县| 兴业县| 军事| 武宁县| 三原县| 翁牛特旗| 梅州市| 离岛区| 瑞金市| 商丘市| 双柏县| 呼图壁县| 延吉市| 垫江县| 信丰县| 阳江市| 通化市| 嘉荫县| 馆陶县|