以前大多数时间都是做.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配置文件
Hibernate配置文件
 1 <?xml version="1.0"?>
<?xml version="1.0"?>
 2 <!DOCTYPE hibernate-configuration PUBLIC
<!DOCTYPE hibernate-configuration PUBLIC 
 3 "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
 4 "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
    "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
 5 
    
 6 <hibernate-configuration>
    <hibernate-configuration>
 7 <session-factory>
       <session-factory>
 8 <!--显示SQL-->
                    <!--显示SQL-->
 9 <property name="show_sql">true</property>
          <property name="show_sql">true</property>
10 <property name="format_sql">true</property>
          <property name="format_sql">true</property>
11 <!-- SQL方言(ORACLE) -->
          <!-- SQL方言(ORACLE) -->
12 <property name="dialect">org.hibernate.dialect.Oracle9Dialect</property>
          <property name="dialect">org.hibernate.dialect.Oracle9Dialect</property>
13 <!-- 数据库连接配置 -->
                    <!-- 数据库连接配置 -->
14 <property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
          <property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
15 <!--连接字符串  -->
                    <!--连接字符串  -->
16 <property name="connection.url">jdbc:oracle:thin:@localhost:1521:beniao</property>
          <property name="connection.url">jdbc:oracle:thin:@localhost:1521:beniao</property>
17 <property name="connection.username">system</property>
          <property name="connection.username">system</property>
18 <property name="connection.password">manager</property>
          <property name="connection.password">manager</property>
19 
          
20 <!--配置连接池-->
                    <!--配置连接池-->
21 <property name="c3p0.max_size">4</property>
          <property name="c3p0.max_size">4</property>
22 <property name="c3p0.mix_size">2</property>
          <property name="c3p0.mix_size">2</property>
23 <property name="c3p0.timeout">5000</property>
          <property name="c3p0.timeout">5000</property>
24 <property name="c3p0.max_statements">100</property>
          <property name="c3p0.max_statements">100</property>
25 <property name="c3p0.idle_test_period">3000</property>
          <property name="c3p0.idle_test_period">3000</property>
26 <property name="c3p0.acquire_increment">2</property>
          <property name="c3p0.acquire_increment">2</property>
27 <property name="c3p0.validate">false</property>
          <property name="c3p0.validate">false</property>
28 
               
29 <property name="connection.pool_size">1</property>
          <property name="connection.pool_size">1</property>
30 <property name="current_session_context_class">thread</property>
          <property name="current_session_context_class">thread</property>
31 <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
          <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
32 <!-- property name="hbm2ddl.auto">create</property> -->
          <!-- property name="hbm2ddl.auto">create</property> -->
33 
                    
34 <mapping resource="day/one/Person.hbm.xml"/>
          <mapping resource="day/one/Person.hbm.xml"/>
35 </session-factory>
       </session-factory>
36 </hibernate-configuration>
    </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映射文件
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配置文件
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 }
        如上就完成了对一个简单的对象的持久化操作,将构造好的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"-->
<!--id特殊,不使用property,hibernate为id的映射提供了专用的标记"id"-->
2 <id name="id" column="id" unsaved-value="-1">
<id name="id" column="id" unsaved-value="-1">
3
4 <!--当属性名与表的字段名相同时,可以确省column属性配置-->
<!--当属性名与表的字段名相同时,可以确省column属性配置-->
5 <property name="name" column="name" />
<property name="name" column="name" />  
6 <property name="age" />
<property name="age" />
7 <property name="phone"/>
<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 -
SQL:393 - 
 2 insert
    insert 
 3 into
    into
 4 t_Person
        t_Person
 5 (name, age, phone, id)
        (name, age, phone, id) 
 6 values
    values
 7 (?, ?, ?, ?)
        (?, ?, ?, ?)
 8 Hibernate:
Hibernate: 
 9 insert
    insert 
10 into
    into
11 t_Person
        t_Person
12 (name, age, phone, id)
        (name, age, phone, id) 
13 values
    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