非本人總結的筆記,抄點筆記復習復習。感謝傳智博客及黑馬程序猿
記筆記啊記筆記
持久化類的狀態
持久化類三種狀態
持久化類有三種狀態,區分不同的狀態,使用兩種操作區分:
? 第一個 判斷對象是否有oid
? 第二個 判斷對象是否與session相關聯
1、瞬時態
沒有oid,沒有與session相關聯
User user = new User();
user.setUsername("xxx");
user.setBirthday(new Date());
2、持久態
有oid,與session相關聯
User user = (User)session.get(User.class, 1);
3、托管態
有oid,沒有與session相關聯
User user = new User();
user.setId(1);
user.setUsername("大黃蜂");
三種狀態之間轉換
瞬時態
? 轉換成持久態:調用save方法,saveOrUpdate方法實現
? 狀態成脫管態:設置oid值
持久態
? 轉換成瞬時態:調用delete方法實現
? 轉換成脫管態:調用session里面的close方法實現
脫管態
? 轉換成瞬時態:設置oid值為空
? 轉換成持久態:調用update和saveOrUpdate方法實現
Hibernate的一級緩存
什么是緩存
把數據不放到文件系統中,放到系統內存中,可以直接從內存中獲取數據,提高獲取數據的效率
Hibernate的緩存
Hibernate的一級緩存
在Hibernate中的一級緩存默認是打開的,一級緩存使用的范圍是session范圍的。從session創建,到session關閉的過程。如果session關閉了,那么一級緩存也就關閉了。
Hibernate的二級緩存
在Hibernate中的二級緩存默認不是打開的,手動設置才可以使用。二級緩存使用范圍是sessionFactory范圍的二級緩存。
驗證一級緩存的存在
第一個操作:首先添加記錄,添加完成后,根據oid進行查詢
//添加操作
User user = new User();
user.setUsername("岳不群");
user.setBirthday(new Date());
//調用save方法
Serializable id = session.save(user);
//根據返回的id值查詢
User u = (User) session.get(User.class, id);
System.out.println(u);
第一次執行添加操作,發送sql語句,實現添加數據到數據庫
第二次根據添加之后返回的id進行查詢,沒有查詢數據庫,而是查詢一級緩存內容
第二個操作:第一次查詢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);
第一次查詢數據庫獲取數據,第二次沒有查詢數據庫,查詢一級緩存的內容
持久態自動更新數據庫
//查詢id是2的記錄
//持久態
User user = (User) session.get(User.class, 2);
//設置要修改的值
user.setUsername("哈哈");
//調用update
//session.update(user);
不需要調用update方法實現修改
一級緩存的快照區(副本)
//查詢id是2的記錄
//持久態
User user = (User) session.get(User.class, 2);
//設置要修改的值
user.setUsername("哈哈");
//調用update
//session.update(user);
首先根據id查詢用戶數據,返回user是持久態對象。
首先把返回的持久態user對象放到一級緩存中,另外,把user對象復制一份,再放到一級緩存對應的快照區。
設置了持久態對象里面的值的時候(修改了user里面的值),執行之后
首先,同步更新一級緩存中的內容;其次,但是不會更新對應快照區的內容
提交了事務之后,實現比較一級緩存和快照區的內容是否相同,如果不相同,把一級緩存中的內容更新到數據庫里
一級緩存使用Java的集合存儲,使用map集合
Key是一級緩存,Value是快照區
操作持久化類的方法
常用的方法
描述 | 方法 |
---|---|
添加 | save() |
修改 | update() |
刪除 | delete() |
根據id查詢 | get()、load() |
添加或修改 | saveOrUpdate() |
saveOrUpdate方法使用(保存、修改)
這個方法可以實現添加操作,也可以實現修改操作。根據實體類的不同狀態實現不同的操作
第一個 實現添加操作
當實體類狀態是瞬時態時候,調用這個方法實現添加操作
//實現添加操作
//瞬時態
User user = new User();
user.setUsername("東方不敗");
user.setBirthday(new Date());
//執行saveOrUpdate方法
session.saveOrUpdate(user);
第二個 實現修改操作
持久化類狀態是持久態和脫管態時,實現修改操作
//實現修改操作
User user = (User) session.get(User.class, 1);
user.setUsername("令狐沖");
//調用方法
session.saveOrUpdate(user);
//脫管態
User user = new User();
user.setId(2);
user.setUsername("任盈盈");
user.setBirthday(new Date());
//調用方法
session.saveOrUpdate(user);
load方法使用(延遲查詢)
load方法和get方法相同,根據id查詢數據,返回對象
區別:
? get方法:立刻查詢,執行方法之后,馬上查詢數據庫
? load方法:延遲查詢,執行load方法之后,不會馬上查詢數據庫,得到返回對象里面的值的時候才會去查詢數據庫
//get方法查詢
User user = (User) session.get(User.class, 1);
System.out.println(user);
執行get方法之后,立刻發送語句查詢數據庫
//load方法查詢
User user = (User) session.load(User.class, 3);
System.out.println(user.getId());
System.out.println(user.getUsername());
執行load方法之后,沒有發送sql語句查詢數據庫,返回實體類對象中只有一個id值,但是得到實體類對象中除了id值之外其他值的時候,才會發送sql語句查詢數據庫
Hibernate的一對多關系映射
內容回顧
表與表之間關系
一對多
范例:一個客戶可以有多個訂單,一個訂單只能屬于一個客戶
建表原則:在多的那一端創建字段作為外鍵,指向一的那一端的主鍵
多對多
范例:一定訂單里面可以有多個商品,一個商品可以屬于多個訂單;一個學生可以選擇多個課程,一個課程可以被多個學生選擇
建表原則:創建第三張表,至少有兩個字段,左為外鍵,指向另外兩張表的主鍵
一對一
范例:一個公司對應一個注冊地址,一個注冊地址只能有一個公司
Hibernate的一對多關系映射
第一步 創建客戶和訂單的實體類
第二步 讓實體類之間相互表示
客戶實體類 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集合有序的 并且內容不重復
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;
}
}
第三步 使用映射文件配置一對多關系(兩個映射文件)
創建客戶映射文件 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">
<!-- 一對多里面,外鍵雙向維護關系
column: 外鍵名稱 一致
-->
<key column="coid"></key>
<!-- 指定訂單實體類位置
class: 訂單實體類全路徑
-->
<one-to-many class="cn.itcast.onetomany.Orders"></one-to-many>
</set>
</class>
</hibernate-mapping>
創建訂單映射文件夾 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>
第四步 需要把配置的映射文件引入到核心文件中
創建核心配置文件 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>
<!-- 配置數據庫的相關信息 -->
<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>
<!-- 配置數據庫的方言
比如在mysql里面有關鍵字 limit ,只能使用在mysql里面
讓hibernate識別到不同數據庫自己特有的語句
-->
<property name="hibernate.dialect">
org.hibernate.dialect.MySQLDialect
</property>
<!-- 配置hibernate的相關信息 -->
<!-- 是否顯示底層的sql語句 -->
<property name="hibernate.show_sql">true</property>
<!-- 是否格式化sql語句 -->
<property name="hibernate.format_sql">true</property>
<!-- hibernate會幫自己創建數據庫表,默認不會創建,需要配置
值 update: 如果數據庫里面不存在表,創建;如果已經存在,更新
-->
<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>
第五步 創建工具類運行建表
創建工具類HibernateUtils工具類,并添加main方法
package cn.itcast.utils;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
/**
* 創建sessionFactory對象
*/
public class HibernateUtils {
static Configuration cfg = null;
static SessionFactory sessionFactory = null;
//靜態代碼塊
static {
cfg = new Configuration();
cfg.configure();
//創建sessionFactory
sessionFactory = cfg.buildSessionFactory();
}
//提供得到Session的方法
public static Session getSession() {
Session session = sessionFactory.openSession();
return session;
}
public static void main(String[] args) {
}
}
一對多的級聯保存(同時向多個表里添加數據)
有客戶,有訂單。比如添加一個客戶,同時添加這個客戶對應多個訂單
原始方式:(開發一般不用)
創建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;
/**
* 演示級聯保存操作
*/
public class TestOneToMany {
@Test
public void testSave1() {
Session session = null;
Transaction tx = null;
try {
session = HibernateUtils.getSession();
tx = session.beginTransaction();
//第一步創建不同對象
//添加一個用戶
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);
//第二步互相表示
//設置用戶和訂單之間的關聯關系
//表示用戶里面有兩個訂單
//把兩個訂單放到customer的set集合里面
c1.getSetOrders().add(o1);
c1.getSetOrders().add(o2);
//表示兩個訂單所屬的用戶
o1.setCustomer(c1);
o2.setCustomer(c1);
//第三步添加這些對象
//調用方法保存
session.save(c1);
session.save(o1);
session.save(o2);
tx.commit();
}catch(Exception e) {
e.printStackTrace();
tx.rollback();
}finally {
session.close();
}
}
}
這種方法如果只保存用戶 或者只保存訂單,不能進行操作,出現異常
級聯保存另外實現方式(都使用)
設置互相表示的關系的時候,只需要設置一方,可以直接保存一方就可以了
但是在哪一方進行保存,需要在哪一方配置cascade="save-update"
通過客戶進行保存
創建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;
/**
* 演示級聯保存操作
*/
public class TestOneToMany {
//演示通過用戶進行保存
@Test
public void testSave2() {
Session session = null;
Transaction tx = null;
try {
session = HibernateUtils.getSession();
tx = session.beginTransaction();
//第一步 創建實體類對象
//添加一個用戶
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);
//第二步 設置用戶所有的訂單
//設置用戶里面的所有的訂單
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" : 級聯保存
cascade="delete"
-->
<set name="setOrders" cascade="save-update">
<!-- 一對多里面,外鍵雙向維護關系
column: 外鍵名稱
-->
<key column="coid"></key>
<!-- 指定訂單實體類位置
class: 訂單實體類全路徑
-->
<one-to-many class="cn.itcast.onetomany.Orders"></one-to-many>
</set>
</class>
</hibernate-mapping>
通過訂單進行保存
創建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;
/**
* 演示級聯保存操作
*/
public class TestOneToMany {
//演示通過訂單進行保存
@Test
public void testSave3() {
Session session = null;
Transaction tx = null;
try {
session = HibernateUtils.getSession();
tx = session.beginTransaction();
//第一步 創建實體類對象
//添加一個用戶
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);
//第二步 設置用戶所有的訂單
//設置訂單所屬的用戶
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" : 級聯保存
-->
<many-to-one name="customer"
class="cn.itcast.onetomany.Customer" column="coid" cascade="save-update"></many-to-one>
</class>
</hibernate-mapping>
一對多的級聯刪除(同時刪除多個表里面管理的數據)
不配置方法用戶刪除但是只是把訂單變為null(不用)
創建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;
/**
* 演示級聯刪除操作
*/
public class TestOneToMany {
//級聯刪除操作
@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();
}
}
}
根據用戶刪除配置方法(都用)
在hibernate的一對多的進行刪除操作時候
比如刪除用戶,首先把用戶關聯的訂單的外鍵設置為NULL,再刪除用戶
1、創建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;
/**
* 演示級聯刪除操作
*/
public class TestOneToMany {
//級聯刪除操作
@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" : 級聯保存
cascade="delete"
cascade="save-update,delete"多個屬性用,號隔開
-->
<set name="setOrders" cascade="save-update,delete">
<!-- 一對多里面,外鍵雙向維護關系
column: 外鍵名稱
-->
<key column="coid"></key>
<!-- 指定訂單實體類位置
class: 訂單實體類全路徑
-->
<one-to-many class="cn.itcast.onetomany.Orders"></one-to-many>
</set>
</class>
</hibernate-mapping>
根據訂單刪除配置方法(不用)
1、創建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;
/**
* 演示級聯刪除操作
*/
public class TestOneToMany {
//級聯刪除操作
@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的多對多關系映射
第一步 創建實體類
第二步 讓學生和課程的實體類相關聯
學生類 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;
//第二步 學生選擇課程 ,一個學生可以選擇多門課程
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;
// 第二步 在課程端表示被哪些學生選擇,一門課程可以被多個學生選擇
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;
}
}
第三步 使用映射文件配置多對多關系(兩個映射文件)
學生映射文件 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>
<!-- 配置學生選擇的多門課程 -->
<set name="setCourse" table="STU_COURSE">
<!-- 當前配置的實體類 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>
<!-- 配置課程被哪些學生選擇 -->
<set name="setStudent" table="STU_COURSE">
<!-- 當前配置的課程 course 在第三張表里面的外鍵名稱 -->
<key column="c_id"></key>
<!--
class: 學生的全路徑
column:學生表在第三張表外鍵名稱
-->
<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>
<!-- 配置數據庫的相關信息 -->
<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>
<!-- 配置數據庫的方言
比如在mysql里面有關鍵字 limit ,只能使用在mysql里面
讓hibernate識別到不同數據庫自己特有的語句
-->
<property name="hibernate.dialect">
org.hibernate.dialect.MySQLDialect
</property>
<!-- 配置hibernate的相關信息 -->
<!-- 是否顯示底層的sql語句 -->
<property name="hibernate.show_sql">true</property>
<!-- 是否格式化sql語句 -->
<property name="hibernate.format_sql">true</property>
<!-- hibernate會幫自己創建數據庫表,默認不會創建,需要配置
值 update: 如果數據庫里面不存在表,創建;如果已經存在,更新
-->
<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>
第五步 創建工具類運行建表
HibernateUtils工具類 main方法
package cn.itcast.utils;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
/**
* 創建sessionFactory對象
*/
public class HibernateUtils {
static Configuration cfg = null;
static SessionFactory sessionFactory = null;
//靜態代碼塊
static {
cfg = new Configuration();
cfg.configure();
//創建sessionFactory
sessionFactory = cfg.buildSessionFactory();
}
//提供得到Session的方法
public static Session getSession() {
Session session = sessionFactory.openSession();
return session;
}
public static void main(String[] args) {
}
}
多對多級聯保存
創建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 testSave2() {
Session session = null;
Transaction tx = null;
try {
session = HibernateUtils.getSession();
tx = session.beginTransaction();
//添加兩個學生
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設計");
Course c2 = new Course();
c2.setCname("java開發");
Course c3 = new Course();
c3.setCname("韓語");
//根據課程保存
// 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();
}
}
//根據學生保存
@Test
public void testSave1() {
Session session = null;
Transaction tx = null;
try {
session = HibernateUtils.getSession();
tx = session.beginTransaction();
//添加兩個學生
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("美容美發");
Course c3 = new Course();
c3.setCname("廚師");
//根據學生保存
// 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();
}
}
}
根據學生保存 配置學生映射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>
<!-- 配置學生選擇的多門課程 cascade="save-update" -->
<set name="setCourse" table="STU_COURSE" cascade="save-update">
<!-- 當前配置的實體類 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>
根據課程保存 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>
<!-- 配置課程被哪些學生選擇 cascade="save-update"-->
<set name="setStudent" table="STU_COURSE" cascade="save-update">
<!-- 當前配置的課程 course 在第三張表里面的外鍵名稱 -->
<key column="c_id"></key>
<!--
class: 學生的全路徑
column:學生表在第三張表外鍵名稱
-->
<many-to-many class="cn.itcast.manytomany.Student" column="s_id"></many-to-many>
</set>
</class>
</hibernate-mapping>
多對多級聯刪除(不用)
創建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的學生刪除
Student s = (Student) session.get(Student.class, 1);
session.delete(s);
tx.commit();
}catch(Exception e) {
e.printStackTrace();
tx.rollback();
}finally {
session.close();
}
}
}
根據學生刪除 配置學生映射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>
<!-- 配置學生選擇的多門課程 cascade="delete"-->
<set name="setCourse" table="STU_COURSE" cascade="save-update,delete">
<!-- 當前配置的實體類 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>
根據課程刪除 配置課程映射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>
<!-- 配置課程被哪些學生選擇 cascade="delete"-->
<set name="setStudent" table="STU_COURSE" cascade="save-update,delete">
<!-- 當前配置的課程 course 在第三張表里面的外鍵名稱 -->
<key column="c_id"></key>
<!--
class: 學生的全路徑
column:學生表在第三張表外鍵名稱
-->
<many-to-many class="cn.itcast.manytomany.Student" column="s_id"></many-to-many>
</set>
</class>
</hibernate-mapping>