1. 程式人生 > >hibernate學習(2)

hibernate學習(2)

1 實體類編寫規則

2 hibernate主鍵生成策略

3實體類操作

(1)crud操作

(2)實體物件狀態

4 hibernate的一級快取

5 hibernate事務操作

(1)事務程式碼規則寫法

6 hibernate其他的api(查詢)

實體類編寫規則

1 實體類裡面屬性私有的

2 私有屬性使用公開的set方法和get方法操作

3 要求實體類有屬性作為唯一值(一般都使用id值)

4 實體類屬性建議不使用基本資料型別,使用基本資料型別對應的包裝類。

(1)八個基本資料型別對應的包裝類

-int - Integer

-char--Character

-其他的都是首字母大寫 比如double-Double

(2)比如表示學生的分數,假如 int score;

-比如學生得了0分,int score-0;

-如果表示學生沒有參加考試,int scrore無法為null,int score不能準確表示學生是否參加考試

解決:使用包裝類可以了,Integer score=0,學生得了0分

表示學生沒有參加考試,Integer score=null;

 

Hibernate主鍵生成策略

1 hibernate要求實體類裡面有一個屬性作為唯一值,對應主鍵,主鍵可以不同生成策略

2 hibernate主鍵生成策略有很多的值

<!-- 設定資料庫id增長策略 native:生成表id值就是主鍵自動增長 
--> <generator class="native"></generator>

 

主要記住native和uuid。

identity只能用在mysql中,sequence只能用在oracle中。

因為不知道用什麼資料庫,所以用native,它會幫我們根據不同的資料庫選擇不一樣的值。

(1)native:根據使用的資料庫幫我們選擇哪個值

CREATE TABLE `t_user` (
  `uid` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(255) DEFAULT
NULL, `password` varchar(255) DEFAULT NULL, `address` varchar(255) DEFAULT NULL, PRIMARY KEY (`uid`) ) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8 |

 (2)uuid:hibernate幫我們生成uuid值。

(1)使用uuid生成策略,實體類id屬性型別必須是字串型別。

 在User.java中

private String uid;
//如果有哪個屬性值沒有生成get和set方法,那麼程式會出現異常
    

在User.hbm.xml中

<generator class="uuid">
</generator>

show create table t_user;展示如下所示:

CREATE TABLE `t_user` (
  `uid` varchar(255) NOT NULL,
  `username` varchar(255) DEFAULT NULL,
  `password` varchar(255) DEFAULT NULL,
  `address` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`uid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |

 

實體類操作

對實體類crud操作

新增操作

1 呼叫session裡面的save方法實現

//新增功能
User user = new User();
user.setUsername("xiaoMA");
user.setPassword("250");
user.setAddress("China");
session.save(user);

根據id查詢

 hibernate可以幫我們建立表,但無法建立資料庫。

1 呼叫session裡面的get方法實現

//4 根據id查詢
//呼叫session裡面的get方法
//第一個引數:實體類的class
//第二個引數:id值
User user = session.get(User.class, 1);

底層輸出語句

<!-- 輸出底層sql語句 -->
<property name="hibernate.show_sql">true</property>

的輸出結果是:

Hibernate: 
    select
        user0_.uid as uid1_0_0_,
        user0_.username as username2_0_0_,
        user0_.password as password3_0_0_,
        user0_.address as address4_0_0_ 
    from
        t_user user0_ 
    where
        user0_.uid=?
User [uid=1, username=lucy, password=123, address=china]

修改操作

(1)根據id查詢,返回物件

// 4 修改操作
// 修改uid=2記錄username值
User user = session.get(User.class, 2);
//4.2向返回的user物件裡面設定修改之後的值
user.setUsername("dongfangbubai");
//4.3 呼叫session方法update修改
//執行過程:到user物件裡面找到uid值,根據uid進行修改
session.update(user);

底層程式碼

Hibernate: 
    select
        user0_.uid as uid1_0_0_,
        user0_.username as username2_0_0_,
        user0_.password as password3_0_0_,
        user0_.address as address4_0_0_ 
    from
        t_user user0_ 
    where
        user0_.uid=?
Hibernate: 
    update
        t_user 
    set
        username=?,
        password=?,
        address=? 
    where
        uid=?

刪除操作

// 4 刪除操作
// 第一種 根據id查詢物件
User user = session.get(User.class, 2);
session.delete(user);

第二種刪除方式

//第二種
User user = new User();
user.setUid(3);
session.delete(user);

 

save和update

在表中已經有了uid值為1的資料,再執行下面語句,有的(主鍵不是自動增長的)執行會報錯,有的會另外增加一條資料(uid值不一樣)。

User user = new User();
user.setUid(1);
user.setUsername("mary");
user.setPassword("250");
user.setAddress("yuenan");
        
session.save(user);

同樣下面程式碼,執行不會報錯,

User user = new User();
user.setUid(1);
user.setUsername("tom");
        
session.update(user);

但是導致剩餘沒有賦值的欄位為空

所以一般都不建議這樣做。

實體類物件狀態(概念)

1 實體類狀態有三種

(1)瞬時態:物件裡面沒有id值,物件與session沒有關聯

User u = new User();
        u.setUsername("jack");
        u.setPassword("124");
        u.setAddress("China");
        session.save(u);

(2)持久態:物件有id值,物件與session有關聯

User user = session.get(User.class, 1);

(3)託管態:物件有id值,物件與session沒有關聯

User user = new User();
user.setUid(3);

2 演示操作實體類物件的方法

(1)saveOrUpdate方法:實現新增、實現修改

瞬時態物件

//1 新增操作
User user = new User();
user.setUsername("jack");
user.setPassword("520");
user.setAddress("north korean");
        
//實體類物件狀態是瞬時態,做新增操作
session.saveOrUpdate(user);

 託管態物件

User user = new User();
user.setUid(2);//表中有uid為2的資料
user.setUsername("rose");
user.setPassword("1234");
user.setAddress("aerbaliya");
        
//實體類物件狀態是託管態,做修改操作
session.saveOrUpdate(user);

查詢先後結果如下所示:

持久態物件

//持久態
User user = session.get(User.class,7);
user.setUsername("rose");
        
//實體類物件狀態是持久態,做修改操作
session.saveOrUpdate(user);
        

執行報錯,不知是不是主鍵沒有設定動態增長的原因。

 

Hibernate的一級快取

 什麼是快取

 1 資料存到資料庫裡面,資料庫本身是檔案系統,使用流方式操作檔案,效率並不是很高。

(1)把資料存到記憶體中,不需要使用流的方式,可以直接讀取記憶體中資料

(2)把資料放到記憶體中,提供讀取效率

Hibernate快取

1 hibernate框架中提供了很多優化方式,hibernate的快取就是一種優化方式

2 hibernate快取特點:

第一類 hiberante的一級快取

(1)hibernate的一級快取預設開啟的

(2)hibernate的一級快取使用範圍,是session的範圍,從session建立到session關閉範圍

(3)hibernate的一級快取中,儲存資料必須是持久態資料

第二類 hibernate的二級快取

(1)目前已經不使用了,替代技術redis

(2)二級快取預設不是開啟的,需要配置

(3)二級快取使用範圍,是sessionFactory範圍

驗證一級快取存在

1 驗證方式

(1)首先根據uid=1查詢,返回物件

(2)其次再根據uid=1查詢,返回物件

//1 根據uid=2查詢
        // 執行第一個get方法是否查詢資料庫,是否傳送sql語句
        User user1 = session.get(User.class, 2);
        System.out.println(user1);
        
        //2 再根據uid=6查詢
        //執行第二個get方法是否查詢資料庫,是否傳送sql語句
        User user2 = session.get(User.class, 2);
        System.out.println(user2);

 

Hibernate: 
    select
        user0_.uid as uid1_0_0_,
        user0_.username as username2_0_0_,
        user0_.password as password3_0_0_,
        user0_.address as address4_0_0_ 
    from
        t_user user0_ 
    where
        user0_.uid=?
User [uid=2, username=rose, password=5678, address=aerbaliya]
User [uid=2, username=rose, password=5678, address=aerbaliya]

第一步執行get方法之後,傳送sql語句查詢資料庫

第二個執行get方法之後,沒有傳送sql語句,查詢一級快取內容。

一級快取的執行過程