Hibernate 学习笔记(一对多、多对多操作)
hibernate 一对多映射配置
1. 首先创建两个实体类,我便以客户与联系人为例子说明
2. 两个实体类之间要相互的表示
(1) 在客户实体类里面有多个联系人
//hibernate 中要求使用set集合来存储类似这种情况
private Set<LinkMan> setLinkMan = new HashSet<LinkMan>();
(2) 一个联系人属于一个客户
//表示联系人所属于的客户
private Customer customer;
3. 映射文件里面配置一对多的关系
(1) 客户映射文件中表示所有联系人,使用 set 标签表示多个联系人,其中 name 属性填写的是一对多关系中多的一方集合的名字,即填写客户实体类里面客户 set 集合的名称,而里面的 key 标签是指名数据库表的外键名称,<one - to-many> 标签是指明两个实体类的关系为一对多、class 属性填写的是多的一方的实体类路径
<!-- 在客户的映射文件中表示所有联系人 -->
<set name="setLinkMan">
<!-- 一对多建表,有外键
Hibernate双向维护外键,两方都要配置
column属性值是外键名称
-->
<key column="clid"></key>
<!-- 客户所有的联系人,class里面写联系人实体类全路径 -->
<one-to-many class="entity.LinkMan"/>
</set>
(2) 在联系人实体类里面表示所属的客户,同样,<many-to-one> 是指明两个实体类的关系,其中 class 指明一的那一方实体类的全路径,而 column 是需要填写外键的名称,也就是之前在客户实体类配置文件里填写的外键
<!-- 联系人所属的客户 -->
<many-to-one name="customer" class="entity.Customer" column="clid"></many-to-one>
4. 在核心配置文件中将两个映射文件引入
hibernate 一对多级联操作
1. 级联保存(例如:添加一个客户,为这个客户添加联系人)
(1) 复杂做法,需要在两个实体类之间相互表示关系,对两张表同时更新
//创建客户的对象
Customer customer = new Customer();
customer.setCustName("it");
customer.setCustLevel("vip");
customer.setCustSource("net");
customer.setCustPhone("110");
customer.setCustMobile("999");
//创建联系人对象
LinkMan linkMan = new LinkMan();
linkMan.setLkm_name("luck");
linkMan.setLkm_gender("男");
linkMan.setLkm_phone("121");
//建立两个实体类之间的关系
customer.getSetLinkMan().add(linkMan);
linkMan.setCustomer(customer);
//向数据库中存储
session.save(linkMan);
session.save(customer);
(2) 简化做法,首先需要在多的一方的映射文件中配置,在其 set 标签里加一个属性,cascade 属性,它的值有 save-update、delete 等,分别表示级联更新、级联删除,多个属性之间用逗号隔开如:“save-update,delete”。这时候只需要将联系人加入到客户里面、更新客户即可
<set name="setLinkMan" cascade="save-update">
customer.getSetLinkMan().add(linkMan);
session.save(customer);
2. 级联删除(例如:删除一个客户,这个客户里面的所有联系人也要删除)
(1) 需要在配置文件里面配置,参照上文
<set name="setLinkMan" cascade="save-update,delete">
(2) 在代码中就可以直接删除客户了
Customer customer = session.get(Customer.class, 1);
session.delete(customer);`
hibernate 中一对多的修改操作
1. 直接修改会产生一个问题,需要配置一个属性 inverse="true",因为 Hibernate 对外键是双向维护,会对外键进行两次更新,降低了效率,因此将 inverter 属性设置为 true 可以让一的一方放弃维护。
Customer baidu = session.get(Customer.class, 4);
LinkMan linkMan = session.get(LinkMan.class, 3);
baidu.getSetLinkMan().add(linkMan);
linkMan.setCustomer(baidu);
hibernate 的多对多操作(例:用户和角色)
1. 多对多的映射配置
(1) 创建实体类,用户和角色
User
private Integer user_id;
private String user_Name;
private String user_password;
Role
private Integer role_id;
private String role_name;
private String role_memo;
(2) 一个用户表示多个角色
private Set<Role> setRole = new HashSet<Role>();
(3) 一个角色有多个用户
private Set<User> setUser = new HashSet<User>();
(4) 配置多对多关系,与一对多关系中多的一方配置相似
角色的配置文件
<set name="setUser" table="user_role" cascade="save-update">
<!-- 当前映射文件,在第三张表中的外键名称 -->
<key column="roleid"></key>
<!--
class属性:角色实体类全路径
column属性:角色在第三张表的外键名称
-->
<many-to-many class="entity.User" column="userid"></many-to-many>
</set>
用户的配置文件
<!-- 在用户里面表示所有的角色
name属性:角色set集合的名称
table属性:第三张表的名称
-->
<set name="setRole" table="user_role" cascade="save-update">
<!-- 当前映射文件,在第三张表中的外键名称 -->
<key column="userid"></key>
<!--
class属性:角色实体类全路径
column属性:角色在第三张表的外键名称
-->
<many-to-many class="entity.Role" column="roleid"></many-to-many>
</set>
(5) 在核心配置文件导入映射文件
2. 多对多的级联保存
(1) 根据用户保存角色,在用户映射文件里面讲 set 标签里的 cascade 属性设置为 save-update
//建立用户
User user1 = new User();
User user2 = new User();
//建立角色
Role r1 = new Role();
Role r2 = new Role();
Role r3 = new Role();
//user1有r1\r2的角色
user1.getSetRole().add(r1);
user1.getSetRole().add(r2);
//user2有r2\r3的角色
user2.getSetRole().add(r2);
user2.getSetRole().add(r3);
//保存用户
session.save(user1);
session.save(user2);
3. 多对多的级联删除一般不会去用,因为会导致用户与角色表的数据删除,因此不需要级联删除,只需要去维护第三张关系表就可以了
4. 维护第三张表
(1) 让用户有某些角色,直接将用户和角色查出来,在用户的角色集合中添加即可
User user = session.get(User.class, 3);
Role role = session.get(Role.class,1);
user.getSetRole().add(role);
(2) 让用户没有某些角色,也是直接将用户和角色查出来,在用户的角色集合中删除即可
User user = session.get(User.class, 3);
Role role = session.get(Role.class,1);
user.getSetRole().remove(role);
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于