以前大多數時間都是做.NET,對JAVA的開源框架這塊就簡單的了解了下,沒怎么認真的學習過,從今天開始我又將參與一個J2EE的項目,因公司的同事幾乎全是.NET,今天就和同事一起學習Hibernate這玩意,簡單記錄些筆記于此,以便以后方便查看,也給初學Hibernate的朋友一點參考.文章中我會將理論和實例結合.
一、初識Hibernate
Hibernate是........這個我就不多說了,網上到處都可以搜索到.
二、配置Hibernate開發環境
在開發Hibernate應用的時候需要預先把相應的JAR包配置到CLASS_PATH,我使用的是MyEclipse作為開發工具,主要的JAR大致如下:
---antlr.jar
---cglib.jar
---asm.jar
---asm-attrs.jar
---commons-collections.jar
---commons-logging.jar
---ehcache.jar
---hibernate3.jar
---jta.jar
---dom4j.jar
---log4j.jar
這些包從何來,它們都可以從Hibernate網站下載的Hibernate發布包里找到,在lib目錄下。
另外就是還需要一個連接數據庫的驅動,我使用的是Oracle數據庫。
三、開發Hibernate程序的步驟
開發Hibernate程序通常分為下面這幾步:
1、 建立JavaBean--> 每個JavaBean必須提供一個無參的構造函數,并為private屬性提供get/set訪問方法。如下:
1 package day.one;
2
3 public class Person {
4 private int id;
5 private String name;
6 private int age;
7 private String phone;
8
9 public int getAge() {
10 return age;
11 }
12
13 public void setAge(int age) {
14 this.age = age;
15 }
16
17 public int getId() {
18 return id;
19 }
20
21 public void setId(int id) {
22 this.id = id;
23 }
24
25 public String getName() {
26 return name;
27 }
28
29 public void setName(String name) {
30 this.name = name;
31 }
32
33 public String getPhone() {
34 return phone;
35 }
36
37 public void setPhone(String phone) {
38 this.phone = phone;
39 }
40
41 public Person() {
42 }
43
44 public Person(String name, int age, String phone) {
45 super();
46 this.name = name;
47 this.age = age;
48 this.phone = phone;
49 }
50 }
2、編寫映射文件(*.hbm.xml)-->這一步在Hibernate開發中最為重要,工作量是很大的。詳細配置格式可查看Hibernate包下的src/org/hibernate/hibernate-mapping-3.0.dtd,下面代碼塊便是上面Person的配置文件:
1 <?xml version="1.0"?>
2 <!DOCTYPE hibernate-mapping PUBLIC
3 "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
4 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
5
6 <hibernate-mapping package="day.one">
7 <class name="Person" table="t_Person">
8 <id name="id" column="id" unsaved-value="-1">
9 <!--主建生成策略 -->
10 <generator class="sequence">
11 <param name="sequence">Person_id_seq</param>
12 </generator>
13 </id>
14 <!--當屬性名與表的字段名相同時,可以確省column屬性配置-->
15 <property name="name" column="name" />
16 <property name="age" />
17 <property name="phone"/>
18 </class>
19 </hibernate-mapping>
3、創建數據表與主鍵生成的Sequence
上面Person這個JavaBean已經建立好了,并寫好了相應的配置文件,現在就需要把對應的數據庫表建立好,我使用的是Oracle數據庫,建表和建立主鍵生成的Sequence的命令如下:
1 --創建t_Person表
2 create table t_Person
3 (
4 id number(7) primary key,
5 name varchar2(30) not null,
6 age number(4) not null,
7 phone varchar2(20)
8 );
9
10 --創建t_Person的主鍵生成Sequence
11 create sequence person_id_seq;
12 select * from t_person;
4、編寫Hibernate配置文件(hibernate.cfg.xml)-->詳細配置格式可查看Hibernate包下的src/org/hibernate/hibernate-configuration-3.0.dtd文件,里面有詳細的描述。下邊是Hibernate的配置文件的簡單結構:
1 <hibernate-configuration>
2 <session-factory>
3 <property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
4 <!--詳細配置信息可查看Hibernate包下的etc/hibernate.properties -->
5 </session-factory>
6 <hibernate-configuration>
下面便是我配置的一個完整(相對完整,僅供參考)的Hibernate的配置文件,如下:

Hibernate配置文件
1
<?xml version="1.0"?>
2
<!DOCTYPE hibernate-configuration PUBLIC
3
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
4
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
5
6
<hibernate-configuration>
7
<session-factory>
8
<!--顯示SQL-->
9
<property name="show_sql">true</property>
10
<property name="format_sql">true</property>
11
<!-- SQL方言(ORACLE) -->
12
<property name="dialect">org.hibernate.dialect.Oracle9Dialect</property>
13
<!-- 數據庫連接配置 -->
14
<property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
15
<!--連接字符串 -->
16
<property name="connection.url">jdbc:oracle:thin:@localhost:1521:beniao</property>
17
<property name="connection.username">system</property>
18
<property name="connection.password">manager</property>
19
20
<!--配置連接池-->
21
<property name="c3p0.max_size">4</property>
22
<property name="c3p0.mix_size">2</property>
23
<property name="c3p0.timeout">5000</property>
24
<property name="c3p0.max_statements">100</property>
25
<property name="c3p0.idle_test_period">3000</property>
26
<property name="c3p0.acquire_increment">2</property>
27
<property name="c3p0.validate">false</property>
28
29
<property name="connection.pool_size">1</property>
30
<property name="current_session_context_class">thread</property>
31
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
32
<!-- property name="hbm2ddl.auto">create</property> -->
33
34
<mapping resource="day/one/Person.hbm.xml"/>
35
</session-factory>
36
</hibernate-configuration>
4、創建配置(Configuration)
Configuration cfg = new Configuration().configure();
5、 構建會話工廠(SessionFactory)
SessionFactory = cfg.buildSessionFactory();
6、打開會話(session)
Session session = sf.openSession();
7、啟動事務(Transaction)
Transaction ts = session.beginTransaction();
8、持久化操作(CUQD)
session.save(*); *表示一個對象
session.update(*);
session.delete(*);
..........................................
9、提交事務(commit)
ts.commit();
10、事務回滾(rollback)
ts.rollback();
四、第一個Hibernate程序

需要持久化的實體類
1 package day.one;
2
3 public class Person {
4 private int id;
5 private String name;
6 private int age;
7 private String phone;
8
9 public int getAge() {
10 return age;
11 }
12
13 public void setAge(int age) {
14 this.age = age;
15 }
16
17 public int getId() {
18 return id;
19 }
20
21 public void setId(int id) {
22 this.id = id;
23 }
24
25 public String getName() {
26 return name;
27 }
28
29 public void setName(String name) {
30 this.name = name;
31 }
32
33 public String getPhone() {
34 return phone;
35 }
36
37 public void setPhone(String phone) {
38 this.phone = phone;
39 }
40
41 public Person() {
42 }
43
44 public Person(String name, int age, String phone) {
45 super();
46 this.name = name;
47 this.age = age;
48 this.phone = phone;
49 }
50 }
51
52

Hibernate映射文件
1 <?xml version="1.0"?>
2 <!DOCTYPE hibernate-mapping PUBLIC
3 "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
4 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
5
6 <hibernate-mapping package="day.one">
7 <class name="Person" table="t_Person">
8 <id name="id" column="id" unsaved-value="-1">
9 <!--主建生成策略 -->
10 <generator class="sequence">
11 <param name="sequence">Person_id_seq</param>
12 </generator>
13 </id>
14 <!--當屬性名與表的字段名相同時,可以確省column屬性配置-->
15 <property name="name" column="name" />
16 <property name="age" />
17 <property name="phone"/>
18 </class>
19 </hibernate-mapping>

Hibernate配置文件
1 <?xml version="1.0"?>
2 <!DOCTYPE hibernate-configuration PUBLIC
3 "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
4 "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
5
6 <hibernate-configuration>
7 <session-factory>
8 <!--顯示SQL-->
9 <property name="show_sql">true</property>
10 <property name="format_sql">true</property>
11 <!-- SQL方言(ORACLE) -->
12 <property name="dialect">org.hibernate.dialect.Oracle9Dialect</property>
13 <!-- 數據庫連接配置 -->
14 <property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
15 <!--連接字符串 -->
16 <property name="connection.url">jdbc:oracle:thin:@localhost:1521:beniao</property>
17 <property name="connection.username">system</property>
18 <property name="connection.password">manager</property>
19
20 <!--配置連接池-->
21 <property name="c3p0.max_size">4</property>
22 <property name="c3p0.mix_size">2</property>
23 <property name="c3p0.timeout">5000</property>
24 <property name="c3p0.max_statements">100</property>
25 <property name="c3p0.idle_test_period">3000</property>
26 <property name="c3p0.acquire_increment">2</property>
27 <property name="c3p0.validate">false</property>
28
29 <property name="connection.pool_size">1</property>
30 <property name="current_session_context_class">thread</property>
31 <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
32 <!-- property name="hbm2ddl.auto">create</property> -->
33
34 <mapping resource="day/one/Person.hbm.xml"/>
35
36 </session-factory>
37 </hibernate-configuration>

操作客戶端
1 package day.one;
2
3 import org.hibernate.Session;
4 import org.hibernate.SessionFactory;
5 import org.hibernate.Transaction;
6 import org.hibernate.cfg.Configuration;
7
8 public class TestPerson {
9
10 public static void main(String[] args) {
11 //創建配置
12 Configuration cfg=new Configuration().configure();
13 //構建會話工廠
14 SessionFactory sessionFactory = cfg.buildSessionFactory();
15 //打開會話
16 Session session = sessionFactory.openSession();
17 //啟動事務
18 Transaction tx = session.beginTransaction();
19 //構建持久化對象
20 Person person = new Person("beniao",22,"158705555555");
21 //持久化操作
22 session.save(person);
23 //提交事務
24 tx.commit();
25 }
26 }
五、Hibernate映射過程分析
如上就完成了對一個簡單的對象的持久化操作,將構造好的Person對象通過Hibernate持久化操作到數據庫。OK,下面我們來簡單的分析下Hibernate做持久化的過程,他是怎么來完成映射的呢?
1 11:29:36,562 INFO HbmBinder:300 - Mapping class: day.one.Person -> t_Person
2 11:29:36,593 DEBUG HbmBinder:1270 - Mapped property: id -> id
3 11:29:36,609 DEBUG HbmBinder:1270 - Mapped property: name -> name
4 11:29:36,609 DEBUG HbmBinder:1270 - Mapped property: age -> age
5 11:29:36,609 DEBUG HbmBinder:1270 - Mapped property: phone -> phone
上面這幾行輸入信息是在運行的時候輸出的,詳細可以查看控制臺的輸出信息。我們可以看出,Hibernate他在中間做了些什么工作呢?
1、將day.one.Person這個類映射到了數據庫的t_Person表,而這正是我們在映射文件中通過table屬性來配置的,如下,將Person這個持久化類映射到數據庫的t_Person表:
1 <class name="Person" table="t_Person">
2、后面四行DEBUG輸出的內容我想就不用多說了,也就是把映射文件里配置的property影射到數據庫指定的字段:
1
<!--id特殊,不使用property,hibernate為id的映射提供了專用的標記"id"-->
2
<id name="id" column="id" unsaved-value="-1">
3
4
<!--當屬性名與表的字段名相同時,可以確省column屬性配置-->
5
<property name="name" column="name" />
6
<property name="age" />
7
<property name="phone"/>
8
9
六、Hibernate持久化原理分析
我們可以查看程序運行時輸入的DEBUG信息,下面是截取的一部分:
1 select: select id from t_Person where id =?
2 select: select person_.id, person_.name as name0_, person_.age as age0_, person_.phone as phone0_ from t_Person person_
where person_.id=?
3 Insert 0: insert into t_Person (name, age, phone, id) values (?, ?, ?, ?)
4 Update 0: update t_Person set name=?, age=?, phone=? where id=?
5 Delete 0: delete from t_Person where id=?
當Hibernate成功完成映射后,表會為我們的持久化對象生成如上的相關SQL語句,這一步就是為后面做持久化操作做準備。我們在映射配置文件里指定的id生成策略為Sequence,這時Hibernate 就會先到數據庫里去將指定的sequence查詢出來賦值給持久化對象的id屬性,然后在做其他的持久化操作。生成的查詢語句如下:
1 SQL:393 -
2 select
3 Person_id_seq.nextval
4 from
5 dual
6 Hibernate:
7 select
8 Person_id_seq.nextval
9 from
10 dual
最終做持久化操作的時候便會條用上面所生成的SQL語句,Hibernate的底層在去通過JDBC完成數據庫的相關操作。就本文前的實例程序,我們是將構造的Person對象持久化到數據庫,那么他調用的SQL就如下:
1
SQL:393 -
2
insert
3
into
4
t_Person
5
(name, age, phone, id)
6
values
7
(?, ?, ?, ?)
8
Hibernate:
9
insert
10
into
11
t_Person
12
(name, age, phone, id)
13
values
14
(?, ?, ?, ?)
OK,下面我們在來做一個查詢的操作,將剛剛通過session.save(person)到數據庫的這條記錄查詢出來,看看DEBUG出的SQL語句是什么樣的:
1 SQL:393 -
2 select
3 person0_.id as id0_0_,
4 person0_.name as name0_0_,
5 person0_.age as age0_0_,
6 person0_.phone as phone0_0_
7 from
8 t_Person person0_
9 where
10 person0_.id=?
11 Hibernate:
12 select
13 person0_.id as id0_0_,
14 person0_.name as name0_0_,
15 person0_.age as age0_0_,
16 person0_.phone as phone0_0_
17 from
18 t_Person person0_
19 where
20 person0_.id=?
現在就很容易看出了,無論是做什么樣的持久化操作,他都是圍繞著映射后所生成的SQL來處理的,其實這里的關鍵還是映射文件,映射文件配置好了,用Hibernate做持久化就不在是什么難事了。
本文就介紹于此,下一篇將介紹使用Hibernate來做一對一(OneToOne)的關系影射。
注:原創文章版權歸作者,歡迎轉載,未經作者同意必須注明文章出處或在頁面適當位置給出原文連接,謝謝!
文章出處:http://beniao.blogjava.net 作者:Beniao 時間:2008.08.14
我的.NET技術博客:http://beniao.cnblogs.com