多對多的映射關(guān)系酒来,這里我用的是角色跟用戶兩個實(shí)體,一個用戶可能有多個角色肪凛,一個角色同時有多個用戶堰汉。
1、數(shù)據(jù)庫對象關(guān)系
多對多.png
2伟墙、實(shí)體關(guān)系
多對多實(shí)體關(guān)系.png
3翘鸭、建表
user表:
CREATE TABLE user(
user_id BIGINT(32) PRIMARY KEY auto_increment,
user_name VARCHAR(32) not NULL,
user_code VARCHAR(32) not NULL,
user_password VARCHAR(32) not NULL
)ENGINE=INNODB CHARSET=utf8;
role表:
CREATE TABLE role(
role_id BIGINT(32) PRIMARY KEY auto_increment,
role_name VARCHAR(32) not NULL,
role_memo VARCHAR(128) DEFAULT NULL
)ENGINE=INNODB CHARSET=utf8;
4、編寫實(shí)體與實(shí)體映射文件:
User.java
package com.nieshenkuan.model;
import java.util.HashSet;
import java.util.Set;
public class User {
// CREATE TABLE user(
// user_id BIGINT(32) PRIMARY KEY auto_increment,
// user_name VARCHAR(32) not NULL,
// user_code VARCHAR(32) not NULL,
// user_password VARCHAR(32) not NULL
// )ENGINE=INNODB CHARSET=utf8;
private Long user_id;
private String user_name;
private String user_code;
private String user_password;
private Set<Role> roles=new HashSet<>();
public Set<Role> getRoles() {
return roles;
}
public void setRoles(Set<Role> roles) {
this.roles = roles;
}
public Long getUser_id() {
return user_id;
}
public void setUser_id(Long user_id) {
this.user_id = user_id;
}
public String getUser_name() {
return user_name;
}
public void setUser_name(String user_name) {
this.user_name = user_name;
}
public String getUser_code() {
return user_code;
}
public void setUser_code(String user_code) {
this.user_code = user_code;
}
public String getUser_password() {
return user_password;
}
public void setUser_password(String user_password) {
this.user_password = user_password;
}
}
User.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2017-12-28 11:22:51 by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping package="com.nieshenkuan.model">
<class name="User" table="user" lazy="false">
<id name="user_id" >
<column name="user_id"></column>
<generator class="native"></generator>
</id>
<property name="user_name"></property>
<property name="user_code"></property>
<property name="user_password"></property>
<!--
級聯(lián)操作
save
save-update
delete
all
在多對多的時候戳葵,一般如果用的話就乓,只用save-update
delete要慎用
建議不使用
-->
<!--
lazy:懶加載,延遲加載
true
false
extra 極其懶惰
fetch 用什么sql去查詢
select(默認(rèn)值) 單表查詢
join 多表查詢
subselect 子查詢
-->
<set name="roles" table="sys_user_role" cascade="all" lazy="true" fetch="join" >
<key>
<column name="user_id"></column>
</key>
<many-to-many class="Role" column="role_id"></many-to-many>
</set>
</class>
</hibernate-mapping>
Role.java
package com.nieshenkuan.model;
import java.util.HashSet;
import java.util.Set;
public class Role {
// CREATE TABLE role(
// role_id BIGINT(32) PRIMARY KEY auto_increment,
// role_name VARCHAR(32) not NULL,
// role_memo VARCHAR(128) DEFAULT NULL
// )ENGINE=INNODB CHARSET=utf8;
private Long role_id;
private String role_name;
private String role_memo;
private Set<User> users=new HashSet<>();
public Set<User> getUsers() {
return users;
}
public void setUsers(Set<User> users) {
this.users = users;
}
public Long getRole_id() {
return role_id;
}
public void setRole_id(Long role_id) {
this.role_id = role_id;
}
public String getRole_name() {
return role_name;
}
public void setRole_name(String role_name) {
this.role_name = role_name;
}
public String getRole_memo() {
return role_memo;
}
public void setRole_memo(String role_memo) {
this.role_memo = role_memo;
}
}
Role.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2017-12-28 11:22:51 by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping package="com.nieshenkuan.model">
<class name="Role" table="role">
<id name="role_id" >
<column name="role_id"></column>
<generator class="native"></generator>
</id>
<property name="role_name"></property>
<property name="role_memo"></property>
<set name="users" table="sys_user_role" inverse="true">
<key column="role_id"></key>
<many-to-many class="User" column="user_id"></many-to-many>
</set>
</class>
</hibernate-mapping>
5拱烁、測試
/**
* 添加數(shù)據(jù)
*/
@Test
public void test() {
Session session = HibernateUtils.openSession();
Transaction transaction = session.beginTransaction();
// ---------------------------------------------
User u1=new User();
u1.setUser_name("小飛");
u1.setUser_code("ww");
u1.setUser_password("ww1");
User u2=new User();
u2.setUser_name("大飛");
u2.setUser_code("ee");
u2.setUser_password("ee2");
Role role1=new Role();
role1.setRole_name("設(shè)計師");
Role role2=new Role();
role2.setRole_name("程序員");
u1.getRoles().add(role1);
u1.getRoles().add(role2);
u2.getRoles().add(role1);
u2.getRoles().add(role2);
// role1.getUsers().add(u1);
// role1.getUsers().add(u2);
//
// role2.getUsers().add(u1);
// role2.getUsers().add(u2);
session.save(u1);
session.save(u2);
session.save(role1);
session.save(role2);
// ----------------------------------------------
transaction.commit();
session.close();
}
/**
* 查詢數(shù)據(jù)
*/
@Test
public void fun1() {
Session session = HibernateUtils.openSession();
Transaction transaction = session.beginTransaction();
// ---------------------------------------------
//hibernate懶加載
//當(dāng)使用到對象的時候生蚁,才去執(zhí)行sql
//絕大程度上是好的
User user = session.load(User.class, 1l);
Set<Role> roles=user.getRoles();
for(Role role:roles) {
System.out.println(role.getRole_name());
}
Role role = session.load(Role.class, 1l);
Set<User> users=role.getUsers();
for(User user_obj:users) {
System.out.println(user_obj.getUser_name());
}
// ----------------------------------------------
transaction.commit();
session.close();
}
總結(jié)
總結(jié):多對多的關(guān)系不需要建立外鍵,只是建立一個虛擬的中間表戏自。
只需要在兩個多的一方實(shí)體中都有一個對方實(shí)體的集合就可以了邦投。具體的實(shí)體映射文件詳解如下:
user對象的映射文件:
<set name="roles" table="sys_user_role" cascade="all" lazy="true" fetch="join" >
<key>
<column name="user_id"></column>
</key>
<many-to-many class="Role" column="role_id"></many-to-many>
</set>
配置詳解:
name:是user實(shí)體中set集合對象的對象名。
table:是中間表的名字擅笔,隨便取志衣。但是兩個中間表的名字要一樣。
key:user表中的主鍵名字作為中間表的一個字段
many-to-many中的:
class:是另一個多的一方的實(shí)體名
column:是另一個多的一方中主鍵名猛们。
當(dāng)然念脯,role的實(shí)體映射文件也是類似:如下
<set name="users" table="sys_user_role" inverse="true">
<key column="role_id"></key>
<many-to-many class="User" column="user_id"></many-to-many>
</set>
這里的name跟talbe以及key都不再講解了,跟上面一樣阅懦。
其實(shí)many-to-many也是一樣配置的和二。
class是另一個多的一方的實(shí)體名,
column是另一個多的一方中的主鍵名耳胎。