Hibernate(一)

  

1、簡介mysql

Hibernate 架構是分層的,做爲數據訪問層,你沒必要知道底層 API 。Hibernate 利用數據庫以及配置數據來爲應用程序提供持續性服務(以及持續性對象)。spring

下面是一個很是高水平的 Hibernate 應用程序架構視圖。sql

下面是一個詳細的 Hibernate 應用程序體系結構視圖以及一些重要的類。數據庫

Hibernate 使用不一樣的現存 Java API,好比 JDBC,Java 事務 API(JTA),以及 Java 命名和目錄界面(JNDI)。JDBC 提供了一個基本的抽象級別的通用關係數據庫的功能, Hibernate 支持幾乎全部帶有 JDBC 驅動的數據庫。JNDI 和 JTA 容許 Hibernate 與 J2EE 應用程序服務器相集成。apache

下面的部分簡要地描述了在 Hibernate 應用程序架構所涉及的每個類對象。緩存

配置對象

配置對象是你在任何 Hibernate 應用程序中創造的第一個 Hibernate 對象,而且常常只在應用程序初始化期間創造。它表明了 Hibernate 所需一個配置或屬性文件。配置對象提供了兩種基礎組件。安全

  • 數據庫鏈接:由 Hibernate 支持的一個或多個配置文件處理。這些文件是 hibernate.properties 和 hibernate.cfg.xml
  • 類映射設置:這個組件創造了 Java 類和數據庫表格之間的聯繫。

SessionFactory 對象

配置對象被用於創造一個 SessionFactory 對象,使用提供的配置文件爲應用程序依次配置 Hibernate,並容許實例化一個會話對象。SessionFactory 是一個線程安全對象並由應用程序全部的線程所使用。服務器

SessionFactory 是一個重量級對象因此一般它都是在應用程序啓動時創造而後留存爲之後使用。每一個數據庫須要一個 SessionFactory 對象使用一個單獨的配置文件。因此若是你使用多種數據庫那麼你要創造多種 SessionFactory 對象。session

Session 對象

一個會話被用於與數據庫的物理鏈接。Session 對象是輕量級的,並被設計爲每次實例化都須要與數據庫的交互。持久對象經過 Session 對象保存和檢索。架構

Session 對象不該該長時間保持開啓狀態由於它們一般狀況下並不是線程安全,而且它們應該按照所需創造和銷燬。

Transaction 對象

一個事務表明了與數據庫工做的一個單元而且大部分 RDBMS 支持事務功能。在 Hibernate 中事務由底層事務管理器和事務(來自 JDBC 或者 JTA)處理。

這是一個選擇性對象,Hibernate 應用程序可能不選擇使用這個接口,而是在本身應用程序代碼中管理事務。

Query 對象

Query 對象使用 SQL 或者 Hibernate 查詢語言(HQL)字符串在數據庫中來檢索數據並創造對象。一個查詢的實例被用於連結查詢參數,限制由查詢返回的結果數量,並最終執行查詢。

Criteria 對象

Criteria 對象被用於創造和執行面向規則查詢的對象來檢索對象。

執行原理與流程

a、應用程序先調用Configuration類,該類讀取Hibernate配置文件及映射文件中的信息,

b、並用這些信息生成一個SessionFactory對象,

c、而後從SessionFactory對象生成一個Session對象,

d、並用Session對象生成Transaction對象;

e、可經過Session對象的get(),load(),save(),update(),delete()和saveOrUpdate()、createQuery()等方法對進行CURD等操做;

f、提交事物。

2、配置

一、所需jar包

二、Hibernate.cfg.xml

<!--標準的XML文件的起始行,version='1.0'代表XML的版本,encoding='gb2312'代表XML文件的編碼方式--> 
<?xml version='1.0' encoding='gb2312'?> 

<!--代表解析本XML文件的DTD文檔位置,DTD是Document Type Definition 的縮寫,即文檔類型的定義,XML解析器使用DTD文檔來檢查XML文件的合法性。
  hibernate.sourceforge.net/hibernate-configuration-3.0dtd能夠在Hibernate3.1.3軟件包中的src\org\hibernate目錄中找到此文件--> 
<!DOCTYPE hibernate-configuration PUBLIC 
          "-//Hibernate/Hibernate Configuration DTD 3.0//EN" 
          "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> 

    <!--聲明Hibernate配置文件的開始-->      
    <hibernate-configuration> 
     <!--代表如下的配置是針對session-factory配置的,SessionFactory是Hibernate中的一個類,
       這個類主要負責保存HIbernate的配置信息,以及對Session的操做-->
      <session-factory>    
         <!--配置數據庫的驅動程序,Hibernate在鏈接數據庫時,須要用到數據庫的驅動程序--> 
          <property name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver </property> 

         <!--設置數據庫的鏈接url:jdbc:oracle:thin:@localhost:1521:orcl,其中localhost表示oracle數據庫服務器名稱,此處爲本機,orcl是數據庫名-->  
          <property name="hibernate.connection.url">jdbc:oracle:thin:@localhost:1521:orcl</hibernate> 

        <!--鏈接數據庫是用戶名--> 
          <property name="hibernate.connection.username">scott</property> 

          <!--鏈接數據庫是密碼--> 
          <property name="hibernate.connection.password">123456 </property>   
     
          <!--數據庫鏈接池的大小--> 
          <property name="hibernate.connection.pool.size">20 </property>    
    
          <!--是否在後臺顯示Hibernate用到的SQL語句,開發時設置爲true,便於查錯,程序運行時能夠在Eclipse的控制檯顯示Hibernate的執行Sql語句。
         項目部署後能夠設置爲false,提升運行效率--> 
         <property name="hibernate.show_sql">true </property> 

          <!--jdbc.fetch_size是指Hibernate每次從數據庫中取出並放到JDBC的Statement中的記錄條數。Fetch Size設的越大,讀數據庫的次數越少,速度越快,
          Fetch Size越小,讀數據庫的次數越多,速度越慢--> 
          <property name="jdbc.fetch_size">50 </property> 

          <!--jdbc.batch_size是指Hibernate批量插入,刪除和更新時每次操做的記錄數。Batch Size越大,
          批量操做的向數據庫發送Sql的次數越少,速度就越快,一樣耗用內存就越大--> 
          <property name="jdbc.batch_size">23 </property> 

          <!--jdbc.use_scrollable_resultset是否容許Hibernate用JDBC的可滾動的結果集。對分頁的結果集。對分頁時的設置很是有幫助--> 
          <property name="jdbc.use_scrollable_resultset">false </property> 

          <!--connection.useUnicode 鏈接數據庫時是否使用Unicode編碼--> 
          <property name="Connection.useUnicode">true </property> 

          <!--connection.characterEncoding鏈接數據庫時數據的傳輸字符集編碼方式,最好設置爲gbk,用gb2312有的字符不全--> 
          <property name="connection.characterEncoding">gbk </property>      
        
          <!--hibernate.dialect 是Hibernate使用的數據庫方言,就是要用Hibernate鏈接那種類型的數據庫服務器。--> 
          <property name="hibernate.dialect">org.hibernate.dialect.OracleDialect</property> 

          <!--指定映射文件爲「hibernate/ch1/UserInfo.hbm.xml」-->        
          <mapping resource="org/mxg/UserInfo.hbm.xml"> 
    </session-factory> 
  </hibernate-configuration>    
  
  <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">  
    <!-- 鏈接驅動 -->
    <property name="driverClassName" value="${jdbc.driverClassName}" />  
    <!-- 鏈接url -->
     <property name="url" value="${jdbc.url}" />  
     <!-- 鏈接用戶名 -->   
     <property name="username" value="${jdbc.username}" />  
     <!-- 鏈接密碼   --> 
     <property name="password" value="${jdbc.password}" />  
  </bean>  
  
  <bean id="hbSessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">  
    <property name="dataSource" ref="dataSource" />  
    <property name="configLocation">  
      <!-- hibernate配置文件位置    -->
       <value>WEB-INF/hibernate.cfg.xml </value>  
    </property>  
    <property name="configurationClass"  value="org.hibernate.cfg.AnnotationConfiguration" />  
    <property name="hibernateProperties">  
      <props>  
        <!--針對oracle數據庫的方言,特定的關係數據庫生成優化的SQL    -->
         <prop key="hibernate.dialect">  org.hibernate.dialect.OracleDialect  </prop>  
        <!--選擇HQL解析器的實現    -->
         <prop key="hibernate.query.factory_class">  org.hibernate.hql.ast.ASTQueryTranslatorFactory </prop>  
         <!-- 是否在控制檯打印sql語句    -->
         <prop key="hibernate.show_sql">true </prop>  
         <!-- 在Hibernate系統參數中hibernate.use_outer_join被打開的狀況下,該參數用來容許使用outer join來載入此集合的數據。    -->
         <prop key="hibernate.use_outer_join">true </prop>  
        <!-- 默認打開,啓用cglib反射優化。cglib是用來在Hibernate中動態生成PO字節碼的,打開優化能夠加快字節碼構造的速度    -->
        <prop key="hibernate.cglib.use_reflection_optimizer">true </prop>  
        <!-- 輸出格式化後的sql,更方便查看    -->
        <prop key="hibernate.format_sql">true </prop>  
             <!-- 「useUnicode」和「characterEncoding」決定了它是否在客戶端和服務器端傳輸過程當中進行Encode,以及如何進行Encode    -->
        <prop key="hibernate.connection.useUnicode">true </prop>  
        <!-- 容許查詢緩存, 個別查詢仍然須要被設置爲可緩存的.     -->
        <prop key="hibernate.cache.use_query_cache">false </prop>  
        <prop key="hibernate.default_batch_fetch_size">16 </prop>  
        <!--鏈接池的最大活動個數    -->
         <prop key="hibernate.dbcp.maxActive">100 </prop>  
        <!-- 當鏈接池中的鏈接已經被耗盡的時候,DBCP將怎樣處理(0 = 失敗,1 = 等待,2  =  增加)    -->
        <prop key="hibernate.dbcp.whenExhaustedAction">1 </prop>  
        <!-- 最大等待時間    -->
        <prop key="hibernate.dbcp.maxWait">1200 </prop>  
        <!-- 沒有人用鏈接的時候,最大閒置的鏈接個數     -- >
        <prop key="hibernate.dbcp.maxIdle">10 </prop>  
        <!-- 如下是對prepared statement的處理,同上。  -->
        <prop key="hibernate.dbcp.ps.maxActive">100 </prop>  
        <prop key="hibernate.dbcp.ps.whenExhaustedAction">1 </prop>  
        <prop key="hibernate.dbcp.ps.maxWait">1200 </prop>  
        <prop key="hibernate.dbcp.ps.maxIdle">10 </prop>  
      </props>  
    </property>  
  </bean>

三、hibernate.properties 數據庫的配置信息

##---------Oracle---------
#hibernate.databaseType=oracle
#hibernate.dialect=org.hibernate.dialect.Oracle10gDialect
#jdbc_url=jdbc:oracle:thin:@192.168.10.82:1521:ora11g
#jdbc_username=valleyplatform_test
#jdbc_password=valleyplatform_test
#jdbc_testsql=select * from dual

##---------MySQL---------
hibernate.databaseType=mysql
hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
jdbc_url=jdbc:mysql://192.168.1.204:3306/platform-appraise
jdbc_username=root
jdbc_password=123456
jdbc_testsql=select X

##SQLServer
#hibernate.databaseType=mssql
#hibernate.dialect=org.hibernate.dialect.SQLServer2008Dialect
#jdbc_url=jdbc:jtds:sqlserver://192.168.10.181:1433/platform2-branches-gxr
#jdbc_username=sa
#jdbc_password=
#jdbc_testsql=select 1


##---------DM達夢---------
#hibernate.databaseType=oracle
#hibernate.dialect=org.hibernate.dialect.DmDialect
#jdbc_url=jdbc:dm://192.168.10.166:5236/DAMENG
#jdbc_username=PLATFORM2-BRANCHES-GXR
#jdbc_password=PLATFORM2-BRANCHES-GXR
#jdbc_password=sginfo123
#jdbc_testsql=select id from dual


##---------H2---------


##Database config
#表生成策略
hibernate.hbm2ddl.auto=update
#是否打印SQL語句
hibernate.show_sql=false
#在 log 和 console 中打印出更漂亮的 SQL。
hibernate.format_sql=false
若是開啓,Hibernate 將在 SQL 中生成有助於調試的註釋信息,默認值爲 false。
hibernate.use_sql_comments=false

 

hibernate.hbm2ddl.auto的四個屬性解釋 這個屬性標籤中有四個參數能夠寫,這四個參數是對數據庫中插入的進行不一樣的操做,分別爲:

(1)create-drop

(2)create

(3)update

(4)validate

下面分別來介紹他們的做用以及對數據庫中的影響

(1) create-drop create-drop:表示在hebarinate初始化時建立表格,程序運行結束的時候會刪除相應的表格,在實際項目中不用

(2)create 在hibernate初始化時會建立表格,在運行結束以後不刪除表格,而是在下一次運行的時候若是有舊的刪掉,沒有舊的,從新建表格

(3)update 只是根據映射文件去和數據庫中的表對應起來,若是不一致,就更新表的結構

(4)validate 校驗映射文件和數據庫中的表是否是能對應起來,不能對應報錯,實際中經常使用 注:在使用的時候必需要慎重,我就是在當時學習的時候所設置的屬性是validate,因此只要改了數據庫名就會拋初始化異常,當時我鬱悶了半天都不知道是怎麼回事,沒有往這方面想,後來才知到balidate是在沒有數據庫名的時候不讓你建立,會拋異常的

當hibernate不和Spring一塊兒使用時要創建 類.hbm.xml與Hibernate.cfg.xml相對應

以下單獨使用Hibernate

5.1 導入相關Jar包:Hibernate模式不僅是本身內部實現,一樣也導入了許多外部的jar包,下面是Hibernate3.6.0框架的基本jar包

    我使用的是mysql數據庫,能夠根據本身使用的數據庫添加相關驅動Jar包

 

  5.2 先建立一個User實體

1 package com.a_helloworld;
 2 
 3 public class User {
 4 
 5     private int id;
 6     private String name;
 7     public int getId() {
 8         return id;
 9     }
10     public void setId(int id) {
11         this.id = id;
12     }
13     public String getName() {
14         return name;
15     }
16     public void setName(String name) {
17         this.name = name;
18     }
19     
20     @Override
21     public String toString() {
22         return "User [id=" + id + ", name=" + name + "]";
23     }
24     
25     
26 }

 5.3 配置User實體在數據庫表的映射user.hbm.xml

   

<?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="com.a_helloworld">
    
    <!-- 屬性table 表示在數據庫中的表名  -->
    <class name="User" table="user_1" >
        <id name="id" column="id" type="int">
            <!-- 值native表示會根據數據庫來建立不一樣的主鍵生成策略 -->
            <generator class="native"></generator>
        </id>
        <property name="name" column="name" type="string"></property>
    </class>
</hibernate-mapping>

  5.4 簡單配置hibernate.cfg.xml配置文件,這個文件名能夠隨便修改(xxx.cfg.xml),可是沒多大意義,通常不建議修改。配置的信息以下:

1 <!DOCTYPE hibernate-configuration PUBLIC
 2     "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
 3     "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
 4 
 5 <hibernate-configuration>
 6     <session-factory name="foo">
 7     
 8         <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
 9         <property name="connection.username">root</property>
10         <property name="connection.password">123456</property>
11         <property name="connection.url">jdbc:mysql:///user</property>
12         
13         <!-- 要根據本身使用的數據庫來配置相對應的屬性,也成方言,針對不一樣數據庫
14              關於怎麼配置能夠查看HibernateAPI
15          -->
16         <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
17         
18         <!-- Hibernate 創建的SQL語句會顯示在控制檯 -->
19         <property name="hibernate.show_sql">true</property>
20         
21         <!-- 選擇方案,經常使用值:validate | update | create | create-drop -->
22         <property name="hbm2ddl.auto">update</property>
23         
24         <mapping resource="com/a_helloworld/user.hbm.xml"/> -- 導入實體映射配置,程序每次啓動都會自動檢索
25         
26     </session-factory>
27 </hibernate-configuration>

 

以上Hibernate簡單配置已經基本完成,能夠添加一個測試類來測試是否成功

package com.a_helloworld;


import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.Session;
import org.junit.Test;

public class Demo {

    private static SessionFactory sf = new Configuration()//
            .configure("hibernate.cfg.xml")//
            .buildSessionFactory();
    
    @Test
    public void addUser(){
        Session session = null;
        Transaction tran = null;
        try{
            session = sf.openSession(); // 建立一個Session
            tran = session.beginTransaction(); //開啓事務
            
            User user = new User();
            user.setName("張三");
            session.save(user);
            
            tran.commit();//事務提交
        }catch(Exception e){
            tran.rollback(); //事務回滾
            throw(e);
        }finally{
            session.close(); //關閉session
        }
    }
    
    @Test
    public void getUser(){
        Session session = null;
        Transaction tran = null;
        try{
            session = sf.openSession(); // 建立一個Session
            tran = session.beginTransaction(); //開啓事務
            
            /*這裏指明你要得到哪一個類型,Hibernate會根據類名查詢映射配置文件到數據庫查詢哪張表,根據指定
             * id查詢實體,經過反射機制建立實體對象
            */
            User user = (User) session.get(User.class, 1); //執行查詢,get
            
            tran.commit();//事務提交
        }catch(Exception e){
            tran.rollback(); //事務回滾
            throw(e);
        }finally{
            session.close(); //關閉session
        }
    }
    @Test
    public void updateUser(){
        Session session = null;
        Transaction tran = null;
        try{
            session = sf.openSession(); // 建立一個Session
            tran = session.beginTransaction(); //開啓事務
            
            User user = new User();            
            user.setId(1);//這裏指定了要更新的數據id爲1
            user.setName("李四");// 把名字 「張三」 修改成 「李四」        
            session.update(user);//執行更新    
            
            tran.commit();//事務提交
        }catch(Exception e){
            tran.rollback(); //事務回滾
            throw(e);
        }finally{
            session.close(); //關閉session
        }
    }
    
    @Test
    public void deleteUser(){
        Session session = null;
        Transaction tran = null;
        try{
            session = sf.openSession(); // 建立一個Session
            tran = session.beginTransaction(); //開啓事務
            
            User user = new User();
            user.setId(1);//這裏指定了要更新的數據id爲1
            session.delete(user); //執行刪除
            
            tran.commit();//事務提交
        }catch(Exception e){
            tran.rollback(); //事務回滾
            throw(e);
        }finally{
            session.close(); //關閉session
        }
    }
    
}
相關文章
相關標籤/搜索