Hibernate框架學習

女人的驕傲發表於2018-08-04

 

  • 什麼是框架

框架就是一個半成品的專案,我們書寫專案可以從半成品的專案開始寫,這樣能夠大大的提高開發效率。

不必糾結於框架本身的實現,只要學會如何使用這個框架即可。

  • 什麼是Hibernate框架

這個框架應用於DAO層

ORM:Object relaction mapping

實體類和資料表之間建立了聯絡,通過操作物件,直接對資料庫進行修改。

 

 

Hibernate框架搭建

 

1、導包

匯入required目錄下的所有包,然後在匯入資料庫驅動包

2、準備一個實體類

  • 所有的屬性應該設定為私有,並新增get-set方法

  • 建構函式要麼不寫,如果要寫至少要寫兩個(必須包含一個空的)

  • 屬性的型別應是包裝型別

  • 必須擁有一個主鍵

3、準備資料庫

資料庫必須由我們自己建立,資料庫表,可以由hibernte自動建立,如果手動建立,表中的欄位要和實體類一一對應。

4、建立實體類和資料庫表之間的對映配置檔案

建立一個  實體類名+.hbm+.xml

建議這個檔案的目錄和實體類在同一目錄下

Column:與資料庫欄位有關

 

<hibernate-mapping>
    <class name="cn.hd.bean.User" table="t_user">
        <id name="id" column="id">
            <generator class="native"></generator>
        </id>
        <property name="name" column="name"></property>
        <property name="sex" column="sex"></property>
        <property name="age" column="age"></property>
        <property name="balance" column="balance"></property>
    </class>
</hibernate-mapping>

 

5、書寫核心配置檔案

名字必須為hibernate.cfg.xml

檔案的位置必須放在src目錄下

匯入約束

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

 

書寫配置

<hibernate-configuration>
    <session-factory>
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate01</property>
        <!-- 資料庫連線使用者名稱 -->
        <property name="hibernate.connection.username">root</property>
        <!-- 資料庫連線密碼 -->
        <property name="hibernate.connection.password">123456</property>

        <property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>

        <property name="hibernate.show_sql">true</property>
        <property name="hibernate.format_sql">true</property>

        <property name="hibernate.hbm2ddl.auto">update</property>

        <property name="hibernate.connection.isolation">4</property>

        <mapping resource="cn/hd/bean/User.hbm.xml"></mapping>


    </session-factory>
</hibernate-configuration>

 

6、書寫測試程式碼

 

public static void main(String[] args) {
    //讀取配置檔案
    Configuration cfg = new Configuration();
    cfg.configure();
    //建立sessionFaction
    SessionFactory sessionFactory = cfg.buildSessionFactory();
    //獲得一個session
    Session session = sessionFactory.openSession();
    //開啟事務
    Transaction transaction=session.beginTransaction();
    User user = new User();
    user.setName("大紅");
    user.setSex("女");
    user.setAge(20);
    user.setBalance(28000);
    session.save(user);
    //提交事務
    transaction.commit();
    //釋放資源
    session.close();
    sessionFactory.close();
}

 

配置檔案詳解

1、對映檔案

<!--下面class中的類的路徑,下面的class name屬性可以簡寫-->
<hibernate-mapping>
    <!--對映類和資料庫表之間的關係-->
    <!--name屬性是實體類名 寫完整路徑名-->
    <!--table屬性 資料庫表名字-->
<class name="cn.hd.bean.User" table="t_user">
    <!--對映檔案中必須擁有主鍵-->
    <id name="id" column="id">
        <!--主鍵生成策略
        identity:mysql自動遞增
        increment:
        sequence:Orancel資料庫中的自動遞增
        native:自動遞增(3和1)
        assigned
        uuid:百度
        -->
        <generator class="native"></generator>
    </id>
    <!--基本屬性 在這裡可以設定資料表屬性
    欄位型別 長度 不為空 預設值
    -->
    <property name="name" column="name"></property>
    <property name="sex" column="sex"></property>
    <property name="age" column="age"></property>
    <property name="balance" column="balance"></property>
</class>
</hibernate-mapping>

 

2、核心配置檔案詳解

名字和位置都必須按照規定來

<hibernate-configuration>
    <session-factory>
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate01</property>
        <!-- 資料庫連線使用者名稱 -->
        <property name="hibernate.connection.username">root</property>
        <!-- 資料庫連線密碼 -->
        <property name="hibernate.connection.password">123456</property>

        <!--方言 必須要設定

        -->
        <property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>

        <!--在控制檯展示sql語句 不必須-->
        <property name="hibernate.show_sql">true</property>
        <!--sql語句格式化輸出-->
        <property name="hibernate.format_sql">true</property>
<!--
        1、update 如果對映檔案和資料庫表保持一致就不修改,
        如果沒有就自動建立表
        2、create 每次執行都會重新建立一個表
        3、create-drop 先將原來表刪除 然後重新建立
        4、validate 只做校驗,不修改表
-->
        <property name="hibernate.hbm2ddl.auto">update</property>

        <!--事務的隔離界別
        1
        2
        4
        8

        髒讀
        幻讀
        不可重複讀
        序列化
        -->
        <property name="hibernate.connection.isolation">4</property>

        <!--掃描對映檔案
        class 必須 對映檔案和配置檔名字和路徑保持一致
        package 掃描該報下的所有配置檔案
        resource 指定某個確定xml配置檔案
        -->
        <mapping resource="cn/hd/bean/User.hbm.xml"></mapping>


    </session-factory>
</hibernate-configuration>

3、HibernateAPI詳解

package cn.fdw.test;

import cn.fdw.bean.User;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

public class Demo {
    public static void main(String[] args) {
        //1、讀取配置檔案
        Configuration cfg = new Configuration().configure();
        //2、建立sessionFactory類
        /*
        * 1、建立 session 、connection
        * 2、建立的時候會檢查資料的資訊,去更新資料庫的結構
        * */
        SessionFactory sessionFactory = cfg.buildSessionFactory();
        //3、獲得一個session
        /*
        * 1、獲得事務  crud(增查改刪)
        * */
        Session session = sessionFactory.openSession();
        //開啟事務
        Transaction transaction = session.beginTransaction();
        //---------------------------------------------
        User user = new User();
        user.setName("大紅");
        user.setAge(20);
        user.setSex("女");
        user.setBalance(28000);

        session.save(user);
        //---------------------------------------------
        //提交事務
        transaction.commit();
        //回滾·事務
//       transaction.rollback();
        //釋放資源
        session.close();
        sessionFactory.close();

    }
}

 

 

 

 

Crud

儲存 save(裡面不允許有id)

更新 update

刪除 delete

查詢 get

 

 

 

 

 

 

Hibernate物件的狀態

(下面id為主鍵)

瞬時狀態:一個物件既沒有id也沒有和session繫結的物件

持久化狀態:一個物件沒有id也和session繫結在一起

遊離狀態:有id沒有和session繫結

Hibernate提供的四個crud不是增刪改查的意思,而是改變物件的狀態從而達到修改資料庫的目的

 

saveOrUpdate

持久化狀態的物件,隨著物件的資料更該,資料庫會自動更新。

 

 

 

Hibernate 查詢

  1. hql

               hql是hibernate的獨家語言。            

 @Test
public void fun(){
    //select * from t_user
    String hql = "from User";
    Query query = session.createQuery(hql);
    List<User> list = query.list();
    System.out.println(list);
}

//佔位符查詢
@Test
public void fun1(){
    //select * from t_user where name = ?
    //不會出現表名字和欄位名,只會出現類名和類的屬性名
    String hql = "from User where name = ?";
    Query query = session.createQuery(hql);
    //設定引數的時候,下標是從0開始
    query.setParameter(0,"狗子");
    List<User> list = query.list();
    System.out.println(list);
}

//佔位符的方式有兩種
//字串的方式:+str
@Test
public void fun2(){
    /*String hql = "from User where name = :name";
    Query query = session.createQuery(hql);
    //設定引數的時候,下標是從0開始
    query.setParameter("name","狗子");
    //List<User> list = query.list();
    //System.out.println(list);
    User user= (User) query.uniqueResult();
    System.out.println(user);*/

    String hql="from User where name = :name and balance< :balance";
    Query query=session.createQuery(hql);
    //設定引數的時候, 下標是從0 開始
    query.setParameter("balance",12900);
    query.setParameter("name","張三");
    //        List<User> list=query.list();
    //       System.out.println(list);
    User user=(User)query.uniqueResult();
    System.out.println(user);

}

@Test
public void fun3(){
    String hql = "from User";
    Query query = session.createQuery(hql);
    //從第0條資料查詢兩個
    query.setFirstResult(0);
    query.setMaxResults(2);
    List<User> list = query.list();
    System.out.println(list);
}

  1. Criteria

or() 或者

and()  並且

equal() 等於

notEqual  不等於

like   模糊

isNull   為空

in()

 gt()大於

ge()   大於等於

lt  小於

lt()小於等於

Between  在,,,,之間

 

  1. 使用session建立criteriaBuilder

使用工廠類 建立criteriaQuery

指定根元素

新增條件

將條件封裝到query

把query傳給session.createrQuery

得到結果集

3、sql原生態的查詢方式

應用的環境

hql 推薦使用 適用於一些簡單的查詢

criteria 推薦使用 只適用於單表查詢

sql 不推薦 非常非常複雜的查詢,推薦使用sql

 

 

事務

 

事務的出現就是為了解決事務安全

 

同時對兩張表進行操作,當操作完第一張表,然後出現了異常導致第二張表的資料出現了問題,這樣的情況就叫做事務安全。

 

事務特性:

原子性  一致性  永續性

 

由於有了事務,就有了問題叫做事務執行緒安全。

  1. 髒讀資料

         張三 發貨1 和李四 付錢2

             2開啟的事務

             1 發貨 事務的提交

              2 事務回滾

  1. 不可重複讀

           酒店 兩個櫃檯 A B 客戶C

             C找到了A櫃檯 2201

           身份證找到了 2201房間沒有了

           客戶D 找到了櫃檯B 住房2201

  1. 虛讀(幻讀)

             資料庫中又100條訂單,讀取了一次100條

              另外一個事務插入進來增加了一條訂單,101

               有讀取一次 發現前後讀取的資料不一致

 

 

為了解決以上3個問題,事務隔離,隔離性 4中級別

1讀未提交    哪種都不解決  (效率最高 最不安全)

2讀已提交    髒讀

4可重複讀    髒讀和不可重複讀(最常用的Mysql預設的級別就是4)

8序列化      所有的問題都解決(效率最低)

 

 

 

 

Hibernate中事務的應用

事務應該在service層開啟和提交或者回滾

 

事物的開啟需要 session

獲得session有兩種方式:

       openSession 每次開啟都是一個新的執行緒

       getCurrentSession 執行緒繫結的session

service層有session

dao層也有session    這兩個session必須保證是同一個session

這樣的事務的提交才能起作用

Hibernate框架中所有增刪改 都必須提交事務才能最終修改到資料庫,所以在增刪改操作中必須使用getCurrentSession

 

使用currentSession必須再配置檔案中假如屬性

<property name="hibernate.current_session_context_class">thread</property>

 

 

 

表與表之間的關係


1對1關係  賬號
1對多關係   
多對多關係

 

 

 

Hibernate維護一對多關係

  1. 在實體類中加上對應的屬性

           職工類 加入一個 企業型別屬性

           企業類 假如職工的集合 set

  1. 在配置檔案中增加以下程式碼

多的一方

<many-to-one name="enterprise" class="cn.hd.bean.Enterprise" column="enterpriseId"></many-to-one>

一的一方

<set name="employees">
    <key column="enterpriseId"></key>
    <one-to-many class="cn.hd.bean.Employee"></one-to-many>
</set>

 

  1. 在程式碼中維護關係時

要為兩方都新增對應的屬性

 

 

 

級聯操作

cascade

delete

create

save-update

加在多的一方 在程式碼中就要使用多的一方維護或者一的一方維護

<many-to-one cascade="save-update" name="enterprise" class="cn.hd.bean.Enterprise" column="enterpriseId"></many-to-one>

el.setEnterprise(enterprise);
e2.setEnterprise(enterprise);

 

加在一的一方就要用一的一方維護

<set name="employees" cascade="save-update">

enterprise.getEmployees().add(el);
enterprise.getEmployees().add(e2);

 

 

關係的維護

inverse true 就是放棄維護關係

讓一的一方放棄(欄位存在多的一方)

 

多對多關係

<set name="teachers" table="teacher_student" inverse="true">
    <key column="stuId"></key>
    <many-to-many column="teaId" class="cn.hd.bean.Teacher"></many-to-many>
</set>

 

 

 

 

Hibernate查詢的方式

  1. crud

          get方法 需要主鍵和.class檔案

  1. hql 比較常見(一般查詢)
  2. criteria 適用於表單
  3. sql 適用於複雜查詢
  4. 物件導航查詢

分頁查詢

排序查詢

基本條件查詢

模糊查詢

 

 

 

多表查詢

  1. 笛卡爾積

         A集合 B集合

         A集合中和B集合中所有的元素,自由組合生成新的資料

  1. 內連線

         隱式內連線

SELECT * from t_employee,t_enterprise WHERE t_employee.enterpriseId=t_enterprise.id;

         顯示內連線

SELECT * from t_employee t1 INNER JOIN t_enterprise t2 on t1.enterpriseId = t2.id;

  1. 外連線

          右外連線

SELECTSELECT * from t_employee t1 RIGHT JOIN t_enterprise t2 on t1.enterpriseId = t2.id;

左外連線和右外連線沒有什麼太大的區別

 

 

 

 

Hibernate實現多表查詢

迫切內連線

String hql = "from Enterprise e inner join fetch e.employess";

內連線

String hql = "from Enterprise e inner join e.employess";

  區別就是:結果的封裝一個是陣列(普通),一個是物件(迫切);

 

 

 

 

檢索策略

 

Hibernate快取技術

Hibernate預設開啟一級

二級快取(廢棄)redis

 

Hibernate批量抓取

 

相關文章