多对多关联映射需要新增加一张表才完成基本映射,他的实例场景如下:
用户与他的角色(一个用户拥有多个角色,一个角色还可以属于多个用户)
多对多关联映射,需要一个中间表,两个表中的主键放到第三张做一个关联,用第三张表来解决可能会造成数据冗余的问题,多对多的关联映射,在实体类中,跟一对多一样,也是用集合来表示的。
单向关联映射则是只能由A端去操作B端,B端不能操作A端的数据。而双向关联映射则是A,B两端都可以操作另一端的数据。
(1)XML版
SQL文件为:
CREATE TABLE `user` (
`id` varchar(255) NOT NULL,
`uname` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `role` (
`id` varchar(255) NOT NULL,
`rname` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `user_role` (
`userid` varchar(255) DEFAULT NULL,
`roleid` varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Role实体类:
package Hibernate_demo1.Demo9.Entity;
import java.util.Set;
public class Role {
private String id;
private String rname;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getRname() {
return rname;
}
public void setRname(String rname) {
this.rname = rname;
}
}
User实体类:
package Hibernate_demo1.Demo9.Entity;
import java.util.Set;
public class User {
private String id;
private String uname;
private Set<Role> roles; //角色集合,一个用户可以有多个角色
public String getUname() {
return uname;
}
public void setUname(String uname) {
this.uname = uname;
}
public Set<Role> getRoles() {
return roles;
}
public void setRoles(Set<Role> roles) {
this.roles = roles;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return uname;
}
public void setName(String name) {
this.uname = name;
}
}
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">
<hibernate-mapping>
<class name="Hibernate_demo1.Demo9.Entity.Role" table="role">
<id name="id" type="java.lang.String">
<column name="id"/>
<generator class="uuid">
</generator>
</id>
<property name="rname" column="rname"/>
</class>
</hibernate-mapping>
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">
<hibernate-mapping>
<class name="Hibernate_demo1.Demo9.Entity.User" table="user">
<id name="id">
<generator class="uuid">
</generator>
</id>
<property name="uname" column="uname"/>
<!--
使用<set>标签映射集合(set),标签中的name值为对象属性名(集合roles)
而使用table属性是用于生成第三方表名称,例:table="user_role"
但是第三方面中的字段是自动加入的,作为外键分别指向其它表。
所以用<key>标签设置,例:<key column="userid"/>
意思是:在第三方表(user_role)中加入一个外键并且指向当前的映射实体类所对应的表(user)
使用<many-to-many>来指定此映射集合所对象的类(实例类)
并且使用column属性加入一个外键指向Role实体类所对应的表(role)
-->
<set name="roles" table="user_role">
<key column="userid"/>
<many-to-many class="Hibernate_demo1.Demo9.Entity.Role" column="roleid"/>
</set>
</class>
</hibernate-mapping>
测试类如下:
package Hibernate_demo1.Demo9;
import java.util.HashSet;
import java.util.Set;
import org.hibernate.Session;
import Hibernate_demo1.Demo9.Entity.Role;
import Hibernate_demo1.Demo9.Entity.User;
import Hibernate_demo1.Demo9.Util.HibernateUtils;
public class App
{
public static void main( String[] args )
{
Session session = null;
try{
session = HibernateUtils.getSession();
session.beginTransaction();
//创建三个角色
Role ro1=new Role();
ro1.setRname("程序员");
//保存角色
session.save(ro1);
Role ro2=new Role();
ro2.setRname("产品经理");
//保存角色
session.save(ro2);
Role ro3=new Role();
ro3.setRname("CEO");
//保存角色
session.save(ro3);
//创建两个用户
User use1=new User();
use1.setName("小明");
User use2=new User();
use2.setName("小黑");
Set<Role> su=new HashSet();
su.add(ro1);
su.add(ro2);
//给小明设置角色为(程序员,产品经理)
use1.setRoles(su);
Set<Role> su1=new HashSet();
su1.add(ro3);
//给小黑设置角色为(CEO)
use2.setRoles(su1);
session.save(use1);
session.save(use2);
session.getTransaction().commit();
}catch(Exception e){
e.printStackTrace();
session.getTransaction().rollback();
}finally{
HibernateUtils.closeSession(session);
}
}
}
执行结果如下:
Hibernate:
insert
into
role
(rname, id)
values
(?, ?)
Hibernate:
insert
into
role
(rname, id)
values
(?, ?)
Hibernate:
insert
into
role
(rname, id)
values
(?, ?)
Hibernate:
insert
into
user
(uname, id)
values
(?, ?)
Hibernate:
insert
into
user
(uname, id)
values
(?, ?)
Hibernate:
insert
into
user_role
(userid, roleid)
values
(?, ?)
Hibernate:
insert
into
user_role
(userid, roleid)
values
(?, ?)
Hibernate:
insert
into
user_role
(userid, roleid)
values
(?, ?)
Role表
User表
user_role表
示例:http://download.youkuaiyun.com/detail/u011781521/9834640
(2)注解版
Role类
package Hibernate_demo1.Demo10.Entity;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import org.hibernate.annotations.GenericGenerator;
@Entity
@Table(name="role")
public class Role {
@Id
@GenericGenerator(name="uuidGenerator", strategy="uuid")
@GeneratedValue(generator="uuidGenerator")
private String id;
@Column(name="rname")
private String rname;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getRname() {
return rname;
}
public void setRname(String rname) {
this.rname = rname;
}
}
User类
package Hibernate_demo1.Demo10.Entity;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.OrderBy;
import javax.persistence.Table;
import org.hibernate.annotations.GenericGenerator;
@Entity
@Table(name="user")
public class User {
@Id
@GenericGenerator(name="uuidGenerator", strategy="uuid")
@GeneratedValue(generator="uuidGenerator")
private String id;
@Column(name="uname")
private String uname;
@ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@JoinTable(name = "user_role", joinColumns = {@JoinColumn(name ="userid" )}, inverseJoinColumns = { @JoinColumn(name = "roleid") })
private Set<Role> roles; //角色集合,一个用户可以有多个角色
public String getUname() {
return uname;
}
public void setUname(String uname) {
this.uname = uname;
}
public Set<Role> getRoles() {
return roles;
}
public void setRoles(Set<Role> roles) {
this.roles = roles;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return uname;
}
public void setName(String name) {
this.uname = name;
}
}
测试类:
package Hibernate_demo1.Demo10;
import java.util.HashSet;
import java.util.Set;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import Hibernate_demo1.Demo10.Entity.Role;
import Hibernate_demo1.Demo10.Entity.User;
/**
* Hello world!
*
*/
public class App
{
public static void main( String[] args )
{
SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
Session session = sessionFactory.getCurrentSession();
Transaction tx = session.beginTransaction();
//创建三个角色
Role ro1=new Role();
ro1.setRname("程序员");
//保存角色
session.save(ro1);
Role ro2=new Role();
ro2.setRname("产品经理");
//保存角色
session.save(ro2);
Role ro3=new Role();
ro3.setRname("CEO");
//保存角色
session.save(ro3);
//创建两个用户
User use1=new User();
use1.setName("小明");
User use2=new User();
use2.setName("小黑");
Set<Role> su=new HashSet();
su.add(ro1);
su.add(ro2);
//给小明设置角色为(程序员,产品经理)
use1.setRoles(su);
Set<Role> su1=new HashSet();
su1.add(ro3);
//给小黑设置角色为(CEO)
use2.setRoles(su1);
session.save(use1);
session.save(use2);
tx.commit();
session.close();
}
}
执行结果如下:
Hibernate:
insert
into
role
(rname, id)
values
(?, ?)
Hibernate:
insert
into
role
(rname, id)
values
(?, ?)
Hibernate:
insert
into
role
(rname, id)
values
(?, ?)
Hibernate:
insert
into
user
(uname, id)
values
(?, ?)
Hibernate:
insert
into
user
(uname, id)
values
(?, ?)
Hibernate:
insert
into
user_role
(userid, roleid)
values
(?, ?)
Hibernate:
insert
into
user_role
(userid, roleid)
values
(?, ?)
Hibernate:
insert
into
user_role
(userid, roleid)
values
(?, ?)
示例:http://download.youkuaiyun.com/detail/u011781521/9834643