hibernate一对多操作
一对多映射配置
- 1.创建实体类
- 2.让两个实体类之间互相表示
// 在客户实体类里面表示多个联系人,一个客户有多个联系人
// hibernate要求使用集合表示多的数据,使用set集合
private Set<LinkMan> setLinkMan = new HashSet<LinkMan>();
public Set<LinkMan> getSetLinkMan() {
return setLinkMan;
}
public void setSetLinkMan(Set<LinkMan> setLinkMan) {
this.setLinkMan = setLinkMan;
}
// 在联系人实体类里面表示所属客户:一个联系人只能属于一个客户
private Customer customer;
public Customer getCustomer() {
return customer;
}
public void setCustomer(Customer customer) {
this.customer = customer;
}
- 3.配置映射关系
- 一般一个实体类对应一个映射文件
- 把映射最基本配置完成
- 在映射文件中,配置一对多关系
<!-- 在客户映射文件中,表示所有联系人
使用set标签表示所有联系人,set标签里面有name属性:属性值写在客户实体类里面表示联系人的set集合名称 -->
<set name="setLinkMan">
<key column="clid"></key>
<one-to-many class="com.entity.LinkMan"/>
</set>
<!-- 表示联系人所属客户
name属性:因为在联系人实体类使用customer对象表示,写customer名称
class属性:customer全路径
column属性:外键名称 -->
<many-to-one name="customer" class="com.entity.Customer" column="clid"></many-to-one>
一对多级联保存
级联保存
1.添加一个客户,为这个客户添加一个联系人
// 复杂写法
// 添加一个客户,为这个客户添加一个联系人
// 1 创建客户和联系人
Customer customer = new Customer();
customer.setCustName("传智播客");
customer.setCustLevel("vip");
customer.setCustSource("网络");
customer.setCustPhone("110");
customer.setCustMobile("999");
LinkMan linkman = new LinkMan();
linkman.setLkm_name("lucy");
linkman.setLkm_gender("男");
linkman.setLkm_phone("911");
// 2 在客户表示联系人,在联系人表示客户
// 建立客户对象和联系人对象关系
// 2.1 把联系人放到客户实体类对象的set集合里面
customer.getSetLinkMan().add(linkman);
// 2.2 把客户放到联系人里面
linkman.setCustomer(customer);
// 3 保存到数据库
session.save(customer);
session.save(linkman);
2.简化写法
- 第一步:在客户映射文件中进行配置
<set name="setLinkMan" cascade="save-update">
- 第二步:创建客户和联系人对象,只需要把联系人放到客户里面就可以了,最终只需要保存客户就可以了
// 添加一个客户,为这个客户添加一个联系人
// 1 创建客户和联系人
Customer customer = new Customer();
customer.setCustName("百度");
customer.setCustLevel("普通客户");
customer.setCustSource("网络");
customer.setCustPhone("110");
customer.setCustMobile("999");
LinkMan linkman = new LinkMan();
linkman.setLkm_name("小孩");
linkman.setLkm_gender("男");
linkman.setLkm_phone("911");
// 2 把联系人放到客户里
customer.getSetLinkMan().add(linkman);
// 3 保存客户
session.save(customer);
一对多级联删除
级联删除
1.删除某一个客户,这个客户里面的多有的联系人也删除
2.具体实现
- 第一步:在客户的映射文件set标签,进行配置
- (1)使用属性cascade属性值delete
<set name="setLinkMan" cascade="save-update,delete">
- 第二步:在代码中直接删除客户
- (1)根据id查询对象,调用session里面的delete方法
// 1 根据id查询客户对象
Customer customer = session.get(Customer.class, 2);
// 2 调用删除方法
session.delete(customer);
一对多修改操作
1.让Lucy联系人所属客户不是传智播客,而是百度
// 1 根据id查询Lucy联系人,根据id查询百度的客户
Customer baidu = session.get(Customer.class, 3);
LinkMan lucy = session.get(LinkMan.class, 1);
// 2 设置持久态对象值
// 把联系人放到客户里
baidu.getSetLinkMan().add(lucy);
// 把客户放到联系人里
lucy.setCustomer(baidu);
inverse属性
(1)因为hibernate双向维护外键,在客户和联系人里面都需要维护外键,效率低
(2)解决方法:让其中一方不维护外键
- 一对多里面,让其中一方放弃外键维护
(3)具体实现:
- 放弃关系维护映射文件中配置,在set标签上使用inverse属性
<!-- inverse属性默认值为false,即不放弃关系维护;true,即放弃关系维护 -->
<set name="setLinkMan" inverse="true">
hibernate多对多操作
多对多映射配置
以用户和角色为例
- 第一步:创建实体类
- 第二步:两个实体类之间互相表示
- (1)用户里面表示所有角色
- (2)一个角色有多个用户,使用set集合
- 第三步:配置映射关系
- (1)基本配置
- (2)配置多对多关系
在用户里面表示所有角色,使用set标签
在角色里面表示所有用户,使用set标签
<!-- 在用户里面表示所有角色,使用set标签 -->
<!-- name属性:角色set集合名称
table属性:第三张表名称 -->
<set name="setRole" table="user_role">
<!-- key标签里面配置
配置当前映射文件在第三张表的名称
-->
<key column="userid"></key>
<!-- class:角色实体类全路径
column:角色在第三张表外键名称 -->
<many-to-many class="com.manytomany.Role" column="roleid"></many-to-many>
<!-- 在角色里面表示所有用户,使用set标签 -->
<set name="setUser" table="user_role">
<key column="roleid"></key>
<many-to-many class="com.manytomany.User" column="userid"></many-to-many>
</set>
- 第四步:在核心配置文件中引入映射文件
<mapping resource="com/manytomany/Role.hbm.xml"/>
<mapping resource="com/manytomany/User.hbm.xml"/>
- 测试:
多对多级联保存
- 根据用户保存角色
- 第一步:在用户配置文件中set标签进行配置,cascade值save-update
<set name="setRole" table="user_role" cascade="save-update">
- 第二步:写代码实现
- 创建用户和角色对象,把角色放到用户里面,最终保存用户就可以了
- 第一步:在用户配置文件中set标签进行配置,cascade值save-update
// 添加两个用户,为每个用户添加两个角色
// 1 创建对象
// 2 建立关系,把角色放到用户里
// user1 -- role1/role2
user1.getSetRole().add(role1);
user1.getSetRole().add(role2);
// user2 -- role2/role3
user2.getSetRole().add(role2);
user2.getSetRole().add(role3);
// 3 保存用户
session.save(user1);
session.save(user2);
多对多级联删除
- 第一步:在set标签进行配置,cascade标签的delete
- 第二步:根据id查询对象,调用session对象的的delete方法
维护第三张表
- 用户和角色是多对多关系,维护关系通过第三张表维护
- 让某个用户有某个角色
- 第一步:根据id查询用户和角色
- 第二步:把角色放到用户里
- 把角色对象放到set集合
// 让某个用户有某个角色
// 让Lucy有保安角色
// 1 查询lucy和保安角色
User lucy = session.get(User.class, 1);
Role role = session.get(Role.class, 3);
// 2 把角色放到用户的set集合里面
lucy.getSetRole().add(role);
- 让某个用户没有某个角色
- 第一步:根据id查询用户和角色
- 第二步:从用户里面把角色去掉
- 从用户的set集合里删除角色
// 让某个用户有某个角色
// 让Lucy有保安角色
// 1 查询lucy和保安角色
User user = session.get(User.class, 1);
Role role = session.get(Role.class, 3);
// 2 把角色放到用户的set集合里面
user.getSetRole().remove(role);