重拾Java EE——Hibernate(1)基礎篇

1.框架體系結構

2.hibernate入門

2.1 ORM框架

Hibernate是一個數據持久化層的ORM框架.
Object:對象,java對象,此處特指JavaBean
Relational:關係,二維表,數據庫中的表。

映射|映射元數據:對象中屬性,與表的字段,存在對應關係。

2.2 什麼是hibernate

  • Hibernate是輕量級JavaEE應用的持久層解決方案,是一個關係數據庫ORM框架
  • ORM 就是通過將Java對象映射到數據庫表,通過操作Java對象,就可以完成對數據表的操作
  • Hibernate提供了對關係型數據庫增刪改成操作

2.3 主流的ORM框架

  • JPA Java Persistence API.JPA通過JDK 5.0註解或XML描述對象-關係表的映射關係(只有接口規範)
  • Hibernate 最流行ORM框架,通過對象-關係映射配置,可以完全脫離底層SQL
  • MyBatis 本是apache的一個開源項目 iBatis,支持普通 SQL查詢,存儲過程和高級映射的優秀持久層框架
  • Apache DBUtils 、Spring JDBCTemplate

2.4 優點

  • Hibernate對JDBC訪問數據庫的代碼做了封裝,大大簡化了數據訪問層繁瑣的重複性代碼
  • Hibernate是一個基於jdbc的主流持久化框架,是一個優秀的orm實現,它很大程度的簡化了dao層編碼工作 session.save(User);
  • Hibernate使用java的反射機制
  • Hibernate的性能非常好,因爲它是一個輕量級框架。映射的靈活性很出色。它支持很多關係型數據庫,從一對一到多對多的各種複雜關係

3 入門案例【掌握】

3.1 編寫流程

1. 導入jar包

2. 創建數據庫和表

3. 編寫核心配置文件(hibernate.cfg.xml)--> 配置獲得鏈接等參數

4. 編寫映射文件 hibernate mapping(*.hbm.xml)

5 使用api測試

3.2 數據庫和表

create database h_day01_db;
use h_day01_db;
create table t_user(
  id int auto_increment primary key,
  username varchar(50),
  password varchar(30)
);

3.3 導入jar包

版本:3.6.10 –> hibernate 4 建議註解開發,hibernate 4 對 3 不兼容。

目錄結構

jar介紹(9個)
核心(1個): hibernate3.jar
必須(6個):\lib\required
jpa規範(1個):lib\jpa : hibernate-jpa-2.0-api-1.0.1.Final.jar
mysql驅動(1個): mysql-connector-java-5.0.8-bin.jar

3.4 編寫JavaBean + 映射文件

文件位置:javabean同包
文件名稱:javabean同名
擴展名:*.hbm.xml
內容:
添加約束

“`java
public class User {

/*
 * create table t_user(
      id int auto_increment primary key,
      username varchar(50),
      password varchar(30)
    );
 */
private Integer uid;
private String username;
private String password;

 ```xml
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="com.itheima.a_hello.User" table="t_user">
        <!-- 主鍵 -->
        <id name="uid">
            <!-- 固定值:主鍵生成策略 -->
            <generator class="native"></generator>
        </id>

        <!-- 普通屬性 -->
        <property name="username"></property>
        <property name="password"></property>

    </class>
</hibernate-mapping>

3.5 編寫核心配置文件

位置:類路徑(classpath、src)–>WEB-INF/classes
名稱:hibernate.cfg.xml
內容:
添加約束

<!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <!-- 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>

        <!-- 添加映射文件 -->
        <mapping resource="com/itheima/a_hello/User.hbm.xml"/>
    </session-factory>

</hibernate-configuration>

3.6 測試

@Test
    public void demo01(){
        User user = new User();
        user.setUsername("偉哥哥");
        user.setPassword("1234");


        //1 加載配置文件獲得核心配置對象
        Configuration config = new Configuration().configure();
        //2 獲得工廠 SessionFactory,相當於連接池
        SessionFactory factory = config.buildSessionFactory();
        //3獲得會話session,相當於鏈接Connection
        Session session = factory.openSession();
        //4 開啓事務
        Transaction transaction = session.beginTransaction();

        //操作
        session.save(user);

        //5 提交事務 | 回滾事務
        transaction.commit();
        //6 釋放資源--關閉session
        session.close();
        //7 釋放資源--關閉工廠factory
        factory.close();
    }

3.7 常見異常

解決方案:
將映射文件添加到核心配置文件中 hbm.xml –> hibernate.cfg.xml

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 與本地線程綁定 -->
<property name="hibernate.current_session_context_class">thread</property>

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個條件的屬性,那麼就增加一個沒有意義的列.作爲主鍵.

6.4 基本數據與包裝類型

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

6.5 類型對應

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 自然主鍵,由程序自己維護。【】
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章