黄色网页视频 I 影音先锋日日狠狠久久 I 秋霞午夜毛片 I 秋霞一二三区 I 国产成人片无码视频 I 国产 精品 自在自线 I av免费观看网站 I 日本精品久久久久中文字幕5 I 91看视频 I 看全色黄大色黄女片18 I 精品不卡一区 I 亚洲最新精品 I 欧美 激情 在线 I 人妻少妇精品久久 I 国产99视频精品免费专区 I 欧美影院 I 欧美精品在欧美一区二区少妇 I av大片网站 I 国产精品黄色片 I 888久久 I 狠狠干最新 I 看看黄色一级片 I 黄色精品久久 I 三级av在线 I 69色综合 I 国产日韩欧美91 I 亚洲精品偷拍 I 激情小说亚洲图片 I 久久国产视频精品 I 国产综合精品一区二区三区 I 色婷婷国产 I 最新成人av在线 I 国产私拍精品 I 日韩成人影音 I 日日夜夜天天综合

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

系統(tǒng) 2364 0

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

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

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

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

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

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

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

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

準(zhǔn)備:

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

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

數(shù)據(jù)庫的jdbc驅(qū)動(dòng)程序,本例使用mysql,驅(qū)動(dòng)程序?yàn)閙ysql-connector-java-5.0.4。

布置實(shí)驗(yàn)場(chǎng)所:

建立“test”文件夾(其實(shí)叫什么都無所謂),再在test文件夾下建立4個(gè)文件夾: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ū)動(dòng)程序:mysql-connector-java-5.0.4-bin.jar也放進(jìn)lib文件夾里,

這樣,所需要的類資源都準(zhǔn)備好了。

進(jìn)入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屬性注意修改成你自己的密碼就行了。那兩個(gè)mapping元素是本例要?jiǎng)?chuàng)建的兩個(gè)hbm文件,待會(huì)兒我們?cè)賹?shí)際地創(chuàng)建它,現(xiàn)在不用管。

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

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

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

?

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

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

還是在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>

這兩個(gè)文件是純粹的hbm文件描述實(shí)體類的方式,看上去很簡(jiǎn)潔,層次很清晰。需要仔細(xì)看明白的是其中的那個(gè)set元素:

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

到此為止,與業(yè)務(wù)相關(guān)的東西已經(jīng)描述完畢,剩下的就是編寫ant腳本來實(shí)際生成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腳本,需要注意的是那兩個(gè)特殊的任務(wù):hbm2java和hbm2ddl,這兩個(gè)任務(wù)是hibernatetools里帶的,需要定義出來,就不多說了。

好了,安裝好ant之后就可以運(yùn)行這個(gè)腳本了,生成java文件:

?

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

?

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

hibernate3.2由hbm文件生成pojo和ddl以及相關(guān)問題的一點(diǎ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)問題的一點(diǎn)討論

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


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

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

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

【本文對(duì)您有幫助就好】

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

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論