原文:JPA implementation patterns: Field access vs. property access
作者:Vincent Partington
出处:http://blog.xebia.com/2009/06/13/jpa-implementation-patterns-field-access-vs-property-access/
上周我的同事Albert Sikkema写了一篇关于使用UUID作为主键的博客,很有意思的一篇东西,再次谢谢你,Albert!本周我将继续这一JPA实施模式系列,讨论域访问(field access)和属性访问(property access)两者的优缺点比较。
JPA规范为持久性提供程序(persistence provider)提供两种访问实体的持久内容的方式,持久性提供程序既可以调用JavaBean风格的属性访问方法(getter和setter方法),也可以直接访问实体的实例域,使用哪一种方法则取决于你是否已经为实体的属性或者域设定了注解。
JPA 1.0规范不允许在一个实体内,或甚至是实体的层次结构内混合使用访问类型,如果域和属性这两种注解都被设定了的话,那么行为方式会是不确定的。JPA 2.0规范使用@Access注解来使得在一个实体或者实体层次结构中混合使用访问类型变成可能的。
不过令人感兴趣的问题依然存在:使用哪一种访问类型?这是一个以前已经讨论过的问题,但也是我无法抗拒进行评论的一个问题。
封装性—属性访问据说是为了提供更好的封装性,因为直接访问域是不好的,真是这样吗?实际的情况是,使用属性访问迫使你为所有的持久属性编写getter和setter方法。这些方法不仅允许JPA提供程序设置域,而且允许实体类的任何其他用户这样做!使用域访问则允许你只编写想要的getter和setter方法(它们是邪恶的,还记得吗?),以及还可以把它们编写成你想要的样子,例如,在setter方法中进行验证或者在getter方法中进行一些计算。相反,在使用属性访问时,使这些方法变得更聪明则只是在自找麻烦。
性能—有些人宁愿选择域访问,因为它看起来比属性访问提供了更好的性能,不过这是一个非常糟糕的选择域访问的理由。现在的优化JVM会使得属性访问的执行与域访问同样地快,而且在任何情况下,数据库的调用都要比域访问或者方法调用慢上几个数量级。
Hibernate的延迟加载—Hibernate延迟加载的实现总是在代理的任意方法被调用时初始化该延迟代理,唯一的例外是在使用属性访问的时候,使用了@Id这一注解来进行注释了的方法。但是在使用域访问的时候就不存在这样的方法,而且Hibernate甚至在调用返回实体标识的方法的时候也会初始化代理。虽然有些人建议使用属性访问直到这一错误被修正,不过我并不赞成在框架错误方面进行基础的设计决策,如果该错误确实是损害了性能的话,你可能会想尝试用以下代码来获取实体的id:
Serializable id = ((HibernateProxy) entity).getHibernateLazyInitializer().getIdentifier()
代码并不友好,但至少可局部用在你真正需要它的地方。
Hibernate的域访问—最好要知道,虽然对于Hibernate来说,使用域访问来填充实体是可以的,不过你的代码仍应该通过方法来访问这些值,否则你将陷入我的同事Maarten Winkels提到的Hibernate代理陷阱的第一个之中。
总结一下,我认为域访问是适宜使用的方式,因为它提供了更好的封装性(没有它的话,妥善管理双向关联是不可能的),并且性能影响可以忽略不计(十大性能问题中的第一条#1仍然是数据库和Java应用之间的相互影响)。唯一的缺点是,Hibernate延迟加载实现的局面有些混乱,这就要求你在使用域访问的时候要额外地小心。
你喜欢使用什么样的访问类型?在域访问和属性访问的实现方式方面,你有没有发现JPA提供程序有任何不同于Hibernate的地方?请在下面留下评论以便让我知道,我们在下一篇JPA实施模式的博客中再见,下次我会谈谈JPA中的继承层次结构。
分享到:
相关推荐
Spring Data JPA 是一款基于 Java 持久层 API(JPA)的框架,提供了一个通用的数据访问层解决方案,能够简化 Java 应用程序中的数据访问工作。Spring Boot 作为一个流行的 Java 框架,提供了一个快速开发的平台,...
在实际项目中,我们可能还需要配置数据库连接,比如在`application.properties`或`application.yml`中设置数据源和JPA属性,如: ```properties spring.datasource.url=jdbc:mysql://localhost:3306/testdb spring....
在处理关联关系时,Spring Data JPA提供了懒加载和急加载(Eager vs Lazy Fetching)机制,通过配置实体类的属性映射,可以在需要时按需加载关联的数据,避免了N+1查询问题。同时,它还支持级联操作(Cascade ...
【标题】"notes_JPA_JSF:使用JSF和JPA实施来重建Notes项目"涉及的是在Java开发环境中,利用JavaServer Faces (JSF) 和 Java Persistence API (JPA) 技术重构建一个名为Notes的项目。JSF是Java EE平台上的一个用户...
总结来说,Spring MVC结合JPA和JpaRepository提供了一个高效、灵活的数据访问解决方案。通过定义接口和使用命名查询,我们可以轻松地进行数据库交互,同时保持代码的简洁和可维护性。这使得开发者能够更专注于业务...
JPA(Java Persistence API)是一种 Java 持久化 API,提供了一个通用的持久化机制,允许开发者使用面向对象的方式来访问关系型数据库。下面是 JPA 核心知识的讲解,包括 JPA 概述、JPA 入门、JPA 实体、JPA 实体...
1:JPA: : 2:对象数据库: ://www.objectdb.com/ 3:JPA 性能基准: ://www.jpab.org/All/All/All.html 支持功能 支持所有蓝图功能, 除外 支撑 支持 支持 Java 5、6 或 7 支持 JPA 你需要哪一个取决于你想用...
首先,Hibernate的核心概念是对象关系映射(ORM),它通过在Java对象和数据库记录之间建立映射关系,实现了数据的透明访问。ORM解决了传统的JDBC编程模式中数据访问的繁琐性,提高了开发效率。在Hibernate中,实体类...
学习和掌握JPA对于开发Java企业级应用至关重要,因为它简化了数据库操作,使得开发者可以更专注于业务逻辑,而不是底层的数据访问细节。同时,了解JPA还可以帮助你更好地理解和使用其他ORM框架,如Hibernate和...
一共有三个分卷。全部下载才能解压。 这本书不错,值得一看。
### JPA和Hibernate的关系 #### 一、JPA概述 JPA(Java Persistence API)是Java平台上的标准ORM(Object Relational Mapping)接口,作为Java EE 5的一部分被引入,旨在提供一种统一的方式用于访问数据库。它定义...
默认情况下,JPA通过getter和setter方法来访问实体的属性,这就是所谓的`FIELD`访问模式。然而,开发者也可以选择使用`PROPERTY`访问模式,即通过字段的getter和setter方法来处理数据。混合访问模式允许在实体的不同...
本文是介绍Spring-data-jpa的PPT的学习笔记,整理了Spring Data JPA相关知识配置和实践源码. 本文介绍知识点有: JPA与Spring的相关配置 JPA 方法名常用查询 JPA 使用@Query注解实现JPQL和本地自定义查询 JPA API 条件...
使用JPA访问数据: : 。 使用REST访问JPA数据: : 。项目中的Bean全部采用进行精简,需要配合IDE插件使用,在此项目不进行讨论,如需了解更多,参考以下链接:官方文档地址: : 。官方下载地址: : 。 lombok-...
JPA 提供了一种简单的方法来存储和检索应用程序中的数据。通过使用注解或 XML 描述对象-关系映射元数据,开发人员可以轻松地将 Java 对象与数据库表关联起来。 在本篇内容中,我们将深入探讨 JPA 注解的一些核心...
标签中的“源码”和“工具”可能指的是项目中包含了相关的源代码示例和可能使用的JPA实现工具,如Hibernate或OpenJPA。这些工具通常带有丰富的API和实用功能,比如Hibernate的Criteria API、HQL等,可以帮助开发者更...
春天数据jpa额外使用jpa的spring数据更舒适我爱spring-data-jpa,她放开我的双手,粗鲁的方法很无聊! 然而,尽管她为我们提供了规范解决方案,但她在动态本机查询上并不完美,而且她的返回类型必须是一个实体,但是...
JPA是Java应用中处理数据库操作的强大工具,尤其当它与Spring框架结合时,能够提供一个高度集成和可扩展的数据访问解决方案。理解并熟练掌握JPA的各种关系映射机制对于高效地设计和实现数据密集型应用程序至关重要。...