这篇文章将重点介绍如何在Spring项目中引入Spring Data JPA,并全面配置持久化层。
2.Spring Data生成的DAO–不再有DAO的实现
DAO层的设计中含有很多样板代码,它应该被简化。这种简化的好处有很多:减少我们需要定义和维护的组件数量;维护数据访问模式的一致性;以及维护配置的一致性。
Spring Data将这一简化又向前推进了一步,使得完全删除DAO的实现成为可能。现在DAO的接口是我们唯一需要明确定义的组件。
为了开始利用JPA的Spring Data编程模型,一个DAO接口需要扩展JPA特定的Repository接口JpaRepository
。这将使Spring Data能够找到这个接口并自动为其创建一个实现。 通过扩展接口,我们得到了标准DAO中可用的CRUD方法。
3.自定义访问方法和查询
正如上文所讨论的,通过实现Repository的一个接口,DAO将定义和实现一些基本的CRUD方法和查询。
为了定义更具体的访问方法,Spring JPA支持以下选项:
-
只需在接口中定义一个新的方法
-
通过使用@Query注解来提供JPQL查询。
-
使用Spring Data中更高级的Specification和Querydsl支持。
-
通过JPA命名查询定义自定义查询
第三个选项,Specification和Querydsl支持,类似于JPA标准,但使用更灵活和方便的API。这使得整个操作的可读性和可重用性大大增强。在处理大量的固定查询时,这种API的优势将变得更加明显,因为我们有可能通过数量较少的可重用代码块来更简洁地表达这些查询。
最后一种方案的缺点是,它要么涉及到XML,要么让实体类承担查询的负担。
3.1 自动的自定义查询
当Spring Data创建一个新的Repository实现时,它分析了所有由接口定义的方法,并试图从方法名称中自动生成查询。虽然这有一些局限性,但这是一种非常强大和优雅的方式,只需少量工作就可以定义新的自定义访问方法。
我们可以看一个例子。如果实体有一个名字字段以及Java Bean标准的getter和setter方法,我们将在DAO接口中定义findByName方法。这将自动生成正确的查询:
public interface IFooDAO extends JpaRepository<Foo, Long> {
Foo findByName(String name);
}
复制代码
这是一个相对简单的例子。查询创建机制支持更多的关键词:
如果解析器不能将该属性与域对象字段相匹配,我们会看到以下异常。
java.lang.IllegalArgumentException: No property nam found for type class com.jayxu.spring.data.persistence.model.Foo
复制代码
3.2 手动自定义查询
现在让我们看看一个自定义查询,我们将通过@Query注解来定义。
@Query(“SELECT f FROM Foo f WHERE LOWER(f.name) = LOWER(:name)”)
Foo retrieveByName(@Param(“name”) String name);
复制代码
4.事务的配置
Spring管理的DAO的实现是隐藏的,因为我们并不直接使用它。然而,它是一个很简单的实现,即SimpleJpaRepository
,它使用注解定义了事务语义。
更明确地说,这在类的层面上使用了一个只读的@Transactional注解,然后对非只读的方法进行重写。其余的事务语义是默认的,但这些可以很容易地被每个方法手动重写。
4.1 异常转译仍然是ok的
在Java中,我们通常使用try-catch语句捕获异常,进行异常处理。但有些时候,我们使用try-catch捕获一个异常,但却不进行异常处理,反而是抛出另一个异常,这就称为异常转译。
现在的问题是:由于Spring Data JPA不依赖于旧的ORM模板(JpaTemplate、HibernateTemplate),而且它们从Spring 5开始就被删除了,我们是否还能让我们的JPA异常被翻译成Spring的DataAccessException层次结构?
答案是,我们当然要这样做。通过在DAO上使用@Repository注解,仍然可以实现异常转译。这个注解使Spring Bean后理器能够用容器中发现的所有PersistenceExceptionTranslator实例告知所有@Repository Bean,并像以前一样提供异常转译。
让我们用一个集成测试来验证异常转译。
@Test(expected = DataIntegrityViolationException.class)
public void givenFooHasNoName_whenInvalidEntityIsCreated_thenDataException() {
service.create(new Foo());
}
复制代码
请记住,异常转译是通过代理完成的。为了让Spring能够围绕DAO类创建代理,这些类必须不被声明为final。
5.Spring Data JPA Repository配置
为了激活Spring JPA repository的支持,我们可以使用@EnableJpaRepositories注解并指定包含DAO接口的包。
@EnableJpaRepositories(basePackages = “com.jayxu.spring.data.persistence.repository”)
public class PersistenceConfig {
…
}
复制代码
我们可以用XML配置做同样的事情。
<jpa:repositories base-package=“com.jayxu.spring.data.persistence.repository” />
总结
面试难免让人焦虑不安。经历过的人都懂的。但是如果你提前预测面试官要问你的问题并想出得体的回答方式,就会容易很多。
此外,都说“面试造火箭,工作拧螺丝”,那对于准备面试的朋友,你只需懂一个字:刷!
给我刷刷刷刷,使劲儿刷刷刷刷刷!今天既是来谈面试的,那就必须得来整点面试真题,这不花了我整28天,做了份“Java一线大厂高岗面试题解析合集:JAVA基础-中级-高级面试+SSM框架+分布式+性能调优+微服务+并发编程+网络+设计模式+数据结构与算法等”
且除了单纯的刷题,也得需准备一本【JAVA进阶核心知识手册】:JVM、JAVA集合、JAVA多线程并发、JAVA基础、Spring 原理、微服务、Netty与RPC、网络、日志、Zookeeper、Kafka、RabbitMQ、Hbase、MongoDB、Cassandra、设计模式、负载均衡、数据库、一致性算法、JAVA算法、数据结构、加密算法、分布式缓存、Hadoop、Spark、Storm、YARN、机器学习、云计算,用来查漏补缺最好不过。
JAVA多线程并发、JAVA基础、Spring 原理、微服务、Netty与RPC、网络、日志、Zookeeper、Kafka、RabbitMQ、Hbase、MongoDB、Cassandra、设计模式、负载均衡、数据库、一致性算法、JAVA算法、数据结构、加密算法、分布式缓存、Hadoop、Spark、Storm、YARN、机器学习、云计算,用来查漏补缺最好不过。
[外链图片转存中…(img-iW6PvMjm-1714456234000)]