Hibernate中多对多的javabean文件的编写和映射文件的配置
下面是用户与角色的例子:多个用户对应多个角色
User.java
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
public class User implements Serializable{
private Integer uid;
private String uname;
//一个用户可以有多个角色
private Set<Role> roles=new HashSet<>();
public Integer getUid() {
return uid;
}
public void setUid(Integer uid) {
this.uid = uid;
}
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;
}
}
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="com.haha.domain.User" table="user">
<id name="uid">
<generator class="native"></generator>
</id>
<property name="uname"/>
<!--
配置对应的多的一方,name对应javabean中的set集合的属性名,
多对多需要一个中间表,中间表中有两个外键,组合成组合主键。
table对应中间表的名字
-->
<set name="roles" table="user_role">
<!--key中的column对应当前映射文件的外键 -->
<key column="uid"/>
<!--many-to-many中column对应另一个外键 -->
<many-to-many class="com.haha.domain.Role" column="rid"/>
</set>
</class>
</hibernate-mapping>
Role.java
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
public class Role implements Serializable{
private Integer rid;
private String rname;
//多个角色可以属于多个用户
private Set<User> users=new HashSet<>();
public Integer getRid() {
return rid;
}
public void setRid(Integer rid) {
this.rid = rid;
}
public String getRname() {
return rname;
}
public void setRname(String rname) {
this.rname = rname;
}
public Set<User> getUsers() {
return users;
}
public void setUsers(Set<User> users) {
this.users = users;
}
}
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="com.haha.domain.Role" table="role">
<id name="rid">
<generator class="native"/>
</id>
<property name="rname"/>
<!--
配置对应的多的一方,name对应javabean中的set集合的属性名,
多对多需要一个中间表,中间表中有两个外键,组合成组合主键。
table对应中间表的名字
-->
<set name="users" table="user_role">
<!--key中的column对应当前映射文件的外键 -->
<key column="rid"/>
<!--many-to-many中column对应另一个外键 -->
<many-to-many column="uid" class="com.haha.domain.User"/>
</set>
</class>
</hibernate-mapping>
下面是我自己写的有助于理解的小例子
多对多级联保存
/**
* 保存数据,双向关联时,不经常操作的一方应该放弃外键维护,不然会存外键重复
* 经常操作的一方级联保存,存储数据
* 在Role.hbm.xml中
* <set name="users" table="user_role" inverse="true">
* 在User.hbm.xml中
* <set name="roles" table="user_role" cascade="save-update">
*/
@Test
public void run1(){
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
User u1=new User();
u1.setUname("哈哈");
User u2=new User();
u2.setUname("嘻嘻");
Role r1=new Role();
r1.setRname("作家");
Role r2=new Role();
r2.setRname("程序员");
Role r3=new Role();
r3.setRname("演员");
//双向关联
u1.getRoles().add(r1);
u1.getRoles().add(r2);
u2.getRoles().add(r3);
u2.getRoles().add(r1);
r1.getUsers().add(u1);
r1.getUsers().add(u2);
r2.getUsers().add(u1);
r3.getUsers().add(u2);
session.save(u1);
session.save(u2);
tx.commit();
}
删除操作
/**
* 删除操作,在多对多时,双向级联删除根本不能配置
* 因为数据之间有相互引用关系,如果配了的话,可能会清除数据
* 所以当你想删除他们之间的关系时,操作set集合,从而删除中间表的数据
*/
@Test
public void run2(){
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
User user = session.get(User.class, 3);
Role role=session.get(Role.class, 1);
user.getRoles().remove(role);
tx.commit();
}
对象导航查询
是根据已经加载的对象,导航到它的关联对象。它利用类与类之间的关系来检索对象。对象导航查询默认的都是延迟加载,就是用的时候才会加载,不会立即加载。如果你不想用延迟加载,可以加 lazy="false"
/**
* 对象导航查询
*/
@Test
public void run3(){
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
User user = session.get(User.class, 4);
System.out.println("======");
Set<Role> roles = user.getRoles();
for (Role role : roles) {
System.out.println(role.getRname());
}
tx.commit();
}