Hibernate关联映射

双向关联关系下的增删改操作

1.cascade属性(一般建议在"一"对"多"的 “一” 的部分使用)

cascade属性值描述
none当Session操作当前对象时,忽略其他关联对象.它是cascade属性的默认值
save-update当通过Session 的 save() 、update()及saveOrUpdate()方法来保存或更新当前对象时,级联属性保存所有关联的瞬时状态的对象,并且 级联耿勋所有关联的游离状态的对象
delete当通过Session的 delete()方法删除当前对象时,会级联删除所有关联的对象
all包含所有的级联行为

2.< set >元素的inverse属性
例子: dept 中有 set emps 属性,在进行 添加新部门并添加雇员信息时,Hibernate为了可靠性 会执行update 外键 语句.
< set >元素的inverse属性的值有两个,即turefalse.
false属性: 会主动方会负责维护关联关系,也就是会主动的执行Update 外键的语句.(是最安全的)
true属性: 不负责维护关联关系.不执行update 外键的语句
经验:
1.在建立两个对象的双向关联时,应该同时修改两个关联对象的相关属性.
2.建议inverse设置为 ture.
代码解释:

  //场景  添加新的部门 并添加相应的员工
  Emp emp=new Emp();
  emp.setEname("hell0sss");
  Dept dept=new Dept();
  dept.setDeptno((byte)20);
  emp.setDept(dept);
  dept.getEmps().add(emp);
  new EmpBiz().saveOrUpdate(emp);
多对多关联关系

场 景: 项目表Project 员工表 Emp 关系表ProEmp
一个项目可能多个员工参与 ,一个员工可能参与多个项目.这个就涉及到多对多的关联关系

  • 多对多映射双方都是使用set元素
  • 通过关系表进行映射
  • 需要把一方的 inverse 设置为true
  • 可以分解成两个一对多映射(当关系表(ProEmp)中的字段除了两个表的关系外键(Project ,Emp )外,还有其他字段,我们就需要分解成两个一对多映射)
延迟加载

延迟加载:是当在真正去要数据时,才执行SQL语句进行查询,避免了无所谓的性能开销.
延迟加载策略的设置分为

  1. 类级别的查询策略
  2. 一对多和多对多关联查询策略
  3. 多对一关联的查询策略

1.类级别的查询策略
在类映射文件(如 emp.hbm.xml)中,设置Class 标签属性lazy 属性. true为开启延迟加载,false为关闭.hibernate3 以后的版本 默认为 true,开启延迟加载.
例如:我们想查询 编号为20 的部门,lazy=true时,Hibernate会分配给我们一个代理对象(proxy),并将这个编号交给代理对象,只有当我们访问其它属性时(访问编号,它是不会去发送查询的SQL的),它才会去发送SQL语句去查询这个编号为20的部门信息.如果这个时候Session已经关闭.就会抛异常org.hibernate.LazyInitializationException: could not initialize proxy - no Session(无法初始化代理对象,无会话)
get()和load()的类级别的查询策略区别
**get()方法:**查询数据时 都是立即加载的.
**load()方法:**根据 类映射文件的延迟加载属性 lazy 的设置来执行到底是立即加载还是使用延迟加载,true 是默认值,采用延迟加载,false为立即加载,可以根据实际情况选择.

2.一对多和多对多关联查询策略
在映射文件中,使用 < set >元素的 lazy 属性来设置
例如:dept 类的 set emps 属性
true: 延迟加载
false: 立即加载
extra:(推荐使用) 增强延迟加载,只获取集合size()contains()isEmpty() 方法时,不会初始化集合代理实例,仅通过特定的select语句查询必要的信息,只有在访问集合属性的 iteator()方法时才会初始化emps集合代理实例的初始化

3.多对一关联的查询策略
在映射文件中,< many-to-one > 元素的 lazy 属性用来设置多对一关联关系.例如在 Emp.hbm.xml 文件中
proxy: 默认值,延迟加载.(拿代理对象没有的值,它才会去查询)
no-proxy: 无代理延迟加载.(实际开发中很少用到,了解它的特点即可)
false: 延迟加载.

Open Session In View模式

不推荐使用更改配置文件的方式来对延迟加载来进行设置(影响太大),推荐使用Open Session In View模式这样的方式
在用户的每一次请求过程始终保持一个Session对象打开着.
具体实现有以下三个步骤:
第一步: 把Session 绑定到当前线程上,要保证再一次请求中只有一个Session对象.
代码如下:

public Session currentSession(){
  return HibernateUtil.currentSession();   //HibernateUtil是个工具类 读取配置文件 初始化 SessionFactory 和创建 Session(这里就不贴代码了)
 }

第二步: 用Filter 过滤器在请求到达时打开Session,在页面生成完毕时关闭Session.
代码如下:
在这里插入图片描述
web.xml 中的filter的配置:
代码:

  <filter>
    <description>This is the description of my J2EE component</description>
    <display-name>This is the display name of my J2EE component</display-name>
    <filter-name>OpenSessionInViewFilter</filter-name>
    <filter-class>servlet.OpenSessionInViewFilter</filter-class>
  </filter>
  <filter-mapping>  
    <filter-name>OpenSessionInViewFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping> 

第三步: 调整业务代码,删除和会话及事务管理相关的代码,仅保留业务逻辑代码.
事务管理统一的在过滤器做处理

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值