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);
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于