Java for Web学习笔记(一三六)映射(12)还谈FetchType.LAZY

说明

在前面的学习中(见Java for Web学习笔记(一二七)映射(3)OneToOne),加上fetch = FetchType.LAZY的属性是集合或者Map。反映在SQL中,就是读取其他表格的信息(无论是通过join还是什么)。例如前面学习的@OneToMany、@ElementCollection。就单个表格而言,一次读取所有的列的数据,实际上在MySQL中,即使我们只是SELECT A From Table T,也是将整行数据全部读取。

但是,有这样的场景,表格中某一列的类型是blob或者text,这一列存储信息的size很大。如果我们一次读取多行,这会相当占内存,同时由于数据量大,导致网络时延增大。我们希望对这样类提供LAZY的读取方式,只有用到,采去获取。

小例子

load-time bytecode weaving

对于entity的集合或者Maps属性,Hibernate ORM可以通过proxy对接口实现来获知需要哪些数据。但是对于entity的简单属性,Hibernate需要在bytecode层面来,拦截方法的调用。这就是所谓的load-time bytecode weaving。在Spring中entityManager采用的注入方式,而注入,本身就是在bytecode层面,如果我们不能在接口实现中进行,就在bytecode层面进行处理。

具体的实现就是通过Spring的org.springframework.instrument.classloading.LoadTimeWeaver来检查并使用Tomcat的ClassLoader。我们RootContextConfiguration中加上相关的设置。

@EnableLoadTimeWeaving
......
public class RootContextConfiguration implements AsyncConfigurer, SchedulingConfigurer{
    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean(){
        ... ...
        /* 在书中给的是hibernate.ejb.use_class_enhancer = true,但我们的测试,至少在
        * hibernate 5中是不起作用的,不会真的是LAZY。在Hibernate文档(5.2)的23.6. Bytecode 
        * Enhancement Properties中给出另外一个配置:
        * hibernate.enhancer.enableLazyInitialization = true, 这个能够正常工作。 */
        properties.put("hibernate.enhancer.enableLazyInitialization","true");
        ... ...
    }
    ... ...
}

相关的entity代码

可以直接在Entity相关属性上面加上LAZY的说明,下面是某个例子:

//因为@Lob是没有fetch参数的,因此在@Basic中定义
@Lob @Basic(fetch = FetchType.LAZY)
public byte[] getContents() {
	return contents;
}

除了entity的直接属性外,还可以用到@OneToOne和@ManyToOne,或者是集合和Map属性内的元素。

对于XML和JSON要注意

如果这个entity类需要封装为XML或者JSON在接口传递(一般不建议这样,因为那属于呈现层,不因和数据存储的接口相绑定)。但是如果有这种情况,使用了load-time bytecode weaving就需要注意了,在这个过程中,Hibernate可能会在类加入一些不可以预测的属性或方法。这会影响到XML和JSON的翻译。我们可以在类中标识不自动进行XML或者JSON的转换,除非对属性明确标识。下面是例子:

@Entity
@XmlRootElement(name = "attachment")
@XmlAccessorType(XmlAccessType.NONE)
@JsonAutoDetect(creatorVisibility = JsonAutoDetect.Visibility.NONE,
        fieldVisibility = JsonAutoDetect.Visibility.NONE,
        getterVisibility = JsonAutoDetect.Visibility.NONE,
        isGetterVisibility = JsonAutoDetect.Visibility.NONE,
        setterVisibility = JsonAutoDetect.Visibility.NONE)
public class Attachment implements Serializable{
	......

	@Basic
	@Column(name = "AttachmentName")
	@XmlElement
	@JsonProperty
	public String getName() {
		return name;
	}

	@Lob @Basic(fetch = FetchType.LAZY)
//	@LazyGroup是hibernate提供的标记,不是标准的JPA。当读的时候,会将lazy的相关属性都读入。
//	如果需要区分,某次只读入某个或某些属性,可以使用@LazyGroup进行区分,没有标记就是default了。
//	@LazyGroup( "lobs" )
	@XmlElement
	@XmlSchemaType(name = "base64Binary")
	@JsonProperty
	public byte[] getContents() {
		return contents;
	}
	... ...
}

相关链接:我的Professional Java for Web Applications相关文章

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
FetchType.LAZY是Hibernate中的一种加载策略。当使用懒加载策略时,加载一个实体时,定义为懒加载的属性并不会立即从数据库中加载,而是在需要访问这些属性时才会去数据库中查询加载。 这种策略的好处是可以减少不必要的数据库查询,提高性能。比如在一个用户类中,用户的地址属性在大多数情况下并不需要立即显示出来,只有在需要查看用户资料时才会去查询数据库加载地址信息。而用户名属性则需要在用户登录时立即显示出来,因此需要使用急加载策略。 在Hibernate中,可以通过在实体类的属性上使用注解来设置延迟检索策略。例如,可以使用@OneToMany注解来设置一对多关系中的延迟加载策略。通过设置fetch属性为FetchType.LAZY,可以显式地指定该属性的延迟加载策略。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [hibernate 中 fetch=FetchType.LAZY 懒加载失败处理方法](https://download.csdn.net/download/weixin_38682242/12771863)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [Hibernate,FetchType.LAZYFetchType.EAGER什么区别?](https://blog.csdn.net/B_evan/article/details/53868520)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [孙卫琴的《精通JPA与Hibernate》的读书笔记:FetchType.LAZY延迟检索策略](https://blog.csdn.net/csdnuserlala/article/details/116403315)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值