Hibernate筆記

JavaEE的三層結(jié)構(gòu)

  1. web層:struts2框架
  2. service層:spring框架
  3. dao層:hibernate框架
    MVC思想
  4. m:模型
  5. v:視圖
  6. c:控制器

1 Hibernate概述

1.1 框架

1.1.1 通俗理解

就是少寫部分代碼實(shí)現(xiàn)功能

1.2 Hibernate框架

  1. hibernate框架應(yīng)用在JavaEE三層結(jié)構(gòu)中的dao層
  2. 在dao層hibernate實(shí)現(xiàn)CRUD操作,hibernate底層就是JDBC,對JDBC進(jìn)行封裝,好處是不需要寫復(fù)雜的
    JDBC代碼了,不需要寫SQL語句實(shí)現(xiàn)
  3. hibernate開源輕量級框架
  4. hibernate 版本
    Hibernate3.x
    Hibernate4.x
    Hibernate5.x(2017最新)

1.3 底層實(shí)現(xiàn)

1.3.1 ORM思想
  1. hibernate使用ORM思想對數(shù)據(jù)庫進(jìn)行CRUD操作
  2. 在web階段學(xué)習(xí)Javabean更正確的叫法交:實(shí)體類
  3. ORM:Object Relational Mapping 對象關(guān)系映射
    實(shí)體類數(shù)據(jù)庫 表進(jìn)行一一對應(yīng)關(guān)系
    實(shí)體類數(shù)據(jù)庫 表進(jìn)行對應(yīng)
    實(shí)體類 屬性 里面 字段 對應(yīng)
    不需要操作數(shù)據(jù)庫而是直接操作對應(yīng)的實(shí)體類對象

2 Hibernate使用

2.1 入門

2.1.1 hibernate開發(fā)環(huán)境搭建
1)導(dǎo)入jar包

下載hibernate-release-5.2.10.Final
①壓縮包中的lib中的required文件夾內(nèi)的jar包
②jpa的jar包也在required內(nèi)
③日志jar包.hibernate本身沒有日志輸出jar包,需導(dǎo)入其他日志輸出jar包 log4j,slf4j-log4j,slf4j-api
④mysqk驅(qū)動(dòng)jar包mysql-connector-java

2)創(chuàng)建實(shí)體Bean類

hibernate 要求有個(gè)實(shí)體類有一個(gè)屬性唯一
(可以手動(dòng)在mysql中創(chuàng)建表與bean類屬性對應(yīng),也可以由hibernate自己創(chuàng)建)

package cn.wanxp.entity;

public class User {
    public int getUid() {
        return uid;
    }
    public void setUid(int uid) {
        this.uid = uid;
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }
    /*hibernate 要求有個(gè)實(shí)體類有一個(gè)屬性唯一*/
    private int uid;
    private String username;
    private String password;
    private String address;
}

3) 配置實(shí)體類和數(shù)據(jù)庫表一一對應(yīng)關(guān)系(映射關(guān)系)

實(shí)用配置文件實(shí)現(xiàn)映射關(guān)系
(1) 創(chuàng)建xml格式的配置文件
映射文件的名稱和位置沒有固定要求
-- 建議在實(shí)體類的所在包內(nèi) 實(shí)體類名稱.hbm.xml
(2) 配置文件是xml格式,在配置文件中引入xml約束
-- hibernate里面引入的約束是dtd格式
(3)在包內(nèi)創(chuàng)建映射文件User.hbm.xml
約束可以是本地文件在hibernate-release-5.2.10.Final內(nèi)可搜索到,復(fù)制與User放一起然后寫

<!DOCTYPE hibernate-mapping SYSTEM "hibernate-mapping-3.0.dtd" >  

也可以是網(wǎng)上公用的DTD文件,如果是使用網(wǎng)上的dtd約束則

<!DOCTYPE hibernate-mapping PUBLIC   
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"   
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">  
<!-- 上面這段約束可在hibernate-mapping-3.0.dtd中開頭部分找到 -->      
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping SYSTEM "hibernate-mapping-3.0.dtd" >
<hibernate-mapping>
    <!-- 1配置類和表對應(yīng)
        class標(biāo)簽
            name 屬性: 實(shí)體類全路徑
            table 屬性:數(shù)據(jù)庫名稱(隨意名稱)
     -->
     <class name="cn.wanxp.entity.User" table="t_user">
        <!-- 2配置實(shí)體類id和表id一一對應(yīng)
            要求兩id在各自位置具有唯一性
         -->
         <!-- 
            id標(biāo)簽
                name屬性: 實(shí)體類里面id屬性名稱
                column屬性:生成表字段名稱(名稱隨意)
          -->
         <id name="uid" column="uid">
            <!--設(shè)置數(shù)據(jù)表id增長策略  
                native 生成表id是主鍵和自增長
            -->
            <generator class="native"></generator>
         </id>
         <!-- 配置其他屬性與字段對應(yīng) 
            name屬性:實(shí)體類屬性名稱  
            column屬性:數(shù)據(jù)表字段名稱
         -->
         <property name="username" column="username"></property>
         <property name="password" column="password"></property>
         <property name="address" column="address"></property>
     </class>
    
</hibernate-mapping>
4)創(chuàng)建hibernate的核心配置文件

(1)核心配置文件格式xml,配置文件名稱和位置固定
-位置: 必須src下面
-名稱: 必須hibernate.cfg.xml
(2)引入約束

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

(3)hibernate 操作過程中只會(huì)加載核心配置文件,其它配置文件不會(huì)加載
第一部分:配置數(shù)據(jù)庫信息
第二部分:配置hibernate信息
第三部分:映射文件放在核心配置文件中
注意
①方言
注意下面的這句:是MySQL5Dialect,不是properties文件中的MySQLDialect因?yàn)榘姹静灰粯恿耍?br> 不然無法創(chuàng)建表。原因就是使用沒有5的會(huì)用創(chuàng)建命令type=,而不是engine=

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

②字符集
-1- 如要使用字符集utf8,想要支持中文時(shí):
先創(chuàng)建數(shù)據(jù)庫database加上字符集:create database hibernate_day01 charset utf8 ;
然后在hibernate.cfg.xml加上下面標(biāo)簽屬性,表示和數(shù)據(jù)庫傳遞數(shù)據(jù)采用utf8編碼

<property name="connection.useUnicode">true</property>
<property name="connection.characterEncoding">UTF-8</property>

hibernate.cfg.xml文件如下

<?xml version="1.0" encoding="UTF-8"?>
<!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>
    <!-- 第一部分:配置數(shù)據(jù)庫信息 
        在下載的hibernate-release壓縮包文件夾內(nèi)搜索hibernate.properties打開后可看到對應(yīng)的數(shù)據(jù)庫需要配置的屬性
    -->
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate_day01</property>
        <property name="hibernate.connection.username">root</property>
        <property name="hibernate.connection.password">root</property>
        <property name="connection.useUnicode">true</property>
    <property name="connection.characterEncoding">UTF-8</property>
    <!-- 第二部分:配置hibernate信息,可選的,可以配置也可以不用配置
        同樣能在hibernate.properties搜索到相應(yīng)的值
     -->
        <!-- 如:輸出底層sql語句 -->
        <property name="hibernate.show_sql">true</property>
        <!-- 如:格式化底層sql語句 -->
        <property name="hibernate.format_sql">true</property>
        <!-- 如:hibernate創(chuàng)建表,需要配置后
            update:如果已經(jīng)存在表則更新,若不存在則創(chuàng)建
         -->
        <property name="hibernate.hbm2ddl.auto">update</property>
        <!-- 配置數(shù)據(jù)庫方言
            mysql里實(shí)現(xiàn)分頁關(guān)鍵字 limit 只能在mysql里面
            Oracle數(shù)據(jù)庫,實(shí)現(xiàn)分頁rownum
            在hibernate框架識(shí)別不同數(shù)據(jù)庫自己特有的語句
         -->
        <property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
        
    <!-- 第三部分:配置映射文件 -->
        <!-- resource引入路徑根目錄是src -->
        <mapping resource="/cn/wanxp/entity/User.hbm.xml" />
    </session-factory>
</hibernate-configuration>
5)測試 添加操作 1-4,6,7寫法基本都是固定的,變化的只有第5步

(1)加載hibernate核心配置文件
(2)創(chuàng)建SessionFactory對象
(3)使用SessionFactory創(chuàng)建session對象
(4)開啟事務(wù)
(5)寫具體邏輯
(6)提交事務(wù)
(7)關(guān)閉資源
示例如下

package cn.wanxp.hibernatetest;


import java.io.UnsupportedEncodingException;

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

import cn.wanxp.entity.User;

public class HibernateDemo {
    @Test
    public void testAdd() {
//      (1)加載hibernate核心配置文件  
            //在hibernate里面封裝對象  
            //將會(huì)到src下找到hibernate.cfg.xml的文件
        Configuration cfg = new Configuration();
        cfg.configure();
//      (2)創(chuàng)建SessionFactory對象 
            //讀取hibernate核心配置文件,創(chuàng)建SessionFactory
            //過程中根據(jù)配置文件中的屬性以及映射關(guān)系xml文件創(chuàng)建表
        SessionFactory sessionFactory=cfg.buildSessionFactory();
//      (3)使用SessionFactory創(chuàng)建session對象
            //類似于JDBC連接
        Session session = sessionFactory.openSession();
//      (4)開啟事務(wù)  
        Transaction tx = session.beginTransaction();
//      (5)寫具體邏輯編寫CRUD操作  
         User user = new User();
         String username="張三";
         user.setUsername(username);
         user.setPassword("password1");
         user.setAddress("上海");
         session.save(user);
//      (6)提交事務(wù)  
        tx.commit();
//      (7)關(guān)閉資源 
        session.close();
        sessionFactory.close();
    }
}

效果如下:

hibernate-first-test

2 hibernate詳解

2.1 hibernate配置文件

2.1.1 hibernate映射配置文件
  • 映射文件沒有固定位置
    映射配置文件中,標(biāo)簽name屬性寫實(shí)體類中的屬性名;column可以不用寫,字段名就會(huì)命名為實(shí)體類屬性同一名字。
    property標(biāo)簽type屬性可以設(shè)置數(shù)據(jù)表的字段屬性。
2.1.2 核心配置文件

標(biāo)簽位置要求:

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

配置的三部分要求

  • 數(shù)據(jù)庫部分--必須
  • hibernate部分--可選
  • 映射文件--必須

2.2 hibernate核心api

2.2.1 Configuration
Configuration cfg = new Configuration();
cfg.configure();

上面代碼的過程:從src下找到hibernate.cfg.xml文件并根據(jù)里面的配置,創(chuàng)建對象并加載

2.2.2 SessionFactory
  1. 根據(jù)配置文件中的屬性創(chuàng)建表
<!-- 如:hibernate創(chuàng)建表,需要配置后
  update:如果已經(jīng)存在表則更新,若不存在則創(chuàng)建  
 -->
<property name="hibernate.hbm2ddl.auto">update</property>
  1. 創(chuàng)建SessionFactory過程,特別耗費(fèi)資源,所以一般一個(gè)項(xiàng)目只創(chuàng)建一次
  2. 具體實(shí)現(xiàn)
    (1)寫工具類,寫靜態(tài)代碼塊
package cn.wanxp.utils;

import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class HibernateUtils {
    private static Configuration cfg = null;
    private static SessionFactory sessionFactory = null;
    static {
        cfg = new Configuration();
        cfg.configure();
        sessionFactory = cfg.buildSessionFactory();
        
    }
    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }
}
2.2.3 Session
  1. Sesssion不同方法實(shí)現(xiàn)CRUD操作
    (1) 添加:save
    (2) 修改:update
    (3) 刪除:delete
    (4) 根據(jù)id查詢:get
  2. session對象單線程對象
    (1) session對象不能共用,只能自己使用
2.2.4 Transaction
  1. 事務(wù)對象
Transaction tx =  session.beginTransaction();
  1. 事物提交和回滾方法
tx.commit();
tx.rollback();
  1. 事物
    (1) 事物四個(gè)特性
    原子性、一致性、隔離性、持久性
2.3 配置文件沒有提示

復(fù)制下面的uri

http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd

Eclipse->Preferences->XML Catalog->Add->

location---找到hibernate-configuration-3.0.dtd    
uri----http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd

這樣就能不用聯(lián)網(wǎng)就能使用http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd

3 hibernate

3.1 實(shí)體類編寫

3.1.1 編寫規(guī)則

1) 私有域
2) set-get方法
3) 實(shí)體類有屬性有唯一值
4) 實(shí)體類建議不使用基本類型,使用基本數(shù)據(jù)類型的包裝類
(1) int--Integer,char--Character
(2) 比如表示學(xué)生分?jǐn)?shù)用int就只能表示分?jǐn)?shù)大小,不能使用null表示沒參加,而是用Integer就能解決這個(gè)問題了

3.2 Hibernate主鍵生成策略

1) hibernate要求實(shí)體類厘米嗎必須有一個(gè)屬性作為唯一值,對應(yīng)表主鍵,主鍵可以不同生成策略
2) hibernate主鍵生成策略有很多值
3) 在class里面的值
主要: native,uuid
UUID生成策略的實(shí)體類屬性表id的類型是String類型

private String uid;
<generator>

3.3 Hibernate CRUD

3.3.1 增
User user = new User();
user.setUsername("李四");
user.setPassword("123456");
user.setAddress("上海");
session.save(user);
3.3.2 刪

方法1 查詢-刪除

User user =session.get(User.class , 3);
session.delete(user);

方法2 設(shè)置-刪除

User user = new User();
user.setId(3);
session.delete(user);
3.3.3 改

方法1

方法2 查詢-修改

//李四換成王五
package cn.wanxp.hibernatetest;

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

import cn.wanxp.entity.User;
import cn.wanxp.utils.HibernateUtils;

public class HibernateDemoDay02 {
    @Test
    public void testAdd() {
//      直接調(diào)用SessionFactory調(diào)用靜態(tài)調(diào)用方法   
        SessionFactory sessionFactory = HibernateUtils.getSessionFactory();
//      (3)使用SessionFactory創(chuàng)建session對象
            //類似于JDBC連接
        Session session = sessionFactory.openSession();
//      (4)開啟事務(wù)  
        Transaction tx = session.beginTransaction();
//      (5)寫具體邏輯編寫CRUD操作  
         User user = new User();
         String username="李四";
         user.setUsername(username);
         user.setPassword("password1");
         user.setAddress("上海");
         session.save(user);   
         
         System.out.println(user);
         
         user = session.get(User.class , 3);
         user.setUsername("王五");
         session.update(user);  
         user = session.get(User.class , 3);
         System.out.println(user);
//      (6)提交事務(wù)  
        tx.commit();
//      (7)關(guān)閉資源 
        session.close();
        sessionFactory.close();
    }
}

3.3.4 查
User user = session.get(User.class,2);//查詢并返回id=2的user

3.3.5 save,update,saveOrUpdate

save:id沒有效果 ,只會(huì)直接添加
update:id的對應(yīng)記錄更新所有內(nèi)容

3.4 實(shí)體類對象狀態(tài)

3.4.1實(shí)體類狀態(tài)三種狀態(tài)

1)瞬時(shí)態(tài),對象里面沒有id值,對象與session沒有關(guān)聯(lián)

User user = new User();
user.setUsername("Jack");
user.setPassword("password");
user.setAddress("上海");

2)持久態(tài),對象里有id值,與session相關(guān)聯(lián)

User user = session.get(User.class , 3);
  1. 托管態(tài),對象里有id值,與session沒有關(guān)聯(lián)
user.setId(3);
3.4.2演示操作實(shí)體類對象的方法
  1. saveOrUpdate方法:
  • 實(shí)體類狀態(tài)瞬時(shí)態(tài),這個(gè)方法做的是添加操作
  • 實(shí)體類狀態(tài)托管態(tài),這個(gè)方法做的是修改操作
  • 實(shí)體類狀態(tài)持久態(tài),這個(gè)方法做的是修改操作

4 hibernate的優(yōu)化

4.1 緩存

hibernate有兩級緩存:一級緩存,二級緩存

4.1.1 一級緩存

1)第一類 hibernate一級緩存特點(diǎn)
(1)hibernate的一級緩存默認(rèn)打開的
(2)hibernate的一級緩存適用范圍,是session范圍,從session創(chuàng)建到session關(guān)閉范圍
(3)hibernate的一級緩存中,存儲(chǔ)數(shù)據(jù)必須持久態(tài)數(shù)據(jù)
2)第二類hibernate的二級緩存
(1)目前 已經(jīng)不適用了,替代技術(shù)redis
(2)二級緩存默認(rèn)不是打開的,需要配置
(3)二級緩存使用范圍,是SessionFactory范圍

4.1.2 驗(yàn)證一級緩存的存在

1)驗(yàn)證方式
(1)首先根據(jù)uid=1查詢,返回對象
(2)再次根據(jù)uid=1查詢,返回對象
第二次查詢將不會(huì)查詢數(shù)據(jù)庫而是直接拿出數(shù)據(jù)

4.1.3 一級緩存過程

session.get(),會(huì)先去一級緩存中查詢,若沒有則去數(shù)據(jù)庫,若有直接拿出。
session范圍是指從創(chuàng)建到close();

4.1.4 一級緩存的特點(diǎn)

持久態(tài)會(huì)自動(dòng)執(zhí)行

User user = session.get(User.class , 3);//將對象保存至一級緩存和快照區(qū)
user.setUsername("趙武");   //會(huì)同時(shí)修改:修改user對象里的值,修改持久態(tài)對象的值,修改一級緩存中的內(nèi)容,不會(huì)修改快照區(qū)內(nèi)容
tx.commit();//執(zhí)行到這里即使沒有update,也會(huì)修改數(shù)據(jù)庫
//commit做的內(nèi)容:提交事務(wù),做的事情,比較一級緩存和快照區(qū)內(nèi)容是否相同,若不同則將一級緩存內(nèi)容寫入數(shù)據(jù)庫,若相同則不修改    

效果圖如下

效果圖

4.2 事務(wù)詳解

4.2.1 什么是事務(wù)
4.2.2 事務(wù)的特性

原子性,一致性,隔離性,持久性

4.2.3 不考慮隔離性產(chǎn)生的問題
  1. 臟讀
    2)不可重復(fù)讀
    3)虛讀
4.2.4 設(shè)置事務(wù)隔離級別

1)mysql默認(rèn)隔離級別 repeateable read
2)級別設(shè)置 在hibernate.cfg.xml中

<!--
  1-Read uncommited isolation
  2-Read commited isolation
  4-Repeatable read isolation
  8-Serializable isolation
-->
<property name="hibernate.connection.isolation">4</property>
4.2.5 hibernate規(guī)范的事務(wù)寫法
try{
  //開啟事務(wù)
  //提交事務(wù)
}catch(){
  //回滾事務(wù)
}final{
  //關(guān)閉操作
}
@Test
public void testRollback() {
  SessionFactory sessionFactory = null;
  Session session = null;
  Transaction tx = null;
  try {
    sessionFactory = HibernateUtils.getSessionFactory();
    session = sessionFactory.openSession();
    tx = session.beginTransaction();
    User user = session.get(User.class , 3); 
    user.setUsername("毛毛");
    tx.commit();
  }catch(Exception e) {
    e.printStackTrace();
    tx.rollback();
  }finally{
    session.close();
    sessionFactory.close();
  }
}

4.3 hibernate綁定session線程

4.3.2 介紹

為了保證session是單線程的,而不會(huì)被其它人使用。
注意 由于與本地線程綁定,所以不需要關(guān)閉session了,因?yàn)楸镜鼐€程一完成,session自動(dòng)關(guān)閉

4.3.2 配置
  1. hibernate.cfg.xml中配置
<property name="hibernate.current_session_context_class">thread</property>
  1. 調(diào)用SessionFactory對象里的的方法得到
public static Session getSessionObject(){
  return sessionFactory.getCurrentSession();
}

5 hibernate的api使用

5.1 查詢

Query對象,Criteria對象 SQLQuery對象

5.1.1 Query對象

1)使用Query對象不需要寫sql語句,但是寫hql語句
(1)hql:hibernate query language,hibernate提供查詢語句
這個(gè)hql語句和普通sql很相似
(2) hql和sql語句區(qū)別
sql操作表和字段
hql操作實(shí)體類和屬性
2)查詢所有hql語句:
(1)from實(shí)體類名稱
3) Query對象使用
(1)創(chuàng)建 Query對象
(2)調(diào)用Query對象里的方法得到結(jié)果

Query query = session.createQuery("from User");
List<User> list = query.list();
5.1.2 Criteria對象

1) Query對象使用
(1)創(chuàng)建 Query對象
(2)調(diào)用Query對象里的方法得到結(jié)果

Criteria criteria = session.createCriteria(User.class);
List<User> list = query.list();
5.1.3 SQLQuery對象
  1. 使用SQL底層語句
    2) SQLQuery對象使用
    (1)創(chuàng)建 Query對象
    (2)調(diào)用Query對象里的方法得到結(jié)果(默認(rèn)是數(shù)組)
SQLQuer sqlQuery = session.createSQLQuery("select * from t_user where username='張三'");
//默認(rèn)返回的數(shù)組
List list = query.list();

(3)調(diào)用Query對象里的方法得到結(jié)果為對象的做法

SQLQuer sqlQuery = session.createSQLQuery("select * from t_user where username='張三'");
sqlQuery.addEntity(User.class);
List<User> list = query.list();

6 hibernate的表關(guān)系操作

6.1 表的關(guān)系

1)一對多
一個(gè)分類有多個(gè)商品
2)多對多
訂單與商品,一個(gè)訂單多個(gè)商品,一個(gè)商品多個(gè)訂單
3)一對一
丈夫與妻子

6.2 一對多

6.2.1 一對多表創(chuàng)建

1)創(chuàng)建“一”實(shí)體類并在里面創(chuàng)建“多”的Set(集合)如HashSet
2)創(chuàng)建“多”實(shí)體類并在里面創(chuàng)建“一”的實(shí)體的對象作為私有域
3)創(chuàng)建“一”實(shí)體類映射表,將基本的私有域建立好映射
4)創(chuàng)建“多”實(shí)體類映射表,將基本的私有域建立好映射
5)在配置文件中配置一對多關(guān)系
6)創(chuàng)建核心配置文件hibernate.cfg.xml
下面是一個(gè)例子,客戶(企業(yè))類,每個(gè)(客戶)企業(yè)都有很多員工的聯(lián)系方式,客戶表-員工聯(lián)系方式表就是一對多的關(guān)系

①----客戶實(shí)體類 Customer.java

package cn.wanxp.entity;

import java.util.HashSet;
import java.util.Set;


public class Customer {

    public Integer getCid() {
        return cid;
    }
    public void setCid(Integer cid) {
        this.cid = cid;
    }
    public String getCustomerName() {
        return customerName;
    }
    public void setCustomerName(String customerName) {
        this.customerName = customerName;
    }
    public String getCustomerLevel() {
        return customerLevel;
    }
    public void setCustomerLevel(String customerLevel) {
        this.customerLevel = customerLevel;
    }
    public String getCustomerSource() {
        return customerSource;
    }
    public void setCustomerSource(String customerSource) {
        this.customerSource = customerSource;
    }
    public String getCustomerPhone() {
        return customerPhone;
    }
    public void setCustomerPhone(String customerPhone) {
        this.customerPhone = customerPhone;
    }
    public String getCustomerMobile() {
        return customerMobile;
    }
    public void setCustomerMobile(String customerMobile) {
        this.customerMobile = customerMobile;
    }
    
    //在客戶實(shí)體類中表示多個(gè)聯(lián)系人,一個(gè)客戶對應(yīng)多個(gè)聯(lián)系人   
    //hibernate要求使用集合表示多的數(shù)據(jù),使用Set集合
    private Set<Linkman> setLinkman = new HashSet<Linkman>();
    
    
    public Set<Linkman> getSetLinkman() {
        return setLinkman;
    }
    public void setSetLinkman(Set<Linkman> setLinkman) {
        this.setLinkman = setLinkman;
    }

    private Integer cid;
    private String customerName;
    private String customerLevel;
    private String customerSource;
    private String customerPhone;
    private String customerMobile;
}

②----”多“的表實(shí)體類Linkman.java

package cn.wanxp.entity;

public class Linkman {
    public Integer getLid() {
        return lid;
    }
    public void setLid(Integer lid) {
        this.lid = lid;
    }
    public String getLinkmanName() {
        return linkmanName;
    }
    public void setLinkmanName(String linkmanName) {
        this.linkmanName = linkmanName;
    }
    public String getLinkmanGender() {
        return linkmanGender;
    }
    public void setLinkmanGender(String linkmanGender) {
        this.linkmanGender = linkmanGender;
    }
    public String getLinkmanPhone() {
        return linkmanPhone;
    }
    public void setLinkmanPhone(String linkmanPhone) {
        this.linkmanPhone = linkmanPhone;
    }
    
    //在聯(lián)系人實(shí)體類里表示所屬客戶,一個(gè)聯(lián)系人屬于一個(gè)客戶
    private Customer customer = new Customer();
    
    
    public Customer getCustomer() {
        return customer;
    }
    public void setCustomer(Customer customer) {
        this.customer = customer;
    }

    private Integer lid;
    private String linkmanName;
    private String linkmanGender;
    private String linkmanPhone;
}

③----Customer實(shí)體配置文件Customer.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping SYSTEM "hibernate-mapping-3.0.dtd" >
<hibernate-mapping>
     <class name="cn.wanxp.entity.Customer" table="t_customer">
         <id name="cid" column="cid">
            <generator class="native"></generator>
         </id>
         <property name="customerName" column="customerName"></property>
         <property name="customerLevel" column="customerLevel"></property>
         <property name="customerSource" column="customerSource"></property>
         <property name="customerPhone" column="customerPhone"></property>
         <property name="customerMobile" column="customerMobile"></property>
         <!-- 在客戶映射文件中,表示所有聯(lián)系人,使用set標(biāo)簽表示所有聯(lián)系人 
                set標(biāo)簽里面有name屬性:屬性值寫在客戶實(shí)體類里面表示聯(lián)系惡人的set集合名稱
         -->
         <set name="setLinkman">
            <!-- 一對多建表,有外鍵。hibernate機(jī)制:雙向維護(hù)外鍵,在一和多都有配置外鍵 
                column屬性值:外鍵名稱
            -->
            <key column="cid"></key>
            <one-to-many class="cn.wanxp.entity.Linkman"/>
         </set>
     </class>
</hibernate-mapping>

④----Linkman配置文件 Linkman.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping SYSTEM "hibernate-mapping-3.0.dtd" >
<hibernate-mapping>
     <class name="cn.wanxp.entity.Linkman" table="t_linkman">
        <id name="lid" column="lid">
            <generator class="native"></generator>
         </id>
         <property name="linkmanName" column="linkmanName"></property>
         <property name="linkmanGender" column="linkmanGender"></property>
         <property name="linkmanPhone" column="linkmanPhone"></property>
         <!-- 在聯(lián)系人中配置所屬客戶 
            name屬性:因?yàn)樵诼?lián)系人實(shí)體類使用Customer對象表示。寫customer名稱
            class屬性:Customer全路徑
            column屬性是生成的表格存儲(chǔ)Customer的id的列名稱要與Customer.hbm.xml中key一致
         -->
         <many-to-one name="customer" class="cn.wanxp.entity.Customer" column="cid"></many-to-one>
     </class>
</hibernate-mapping>

⑤----同樣需要將配置文件加入到hibernate核心配置文件中

<mapping resource="/cn/wanxp/entity/Customer.hbm.xml" />
<mapping resource="/cn/wanxp/entity/Linkman.hbm.xml" />

⑥----測試效果

package cn.wanxp.hibernatetest;
import java.io.UnsupportedEncodingException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.Test;
import cn.wanxp.entity.User;
public class HibernateDemoDay03 {
    @Test
    public void testOneToMany() {
        Configuration cfg = new Configuration();
        cfg.configure();
        SessionFactory sessionFactory=cfg.buildSessionFactory();
        Session session = sessionFactory.openSession();
        Transaction tx = session.beginTransaction();
        tx.commit();
        session.close();
        sessionFactory.close();
    }
}

⑦----輸出結(jié)果

Hibernate: 
    
    create table t_customer (
       cid integer not null auto_increment,
        customerName varchar(255),
        customerLevel varchar(255),
        customerSource varchar(255),
        customerPhone varchar(255),
        customerMobile varchar(255),
        primary key (cid)
    ) engine=MyISAM
Hibernate: 
    
    create table t_linkman (
       lid integer not null auto_increment,
        linkmanName varchar(255),
        linkmanGender varchar(255),
        linkmanPhone varchar(255),
        cid integer,
        primary key (lid)
    ) engine=MyISAM
Hibernate: 
    
    alter table t_linkman 
       add constraint FKn4dw5i2knad5dl95xit4v1b0p 
       foreign key (cid) 
       references t_customer (cid)
6.2.1 一對多表操作

1)一對多級聯(lián)保存 -- 復(fù)雜寫法
直接在session中設(shè)置并保存

package cn.wanxp.hibernatetest;
import java.io.UnsupportedEncodingException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.Test;

import cn.wanxp.entity.Customer;
import cn.wanxp.entity.Linkman;
import cn.wanxp.entity.User;
import cn.wanxp.utils.HibernateUtils;
public class HibernateDemoDay03 {
    @Test
    public void testOneToManyAdd() {
        SessionFactory sessionFactory = null;
        Session session = null;
        Transaction tx = null;
        Customer customer = new Customer();
        Linkman linkman = new Linkman();
        try {
            sessionFactory = HibernateUtils.getSessionFactory();
            session = sessionFactory.openSession();
            tx = session.beginTransaction();
            //1創(chuàng)建客戶和聯(lián)系人對象并設(shè)置基本域值
            linkman.setLinkmanName("李四");
            linkman.setLinkmanGender("男");
            linkman.setLinkmanPhone("131313");
            
            customer.setCustomerName("聯(lián)想");
            customer.setCustomerSource("web");
            customer.setCustomerLevel("vip");
            customer.setCustomerPhone("3333");
            customer.setCustomerMobile("1111");
            
            //2在客戶表中和聯(lián)系人表中連接部分分別添加對方
            linkman.setCustomer(customer);
            customer.getSetLinkman().add(linkman);
            //3使用save存儲(chǔ)進(jìn)數(shù)據(jù)表中
            session.save(customer);
            session.save(linkman);
            
            tx.commit();
        }catch(Exception e) {
            e.printStackTrace();
            tx.rollback();
        }finally {
            session.close();
            sessionFactory.close();
        }
    }
}

2)一對多級聯(lián)保存 -- 簡單寫法
第一步在客戶映射文件中進(jìn)行配置
修改Customer.hbm.xml配置文件中的set標(biāo)簽,在set標(biāo)簽中添加 cascade="save-update"屬性

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

上面的HibernateDemoDay03.java就可以修改為

package cn.wanxp.hibernatetest;
import java.io.UnsupportedEncodingException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.Test;

import cn.wanxp.entity.Customer;
import cn.wanxp.entity.Linkman;
import cn.wanxp.entity.User;
import cn.wanxp.utils.HibernateUtils;
public class HibernateDemoDay03 {
   @Test
   public void testOneToManyAdd() {
       SessionFactory sessionFactory = null;
       Session session = null;
       Transaction tx = null;
       Customer customer = new Customer();
       Linkman linkman = new Linkman();
       try {
           sessionFactory = HibernateUtils.getSessionFactory();
           session = sessionFactory.openSession();
           tx = session.beginTransaction();
           //1創(chuàng)建客戶和聯(lián)系人對象并設(shè)置基本域值
           linkman.setLinkmanName("李四");
           linkman.setLinkmanGender("男");
           linkman.setLinkmanPhone("131313");
           
           customer.setCustomerName("聯(lián)想");
           customer.setCustomerSource("web");
           customer.setCustomerLevel("vip");
           customer.setCustomerPhone("3333");
           customer.setCustomerMobile("1111");
           
           //2在客戶表中添加聯(lián)系人實(shí)體類對象,相互
     linkman.setCustomer(customer);
           customer.getSetLinkman().add(linkman);
           //3使用save存儲(chǔ)進(jìn)數(shù)據(jù)表中
           session.save(customer);
           
           tx.commit();
       }catch(Exception e) {
           e.printStackTrace();
           tx.rollback();
       }finally {
           session.close();
           sessionFactory.close();
       }
   }
}

效果如下

hibernate-one-to-many-add

3)一對多刪除
如,刪除某個(gè)客戶,把客戶里面所有的聯(lián)系人刪除

① 在客戶映射文件中進(jìn)行配置(多個(gè)值用逗號隔開)
修改Customer.hbm.xml配置文件中的set標(biāo)簽,在set標(biāo)簽中添加 cascade="save-update,delete"屬性

<set name="setLinkman" cascade="save-update,delete">

② 在代碼中直接刪除
先根據(jù)id查找客戶然后刪除

@Test
public void testOneToManyDelete() {
  SessionFactory sessionFactory = null;
  Session session = null;
  Transaction tx = null;
  Customer customer = new Customer();
  Linkman linkman = new Linkman();
  try {
    sessionFactory = HibernateUtils.getSessionFactory();
    session = sessionFactory.openSession();
    tx = session.beginTransaction();
    
    customer = session.get(Customer.class, 1);
    session.delete(customer);
    
    tx.commit();
  }catch(Exception e) {
    e.printStackTrace();
    tx.rollback();
  }finally {
    session.close();
    sessionFactory.close();
  }
}

效果如下

效果

3)一對多修改
(1)如將多方的ABC三個(gè)記錄中的C的外鍵Y修改為一方的XY中的X

Customer X=session.get(Customer.class,1);
Linkman C=session.get(Linkman.class,3);
X.getSetLinkman().add(C);

(2)一對多的里面,可以讓其中一方放棄維護(hù),用以提高效率。一般讓一放棄維護(hù),多的維護(hù)
(3)具體實(shí)現(xiàn)放棄維護(hù)
set標(biāo)簽中的inverse屬性:放棄true,不放棄false(默認(rèn))

<set name="setLinkman" inverse="true" cascade="save-update,delete">
6.2.2 多對多表
  1. 多對多映射配置
    (1)創(chuàng)建實(shí)體類,用戶和角色
    Person.java
package cn.wanxp.entity;
import java.util.HashSet;
import java.util.Set;
public class Person {
    public Integer getPid() {
        return pid;
    }
    public void setPid(Integer pid) {
        this.pid = pid;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Set<Role> getSetRole() {
        return setRole;
    }
    public void setSetRole(Set<Role> setRole) {
        this.setRole = setRole;
    }
    private Integer pid;
    private String name;
    private Set<Role> setRole = new HashSet<Role>();
}

Role.java

package cn.wanxp.entity;
import java.util.HashSet;
import java.util.Set;
public class Role {
    public Integer getRid() {
        return rid;
    }
    public void setRid(Integer rid) {
        this.rid = rid;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Set<Person> getSetPerson() {
        return setPerson;
    }
    public void setSetPerson(Set<Person> setPerson) {
        this.setPerson = setPerson;
    }
    private Integer rid;
    private String name;
    private Set<Person> setPerson = new HashSet<Person>();
}

(2)讓兩個(gè)實(shí)體類之間相互表示
①用戶里表示所有角色,使用set集合
②一個(gè)角色有多個(gè)用戶,使用set集合
(3)配置映射
①基本配置
②配置多對多關(guān)系
person.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping SYSTEM "hibernate-mapping-3.0.dtd" >
<hibernate-mapping>
     <class name="cn.wanxp.entity.Person" table="t_person">
         <id name="pid" column="pid">
            <generator class="native"></generator>
         </id>
         <property name="name" column="name"></property>
         <!-- 在客戶映射文件中,表示所有聯(lián)系人,使用set標(biāo)簽表示所有聯(lián)系人 
                set標(biāo)簽里面有name屬性:屬性值寫在客戶實(shí)體類里面表示聯(lián)系惡人的set集合名稱
                table:第三張表名
         -->
         <set name="setRole" table="t_person_role" cascade="all">
            <!-- 一對多建表,有外鍵。hibernate機(jī)制:雙向維護(hù)外鍵,在一和多都有配置外鍵 
                key屬性 column當(dāng)前映射文件在第三張表的外鍵名稱
            -->
            <key column="person_id"></key>
            <!-- 一對多建表,有外鍵。hibernate機(jī)制:雙向維護(hù)外鍵,在一和多都有配置外鍵 
                many-to-many屬性 column值Role在第三張表的外鍵名稱
            -->         
            <many-to-many class="cn.wanxp.entity.Role" column="role_id" />
         </set>
     </class>
</hibernate-mapping>

role.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping SYSTEM "hibernate-mapping-3.0.dtd" >
<hibernate-mapping>
     <class name="cn.wanxp.entity.Role" table="t_role">
         <id name="rid" column="rid">
            <generator class="native"></generator>
         </id>
         <property name="name"  column="name"></property>
         <!-- 在客戶映射文件中,表示所有聯(lián)系人,使用set標(biāo)簽表示所有聯(lián)系人 
                set標(biāo)簽里面有name屬性:屬性值寫在客戶實(shí)體類里面表示聯(lián)系惡人的set集合名稱
         -->
         <set name="setPerson" table="t_person_role" cascade="all">
            <!-- 
            key屬性 column當(dāng)前映射文件在第三張表的外鍵名稱
            -->
            <key column="role_id"></key>
            <!-- 一對多建表,有外鍵。hibernate機(jī)制:雙向維護(hù)外鍵,在一和多都有配置外鍵 
                many-to-many屬性 column值Person在第三張表的外鍵名稱
            -->  
            <many-to-many class="cn.wanxp.entity.Person" column="person_id"/>
         </set>
     </class>
</hibernate-mapping>

--在用戶里表示所有角色,使用set標(biāo)簽
--在角色里表示所有用戶,使用set標(biāo)簽
(4)核心配置中引入配置文件
2)多對多級聯(lián)保存

public void testManyToManyAdd() {
  SessionFactory sessionFactory = null;
  Session session = null;
  Transaction tx = null;
  try {
    sessionFactory = HibernateUtils.getSessionFactory();
    session = sessionFactory.openSession();
    tx = session.beginTransaction();
    //創(chuàng)建對象
    Person p1 = new Person();
    Person p2 = new Person();           
    p1.setName("張三");
    p2.setName("李四");
    
    Role r1 = new Role();
    Role r2 = new Role();
    Role r3 = new Role();
    r1.setName("肉坦");
    r2.setName("輸出");
    r3.setName("輔助");
    
    //關(guān)聯(lián)對象
    p1.getSetRole().add(r1);
    p2.getSetRole().add(r2);
    p1.getSetRole().add(r3);

    //保存對象
    session.save(p1);
    session.save(p2);
      
    tx.commit();
  }catch(Exception e) {
    e.printStackTrace();
    tx.rollback();
  }finally {
    session.close();
    sessionFactory.close();
  }
}

效果如下

hibernate-many-to-many-add

3)多對多級聯(lián)刪除
刪除方式同一對多刪除
4)維護(hù)第三張表關(guān)系
用戶表添加角色 搜索用戶表,搜索角色表,在用戶表中添加角色,如p1.getSetRole().add(r5);
用戶表刪除角色 搜索用戶表,搜索角色表,在用戶表中刪除角色,如p1.getSetRole().remove(r2);

7 hibernate 查詢方式

7.1 對象導(dǎo)航查詢

如一對多表格 客戶與聯(lián)系人,根據(jù)某個(gè)id查詢 客戶以及下面的聯(lián)系人
先按照id搜索客戶,然后獲取set集合即可

Customer customer = session.get(Customer.class , 1);
Set<Linkman> setLinkman = customer.getSetlinkman();

7.2 OID查詢

根據(jù)id查詢某一條記錄
按照id搜索客戶

Customer customer = session.get(Customer.class , 1); 

7.3 hql查詢

Query對象,寫hql語句查詢
hql與sql類似
區(qū)別:hql操作實(shí)體類和屬性,sql操作數(shù)據(jù)庫表和字段
過程:創(chuàng)建Query對象,寫hql語句 ,調(diào)用Query對象的方法獲得結(jié)果

7.3.1 查詢所有
//from 實(shí)體類名稱
Query query = session.createQuery("from Customer");
//調(diào)用方法得到結(jié)果  
List<Customer> list = query.list();
7.3.2 條件查詢
//from 實(shí)體類名稱 where 實(shí)體類屬性名稱=? [and 實(shí)體類屬性名稱=? ...] 或者 from 實(shí)體類名稱  實(shí)體類屬性名稱 like ?
Query query = session.createQuery("from Customer c where c.cid=? and c.customerName=?"); 
//問好問號位置從0開始
query.setParameter(0,1);
query.setParameter(1,"百度");
//調(diào)用方法得到結(jié)果  
List<Customer> list = query.list();
7.3.3 排序查詢
//在上面基礎(chǔ)上 加入 order by 實(shí)體類屬性名稱 desc|asc   (desc 降序,asc 升序) 
Query query = session.createQuery("from Customer c where c.cid=? and c.customerName=?" order by c.cid desc); 
7.3.4 分頁查詢
Query query = session.createQuery("from Customer");
//設(shè)置起始位置
query.setFirstResult(0);
//設(shè)置每頁記錄數(shù)量
query.setMaxResult(3);
//調(diào)用方法得到結(jié)果  
List<Customer> list = query.list();

7.3.5 投影查詢

sql:select customerName from Customer; --查詢部分字段而不是所有字段

Query query = session.createQuery("select customerName from Customer");
list<Object> list = query.list();//注意這里的區(qū)別
7.3.6 聚集函數(shù)使用

常用count sum avg max min

//hql:select count(*) from 實(shí)體類名   
Query query = session.createQuery(" select count(*) from Customer"); 
Object obj = query.uniqueResult();

7.4 QBC查詢

1)使用hql需要寫hql語句,但使用qbc是不需要寫語句,只需要方法就行
2)使用qbc操作實(shí)體類和屬性
3)使用Criteria對象進(jìn)行操作

7.4.1 查詢所有
//創(chuàng)建Criteria對象
Criteria criteria = session.createCriteria(Customer.class);
//調(diào)用Criteria對象的方法
List<Customer> list = criteria.list();
7.4.2 條件查詢
//創(chuàng)建Criteria對象
Criteria criteria = session.createCriteria(Customer.class);
//調(diào)用Criteria對象的方法設(shè)置條件  
//add方法添加條件,參數(shù)Restrictions對象的方法,方法里傳入實(shí)體類屬性和值
criteria.add(Restrictions.eq("cid",1));
List<Customer> list = criteria.list();
7.4.3 排序查詢
//創(chuàng)建Criteria對象
Criteria criteria = session.createCriteria(Customer.class);
//調(diào)用Criteria對象的方法設(shè)置條件  
//addOrder方法添加條件,參數(shù)Order對象的方法,方法里傳入實(shí)體類屬性asc升序desc降序
criteria.addOrder(Order.asc("cid"));
List<Customer> list = criteria.list();
7.4.4 分頁查詢
//創(chuàng)建Criteria對象
Criteria criteria = session.createCriteria(Customer.class);
//調(diào)用Criteria對象的方法設(shè)置條件  
//setFirstResult(0)起始位置0,setMaxResult(3)獲得3條記錄
criteria.setFirstResult(0);
criteria.setMaxResult(3);
List<Customer> list = criteria.list();
7.4.5 統(tǒng)計(jì)查詢
//創(chuàng)建Criteria對象
Criteria criteria = session.createCriteria(Customer.class);
//調(diào)用Criteria對象的方法設(shè)置條件  
criteria.setProjection(Projections.rowCount());
Object obj = criteria.uniqueResult();
Long lobj = (Long) obj
int count = lobj.intValue();
System.out.println(count);
7.4.5 離線查詢
//創(chuàng)建DetachedCriteria對象
DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Customer.class);
Criteria criteria = detachedCriteria.getExecutableCriteria(session);
List<Customer> list = criteria.list();

7.5 本地sql查詢

SQLQuery對象,使用普通sql實(shí)現(xiàn)

8 多表查詢

8.1 內(nèi)連接

8.1.1 內(nèi)連接

sql語句:select * from t_customer as c inner join t_linkman as l on c.cid=l.lid;

Query query = session.createQuery("from Customer c inner join c.setLinkman");
//list()返回的Object對象的數(shù)字
List list = query.list();
8.1.2 迫切內(nèi)連接

1)與內(nèi)連接底層是一樣的
2)區(qū)別:使用內(nèi)連接返回list中每部分是數(shù)組,迫切內(nèi)連接返回的是對象
用法:加入關(guān)鍵字fetch

Query query = session.createQuery("from Customer c inner join fetch c.setLinkman");
//list()返回的Object對象的數(shù)字
List list = query.list();

8.2 左外連接

8.2.1 左外連接

sql語句:select * from t_customer as c left outer join t_linkman as l on c.cid=l.lid;

Query query = session.createQuery("from Customer c left outer join c.setLinkman");
//list()返回的Object對象的數(shù)字
List list = query.list();
8.2.2 迫切左外連接

效果用法區(qū)別與內(nèi)連接類似

8.3 右外連接

8.3.1 右外連接

sql語句:select * from t_customer as c right outer join t_linkman as l on c.cid=l.lid;

Query query = session.createQuery("from Customer c right outer join c.setLinkman");
//list()返回的Object對象的數(shù)字
List list = query.list();
8.3.2 迫切右外連接

效果用法區(qū)別與內(nèi)連接類似

9 hibernate檢索策略

9.1 立即查詢

如根據(jù)id查詢,調(diào)用get方法時(shí),一調(diào)用get方法立即發(fā)送查詢語句給數(shù)據(jù)庫

9.2 延遲查詢

如根據(jù)id查詢,調(diào)用load方法時(shí),調(diào)用load方法,不會(huì)立即發(fā)送查詢語句給數(shù)據(jù)庫,只有得到對象里面的值時(shí)才會(huì)發(fā)送查詢語句
分類:類級別延遲,關(guān)聯(lián)級別延遲

9.2.1 類級別延遲

就是上面那種

9.2.2 關(guān)聯(lián)類級別延遲

如查詢Customer時(shí),是否延遲查詢關(guān)聯(lián)的Linkman

默認(rèn)狀態(tài)

Customer customer = session.get(Customer.class , 1);
//執(zhí)行到這里時(shí),只發(fā)送了查詢表t_customer
Set<Linkman> setLinkman = customer.getSetlinkman();
//執(zhí)行到這里時(shí),只發(fā)送了查詢表t_customer
System.out.println(list.size());//執(zhí)行到這里將會(huì)發(fā)送查詢t_linkman表命令

修改延遲
在set標(biāo)簽上修改屬性
fetch :值select
lazy:值
----true:延遲,默認(rèn)
----false:不延遲
----extra:極其延遲,要什么值就去查什么值

10 批量查詢

如獲取所有客戶的聯(lián)系人
方式1 普通方式,效率較低

//下面這種方式經(jīng)過測試效率不高,因?yàn)槊看尾樵円粭l客戶再查詢聯(lián)系人都要發(fā)送查詢命令
Criteria criteria =session.createCriteria(Customer.class);   
List<Customer> list = criteria.list();
for(Customer customer:list){
  Systerm.out.println(customer.getId());
  Set setLinkman =customer.getSetLinkman();
  for(Linkman linkman : setLinkman){
    System.out.println(linkman.getId());
  }
}

方式2 修改配置Customer文件 ,在set標(biāo)簽中加入屬性batch-size,batch-size的值只要是整數(shù)即可,其值越大,發(fā)送的語句命令越少,效率越高

<set name = "setLinkman" batch-size="2">  
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容