八、Hibernate對映之多對多處理
阿新 • • 發佈:2018-12-05
以使用者和角色為例,一個使用者可以有多個角色,一個角色也可以屬於多個使用者,這種關係剛好是多對多的關係.
建立javabean
User.java
public class User {
private Long user_id;
private String user_name;
private String user_password;
private String user_state;
//多對多中關聯的另一方
private Set<Role> roles = new HashSet<Role>();
//get set...
}
Role.java
public class Role {
private Long role_id;
private String role_name;
//多對多中關聯的另一方
private Set<User> users = new HashSet<User>();
//get set...
}
建立對映檔案
User.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="blog.csdn.net.mchenys.domain.User" table="t_user">
<id name="user_id" column="user_id">
<generator class="native"/>
</id>
<property name="user_name" column="user_name"/>
< property name="user_password" column="user_password"/>
<property name="user_state" column="user_state"/>
<!--
set標籤屬性
name:javabean中集合的屬性名
table:中間表的名字,這個必現2邊保持一致
key標籤屬性
column:中間表中對應該類的外來鍵名
many-to-many標籤屬性
class:另一方的類全路徑名
column:另一方的類在中間表的外來鍵名
-->
<set name="roles" table="user_role">
<key column="uid"/>
<many-to-many class="blog.csdn.net.mchenys.domain.Role" column="rid"/>
</set>
</class>
</hibernate-mapping>
Role.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="blog.csdn.net.mchenys.domain.Role" table="t_role">
<id name="role_id" column="role_id">
<generator class="native"/>
</id>
<property name="role_name" column="role_name"/>
<!--
set標籤屬性
name:javabean中集合的屬性名
table:中間表的名字,這個必現2保持一致
inverse:true表示放棄維護外來鍵,多對多關係中必須有一方放棄維護,否則會報錯
key標籤屬性
column:中間表中對應該類的外來鍵名
many-to-many標籤屬性
class:另一方的類全路徑名
column:另一方的類在中間表的外來鍵名
-->
<set name="users" table="user_role" inverse="true">
<key column="rid"/>
<many-to-many class="blog.csdn.net.mchenys.domain.User" column="uid"/>
</set>
</class>
</hibernate-mapping>
修改核心配置檔案
在核心配置檔案中新增對映檔案的路徑
<?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>
<!-- 記住:先配置SessionFactory標籤,一個數據庫對應一個SessionFactory標籤 -->
<session-factory>
<!-- 必須要配置的引數有5個,4大引數,資料庫的方言 -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql:///hibernate_day03</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">1234</property>
<!-- 資料庫的方言 -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- 可選配置 -->
<!-- 顯示SQL語句,在控制檯顯示 -->
<property name="hibernate.show_sql">true</property>
<!-- 格式化SQL語句 -->
<property name="hibernate.format_sql">true</property>
<!-- 生成資料庫的表結構
update:如果沒有表結構,建立表結構。如果存在,不會建立,可動態新增欄位(新增屬性和對映即可),不能刪除欄位
-->
<property name="hibernate.hbm2ddl.auto">update</property>
<!-- 開啟繫結本地的session -->
<property name="hibernate.current_session_context_class">thread</property>
<!-- 對映配置檔案,需要引入對映的配置檔案 -->
<mapping resource="blog/csdn/net/mchenys/domain/User.hbm.xml"/>
<mapping resource="blog/csdn/net/mchenys/domain/Role.hbm.xml"/>
</session-factory>
</hibernate-configuration>
雙向關聯儲存
/**
* 測試雙向關聯儲存
*/
@Test
public void test1(){
Session session = HibernateUtils.getCurrentSession();
Transaction tr = session.beginTransaction();
// 建立使用者
User u1 = new User();
u1.setUser_name("小張");
User u2 = new User();
u2.setUser_name("小李");
// 建立角色
Role r1 = new Role();
r1.setRole_name("管理員");
Role r2 = new Role();
r1.setRole_name("老師");
// 雙向關聯
u1.getRoles().add(r1);
u1.getRoles().add(r2);
r1.getUsers().add(u1);
r2.getUsers().add(u1);
u2.getRoles().add(r1);
r1.getUsers().add(u2);
session.save(u1);
session.save(u2);
session.save(r1);
session.save(r2);
tr.commit();
}
級聯儲存
/**
* 級聯儲存:儲存使用者級聯儲存角色
*/
@Test
public void test2(){
Session session = HibernateUtils.getCurrentSession();
Transaction tr = session.beginTransaction();
// 建立使用者
User u1 = new User();
u1.setUser_name("張三");
User u2 = new User();
u2.setUser_name("趙四");
// 建立角色
Role r1 = new Role();
r1.setRole_name("經理");
Role r2 = new Role();
r2.setRole_name("銷售");
//單項關聯
u1.getRoles().add(r1);
u1.getRoles().add(r2);
u2.getRoles().add(r1);
// 級聯儲存資料
session.save(u1);
session.save(u2);
tr.commit();
}
記得要在User.hbm.xml配置檔案中新增cascade屬性到set標籤上,例如:
如何修改中間表的資料
要修改中間表的資料也很簡單,反應到java層面就是操作集合中的物件,只不過得先通過Hibernate先去查找出相關聯的資料才能操作,下面以張三使用者刪除經理角色為例
/**
* 操作中間表資料:讓張三去掉經理這角色
*/
@Test
public void test3() {
Session session = HibernateUtils.getCurrentSession();
Transaction tr = session.beginTransaction();
// 查詢張三使用者
User user = session.get(User.class, 3L);
// 查詢經理角色
Role role = session.get(Role.class, 4L);
// 操作集合來解除關聯,不需要執行update操作,因為持久態的物件可以有自動更新的功能
user.getRoles().remove(role);
// 提交
tr.commit();
}