Hibernate 02

4 api詳解【多練】

4.1 體系結構

這裏寫圖片描述

PO:persistent object ,用於與數據庫交互數據。–dao層 (JavaBean + hbm )
BO:Business object 業務數據對象。–service層
VO:Value Object 值對象。–web層
開發中:直接使用JavaBean 描述三個對象。

這裏寫圖片描述

4.2 Configuration 配置對象

 hibernate 核心配置文件種類
hibernate.cfg.xml 通常使用xml配置文件,可以配置內容更豐富。
hibernate.properties 用於配置key/value 形式的內容,key不能重複的。配置有很多的侷限性。一般不用。
參考文件:hibernate-distribution-3.6.10.Final\project\etc\ hibernate.properties
提供了核心配置文件常用的配置項,及選擇參數。

1.提供構造 new Configuration() hibernate將自動加載 hibernate.properties文件
hibernate.properties文件必須存放在類路徑(src)下
2.提供方法 configure() 將加載src下的hibernate.cfg.xml

這裏寫圖片描述

3.擴展api
configure(String) 加載指定目錄下的 xml文件

4.手動加載配置文件

// 手動加載指定的配置文件
config.addResource("com/itheima/a_hello/User.hbm.xml");

// 手動加載指定類,對應的映射文件 User--> User.hbm.xml
config.addClass(User.class);

這裏寫圖片描述

 常見異常:

這裏寫圖片描述

開發中:將hbm.xml映射 配置 hibernate.cfg.xml
學習中:可以使用 addClass 或 addResource

4.3 SessionFactory工廠
 SessionFactory 相當於java web連接池,用於管理所有session
 獲得方式:config.buildSessionFactory();
 sessionFactory hibernate緩存配置信息 (數據庫配置信息、映射文件,預定義HQL語句 等)
 SessionFactory線程安全,可以是成員變量,多個線程同時訪問時,不會出現線程併發訪問問題。
 提供api:

//打開一個新的會話 session
factory.openSession();
//獲得當前線程中綁定的會話session
factory.getCurrentSession();

hibernate支持,將創建的session綁定到本地線程中,底層使用ThreadLocal,在程序之間共享session。
1.必須在hibernate.cfg.xml 配置
2 與本地線程綁定
thread

2.如果提交或回滾事務,底層將自動關閉session

4.4 Session 會話

 Session 相當於 JDBC的 Connection – 會話
 通過session操作PO對象 –增刪改查
 session單線程,線程不安全,不能編寫成成員變量。
 session api
save 保存
update 更新
delete 刪除
get 通過id查詢,如果沒有 null
load 通過id查詢,如果沒有拋異常
createQuery(“hql”) 獲得Query對象
createCriteria(Class) 獲得Criteria對象

4.5 Transaction 事務

開啓事務 beginTransaction()
獲得事務 getTransaction()

提交事務:commit()
回滾事務:rollback()

try{
//開啓
//session操作
//提交
} catch(e){
//回滾
}
擴展:不需要手動的管理事務,之後所有的事務管理都交予spring。

4.6 Query對象

 hibernate執行hql語句
 hql語句:hibernate提供面向對象查詢語句,使用對象(類)和屬性進行查詢。區分大小寫。
 獲得 session.createQuery(“hql”)
 方法:
list() 查詢所有
uniqueResult() 獲得一個結果。如果沒有查詢到返回null,如果查詢多條拋異常。

setFirstResult(int) 分頁,開始索引數startIndex
setMaxResults(int) 分頁,每頁顯示個數 pageSize

4.7 Criteria對象(瞭解)
 QBC(query by criteria),hibernate提供純面向對象查詢語言,提供直接使用PO對象進行操作。
 獲得方式:Criteria criteria = session.createCriteria(User.class);
 條件

criteria.add(Restrictions.eq("username", "tom"));
//      Restrictions.gt(propertyName, value)        大於
//      Restrictions.ge(propertyName, value)    大於等於
//      Restrictions.lt(propertyName, value)    小於
//      Restrictions.le(propertyName, value)    小於等於
//  Restrictions.like(propertyName, value)  模糊查詢,注意:模糊查詢值需要使用 % _

4.8 工具類

public class H3Utils {

    // 會話工廠,整個程序只有一份。
    private static SessionFactory factory;

    static{
        //1 加載配置
        Configuration config = new Configuration().configure();

        //2 獲得工廠
        factory = config.buildSessionFactory();
//3 關閉虛擬機時,釋放SessionFactory
            Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {

            @Override
            public void run() {
                System.out.println("虛擬機關閉!釋放資源");
                sf.close();
            }
        }));
    }


    /**
     * 獲得一個新的session
     * @return
     */
    public static Session openSession(){
        return factory.openSession();
    }

    /**
     * 獲得當前線程中綁定session
     * * 注意:必須配置
     * @return
     */
    public static Session getCurrentSession(){
        return factory.getCurrentSession();
    }


}

5 核心配置文件詳解

5.1 詳細配置【多讀】

<!-- SessionFactory,相當於之前學習連接池配置 -->
    <session-factory>
        <!-- 1 基本4項 -->
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.url">jdbc:mysql:///h_day01_db</property>
        <property name="hibernate.connection.username">root</property>
        <property name="hibernate.connection.password">1234</property>

        <!-- 2 與本地線程綁定 -->
        <property name="hibernate.current_session_context_class">thread</property>

        <!-- 3 方言:爲不同的數據庫,不同的版本,生成sql語句(DQL查詢語句)提供依據 
            * mysql 字符串 varchar
            * orcale 字符串 varchar2
        -->
        <property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>

        <!-- 4 sql語句 -->
        <!-- 顯示sql語句 -->
        <property name="hibernate.show_sql">true</property>
        <property name="hibernate.format_sql">true</property>

        <!-- 5 自動創建表(瞭解) ,學習中使用,開發不使用的。
            * 開發中DBA 先創建表,之後根據表生產 PO類
            * 取值:
            update:
                如果表不存在,將創建表。
                如果表已經存在,通過hbm映射文件更新表(添加)。(映射文件必須是數據庫對應)
                    表中的列可以多,不負責刪除。
            create :如果表存在,先刪除,再創建。程序結束時,之前創建的表不刪除。
            create-drop:與create幾乎一樣。如果factory.close()執行,將在JVM關閉同時,將創建的表刪除了。(測試)
            validate:校驗 hbm映射文件 和 表的列是否對應,如果對應正常執行,如果不對應拋出異常。(測試)
        -->
        <property name="hibernate.hbm2ddl.auto">create</property>

        <!-- 6 java web 6.0 存放一個問題
            * BeanFactory 空指針異常
                異常提示:org.hibernate.HibernateException: Unable to get the default Bean Validation factory
            * 解決方案:取消bean校驗
        -->
        <property name="javax.persistence.validation.mode">none</property>

        <!-- 添加映射文件 
            <mapping >添加映射文件
                resource 設置 xml配置文件 (addResource(xml))
                class 配置類 (addClass(User.class)) 配置的是全限定類名
        -->
        <mapping  resource="com/itheima/a_hello/User.hbm.xml"/>
    </session-factory>

6 Hibernate中持久化類

6.1 編寫規則

• 提供一個無參數 public訪問控制符的構造器
• 提供一個標識屬性,映射數據表主鍵字段
• 所有屬性提供public訪問控制符的 set get 方法(javaBean)
• 標識屬性應儘量使用基本數據類型的包裝類型
• 不要用final修飾實體 (將無法生成代理對象進行優化)

6.2 持久化對象的唯一標識 OID

 Java按地址區分同一個類的不同對象.
 關係數據庫用主鍵區分同一條記錄
 Hibernate使用OID來建立內存中的對象和數據庫中記錄的對應關係

結論: 對象的OID和數據庫的表的主鍵對應。爲保證OID的唯一性,應該讓Hibernate來爲OID付值

6.3 區分自然主鍵和代理主鍵

 主鍵需要具備: 不爲空/不能重複/不能改變
自然主鍵: 在業務中,某個屬性符合主鍵的三個要求.那麼該屬性可以作爲主鍵列.
代理主鍵: 在業務中,不存符合以上3個條件的屬性,那麼就增加一個沒有意義的列.作爲主鍵.

 基本數據類型和包裝類型對應hibernate的映射類型相同
 基本類型無法表達null、數字類型的默認值爲0。
 包裝類默認值是null。當對於默認值有業務意義的時候需要使用包裝類。

6.5 類型對應

Java數據類型 Hibernate數據類型 標準SQL數據類型
(PS:對於不同的DB可能有所差異)

這裏寫圖片描述
這裏寫圖片描述

6.6 普通屬性

<hibernate-mapping> 
            package 用於配置PO類所在包
                例如: package="com.itheima.d_hbm"
        <class> 配置 PO類 和 表 之間對應關係
            name:PO類全限定類名
                例如:name="com.itheima.d_hbm.Person"
                如果配置 package,name的取值可以是簡單類名 name="Person"
            table : 數據庫對應的表名
            dynamic-insert="false" 是否支持動態生成insert語句
            dynamic-update="false" 是否支持動態生成update語句
                如果設置true,hibernate底層將判斷提供數據是否爲null,如果爲null,insert或update語句將沒有此項。
        普通字段
            <property>
                name : PO類的屬性
                column : 表中的列名,默認name的值相同
                type:表中列的類型。默認hibernate自己通過getter獲得類型,一般情況不用設置
                    取值1: hibernate類型
                        string 字符串
                        integer 整形
                    取值2: java類型 (全限定類名)
                        java.lang.String 字符串
                    取值3:數據庫類型
                        varchar(長度) 字符串
                        int 整形
                        <property name="birthday">
                            <column name="birthday" sql-type="datetime"></column>
                        </property>
                        javabean 一般使用類型 java.util.Date
                        jdbc規範提供3中
                            java類型              mysql類型
                            java.sql.Date       date
                            java.sql.time       time
                            java.sql.timestamp  timestamp
                            null                datetime

                            以上三個類型都是java.util.Date子類

                length : 列的長度。默認值:255
                not-null : 是否爲null
                unique : 是否唯一
                access:設置映射使用PO類屬性或字段
                    property : 使用PO類屬性,必須提供setter、getter方法
                    field : 使用PO類字段,一般很少使用。
                insert 生成insert語句時,是否使用當前字段。
                update 生成update語句時,是否使用當前字段。
                    默認情況:hibernate生成insert或update語句,使用配置文件所有項
        注意:配置文件如果使用關鍵字,列名必須使用重音符    

6.7 主鍵

主鍵 
            <id>配置主鍵
                name:屬性名稱
                access="" 設置使用屬性還是字段
                column=""  表的列名
                length=""  長度
                type="" 類型
            <generator> class屬性用於設置主鍵生成策略
                1.increment 由hibernate自己維護自動增長
                    底層通過先查詢max值,再+1策略
                    不建議使用,存在線程併發問題
                2.identity hibernate底層採用數據庫本身自動增長列
                    例如:mysql auto_increment
                3.sequence hibernate底層採用數據庫序列
                    例如:oracle 提供序列
                4.hilo 

                    </generator>
                5.native 根據底層數據庫的能力選擇 identity、sequence 或者 hilo 中的一個。
                ##以上策略使用整形,long, short 或者 int 類型
                6.uuid 採用字符串唯一值
                ##以上策略 代理主鍵,有hibernate維護。
                7.assigned 自然主鍵,由程序自己維護。
發佈了94 篇原創文章 · 獲贊 51 · 訪問量 20萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章