您的位置:首页 > 其它

hibernate框架学习笔记9:多对多关系案例

2018-02-18 22:32 399 查看
员工与角色案例:

一个员工可以是多种角色(总监,经理),一种角色可以是多个员工(保洁)

这里发现无法使用外键表达关系,多对多总是创建第三张表来维护关系

这张表至少两列,都是外键,分别引用两张表的主键

员工(用户)实体类:

package utils;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class HibernateUtils {
private static SessionFactory sf;

static{
//1 创建,调用空参构造
Configuration conf = new Configuration().configure();
//2 根据配置信息,创建 SessionFactory对象
sf = conf.buildSessionFactory();
}

//获得session => 获得全新session
public static Session openSession(){
//3 获得session
Session session = sf.openSession();

return session;

}
//获得session => 获得与线程绑定的session
public static Session getCurrentSession(){
//3 获得session
Session session = sf.getCurrentSession();

return session;
}
}


View Code

这里先写一段测试代码:

public void fun1(){
//1 获得session
Session session = HibernateUtils.openSession();
//2 开启事务
Transaction tx = session.beginTransaction();
//-------------------------------------------------
//3操作
//1> 创建两个 User
User u1 = new User();
u1.setUser_name("张三");

User u2 = new User();
u2.setUser_name("李四");

//2> 创建两个 Role
Role r1 = new Role();
r1.setRole_name("保洁");

Role r2 = new Role();
r2.setRole_name("保安");
//3> 用户表达关系
u1.getRoles().add(r1);
u1.getRoles().add(r2);

u2.getRoles().add(r1);
u2.getRoles().add(r2);

//4> 角色表达关系
r1.getUsers().add(u1);
r1.getUsers().add(u2);

r2.getUsers().add(u1);
r2.getUsers().add(u2);

//5> 调用Save方法一次保存
session.save(u1);
session.save(u2);
session.save(r1);
session.save(r2);
//-------------------------------------------------
//4提交事务
tx.commit();
//5关闭资源
session.close();
}


看似很标准,不过运行会报错

原因:默认的inverse属性是维护的,两方关系都要维护,造成主键重复

解决办法:

1.改变代码:

@Test
//保存员工以及角色
public void fun1(){
//1 获得session
Session session = HibernateUtils.openSession();
//2 开启事务
Transaction tx = session.beginTransaction();
//-------------------------------------------------
//3操作
//1> 创建两个 User
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);
u2.getRoles().add(r2);
session.save(u1);
session.save(u2);
session.save(r1);
session.save(r2);
//-------------------------------------------------
//4提交事务
tx.commit();
//5关闭资源
session.close();
}


2.配置文件修改:

Role的配置文件:

<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>


这时候运行那一段代码就不会出错

结论: 将来在开发中,如果遇到多对多关系.一定要选择一方放弃维护关系.
一般谁来放弃要看业务方向. 例如录入员工时,需要为员工指定所属角色.
那么业务方向就是由员工维护角色. 角色不需要维护与员工关系.角色放弃维护

多对多同样有cascade属性:

cascade级联操作:
save-update: 级联保存更新
delete:级联删除
all:级联保存更新+级联删除

结论: cascade简化代码书写.该属性使不使用无所谓. 建议要用只用save-update.
如果使用delete操作太过危险.尤其在多对多中.不建议使用.

多对多的其他操作:

@Test
//为张三新增一个角色
public void fun3(){
//1 获得session
Session session = HibernateUtils.openSession();
//2 开启事务
Transaction tx = session.beginTransaction();
//-------------------------------------------------
//3操作
//1> 获得张三用户
User user = session.get(User.class, 3l);
//2> 创建总经理角色
Role r = new Role();
r.setRole_name("总经理");
//3> 将角色添加到用户中
user.getRoles().add(r);
//4> 将角色转换为持久化
session.save(r);
//-------------------------------------------------
//4提交事务
tx.commit();
//5关闭资源
session.close();
}

@Test
//为张三解除一个角色
public void fun4(){
//1 获得session
Session session = HibernateUtils.openSession();
//2 开启事务
Transaction tx = session.beginTransaction();
//-------------------------------------------------
//3操作
//1> 获得郝强勇用户
User user = session.get(User.class, 3l);
//2> 获得要操作的角色对象(保洁,保安)
Role r1 = session.get(Role.class, 1l);
Role r2 = session.get(Role.class, 2l);
//3> 将角色从用户的角色集合中移除
user.getRoles().remove(r1);
user.getRoles().remove(r2);

//-------------------------------------------------
//4提交事务
tx.commit();
//5关闭资源
session.close();
}


这里是一对多的文章,对比后更有收获

http://www.cnblogs.com/xuyiqing/p/8453165.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: