Hibernate的延迟加载
来源:互联网 发布:大学生单片机比赛 编辑:程序博客网 时间:2024/05/08 23:54
hibernate中,延迟加载大致可以分为两类,一类是延迟属性加载,另一类是延迟关联实体加载。
普通属性:分两种情况,一种是集合属性,一种是非集合属性(如String、Integer......)
集合属性的延迟加载通过PersistentSet、 PersistentList、PersistentBag、PersistentMap、PersistentSortedMap、PersistentSortedSet作为代理类来实现,代理类中保存了session以及owner属性,owner属性表示了集合属性所属的one侧的实体。
非集合类属性的延迟加载相对比较复杂。仅通过@Basic(fetch = FetchType.LAZY)注解是无法实现延迟加载的。需要让实体实现FieldHandled接口,声明FieldHandler属性,通过拦截器原理注入对应的FieldHandler属性,起到类似于上述代理类的作用,FieldHandler同样也保持了session,以及需要延迟加载的属性。
@Basic(fetch = FetchType.LAZY)@Column(name="CONTENT")public String getContent() { if (fieldHandler != null) { return (byte[]) fieldHandler.readObject(this, "content", content); } return null;}public void setContent(byte[] content) { this.content = content;}@Overridepublic void setFieldHandler(FieldHandler handler) { this.fieldHandler = handler;}@Overridepublic FieldHandler getFieldHandler() { return this.fieldHandler;}Hibernate官网对非结合属性的延迟加载有如下的评论:
Lazy property loading requires buildtime bytecode instrumentation. If your persistent classes are not enhanced, Hibernate will ignore lazy property settings and return to immediate fetching.
A different way of avoiding unnecessary column reads, at least for read-only transactions, is to use the projection features of HQL or Criteria queries. This avoids the need for buildtime bytecode processing and is certainly a preferred solution.
大致的意思就是:应该是因为,我们并未用到编译时字节码增强技术的原因。如果只对部分property进行延迟加载的话,hibernate还提供了另外的方式,也是更为推荐的方式,即HQL或者条件查询。
更为推荐的方式说白了就是在查询的时候就过滤掉不需要的属性,以下列出HQL和Criterial的两种实现方法:
// criterial实现criteria.setProjection( Projections.projectionList().add(Projections.property("id"), "id") .add(Projections.property("age"), "age")).setResultTransformer( Transformers.aliasToBean(User.class));// HQL实现Query query = session.createQuery("select u.id as id,u.age as age from User u where u.id=2");query.setResultTransformer(Transformers.aliasToBean(User.class));
关联实体:分两种情况,一种是多对一,另一种是一对一。
关联实体是多个实体时(包括一对多、多对多):此时关联实体将以集合的形式存在,Hibernate 将使用 PersistentSet、PersistentList、PersistentMap、PersistentSortedMap、PersistentSortedSet 等集合来管理延迟加载的实体。这就是前面所介绍的情形。
关联实体是单个实体时(包括一对一、多对一):当 Hibernate 加载某个实体时,延迟的关联实体将是一个动态生成代理对象。Hibernate 使用 Javassist 项目动态生成的代理类——当 Hibernate 延迟加载关联实体时,将会采用 Javassist 生成一个动态代理对象,这个代理对象将负责代理“暂未加载”的关联实体。但是在一对一关系中,延迟加载是有陷阱的。
一对一关联一般有两种形式,一种是主键关联;另一种是外键关联。
主键关联:
Husband:id,name
Wife:id,name
Husband实体:@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY, optional = false)@PrimaryKeyJoinColumngetWife()@GenericGenerator(name = "Wife", strategy = "foreign", parameters = { @Parameter(name = "property", value = "husband") })Wife实体:@OneToOne(mappedBy = "wife", fetch = FetchType.LAZY)getHusband()以上是hibernate中的配置。其中“optional=false”的配置时关键,否则即使配置了fetch策略为lazy,也无法做到在获取husband实体的时候延迟加载wife实体。optional的默认值是true,表示关联的实体可以为null。在一对一的延迟加载中,hibernate并非一定对需要延迟加载的实体生成一个动态代理对象,而是当被关联的实体确定不为null时,才会生成,否则直接将其置为null。所以问题就来了,对于两个通过主键关联的一对一实体,在获取到其中一个实体后,要判断与之关联的实体是否存在,则必须要再查询一次数据库才可以。这也就是为什么在设置了延迟加载策略后,hibernate还是立即发送了一次查询请求给数据库。
要解决一对一关系中的延迟加载,共有两种方法:一种就是上面提到的,把optional设置为false,即关联的实体一定不为null。这样一来,hibernate就会立即为配置延迟加载的实体生成一个动态代理类。
第二种方法就是通过外键来关联,即:
Husband:id,name, wife_idWife:id,name
其中husband_id与Husbande中的id关联
Husband实体:@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)@JoinColumn(name = "wife_id", , referencedColumnName = "id")getWife()Wife实体:@OneToOne(mappedBy = "wife", fetch = FetchType.LAZY)getHusband()这样一来,直接可以通过husband中的wife_id的null与否来判断wife实体是否为null。
- hibernate的延迟加载
- Hibernate的延迟加载
- hibernate 的延迟加载
- hibernate的延迟加载
- hibernate的延迟加载
- Hibernate 的延迟加载
- Hibernate的延迟加载
- Hibernate的延迟加载
- Hibernate 的延迟加载
- Hibernate的延迟加载
- Hibernate的延迟加载
- 关于hibernate的延迟加载
- Hibernate延迟加载的原理
- hibernate 的延迟加载机制
- Hibernate 延迟加载的错误
- Hibernate的延迟加载机制
- hibernate的延迟加载问题
- Hibernate延迟加载的策略
- expression is not assignable
- java安全沙箱机制介绍
- 第四届蓝桥杯之排它平方数
- LINUX 安装mysql 5.1源码
- [转载]如何在Windows版的VirtualBox内设置共享文件夹
- Hibernate的延迟加载
- 给定一个整数N,求解整数N!末尾0的个数
- win7和ubuntu双系统搭建
- RecyclerView--实现 ListView,GridView,瀑布流 效果
- 深刻理解Python中的元类(metaclass)
- 在TQ2440裸机汇编程序中犯的一个令人难以想到的错误
- 写一个函数,判断一个int型的正整数是否是2的幂,即是否可以表示成2^X的形式(不可以用循环)
- 松原咸宁松原菏泽情家缘婚恋俱乐部松原咸宁松原汉中岳阳]婚恋网招商加盟易购网
- 线程的同步