hibernate 表与表之间的关系操作

发布于 2019-01-17  445 次阅读


hibernate 一对多操作:

(1).一对多映射配置

​ (以客户和联系人为例,客户是一,联系人是多)

第一步:导入jar包

第二步:创建实体类(两个,一个客户的,一个联系人)

第三步:让这两个实体类之间相互表示.

(1).在客户实体类里面表示多个联系人.

一个客户里面多个联系人.

//在客户实体类里面表示多个联系人, 一个客户有多个联系人.
//hibernate要求使用集合表示多的数据,使用set集合.
private Set<LinkMan> setLinkMan = new HashSet<LinkMan>();

public Set<LinkMan> getSetLinkMan() {
return setLinkMan;
}
public void setSetLinkMan(Set<LinkMan> setLinkMan) {
this.setLinkMan = setLinkMan;
}
(2).在联系人实体类里面表示所属客户.

​ 一个联系人只能属于一个客户.

//在联系人里面表示所属客户,一个联系人只能属于一个客户.
private Customer customer;
public Customer getCustomer() {
    return customer;
}
public void setCustomer(Customer customer) {
    this.customer = customer;
}

第四步: 配置映射关系:

(1).一个实体类对应一个映射文件

(2).把映射最基本的配置完成

(3).在映射文件中,配置一对多的关系在客户的映射文件中,表示所有的联系人

在联系人中,表示所属的客户.

<!-- 
      在客户的映射文件中,表示所有的联系人 
      使用set标签表示所有的联系人
      set标签里面有name属性, 属性值写在客户实体类里面表示联系人的set集合名称
     -->
<set name="setLinkMan">
    <!-- 
       一对多建表,有外键.
       hibernate机制, 双向维护外键, 在一和多那一方都配置外键.
       column属性值就是外键的名称
       -->
    <key column="clid"></key>
    <!-- 客户所有的联系人,class里面写联系人实体类的全路径 -->
    <one-to-many class="com.yao.entity.LinkMan"/>
</set>

第五步:创建核心配置文件, 把映射文件映入到核心配置文件中

<!-- 
       表示联系人所属的客户
       name属性: 因为在联系人实体类使用customer对象表示,写customer名称
       class属性: customer全路径
       column属性: 外键的名称clid
       -->
<many-to-one name="customer" class="com.yao.entity.Customer" column="clid"></many-to-one>

第六步: 测试, 执行工具类

级联操作:

(2).一对多级联保存

1.级联保存

(1).添加了客户,为这个客户添加了多个联系人

​ (添加客户,为这个客户添加一个联系人)

//添加一个客户,为这个客户添加一个联系人.
//1.创建客户跟联系人的对象
Customer customer = new Customer();
customer.setCustName("同福客栈");
customer.setCustLevel("vip");
customer.setCustSource("网络");
customer.setCustPhone("110");
customer.setCustMobilb("666");
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);
简化写法:(根据客户添加联系人)

​第一步:在客户映射文件中进行配置; 在客户映射配置文件中set标签内进行配置属性==> cascade="save-update"

<set name="setLinkMan" cascade="save-update">

第二步:创建客户和联系人对象,只要把联系人放到客户里面就可以了,最终只需要保存客户就可以了.

//1.创建客户跟联系人的对象
Customer customer = new Customer();
customer.setCustName("龙门客栈");
customer.setCustLevel("普通客户");
customer.setCustSource("网络");
customer.setCustPhone("949");
customer.setCustMobilb("2233");
LinkMan linkMan = new LinkMan();
linkMan.setLkm_name("小花");
linkMan.setLkm_gender("女");
linkMan.setLkm_phone("666");
//2.把联系人放到客户里面
customer.getSetLinkMan().add(linkMan);
//3.保存客户
session.save(customer);
session.save(linkMan);    
(3).一多级联删除

(1).删除某一个客户,这个客户里面的所有联系人也删除(删除某个客户,把客户里面所有的联系人删除)

第一步:在客户映射文件set标签`,进行配置==> cascade="save-delete" (注意, 多个属性用逗号隔开)

(1).使用属性cascade="save-update,delete"

第二步:在代码中直接删除客户.

(1).先根据id查询对象,在调用session里面的delete方法删除

//1.根据id查询出客户对象
Customer customer = session.get(Customer.class, 2);
//2调用方法删除
session.delete(customer);

执行过程:

(1).根据id查询客户

(2).根据外键查询联系人

(3).把联系人的外键设置为null;

(4).删除联系人和客户

(4).一对多修改操作

1.让lucy联系人所属客户不是同福, 而是龙门

//1.根据id查询lucy联系人, 根据id查询百度的客户
Customer Tongfu = session.get(Customer.class, 3);
LinkMan lucy = session.get(LinkMan.class, 1);
//2.设置持久态对象值
//把联系人客户里面
Tongfu.getSetLinkMan().add(lucy);
//把客户放到联系人里面
lucy.setCustomer(Tongfu);
(5).inverse属性

1.因为hibernate双向维护外键,在客户和联系人里面都需要维护外键, 修改客户的时候修改一次外键, 修改联系人的时候也修改一次外键, 造成效率问题.

2.解决方式:让其中一的一方不维护外键一对多里面,让其中一方放弃对外键的维护. 一个国家有总统,国家有很多人,总统不能这个国家所有的人,国家所有的人认识总统.

3.具体实现: 在放弃关系维护映射文件中,进行配置,在set标签上使用inverse属性

<!-- 
       inverse属性默认是false不放弃关系维护
              true 放弃关系维护
      -->
<set name="setLinkMan" cascade="save-update,delete" inverse="true">

hibernate 多对多操作:

(1).多对多映射配置

以用户和角色为例演示

 第一步: 创建实体类: 用户和角色

第二步: 两个实体类之间相互表示

(1).用户里面表示所有角色,使用set集合

(2).一个角色多个用户,使用set集合

第三步: 配置映射关系

(1). 基本配置

(2).配置多对多关系在用户里面表示所有的角色, set标签

<!-- 
        在用户里面表示所有角色, 使用set标签
         name属性, 角色set集合名称
         table属性, 第三张表的名称
        -->
<set name="setRole" table="user_role">
    <!-- key标签里面要配置当前的映射文件在第三张表中外键名称 -->
    <key column="userid"></key>
    <!-- 
         class: 角色实体类全路径
         column: 角色在第三张表外键名称
         -->
    <many-to-many class="com.yao.entity.Role" column="roleid"></many-to-many>
</set>

在角色里面表示所有的用户, set标签

<!-- 在角色里面表示所有的用户, set标签 -->
<set name="setUser" table="user_role">
    <!-- 角色在第三张表的外键 -->
    <key column="roleid"></key>
    <many-to-many class="com.yao.entity.User" column="userid"></many-to-many>
</set>

第四步: 在核心配置文件中映入配置文件

<mapping resource="com/yao/entity/User.hbm.xml"/>
<mapping resource="com/yao/entity/Role.hbm.xml"/>

第五步:测试运行utils类,查看数据库是否创建三张表.

(2).多对多级联保存(重点)

根据用户保存用户第一步:在用户映射配置文件中set标签进行配置, cascade值save-update

<set name="setRole" table="user_role" cascade="save-update">

​第二步:写代码实现(1).创建用户和角色,把角色放到用户里面,最终保存用户就可以了.

//添加连个用户, 为没有用户添加两个角色
User user1 = new User();
user1.setUser_name("lucy");
user1.setUser_password("123");
User user2 = new User();
user2.setUser_name("mary");
user2.setUser_password("456");
Role role1 = new Role();
role1.setRole_name("总经理");
role1.setRole_memo("总经理");    
Role role2 = new Role();
role2.setRole_name("秘书");
role2.setRole_memo("秘书");            
Role role3 = new Role();
role3.setRole_name("保安");
role3.setRole_memo("保安");
//2.建立关系,把角色放到用户里面
//user1 ==> r1/r2
user1.getSetRole().add(role1);
user1.getSetRole().add(role2);
//user2 ==> r2/r3
user2.getSetRole().add(role2);
user2.getSetRole().add(role3);
//3.保存用户
session.save(user1);
session.save(user2);

(3).多对多级联删除

​ 第一步: 在set标签里面进行配置,cascade 里面save-update,delete

<set name="setRole" table="user_role" cascade="save-update,delete">

​ 第二步:(注意: 一般不用, 删除会将相关联的表的全部数据删除)

//级联删除
User user = session.get(User.class, 1);
session.delete(user);

(4).维护第三张表

1.用户和叫是多对多关系, 维护关系是通过第三张表维护

2.让某个用户有某个角色

第一步: 先根据id查询用户和角色

第二步: 把角色对象放到用户里面

(1).把角色对象放到用户set集合

//让lucy有经纪人的角色
//1.查询lucy和经纪人
User lucy = session.get(User.class, 1);
Role role = session.get(Role.class, 4);
//2.把角色放到用户的set集合里面
lucy.getSetRole().add(role);

3.让某个用户没有某个角色.

第一步: 先根据id查询用户和角色

第二步: 从用户里面把角色去掉

(1).从set集合里面把角色移除

//让lucy有经纪人的角色
//1.查询lucy和经纪人
User lucy = session.get(User.class, 2);
Role role = session.get(Role.class, 3);

//从用户里面把角色去掉
lucy.getSetRole().remove(role);

以下是我学习hibernate整理的笔记:

链接:https://pan.baidu.com/s/1Kv9yKKb9XrhvWZUi797F1A 密码:va2b


公交车司机终于在众人的指责中将座位让给了老太太