日韩久久久精品,亚洲精品久久久久久久久久久,亚洲欧美一区二区三区国产精品 ,一区二区福利

hibernate3.2由hbm文件生成pojo和ddl以及相關(guān)問

系統(tǒng) 2197 0

利用hibernateTools里的相關(guān)工具類,使得java實體類(POJO)、hbm映射文件、數(shù)據(jù)庫表(Schema)之間可以相互轉(zhuǎn)化。也就是說,只要有其中一樣,就可以通過各種途徑得到其它兩樣。

如果手里已經(jīng)有了其中一樣?xùn)|西,要想最快建立起應(yīng)用的途徑自然是通過它來生成其它兩樣了。不過,我想在這里討論的是那種從無到有,從想法到實現(xiàn)的那種建立全新應(yīng)用的情況。那么,自然而然就會有一個問題:“從哪里開始?”。實體類?hbm?數(shù)據(jù)庫表?先應(yīng)該建立哪一個,再通過它生成其它兩個?

這個問題我覺得應(yīng)該從Hibernate框架的產(chǎn)生的初忠來考慮:為了解決“面向?qū)ο竽P汀迸c“關(guān)系模型”之間的“阻抗不匹配”。簡而言之,就是說在我們的類圖和E-R關(guān)系圖中各元素的對應(yīng)關(guān)系很難把握,而且容易讓人產(chǎn)生概念的混淆,如“每一個數(shù)據(jù)庫表對應(yīng)一個實體類”等錯誤想法,很容易讓人在設(shè)計實體時不知不覺扔掉很多面向?qū)ο竽P偷膬?yōu)秀思想。其實并不能說哪一個模型是錯,只是因為他們描述問題的方向不同。那么,Hibernate框架就是把這兩個模型“映射”了起來,讓程序員可以在面向?qū)ο蟮氖澜缋锿瓿蓪?shù)據(jù)庫的查詢,而不必關(guān)心底層的數(shù)據(jù)庫表的結(jié)構(gòu)。

說了那么多,直接了當(dāng)?shù)刂v,我不贊成“先建立數(shù)據(jù)表,再通過這個數(shù)據(jù)表生成POJO和hbm文件”這種方案。道理很簡單:如果先就去考慮數(shù)據(jù)庫,那么我們隨后的設(shè)計勢必會受到這個數(shù)據(jù)庫的影響,不利于精確地描述我們的應(yīng)用,Hibernate框架的好處也就體現(xiàn)不出來了(先就把數(shù)據(jù)庫搞定了還要Hibernate來干什么),生成的POJO不用說——內(nèi)容多半很別扭——因為你企圖從一個非面向?qū)ο蟮目蚩蚶镉渤橄蟪雒嫦驅(qū)ο竽P蛠恚ㄒ苍S你會認為這是可以通過經(jīng)驗來避免的,是的,確實是,不過你不覺得這樣一來工作復(fù)雜化了嗎?要考慮的東西增多了)。

面向?qū)ο竽P褪怯脕砭_而自然地描述問題的,這是我的看法,它提供了包含、繼承等等機制,幾乎能把這個世界上的所有事物之間的關(guān)系精確地描述出來——它好比一門語言——怎么方便你就怎么說。那么,先數(shù)據(jù)庫再POJO的做法就好比是先規(guī)定了你只能用哪些詞語之后讓你說話,而先POJO再數(shù)據(jù)庫就好比是讓你隨便說隨便發(fā)揮了,自然后者要好得多。

從軟件工程的角度講,需求——用例——實體這樣一趟走下來,POJO出現(xiàn)在數(shù)據(jù)庫前面是很自然的,在OOA階段就考慮數(shù)據(jù)庫是很不可取的做法(絕對一點講——是錯誤的)。

OK,剩下的POJO和hbm文件之間應(yīng)該先生成哪個呢?我覺得先生成誰都無所謂,都不會對我們的工程產(chǎn)生不利影響了。

hbm文件作為POJO和數(shù)據(jù)庫之間的橋梁,從它入手的話會有一舉兩得的感覺,全是干凈的XML文件。當(dāng)然,貌似利用xDoclet標簽在我們寫POJO代碼的時候自動生成hbm也是很不錯的感覺,這個下次再討論吧,現(xiàn)在給出一個完整可用而且最簡單的hbm生成POJO和Schema的示例:

準備:

下載ant工具,我用的是apache-ant-1.7.0,當(dāng)然,你要會用ant,怎么使用請參考別處,這里不介紹了。

下載hibernate-3.2.1.ga.zip,以及HibernateTools-3.2.0.beta9a.zip,這兩個壓縮包在hibernate官網(wǎng)上有: http://www.hibernate.org/6.html

數(shù)據(jù)庫的jdbc驅(qū)動程序,本例使用mysql,驅(qū)動程序為mysql-connector-java-5.0.4。

布置實驗場所:

建立“test”文件夾(其實叫什么都無所謂),再在test文件夾下建立4個文件夾:config、java、schema、lib。

解壓hibernate-3.2.1.ga.zip,把里面的hibernate-3.2文件夾放在你建立的lib文件夾里面。

解壓HibernateTools-3.2.0.beta9a.zip,找出hibernate-tools.jar,位置在:

\HibernateTools-3.2.0.beta9a\plugins\org.hibernate.eclipse_3.2.0.beta9a\lib\tools;

在與hibernate-tools.jar同樣的位置下找出freemarker.jar;

把hibernate-tools.jar和freemarker.jar都放入你建立的lib文件夾里。

最后把數(shù)據(jù)庫驅(qū)動程序:mysql-connector-java-5.0.4-bin.jar也放進lib文件夾里,

這樣,所需要的類資源都準備好了。

進入config文件夾,首先寫hibernate config文件,文件名: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">root</property>
??<property name="connection.password">XXXXXXXXXX</property><!--Your DB password here.-->
??<property name="connection.url">jdbc:mysql://localhost:3306/courseChoosing</property>
??<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
??<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
??<mapping resource="Student.hbm.xml" />
??<mapping resource="Course.hbm.xml" />
?</session-factory>
</hibernate-configuration>

以上代碼不用過多解釋,就是hibernate的配置文件,其中有連接數(shù)據(jù)庫的重要信息。只是connection.password屬性注意修改成你自己的密碼就行了。那兩個mapping元素是本例要創(chuàng)建的兩個hbm文件,待會兒我們再實際地創(chuàng)建它,現(xiàn)在不用管。

好了,hibernate配置文件寫好了之后,我們現(xiàn)在該討論一下我們將要進行的這個例子的與“業(yè)務(wù)”相關(guān)的話題了:

很簡單——我就拿“學(xué)生選課”這件事來做這個例子,具體描述是這樣的:“一門課可以被多個學(xué)生選,一個學(xué)生也可以選擇多門課。”很顯然,這是一個多對多關(guān)系。畫出實體類圖應(yīng)該是這樣的(PowerDesigner12):

hibernate3.2由hbm文件生成pojo和ddl以及相關(guān)問題的一點討論

?

也就是說,在“學(xué)生”這個類中會有一個set,保存了這個學(xué)生所選的所有的課;同時,在“課程”這個類中也會有一個set,保存了所有要上這門課的學(xué)生。

弄清楚了類圖之后,讓我們用hbm文件來分別描述這兩個類:

還是在config文件夾下,建立Course.hbm.xml和Student.hbm.xml,

Course.hbm.xml的內(nèi)容如下:

<?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>

Student.hbm.xml的內(nèi)容如下:

<?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>

這兩個文件是純粹的hbm文件描述實體類的方式,看上去很簡潔,層次很清晰。需要仔細看明白的是其中的那個set元素:

name屬性是這個set的名字,也就是最后生成的java代碼中的這個set的名字;table屬性是這個set對應(yīng)的數(shù)據(jù)庫表的名字,由于這個是多對多關(guān)系,所以需要另外建立一個表來存儲學(xué)生和課程之間的選擇關(guān)系,不過這種細節(jié)不用管,hibernatetools會做好一切。最重要的是那個inverse屬性,它決定了多對多關(guān)系的兩邊到底由誰來管理雙方的關(guān)系數(shù)據(jù)。inverse設(shè)為“true”的一方將不負責(zé)維護雙方的關(guān)系數(shù)據(jù),本例中考慮實際情況,決定讓“學(xué)生”類來維護這個選課關(guān)系(因為從來只有學(xué)生選課或退出選課,而沒有課選學(xué)生或課踢除學(xué)生的情況),于是將Course類里的set的inverse屬性設(shè)為“true”,Student里的inverse為“false”。順便提一句,如果不指明inverse屬性,那么默認為false。many-to-many元素說明了他們之間的關(guān)系,class屬性指明了當(dāng)前set中對象的類型,column屬性指明了關(guān)系表(courseChoosing)中的外碼名。

到此為止,與業(yè)務(wù)相關(guān)的東西已經(jīng)描述完畢,剩下的就是編寫ant腳本來實際生成ddl和java文件了。

在test文件夾下,建立build.xml文件,其內(nèi)容如下:

<?xml version="1.0"?>
<project name = "test" default = "hbm2java">
?<property name = "configuration-files.dir" value = "config" />
?<property name = "java.code.dir" value = "java" />
?<property name = "schema.dir" value = "schema" />
?<property name = "lib.dir" value = "lib" />
?<property name = "hibernate3.dir" value = "${lib.dir}/hibernate-3.2" />

?<path id = "hibernate3.path">
??<pathelement location = "${hibernate3.dir}/hibernate3.jar" />
??<fileset dir = "${hibernate3.dir}">
???<include name = "**/*.jar" />
??</fileset>
?</path>
?<path id = "mysql.jdbc.driver.path">
??<pathelement location = "${lib.dir}/mysql-connector-java-5.0.4-bin.jar" />
?</path>
?<path id = "hibernate-tools.path">
??<pathelement location = "${lib.dir}/hibernate-tools.jar" />
?</path>
?<path id = "freemarker.path">
??<pathelement location = "${lib.dir}/freemarker.jar" />
?</path>
?<path id = "all-in-one.path">
??<path refid = "hibernate3.path" />
??<path refid = "mysql.jdbc.driver.path" />
??<path refid = "hibernate-tools.path" />
??<path refid = "freemarker.path" />
??<pathelement location = "${configuration-files.dir}" />
?</path>

?<target name = "hbm2java">
??<taskdef name = "hbm2java" classname = "org.hibernate.tool.ant.HibernateToolTask" classpathref = "all-in-one.path" />
??<hbm2java destdir = "${java.code.dir}">
???<configuration configurationfile = "${configuration-files.dir}/hibernate.cfg.xml" />
???<hbm2java jdk5 = "true" />
??</hbm2java>
?</target>
?<target name = "hbm2ddl">
??<taskdef name = "hbm2ddl" classname = "org.hibernate.tool.ant.HibernateToolTask" classpathref = "all-in-one.path" />
??<hbm2ddl destdir = "${schema.dir}">
???<configuration configurationfile = "${configuration-files.dir}/hibernate.cfg.xml" />
???<hbm2ddl export="true" console="false" create="true" update="false" drop="false" outputfilename="courseChoosing.sql" />
??</hbm2ddl>
?</target>

</project>

很平常的ant腳本,需要注意的是那兩個特殊的任務(wù):hbm2java和hbm2ddl,這兩個任務(wù)是hibernatetools里帶的,需要定義出來,就不多說了。

好了,安裝好ant之后就可以運行這個腳本了,生成java文件:

?

hibernate3.2由hbm文件生成pojo和ddl以及相關(guān)問題的一點討論

?

生成數(shù)據(jù)庫表:

hibernate3.2由hbm文件生成pojo和ddl以及相關(guān)問題的一點討論

?

大功告成了,欣賞一下結(jié)果:

在java文件夾中生成的java文件代碼:

Course.java文件:

package courseChoosing;
// Generated 2007-3-7 15:38:42 by Hibernate Tools 3.2.0.b9


import java.util.HashSet;
import java.util.Set;

/**
?* Course generated by hbm2java
?*/
public class Course? implements java.io.Serializable {


???? private long id;
???? private String name;
???? private Integer credit;
???? private Integer totalClasses;
???? private Set<Student> students = new HashSet<Student>(0);

??? public Course() {
??? }

??? public Course(String name, Integer credit, Integer totalClasses, Set<Student> students) {
?????? this.name = name;
?????? this.credit = credit;
?????? this.totalClasses = totalClasses;
?????? this.students = students;
??? }
??
??? public long getId() {
??????? return this.id;
??? }
???
??? public void setId(long id) {
??????? this.id = id;
??? }
??? public String getName() {
??????? return this.name;
??? }
???
??? public void setName(String name) {
??????? this.name = name;
??? }
??? public Integer getCredit() {
??????? return this.credit;
??? }
???
??? public void setCredit(Integer credit) {
??????? this.credit = credit;
??? }
??? public Integer getTotalClasses() {
??????? return this.totalClasses;
??? }
???
??? public void setTotalClasses(Integer totalClasses) {
??????? this.totalClasses = totalClasses;
??? }
??? public Set<Student> getStudents() {
??????? return this.students;
??? }
???
??? public void setStudents(Set<Student> students) {
??????? this.students = students;
??? }

?


}

Student.java文件中的內(nèi)容:

package courseChoosing;
// Generated 2007-3-7 15:38:42 by Hibernate Tools 3.2.0.b9


import java.util.HashSet;
import java.util.Set;

/**
?* Student generated by hbm2java
?*/
public class Student? implements java.io.Serializable {


???? private long id;
???? private String stuNo;
???? private String name;
???? private Character gender;
???? private Set<Course> courses = new HashSet<Course>(0);

??? public Student() {
??? }

??? public Student(String stuNo, String name, Character gender, Set<Course> courses) {
?????? this.stuNo = stuNo;
?????? this.name = name;
?????? this.gender = gender;
?????? this.courses = courses;
??? }
??
??? public long getId() {
??????? return this.id;
??? }
???
??? public void setId(long id) {
??????? this.id = id;
??? }
??? public String getStuNo() {
??????? return this.stuNo;
??? }
???
??? public void setStuNo(String stuNo) {
??????? this.stuNo = stuNo;
??? }
??? public String getName() {
??????? return this.name;
??? }
???
??? public void setName(String name) {
??????? this.name = name;
??? }
??? public Character getGender() {
??????? return this.gender;
??? }
???
??? public void setGender(Character gender) {
??????? this.gender = gender;
??? }
??? public Set<Course> getCourses() {
??????? return this.courses;
??? }
???
??? public void setCourses(Set<Course> courses) {
??????? this.courses = courses;
??? }

?


}

?

schema文件夾中生成的courseChoosing.sql文件內(nèi)容:

create table course (id bigint not null auto_increment, name varchar(50), credit integer, totalClasses integer, primary key (id));
create table courseChoosing (studentId bigint not null, courseId bigint not null, primary key (studentId, courseId));
create table student (id bigint not null auto_increment, stuNo varchar(10), name varchar(20), gender char(1), primary key (id));
alter table courseChoosing add index FK42CD624F924EFB30 (courseId), add constraint FK42CD624F924EFB30 foreign key (courseId) references course (id);
alter table courseChoosing add index FK42CD624F417DBA12 (studentId), add constraint FK42CD624F417DBA12 foreign key (studentId) references student (id);

生成的數(shù)據(jù)庫表(MySQL Administrator):

hibernate3.2由hbm文件生成pojo和ddl以及相關(guān)問題的一點討論

hibernate3.2由hbm文件生成pojo和ddl以及相關(guān)問題的一點討論


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 黎川县| 廉江市| 建瓯市| 神木县| 姚安县| 西乡县| 理塘县| 扎兰屯市| 威海市| 同仁县| 峨眉山市| 拉萨市| 岳西县| 财经| 辉县市| 正镶白旗| 韶山市| 城市| 鞍山市| 贺州市| 张家口市| 孟州市| 永昌县| 赞皇县| 佳木斯市| 莒南县| 繁峙县| 承德市| 镶黄旗| 巴林右旗| 望都县| 西乌珠穆沁旗| 宝兴县| 崇阳县| 枝江市| 宜州市| 德惠市| 康马县| 广水市| 武功县| 休宁县|