java hibernate 多对多_Hibernate 中一对多和多对多映射

1. 一对多映射

1.1 JavaWeb 一对多建表原则

多方表的外键指向一方表的主键;

62845138b40cba326ddd1de134afe80a.png

1.2 编写一对多的 JavaBean

// 客户(一方)和联系人(多方)

// 客户(一方) JavaBean

public class Customer{

private Long cust_id;

private String cust_name;

private Long cust_create_id;

...

// 关联多方

// Hibernate 框架默认的集合是 Set 集合,该集合必须要自己手动初始化

private Set linkmans = new HashSet();

......

}

// 联系人(多方) JavaBean

public class Linkman{

private Long lkm_id;

private String lkm_name;

private String lkm_gender;

...

// 关联一方

// 编写一个对象, 不需要自己 new

private Customer customer;

....

}

1.3 编写一对多的映射配置文件

// Customer.hbm.xml (客户映射配置)

...

// 关联的配置(一方)

// name 表示集合的名称

// column 外键的字段

// Linkman.hbm.xml (联系人映射配置)

...

// 关联的配置(多方)

// name 当前 JavaBean 中的属性

// class 属性的全路径

// column 外键的字段(表)

2. 保存客户和联系人的数据

2.1 双向关联的方式保存数据

public class Demo{

public void fun(){

Session session = HibernateUtils.getCurrentSession();

Transaction tr = session.beginTransaction();

// 创建客户

Customer c1 = new Customer();

c1.setCust_name("张三");

// 创建联系人

Linkman lk1 = new Linkman();

lk1.setLkm_name("熊大");

Linkman lk2 = new Linkman();

lk2.setLkm_name("熊二");

// 双向关联

c1.getLinkmans().add(lk1);

c1.getLinkmans().add(lk2);

lk1.setCustomer(c1);

lk2.setCustomer(c1);

session.save(c1);

session.save(lk1);

session.save(lk2);

tr.commit();

}

}

2.2 级联保存

级联保存:保存一方,同时可以把关联的对象也保存到数据库中!

级联保存是有方向性的.例如,保存客户时,级联保存联系人;或者,保存联系人时,级联保存客户;

使用 cascade="save-update"

// 保存客户,级联保存联系人

// 需要在客户 Customer.hbm.xml 中配置

pulic class Demo{

pulic class fun(){

Session session = HibernateUtils.getCurrentSession();

Transaction tr = session.beginTransaction();

// 创建客户

Customer c1 = new Customer();

c1.setCust_name("张三");

// 创建联系人

Linkman l1 = new Linkman();

l1.setLkm_name("熊大");

Linkman l2 = new Linkman();

l2.setLkm_name("熊二");

// 单向关联

c1.getLinkmans().add(l1);

c1.getLinkmans().add(l2);

l1.setCustomer(c1); // 此处,如果没有,报错.

l2.setCustomer(c1); // 此处,如果没有,报错.

// 保存客户

session.save(c1);

tr.commit();

}

}

// 保存联系人,级联保存客户

// 需要在联系人 Linkman.hbm.xml 中配置

column="lkm_cust_id" cascade="save-update"/>

public class Demo{

public class fun(){

Session session = HibernateUtils.getCurrentSession();

Transaction tr = session.beginTransaction();

// 创建客户

Customer c1 = new Customer();

c1.setCust_name("张三");

// 创建联系人

Linkman l1 = new Linkman();

l1.setLkm_name("熊大");

Linkman l2 = new Linkman();

l2.setLkm_name("熊二");

l1.setCustomer(c1);

l2.setCustomer(c2);

// 保存联系人

session.save(l1);

session.save(l2);

tr.commit();

}

}

2.3 级联删除

级联删除也是有方向性的;

// 删除客户时, 删除联系人(一方级联删除多方), 配置 Customer.hbm.xml

2.4 级联的取值和孤儿删除

1. 级联的取值(cascade 的取值)

none: 不使用级联;

save-update: 级联保存或更新;

delete: 级联删除;

delete-orphan: 孤儿删除(只能应用在一对多关系);

all: 除了 delete-orphan 的所有情况;

all-delete-orphan: 包含了 delete-orphan 的所有情况;

2. 孤儿删除

只有在一对多的环境下才有孤儿删除;

在一对多的关系中,可以将一方认为是父方,将多的一方认为是子方;孤儿删除,就是在解除了父子关系的时候,

将子方记录直接删除;

2.5 让某一方放弃外键的维护,为多对多映射做准备: inverse

在修改客户和联系人的关系时,进行双向关联,双方都会维护外键,会产生多余的 SQL 语句.

产生的原因: session 的一级缓存中的快照机制,会让双方都更新数据库,产生了多余的 SQL 语句.

如果不想产生多余的 SQL 语句,那么需要一方来放弃外键的维护, 由多方来维护!

// 放弃外键维护

// Customer.hbm.xml 进行如下配置

// true 表示放弃; 默认值为 false

3. 多对多映射

3.1 多对多建表原则

以用户和角色为例,需要创建三张表: 用户表,角色表,中间表(维护前面两个表的数据);

使用Hibernate 框架,只要编写两个 JavaBean 以及对应的映射配置文件,中间表会自动生成;

多对多映射关系中,必须有一方放弃外键维护;

f2fe9f5ae828e636526bb4ffc1c1755d.png

// 编写用户和角色的 JavaBean

// 用户的 JavaBean

public class User{

private Long user_id;

private String user_name;

private String user_pwd;

...

private Set roles = new HashSet();

}

// 角色的 JavaBean

public class Role{

private Long role_id;

private String role_name;

private String role_desc;

private Set users = new HashSet();

}

// 编写映射配置文件

// 用户的映射配置文件, User.hbm.xml

// 配置多对多

// name 表示集合的名称

// table 表示中间表的名称

// 当前对象在中间表的外键名称

// class : 集合中存入的对象,对象的全路径

// column: 集合中对象,在中间表的外键名称

// 角色的映射配置文件, Role.hbm.xml

参考资料

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值