Hibernate--day02

非本人總結(jié)的筆記,抄點筆記復(fù)習(xí)復(fù)習(xí)。感謝傳智博客及黑馬程序猿


記筆記啊記筆記

持久化類的狀態(tài)

持久化類三種狀態(tài)

持久化類有三種狀態(tài),區(qū)分不同的狀態(tài),使用兩種操作區(qū)分:

? 第一個 判斷對象是否有oid

? 第二個 判斷對象是否與session相關(guān)聯(lián)

1、瞬時態(tài)

沒有oid,沒有與session相關(guān)聯(lián)

User user = new User();
user.setUsername("xxx");
user.setBirthday(new Date());

2、持久態(tài)

有oid,與session相關(guān)聯(lián)

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

3、托管態(tài)

有oid,沒有與session相關(guān)聯(lián)

User user = new User();
user.setId(1);
user.setUsername("大黃蜂");

三種狀態(tài)之間轉(zhuǎn)換

三種狀態(tài)之間轉(zhuǎn)換

瞬時態(tài)

? 轉(zhuǎn)換成持久態(tài):調(diào)用save方法,saveOrUpdate方法實現(xiàn)

? 狀態(tài)成脫管態(tài):設(shè)置oid值

持久態(tài)

? 轉(zhuǎn)換成瞬時態(tài):調(diào)用delete方法實現(xiàn)

? 轉(zhuǎn)換成脫管態(tài):調(diào)用session里面的close方法實現(xiàn)

脫管態(tài)

? 轉(zhuǎn)換成瞬時態(tài):設(shè)置oid值為空

? 轉(zhuǎn)換成持久態(tài):調(diào)用update和saveOrUpdate方法實現(xiàn)

Hibernate的一級緩存

什么是緩存

把數(shù)據(jù)不放到文件系統(tǒng)中,放到系統(tǒng)內(nèi)存中,可以直接從內(nèi)存中獲取數(shù)據(jù),提高獲取數(shù)據(jù)的效率

Hibernate的緩存

Hibernate的一級緩存

在Hibernate中的一級緩存默認是打開的,一級緩存使用的范圍是session范圍的。從session創(chuàng)建,到session關(guān)閉的過程。如果session關(guān)閉了,那么一級緩存也就關(guān)閉了。

Hibernate的二級緩存

在Hibernate中的二級緩存默認不是打開的,手動設(shè)置才可以使用。二級緩存使用范圍是sessionFactory范圍的二級緩存。

驗證一級緩存的存在

第一個操作:首先添加記錄,添加完成后,根據(jù)oid進行查詢

//添加操作
User user = new User();
user.setUsername("岳不群");
user.setBirthday(new Date());

//調(diào)用save方法
Serializable id = session.save(user);

//根據(jù)返回的id值查詢
User u = (User) session.get(User.class, id);
System.out.println(u);

第一次執(zhí)行添加操作,發(fā)送sql語句,實現(xiàn)添加數(shù)據(jù)到數(shù)據(jù)庫

第二次根據(jù)添加之后返回的id進行查詢,沒有查詢數(shù)據(jù)庫,而是查詢一級緩存內(nèi)容

sql語句

第二個操作:第一次查詢id是1的記錄,第二次再次查詢id值是1的記錄

//第一次查詢id值是1的記錄
User user1 = (User) session.get(User.class, 1);
System.out.println(user1);

//第二次查詢id值是1的記錄
User user2 = (User) session.get(User.class, 1);
System.out.println(user2);

第一次查詢數(shù)據(jù)庫獲取數(shù)據(jù),第二次沒有查詢數(shù)據(jù)庫,查詢一級緩存的內(nèi)容

sql語句

持久態(tài)自動更新數(shù)據(jù)庫

//查詢id是2的記錄
//持久態(tài)
User user = (User) session.get(User.class, 2);
//設(shè)置要修改的值
user.setUsername("哈哈");

//調(diào)用update
//session.update(user);

不需要調(diào)用update方法實現(xiàn)修改

一級緩存的快照區(qū)(副本)

//查詢id是2的記錄
//持久態(tài)
User user = (User) session.get(User.class, 2);
//設(shè)置要修改的值
user.setUsername("哈哈");

//調(diào)用update
//session.update(user);

首先根據(jù)id查詢用戶數(shù)據(jù),返回user是持久態(tài)對象。

首先把返回的持久態(tài)user對象放到一級緩存中,另外,把user對象復(fù)制一份,再放到一級緩存對應(yīng)的快照區(qū)。

設(shè)置了持久態(tài)對象里面的值的時候(修改了user里面的值),執(zhí)行之后

首先,同步更新一級緩存中的內(nèi)容;其次,但是不會更新對應(yīng)快照區(qū)的內(nèi)容

提交了事務(wù)之后,實現(xiàn)比較一級緩存和快照區(qū)的內(nèi)容是否相同,如果不相同,把一級緩存中的內(nèi)容更新到數(shù)據(jù)庫里

一級緩存使用Java的集合存儲,使用map集合

Key是一級緩存,Value是快照區(qū)

圖一
圖二

操作持久化類的方法

常用的方法

描述 方法
添加 save()
修改 update()
刪除 delete()
根據(jù)id查詢 get()、load()
添加或修改 saveOrUpdate()

saveOrUpdate方法使用(保存、修改)

這個方法可以實現(xiàn)添加操作,也可以實現(xiàn)修改操作。根據(jù)實體類的不同狀態(tài)實現(xiàn)不同的操作

第一個 實現(xiàn)添加操作

當(dāng)實體類狀態(tài)是瞬時態(tài)時候,調(diào)用這個方法實現(xiàn)添加操作

//實現(xiàn)添加操作
//瞬時態(tài)
User user = new User();
user.setUsername("東方不敗");
user.setBirthday(new Date());

//執(zhí)行saveOrUpdate方法
session.saveOrUpdate(user);

第二個 實現(xiàn)修改操作

持久化類狀態(tài)是持久態(tài)和脫管態(tài)時,實現(xiàn)修改操作

//實現(xiàn)修改操作
User user = (User) session.get(User.class, 1);
user.setUsername("令狐沖");

//調(diào)用方法
session.saveOrUpdate(user);

//脫管態(tài)
User user = new User();
user.setId(2);
user.setUsername("任盈盈");
user.setBirthday(new Date());

//調(diào)用方法
session.saveOrUpdate(user);

load方法使用(延遲查詢)

load方法和get方法相同,根據(jù)id查詢數(shù)據(jù),返回對象

區(qū)別:

? get方法:立刻查詢,執(zhí)行方法之后,馬上查詢數(shù)據(jù)庫

? load方法:延遲查詢,執(zhí)行l(wèi)oad方法之后,不會馬上查詢數(shù)據(jù)庫,得到返回對象里面的值的時候才會去查詢數(shù)據(jù)庫

//get方法查詢
User user = (User) session.get(User.class, 1);
System.out.println(user);

執(zhí)行g(shù)et方法之后,立刻發(fā)送語句查詢數(shù)據(jù)庫

//load方法查詢
User user = (User) session.load(User.class, 3);
System.out.println(user.getId());
System.out.println(user.getUsername());

執(zhí)行l(wèi)oad方法之后,沒有發(fā)送sql語句查詢數(shù)據(jù)庫,返回實體類對象中只有一個id值,但是得到實體類對象中除了id值之外其他值的時候,才會發(fā)送sql語句查詢數(shù)據(jù)庫

Hibernate的一對多關(guān)系映射

內(nèi)容回顧

表與表之間關(guān)系

一對多

范例:一個客戶可以有多個訂單,一個訂單只能屬于一個客戶

建表原則:在多的那一端創(chuàng)建字段作為外鍵,指向一的那一端的主鍵

示例

多對多

范例:一定訂單里面可以有多個商品,一個商品可以屬于多個訂單;一個學(xué)生可以選擇多個課程,一個課程可以被多個學(xué)生選擇

建表原則:創(chuàng)建第三張表,至少有兩個字段,左為外鍵,指向另外兩張表的主鍵

示例

一對一

范例:一個公司對應(yīng)一個注冊地址,一個注冊地址只能有一個公司

Hibernate的一對多關(guān)系映射

第一步 創(chuàng)建客戶和訂單的實體類

第二步 讓實體類之間相互表示

客戶實體類 Customer

package cn.itcast.onetomany;

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

/**
 * 客戶實體類
 */
public class Customer {

    private Integer cid;
    private String cname;
    private String address;
    
    //在客戶里面表示所有的訂單
    //第二步使用集合表示 set集合  set集合有序的  并且內(nèi)容不重復(fù)
    private Set<Orders> setOrders = new HashSet<Orders>();
    public Set<Orders> getSetOrders() {
        return setOrders;
    }
    public void setSetOrders(Set<Orders> setOrders) {
        this.setOrders = setOrders;
    }
    public Integer getCid() {
        return cid;
    }
    public void setCid(Integer cid) {
        this.cid = cid;
    }
    public String getCname() {
        return cname;
    }
    public void setCname(String cname) {
        this.cname = cname;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }   
}

訂單實體類 Orders

package cn.itcast.onetomany;
/**
 * 訂單實體類
 */
public class Orders {

    private Integer oid;
    private String oname;
    private Integer price;
    
    //第二步表示訂單所屬的客戶
    private Customer customer;
    public Customer getCustomer() {
        return customer;
    }
    public void setCustomer(Customer customer) {
        this.customer = customer;
    }
    public Integer getOid() {
        return oid;
    }
    public void setOid(Integer oid) {
        this.oid = oid;
    }
    public String getOname() {
        return oname;
    }
    public void setOname(String oname) {
        this.oname = oname;
    }
    public Integer getPrice() {
        return price;
    }
    public void setPrice(Integer price) {
        this.price = price;
    }
    
}

第三步 使用映射文件配置一對多關(guān)系(兩個映射文件)

創(chuàng)建客戶映射文件 Customer.hbm.xml 一的一方

<?xml version="1.0" encoding="UTF-8"?>
<!--引入約束-->
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <!--name值Customer實體類的全路徑   table表名 隨便寫-->
    <class name="cn.itcast.onetomany.Customer" table="CUSTOMER">
        <!-- 配置cid; name值與實體類一致column隨意-->
        <id name="cid" column="CID">
            <!-- 配置生成策略 -->
            <generator class="native"></generator>
        </id>
        <!-- 其他的屬性 name值與實體類一致column隨意-->
        <property name="cname" column="CNAME"></property>
        <property name="address" column="ADDRESS"></property>
        <!-- 配置客戶的所有的訂單
            set標簽上面的name:客戶里面所有訂單的set集合的名稱  
         -->
         <set name="setOrders">
            <!-- 一對多里面,外鍵雙向維護關(guān)系
                column: 外鍵名稱  一致
             -->
            <key column="coid"></key>
            <!-- 指定訂單實體類位置 
                class: 訂單實體類全路徑
            -->
            <one-to-many class="cn.itcast.onetomany.Orders"></one-to-many>
         </set>
    </class>
</hibernate-mapping>

創(chuàng)建訂單映射文件夾 Order.hbm.xml 多的一方

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <!--name值Customer實體類的全路徑   table表名 隨便寫-->
     <class name="cn.itcast.onetomany.Orders" table="ORDERS">
         <!-- 配置oid; name值與實體類一致column隨意-->
        <id name="oid" column="OID">
            <!-- 配置生成策略 -->
            <generator class="native"></generator>
        </id>
         <!-- 其他的屬性 name值與實體類一致column隨意-->
        <property name="oname" column="ONAME"></property>
        <property name="price" column="PRICE"></property>
        <!-- 配置訂單所屬哪個用戶 one many  
            name: 在訂單實體類定義用戶類的屬性名稱  
            class: 用戶實體類的全路徑
            column: 外鍵名稱
        -->
        <many-to-one name="customer"
        class="cn.itcast.onetomany.Customer" column="coid" ></many-to-one>
    </class>
</hibernate-mapping>

第四步 需要把配置的映射文件引入到核心文件中

創(chuàng)建核心配置文件 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ù)庫的相關(guān)信息 -->
    <property name="hibernate.connection.driver_class">
        com.mysql.jdbc.Driver
    </property>
    <property name="hibernate.connection.url">
        jdbc:mysql:///hibernate_day02
    </property>
    <property name="hibernate.connection.username">root</property>
    <property name="hibernate.connection.password">root</property>
    <!-- 配置數(shù)據(jù)庫的方言 
        比如在mysql里面有關(guān)鍵字  limit ,只能使用在mysql里面
        讓hibernate識別到不同數(shù)據(jù)庫自己特有的語句
    -->
    <property name="hibernate.dialect">
        org.hibernate.dialect.MySQLDialect
    </property>

    <!-- 配置hibernate的相關(guān)信息 -->
    <!-- 是否顯示底層的sql語句 -->
    <property name="hibernate.show_sql">true</property>
    <!-- 是否格式化sql語句 -->
    <property name="hibernate.format_sql">true</property>
    <!-- hibernate會幫自己創(chuàng)建數(shù)據(jù)庫表,默認不會創(chuàng)建,需要配置 
        值 update: 如果數(shù)據(jù)庫里面不存在表,創(chuàng)建;如果已經(jīng)存在,更新
    -->
    <property name="hibernate.hbm2ddl.auto">update</property>
    <!-- 引入映射配置文件 -->
    <mapping resource="cn/itcast/onetomany/Customer.hbm.xml" />
    <mapping resource="cn/itcast/onetomany/Orders.hbm.xml" />

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

第五步 創(chuàng)建工具類運行建表

創(chuàng)建工具類HibernateUtils工具類,并添加main方法

package cn.itcast.utils;

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

/**
 * 創(chuàng)建sessionFactory對象
 */
public class HibernateUtils {
    
    static Configuration cfg = null;
    static SessionFactory sessionFactory  = null;
    //靜態(tài)代碼塊
    static {
        cfg = new Configuration();
        cfg.configure();
        //創(chuàng)建sessionFactory
        sessionFactory  = cfg.buildSessionFactory();
    }

    //提供得到Session的方法
    public static Session getSession() {
        Session session = sessionFactory.openSession();
        return session;
    }
    
    public static void main(String[] args) {
        
    }
}

一對多的級聯(lián)保存(同時向多個表里添加數(shù)據(jù))

有客戶,有訂單。比如添加一個客戶,同時添加這個客戶對應(yīng)多個訂單

原始方式:(開發(fā)一般不用)

創(chuàng)建TestOneToMany類

package cn.itcast.hibernate.test;

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

import cn.itcast.onetomany.Customer;
import cn.itcast.onetomany.Orders;
import cn.itcast.utils.HibernateUtils;

/**
 * 演示級聯(lián)保存操作
 */
public class TestOneToMany {
    
    @Test
    public void testSave1() {
        Session session = null;
        Transaction tx = null;
        try {
            session = HibernateUtils.getSession();
            tx = session.beginTransaction();
            //第一步創(chuàng)建不同對象
            //添加一個用戶
            Customer c1 = new Customer();
            c1.setCname("小奧");
            c1.setAddress("美國");
            
            //添加用戶對于的兩個訂單
            Orders o1 = new Orders();
            o1.setOname("飛機");
            o1.setPrice(10);
            
            Orders o2 = new Orders();
            o2.setOname("航空母艦");
            o2.setPrice(20);
            //第二步互相表示
            //設(shè)置用戶和訂單之間的關(guān)聯(lián)關(guān)系
            //表示用戶里面有兩個訂單 
            //把兩個訂單放到customer的set集合里面
            c1.getSetOrders().add(o1);
            c1.getSetOrders().add(o2);
            
            //表示兩個訂單所屬的用戶
            o1.setCustomer(c1);
            o2.setCustomer(c1);
            //第三步添加這些對象
            //調(diào)用方法保存
            session.save(c1);
            session.save(o1);
            session.save(o2);
            
            tx.commit();
        }catch(Exception e) {
            e.printStackTrace();
            tx.rollback();
        }finally {
            session.close();
        }
    }
}

這種方法如果只保存用戶 或者只保存訂單,不能進行操作,出現(xiàn)異常

異常

級聯(lián)保存另外實現(xiàn)方式(都使用)

設(shè)置互相表示的關(guān)系的時候,只需要設(shè)置一方,可以直接保存一方就可以了

但是在哪一方進行保存,需要在哪一方配置cascade="save-update"

通過客戶進行保存

創(chuàng)建TestOneToMany測試類

package cn.itcast.hibernate.test;

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

import cn.itcast.onetomany.Customer;
import cn.itcast.onetomany.Orders;
import cn.itcast.utils.HibernateUtils;

/**
 * 演示級聯(lián)保存操作
 */
public class TestOneToMany {

//演示通過用戶進行保存
    @Test
    public void testSave2() {
        Session session = null;
        Transaction tx = null;
        try {
            session = HibernateUtils.getSession();
            tx = session.beginTransaction();
            //第一步 創(chuàng)建實體類對象
            //添加一個用戶
            Customer c1 = new Customer();
            c1.setCname("小溫");
            c1.setAddress("中國");
            
            //添加用戶對于的兩個訂單
            Orders o1 = new Orders();
            o1.setOname("籃球");
            o1.setPrice(30);
            
            Orders o2 = new Orders();
            o2.setOname("足球");
            o2.setPrice(20);
            //第二步 設(shè)置用戶所有的訂單
            //設(shè)置用戶里面的所有的訂單
            c1.getSetOrders().add(o1);
            c1.getSetOrders().add(o2);
            //第三步 直接保存用戶對象
            //保存用戶
            session.save(c1);
            
            tx.commit();
        }catch(Exception e) {
            e.printStackTrace();
            tx.rollback();
        }finally {
            session.close();
        }
    }
}   

第四步 在用戶的映射文件中配置 Customer.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<!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="cn.itcast.onetomany.Customer" table="CUSTOMER">
        <!-- 配置oid -->
        <id name="cid" column="CID">
            <!-- 配置生成策略 -->
            <generator class="native"></generator>
        </id>
        <!-- 其他的屬性 -->
        <property name="cname" column="CNAME"></property>
        <property name="address" column="ADDRESS"></property>
        <!-- 配置客戶的所有的訂單
            set標簽上面的name:客戶里面所有訂單的set集合的名稱  
            cascade="save-update" : 級聯(lián)保存        
            cascade="delete"
         -->
         <set name="setOrders" cascade="save-update">
            <!-- 一對多里面,外鍵雙向維護關(guān)系
                column: 外鍵名稱
             -->
            <key column="coid"></key>
            <!-- 指定訂單實體類位置 
                class: 訂單實體類全路徑
            -->
            <one-to-many class="cn.itcast.onetomany.Orders"></one-to-many>
         </set>
    </class>
</hibernate-mapping>

通過訂單進行保存

創(chuàng)建TestOneToMang測試類

package cn.itcast.hibernate.test;

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

import cn.itcast.onetomany.Customer;
import cn.itcast.onetomany.Orders;
import cn.itcast.utils.HibernateUtils;

/**
 * 演示級聯(lián)保存操作
 */
public class TestOneToMany {

//演示通過訂單進行保存
    @Test
    public void testSave3() {
        Session session = null;
        Transaction tx = null;
        try {
            session = HibernateUtils.getSession();
            tx = session.beginTransaction();
            //第一步 創(chuàng)建實體類對象
            //添加一個用戶
            Customer c1 = new Customer();
            c1.setCname("小江");
            c1.setAddress("中國");
            
            //添加用戶對于的兩個訂單
            Orders o1 = new Orders();
            o1.setOname("眼鏡");
            o1.setPrice(30);
            
            Orders o2 = new Orders();
            o2.setOname("汽車2");
            o2.setPrice(20);
            //第二步 設(shè)置用戶所有的訂單
            //設(shè)置訂單所屬的用戶
            o1.setCustomer(c1);
            o2.setCustomer(c1);
            //第三步 直接保存用戶對象
            //保存訂單
            session.save(o1);
            session.save(o2);
            
            tx.commit();
        }catch(Exception e) {
            e.printStackTrace();
            tx.rollback();
        }finally {
            session.close();
        }
    }
}

第四步 在訂單的映射文件中配置 Order.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<!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="cn.itcast.onetomany.Orders" table="ORDERS">
        <id name="oid" column="OID">
            <generator class="native"></generator>
        </id>
        <property name="oname" column="ONAME"></property>
        <property name="price" column="PRICE"></property>
        <!-- 配置訂單所屬哪個用戶 one many  
            name: 在訂單實體類定義用戶類的屬性名稱
            class: 用戶實體類的全路徑
            column: 外鍵名稱
            cascade="save-update" : 級聯(lián)保存
        -->
        <many-to-one name="customer" 
                class="cn.itcast.onetomany.Customer" column="coid" cascade="save-update"></many-to-one>
    </class>
</hibernate-mapping>

一對多的級聯(lián)刪除(同時刪除多個表里面管理的數(shù)據(jù))

不配置方法用戶刪除但是只是把訂單變?yōu)閚ull(不用)

創(chuàng)建TestOneToMany類

package cn.itcast.hibernate.test;

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

import cn.itcast.onetomany.Customer;
import cn.itcast.onetomany.Orders;
import cn.itcast.utils.HibernateUtils;

/**
 * 演示級聯(lián)刪除操作
 */
public class TestOneToMany {

    //級聯(lián)刪除操作
    @Test
    public void testDelete1() {
        Session session = null;
        Transaction tx = null;
        try {
            session = HibernateUtils.getSession();
            tx = session.beginTransaction();
            
            //刪除cid值是1的記錄
            Customer c1 = (Customer) session.get(Customer.class, 3);
            //刪除操作
            session.delete(c1);
            
            tx.commit();
        }catch(Exception e) {
            e.printStackTrace();
            tx.rollback();
        }finally {
            session.close();
        }
    }
}

根據(jù)用戶刪除配置方法(都用)

在hibernate的一對多的進行刪除操作時候

比如刪除用戶,首先把用戶關(guān)聯(lián)的訂單的外鍵設(shè)置為NULL,再刪除用戶

1、創(chuàng)建TestOneToMany類

package cn.itcast.hibernate.test;

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

import cn.itcast.onetomany.Customer;
import cn.itcast.onetomany.Orders;
import cn.itcast.utils.HibernateUtils;

/**
 * 演示級聯(lián)刪除操作
 */
public class TestOneToMany {

//級聯(lián)刪除操作
    @Test
    public void testDelete1() {
        Session session = null;
        Transaction tx = null;
        try {
            session = HibernateUtils.getSession();
            tx = session.beginTransaction();
            
            //刪除cid值是1的記錄
            Customer c1 = (Customer) session.get(Customer.class, 3);
            //刪除操作
            session.delete(c1);
            
            tx.commit();
        }catch(Exception e) {
            e.printStackTrace();
            tx.rollback();
        }finally {
            session.close();
        }
    }
}

2、在用戶的映射文件中配置 hibernate.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<!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="cn.itcast.onetomany.Customer" table="CUSTOMER">
        <!-- 配置oid -->
        <id name="cid" column="CID">
            <!-- 配置生成策略 -->
            <generator class="native"></generator>
        </id>
        <!-- 其他的屬性 -->
        <property name="cname" column="CNAME"></property>
        <property name="address" column="ADDRESS"></property>
        <!-- 配置客戶的所有的訂單
            set標簽上面的name:客戶里面所有訂單的set集合的名稱  
            cascade="save-update" : 級聯(lián)保存        
            cascade="delete"
            cascade="save-update,delete"多個屬性用,號隔開
         -->
         <set name="setOrders" cascade="save-update,delete">
            <!-- 一對多里面,外鍵雙向維護關(guān)系
                column: 外鍵名稱
             -->
            <key column="coid"></key>
            <!-- 指定訂單實體類位置 
                class: 訂單實體類全路徑
            -->
            <one-to-many class="cn.itcast.onetomany.Orders"></one-to-many>
         </set>
    </class>
</hibernate-mapping>    

根據(jù)訂單刪除配置方法(不用)

1、創(chuàng)建TestOneToMany類

package cn.itcast.hibernate.test;

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

import cn.itcast.onetomany.Customer;
import cn.itcast.onetomany.Orders;
import cn.itcast.utils.HibernateUtils;

/**
 * 演示級聯(lián)刪除操作
 */
public class TestOneToMany {

    //級聯(lián)刪除操作
    @Test
    public void testDelete2() {
        Session session = null;
        Transaction tx = null;
        try {
            session = HibernateUtils.getSession();
            tx = session.beginTransaction();
            
            //刪除oid值是1的訂單
            Orders o1 = (Orders) session.get(Orders.class, 1);
            //刪除操作
            session.delete(o1);
            
            tx.commit();
        }catch(Exception e) {
            e.printStackTrace();
            tx.rollback();
        }finally {
            session.close();
        }
    }
}

2、在訂單的映射文件中配置 Orders.hbml.xml

<?xml version="1.0" encoding="UTF-8"?>
<!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="cn.itcast.onetomany.Orders" table="ORDERS">
        <id name="oid" column="OID">
            <generator class="native"></generator>
        </id>
        <property name="oname" column="ONAME"></property>
        <property name="price" column="PRICE"></property>
        <!-- 配置訂單所屬哪個用戶 one many  
            name: 在訂單實體類定義用戶類的屬性名稱
            class: 用戶實體類的全路徑
            column: 外鍵名稱
            delete刪除
        -->
        <many-to-one name="customer" 
                class="cn.itcast.onetomany.Customer" column="coid" cascade="delete"></many-to-one>
    </class>
</hibernate-mapping>

Hibernate的多對多關(guān)系映射

第一步 創(chuàng)建實體類

第二步 讓學(xué)生和課程的實體類相關(guān)聯(lián)

學(xué)生類 student

package cn.itcast.manytomany;

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

public class Student {

    private Integer sid;
    private String sname;
    private String address;
    
    //第二步 學(xué)生選擇課程 ,一個學(xué)生可以選擇多門課程
    private Set<Course> setCourse = new HashSet<Course>();
    public Set<Course> getSetCourse() {
        return setCourse;
    }
    public void setSetCourse(Set<Course> setCourse) {
        this.setCourse = setCourse;
    }
    public Integer getSid() {
        return sid;
    }
    public void setSid(Integer sid) {
        this.sid = sid;
    }
    public String getSname() {
        return sname;
    }
    public void setSname(String sname) {
        this.sname = sname;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }
}

課程類 Course

package cn.itcast.manytomany;

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

public class Course {

    private Integer cid;
    private String cname;
    
    // 第二步  在課程端表示被哪些學(xué)生選擇,一門課程可以被多個學(xué)生選擇
    private Set<Student> setStudent = new HashSet<Student>();
    public Set<Student> getSetStudent() {
        return setStudent;
    }
    public void setSetStudent(Set<Student> setStudent) {
        this.setStudent = setStudent;
    }
    public Integer getCid() {
        return cid;
    }
    public void setCid(Integer cid) {
        this.cid = cid;
    }
    public String getCname() {
        return cname;
    }
    public void setCname(String cname) {
        this.cname = cname;
    }
    
}

第三步 使用映射文件配置多對多關(guān)系(兩個映射文件)

學(xué)生映射文件 student.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<!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="cn.itcast.manytomany.Student" table="STUDENT">
        <id name="sid" column="SID">
            <generator class="native"></generator>
        </id>
        <property name="sname"></property>
        <property name="address"></property>
        <!-- 配置學(xué)生選擇的多門課程 -->
        <set name="setCourse" table="STU_COURSE">
            <!-- 當(dāng)前配置的實體類  student 在第三張表里面外鍵名稱-->
            <key column="s_id"></key>
            <!-- class: 課程全路徑
                column:課程表在第三張表外鍵名稱
             -->
            <many-to-many class="cn.itcast.manytomany.Course" column="c_id"></many-to-many>
        </set>
    </class>    
</hibernate-mapping>   

課程映射文件 Course.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<!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="cn.itcast.manytomany.Course" table="COURSE">
         <id name="cid" column="CID">
            <generator class="native"></generator>
         </id>
         <property name="cname"></property>
         <!-- 配置課程被哪些學(xué)生選擇 -->
         <set name="setStudent" table="STU_COURSE">
            <!-- 當(dāng)前配置的課程 course 在第三張表里面的外鍵名稱 -->
            <key column="c_id"></key>
            <!-- 
                class: 學(xué)生的全路徑
                column:學(xué)生表在第三張表外鍵名稱
             -->
            <many-to-many class="cn.itcast.manytomany.Student" column="s_id"></many-to-many>
         </set>
    </class>    
</hibernate-mapping>

第四步 需要把配置的映射文件引入到核心配置文件中

核心配置文件 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ù)庫的相關(guān)信息 -->
    <property name="hibernate.connection.driver_class">
        com.mysql.jdbc.Driver
    </property>
    <property name="hibernate.connection.url">
        jdbc:mysql:///hibernate_day02
    </property>
    <property name="hibernate.connection.username">root</property>
    <property name="hibernate.connection.password">root</property>
    <!-- 配置數(shù)據(jù)庫的方言 
        比如在mysql里面有關(guān)鍵字  limit ,只能使用在mysql里面
        讓hibernate識別到不同數(shù)據(jù)庫自己特有的語句
    -->
    <property name="hibernate.dialect">
        org.hibernate.dialect.MySQLDialect
    </property>

    <!-- 配置hibernate的相關(guān)信息 -->
    <!-- 是否顯示底層的sql語句 -->
    <property name="hibernate.show_sql">true</property>
    <!-- 是否格式化sql語句 -->
    <property name="hibernate.format_sql">true</property>
    <!-- hibernate會幫自己創(chuàng)建數(shù)據(jù)庫表,默認不會創(chuàng)建,需要配置 
        值 update: 如果數(shù)據(jù)庫里面不存在表,創(chuàng)建;如果已經(jīng)存在,更新
    -->
    <property name="hibernate.hbm2ddl.auto">update</property>
    <!-- 引入映射配置文件 -->
    <mapping resource="cn/itcast/manytomany/Course.hbm.xml" />
    <mapping resource="cn/itcast/manytomany/Student.hbm.xml" />

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

第五步 創(chuàng)建工具類運行建表

HibernateUtils工具類 main方法

package cn.itcast.utils;

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

/**
 * 創(chuàng)建sessionFactory對象
 */
public class HibernateUtils {
    
    static Configuration cfg = null;
    static SessionFactory sessionFactory  = null;
    //靜態(tài)代碼塊
    static {
        cfg = new Configuration();
        cfg.configure();
        //創(chuàng)建sessionFactory
        sessionFactory  = cfg.buildSessionFactory();
    }

    //提供得到Session的方法
    public static Session getSession() {
        Session session = sessionFactory.openSession();
        return session;
    }
    
    public static void main(String[] args) {
        
    }
}

多對多級聯(lián)保存

創(chuàng)建TestManyToMany類

package cn.itcast.hibernate.test;

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

import cn.itcast.manytomany.Course;
import cn.itcast.manytomany.Student;
import cn.itcast.onetomany.Customer;
import cn.itcast.onetomany.Orders;
import cn.itcast.utils.HibernateUtils;

/**
 * 多對多操作
 */
public class TestManyToMany {
    //根據(jù)課程保存
    @Test
    public void testSave2() {
        Session session = null;
        Transaction tx = null;
        try {
            session = HibernateUtils.getSession();
            tx = session.beginTransaction();
            
            //添加兩個學(xué)生
            Student s1 = new Student();
            s1.setSname("tom");
            s1.setAddress("usa");
            
            Student s2 = new Student();
            s2.setSname("jack");
            s2.setAddress("japan");
            
            //添加課程
            Course c1 = new Course();
            c1.setCname("ui設(shè)計");
            
            Course c2 = new Course();
            c2.setCname("java開發(fā)");
            
            Course c3 = new Course();
            c3.setCname("韓語");
            
            //根據(jù)課程保存
            // s1 -- c1/c2
            // s2 -- c1/c3
            c1.getSetStudent().add(s1);
            c1.getSetStudent().add(s2);
            c2.getSetStudent().add(s1);
            c3.getSetStudent().add(s2);
            
            //保存
            session.save(c1);
            session.save(c2);
            session.save(c3);
            
            tx.commit();
        }catch(Exception e) {
            e.printStackTrace();
            tx.rollback();
        }finally {
            session.close();
        }
    }
    //根據(jù)學(xué)生保存
    @Test
    public void testSave1() {
        Session session = null;
        Transaction tx = null;
        try {
            session = HibernateUtils.getSession();
            tx = session.beginTransaction();
            
            //添加兩個學(xué)生
            Student s1 = new Student();
            s1.setSname("lucy");
            s1.setAddress("china");
            
            Student s2 = new Student();
            s2.setSname("mary");
            s2.setAddress("japan");
            
            //添加課程
            Course c1 = new Course();
            c1.setCname("汽車修理");
            
            Course c2 = new Course();
            c2.setCname("美容美發(fā)");
            
            Course c3 = new Course();
            c3.setCname("廚師");
            
            //根據(jù)學(xué)生保存
            // s1 --- c1 / c2
            // s2 ---- c2 / c3
            s1.getSetCourse().add(c1);
            s1.getSetCourse().add(c2);
            s2.getSetCourse().add(c2);
            s2.getSetCourse().add(c3);
            
            //保存
            session.save(s1);
            session.save(s2);
            
            tx.commit();
        }catch(Exception e) {
            e.printStackTrace();
            tx.rollback();
        }finally {
            session.close();
        }
    }   
}

根據(jù)學(xué)生保存 配置學(xué)生映射student.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<!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="cn.itcast.manytomany.Student" table="STUDENT">
        <id name="sid" column="SID">
            <generator class="native"></generator>
        </id>
        <property name="sname"></property>
        <property name="address"></property>
        <!-- 配置學(xué)生選擇的多門課程     cascade="save-update" -->
        <set name="setCourse" table="STU_COURSE" cascade="save-update">
            <!-- 當(dāng)前配置的實體類  student 在第三張表里面外鍵名稱-->
            <key column="s_id"></key>
            <!-- class: 課程全路徑
                column:課程表在第三張表外鍵名稱
             -->
            <many-to-many class="cn.itcast.manytomany.Course" column="c_id"></many-to-many>
        </set>
    </class>    
</hibernate-mapping>

根據(jù)課程保存 Courses.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<!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="cn.itcast.manytomany.Course" table="COURSE">
         <id name="cid" column="CID">
            <generator class="native"></generator>
         </id>
         <property name="cname"></property>
         <!-- 配置課程被哪些學(xué)生選擇   cascade="save-update"-->
         <set name="setStudent" table="STU_COURSE" cascade="save-update">
            <!-- 當(dāng)前配置的課程 course 在第三張表里面的外鍵名稱 -->
            <key column="c_id"></key>
            <!-- 
                class: 學(xué)生的全路徑
                column:學(xué)生表在第三張表外鍵名稱
             -->
            <many-to-many class="cn.itcast.manytomany.Student" column="s_id"></many-to-many>
         </set>
    </class>    
</hibernate-mapping>

多對多級聯(lián)刪除(不用)

創(chuàng)建TestManyToMany類

package cn.itcast.hibernate.test;

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

import cn.itcast.manytomany.Course;
import cn.itcast.manytomany.Student;
import cn.itcast.onetomany.Customer;
import cn.itcast.onetomany.Orders;
import cn.itcast.utils.HibernateUtils;

/**
 * 多對多操作
 */
public class TestManyToMany {
    //多對多刪除
    @Test
    public void testDelete() {
        Session session = null;
        Transaction tx = null;
        try {
            session = HibernateUtils.getSession();
            tx = session.beginTransaction();
            
            //sid=1的學(xué)生刪除
            Student s = (Student) session.get(Student.class, 1);
            session.delete(s);
            
            tx.commit();
        }catch(Exception e) {
            e.printStackTrace();
            tx.rollback();
        }finally {
            session.close();
        }
    }
}

根據(jù)學(xué)生刪除 配置學(xué)生映射student.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<!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="cn.itcast.manytomany.Student" table="STUDENT">
        <id name="sid" column="SID">
            <generator class="native"></generator>
        </id>
        <property name="sname"></property>
        <property name="address"></property>
        <!-- 配置學(xué)生選擇的多門課程   cascade="delete"-->
        <set name="setCourse" table="STU_COURSE" cascade="save-update,delete">
            <!-- 當(dāng)前配置的實體類  student 在第三張表里面外鍵名稱-->
            <key column="s_id"></key>
            <!-- class: 課程全路徑
                column:課程表在第三張表外鍵名稱
             -->
            <many-to-many class="cn.itcast.manytomany.Course" column="c_id"></many-to-many>
        </set>
    </class>    
</hibernate-mapping>

根據(jù)課程刪除 配置課程映射Courses.hbml.xml

<?xml version="1.0" encoding="UTF-8"?>
<!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="cn.itcast.manytomany.Course" table="COURSE">
         <id name="cid" column="CID">
            <generator class="native"></generator>
         </id>
         <property name="cname"></property>
         <!-- 配置課程被哪些學(xué)生選擇   cascade="delete"-->
         <set name="setStudent" table="STU_COURSE" cascade="save-update,delete">
            <!-- 當(dāng)前配置的課程 course 在第三張表里面的外鍵名稱 -->
            <key column="c_id"></key>
            <!-- 
                class: 學(xué)生的全路徑
                column:學(xué)生表在第三張表外鍵名稱
             -->
            <many-to-many class="cn.itcast.manytomany.Student" column="s_id"></many-to-many>
         </set>
    </class>    
</hibernate-mapping>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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

  • web service 相關(guān) 什么是Web Service? 答:從表面上看,Web Service就是一個應(yīng)用程...
    niuben閱讀 1,085評論 0 3
  • Hibernate: 一個持久化框架 一個ORM框架 加載:根據(jù)特定的OID,把一個對象從數(shù)據(jù)庫加載到內(nèi)存中OID...
    JHMichael閱讀 2,091評論 0 27
  • 如有轉(zhuǎn)載,請申明:轉(zhuǎn)載自 IT天宇: http://www.itdecent.cn/p/50964e92c5fb ...
    IT天宇閱讀 4,312評論 8 33
  • 我有一段友誼,好像破碎了。好像破碎的端口是從我這里開始的?,F(xiàn)在我想要用我的真心重新挽回,可是還是不能回到以前那么...
    綠PZY閱讀 258評論 0 0
  • 前言 大家晚上好,今天早上采用圖文方式獲得較好評價,繼續(xù)采用,如果大家有好的方式也可以提供建議。 鏈接 主題鏈接:...
    陳素封閱讀 274評論 0 1

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