1.使用spring data repositorys
spring data repository abstraction节省了大量的数据访问层实现持久化的代码。
1.1核心概念
Repository是核心接口,接口需要实体类型和实体类id的类型参数。CrudRepository接口继承Repository接口,并提供了对实体类的CRUD功能。实例如下:
public interface CrudRepository<T, ID extends Serializable> extends Repository<T, ID> { <S extends T> S save(S entity); T findOne(ID primaryKey); Iterable<T> findAll(); Long count(); void delete(T entity); boolean exists(ID primaryKey); // … more functionality omitted. }
PagingAndSortingRepository接口继承了CrudRepository接口,提供了对实体的分页功能。代码如下:
public interface PagingAndSortingRepository<T, ID extends Serializable> extends CrudRepository<T, ID> { Iterable<T> findAll(Sort sort); Page<T> findAll(Pageable pageable); }
分页实现代码如下:
PagingAndSortingRepository<User, Long> repository = // … get access to a bean Page<User> users = repository.findAll(new PageRequest(1, 20));
1.2 查询方法
spring data 完成一个查询需要以下4个过程:
(1)建一个继承Repository或Repository的子类的一个接口,并绑定实体类。
public interface PersonRepository extends Repository<User, Long> { … }
(2)在接口中定义查询方法。
List<Person> findByLastname(String lastname);
(3)在sping配置文件中创建接口的代理实例。
<?xml version="1.0" encoding="UTF-8"?> <beans:beans xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/data/jpa" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd"> <repositories base-package="com.acme.repositories" /> </beans>
(4)获得接口实例并执行查询方法。
public class SomeClient { @Autowired private PersonRepository repository; public void doSomething() { List<Person> persons = repository.findByLastname("Matthews"); } }
以下是对4个过程的说明:
定义接口
第一步定义一个指定实体类的接口,这个接口必须继承Repository,并且要输入实体类和ID类型。如果要提供实体的CRUD操作,那么可以用CrudRepository替代Repository接口。
通常,定义的repository接口都继承Repository, CrudRepository or PagingAndSortingRepository接口。有时如果不想继承这些spring data接口,那么也可以给接口注解@RepositoryDefinition来实现。继承CrudRepository 会包含对实体的完整管理操作,如果只想选择性的提供某些方法,那么可以在CrudRepository接口中拷贝想要提供的操作方法放到定义的接口中。
interface MyBaseRepository<T, ID extends Serializable> extends Repository<T, ID> { T findOne(ID id); T save(T entity); } interface UserRepository extends MyBaseRepository<User, Long> { User findByEmailAddress(EmailAddress emailAddress); }
在这第一步为实体类定义了一个基本接口,并且提供了findOne(…) 和 save(…)方法,这些方法会通过匹配CrudRepository接口的签名方法并传递到实现类中。因此,接口UserRepository将包含保存用户、通用id得到唯一用户和通过邮件地址查询用户的功能实现。
定义查询方法
Repository代理能够通过方法名来生成查询语句。它可以直接通过方法名生成,也可以利用策略构建查询语句。
在命名空间中通过query-lookup-strategy属性来配置策略。有些策略在特殊的存储环境下不支持。
CREAT —— create是根据接口方法名来构建查询语句,方法是首先删掉一些固定的常用的前缀,然后在解析剩下的部分。
USE_DECLARED_QUERY——它会查找已经定义的查询语句,如果没发现会抛出异常。这个查询语句是通过某处的注解或其他方法定义的。根据指定的规范文档来查找可用选项,如果在方法被调用时没有找到定义的查询,那么会出现错误。
CREATE_IF_NOT_FOUND (default)——CREATE_IF_NOT_FOUND 结合了 CREATE 和USE_DECLARED_QUERY。首先查找已定义的查询,如果没有找到,会创建一个基于方法名称的查询。这个策略是默认的,如果没有设置的话它将起作用。
Query的创建
spring data 的query构建机制对实体的查询非常有用,它会去掉方法名中的find…By、read…By和 get…By 前缀,然后再解析剩余的部分。方法名中可以加入distinct来表明创建的查询语句需要distinct约束,方法名中的第一个by是查询语句的开始,也可以定义属性的查询条件,并且可以使用and和or来连接多个条件。
public interface PersonRepository extends Repository<User, Long> { List<Person> findByEmailAddressAndLastname(EmailAddress emailAddress, String lastname); // 查询中可带distinct标识 List<Person> findDistinctPeopleByLastnameOrFirstname(String lastname, String firstname); List<Person> findPeopleDistinctByLastnameOrFirstname(String lastname, String firstname); // 属性忽略大小写 List<Person> findByLastnameIgnoreCase(String lastname); // 所有的属性忽略大小写 List<Person> findByLastnameAndFirstnameAllIgnoreCase(String lastname, String firstname); // 带order by排序的查询语句 List<Person> findByLastnameOrderByFirstnameAsc(String lastname); List<Person> findByLastnameOrderByFirstnameDesc(String lastname); }
方法名解析的结果是与持久化储存相关的,但是,还要注意以下几个问题:
- 在多个属性组根据合查询条件时,可以使用and和or连接。另外,还支持Between、LessThan、GreaterThan、Like这样的运算符。这些运算的使用取决于数据库,因此要参考相关文档。
- 方法名的解析支持为各个属性设置IgnoreCase,例如,findByLastnameIgnoreCase(…)或者findByLastnameAndFirstnameAllIgnoreCase(…)。但是,IgnoreCase也可能跟数据库有关系,需要参考相关的文档。
- 在方法名中直接指定order by (desc、asc)来支持排序,另外还支持动态排序,见参数绑定一节。
属性表达式
前面的例子,属性的表达式都是引用了实体本身的属性。当然,还可以引用属性嵌套的属性。例如,Persons类有一个属性Addresses,Addresses里包含一个ZipCodes.属性,那么方法名应该是这样
List<Person> findByAddressZipCode(ZipCode zipCode);
创建属性的遍历如同x.address.zipCode。解析算法是首先取出作为实体属性的完整部分(AddressZipCode),检查这部分是否是实体类的属性,如果是那么解析成功,否则,将这个部分按照驼峰式从右往左分割为两部分(头和尾),将分割的两部分跟实体属性进行匹配,如:AddressZipCode分为AddressZip 和 Code。如果解析器在属性中匹配了去掉尾的头,那么将剩下的尾部再进行同样方式的解析。如果第一次分割不能匹配,解析器会向左移动分割点(Address,ZipCode),并继续解析。
虽然这运用在大多数情况下,但也有可能将属性解析错。假设Person类也有一个addressZip属性,解析器将匹配第一次的分割,其实选择了一个错误的属性并且最终失败(AddressZip中没有code)。要解决这个有歧义性的错误,可以在方法名中利用”_“来手动定义分割点,因此方法名将会像这样:
List<Person> findByAddress_ZipCode(ZipCode zipCode);
特殊参数绑定
以上例子中展示了在查询语句中绑定简单的参数。除此之外,数据访问层还使用一些特殊的类型如Pageable 和、Sort来实现分页和动态排序查询。
Page<User> findByLastname(String lastname, Pageable pageable); List<User> findByLastname(String lastname, Sort sort); List<User> findByLastname(String lastname, Pageable pageable);
第一个方法,通过org.springframework.data.domain.Pageable的实例添加分页到已定义的查询语句中,在Pageable实例中绑定了排序项。如果只要排序,可以在参数中仅添加org.springframework.data.domain.Sort参数,你可以看到,返回了一个List对象。在Page实例所需附加元数据不被创建的情况下,只做了一个简单的查询。
创建Repository实例
创建已定义的Repository接口的实例,最简单的方式是通过使用spring命名空间。
基于XML配置
Spring Data模块包含了一个repositories元素,这个元素允许定义spring扫描的包路径。
<?xml version="1.0" encoding="UTF-8"?> <beans:beans xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/data/jpa" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd"> <repositories base-package="com.acme.repositories" /> </beans:beans>
在这个例子中,"base-package"指定了spring要扫描的包路径com.acme.repositories及全部子包,在这些包下的接口必须继承Repository接口或者是Repository的子接口。基础设施层注册了FactoryBean来代理处理查询方法接口的调用。每个注册的bean名称来源于各接口的名称,因此,UserRepository的接口名称将被注册为userRepository。base-package属性允许采用通配符作为包扫描的格式。
使用过滤器
在<repositories />中可以利用<include-filter />和<exclude-filter /> 元素来更细粒度的控制接口的实例化。例如,在实例化的时候可以排除一些确定的接口,配置如下:
<repositories base-package="com.acme.repositories"> <context:exclude-filter type="regex" expression=".*SomeRepository" /> </repositories>
这个例子在接口实例化的时候不包含以SomeRepository结尾的接口。
基于Java的配置
在javaConfig类上可以通过@Enable${store}Repositories注解来实现。样例如下:
@Configuration @EnableJpaRepositories("com.acme.repositories") class ApplicationConfiguration { @Bean public EntityManagerFactory entityManagerFactory() { // … } }
独立用法
在spring容器之外使用。在项目的类路径下引入spring的包,以编程的方式来来设置Repsitories。SpringData模块中提供了持久类RepositoryFactory来实现,代码如下:
RepositoryFactorySupport factory = … // Instantiate factory here UserRepository repository = factory.getRepository(UserRepository.class);
1.3自定义SpringData Repositories的实现
spring data允许自定义实现数据访问的存取方法,并且可以集成常用CRUD和查询功能。
添加自定义的行为
首先为数据存储建立一个自定义功能的接口及实现。
interface UserRepositoryCustom { public void someCustomMethod(User user); } class UserRepositoryImpl implements UserRepositoryCustom { public void someCustomMethod(User user) { // Your custom implementation } }
在标准接口中继承自定义的接口:
public interface UserRepository extends CrudRepository<User, Long>, UserRepositoryCustom { // Declare query methods here }
配置
如果使用命名空间配置,数据基础框架会在指定的包下自动搜索自定义的实现类,这些类的名称必须满足在repository-impl-postfix元素中指定的命名约定,这个后缀默认配置为Impl。
<repositories base-package="com.acme.repository" /> <repositories base-package="com.acme.repository" repository-impl-postfix="FooBar" />
第一个配置例子会查找com.acme.repository.UserRepositoryImpl,第二个例子查找com.acme.repository.UserRepositoryFooBar。
手动装配
前面的例子如果在基于注解并且只有自动适配的情况下可以很好的运行,因为它会在任意的spring Bean中匹配。如果自定义的实现需要手动装配,那需要声明这个bean并且要以刚刚描述的约定去命名。基础框架会引用手动定义的基于名称的bean,而不是创建自身。
<repositories base-package="com.acme.repository" /> <beans:bean id="userRepositoryImpl" class="…"> <!-- further configuration --> </beans:bean>
为所有的储存添加自定义行为
当想添加一个自定义的行为在所有储存接口时,前面的例子无法做到。
-
定义一个声明共享行为的中间接口。
public interface MyRepository<T, ID extends Serializable> extends JpaRepository<T, ID> { void sharedCustomMethod(ID id); }
现在需要各自的储存接口继承这个中间接口,而不是Repository接口。 -
接下来,创建一个实现了中间接口并且继承了规范库中的基类,这个类会作为Repository代理的自定义基类来执行。
public class MyRepositoryImpl<T, ID extends Serializable> extends SimpleJpaRepository<T, ID> implements MyRepository<T, ID> { private EntityManager entityManager; // There are two constructors to choose from, either can be used. public MyRepositoryImpl(Class<T> domainClass, EntityManager entityManager) { super(domainClass, entityManager); // This is the recommended method for accessing inherited class dependencies. this.entityManager = entityManager; } public void sharedCustomMethod(ID id) { // implementation goes here } }
相关推荐
spring注解完整版+spring data jpa官方文档中文翻译+JPA2.0官方文档 文档内容齐全 值得参考学习
spring data jpa参考文档
是英文版,英文版!SpringData-JPA的官方文档PDF
Spring Data JPA是Spring基于Hibernate开发的一个JPA框架。如果用过Hibernate或者MyBatis的话,就会知道对象关系映射(ORM)框架有多么方便。但是Spring Data JPA框架功能更进一步,为我们做了 一个数据持久层框架...
Spring Data JPA中文文档[1.4.3].pdf SpringBoot实战.pdf springboot知识导图笔记.xmind SpringBoot面试专题及答案.pdf SpringCloud参考指南.pdf SpringCloud面试专题及答案.pdf SpringMVC面试专题及答案.pdf Spring...
Spring Data Jpa常用功能演示配套说明请查看:项目简介本项目采用当前最新版本的2.1.4.RELEASE做基础架构支撑,请参考本项目建议有一定的基础及经验。教程主要针对中文用户,如果您英文良好,建议直接阅读官网帮助...
介绍极简后台管理系统是一个后台管理系统的基础模板,定义好实体类即可自动生成其他所有前引用代码。采用前拆分分离进行开发,全部使用Rest风格API进行数据传递。...参考文档视频教程正在录制中...
中文-英文对照文档,中英对照文档,java,jar包,Maven,第三方jar包,组件,开源组件,第三方组件,Gradle,中文API文档,手册,开发手册,使用手册,参考手册 # 使用方法: 解压 【***.jar中文文档.zip】,再解压其中的 【***-...
中文-英文对照文档,中英对照文档,java,jar包,Maven,第三方jar包,组件,开源组件,第三方组件,Gradle,中文API文档,手册,开发手册,使用手册,参考手册 # 使用方法: 解压 【***.jar中文文档.zip】,再解压其中的 【***-...
中文-英文对照文档,中英对照文档,java,jar包,Maven,第三方jar包,组件,开源组件,第三方组件,Gradle,中文API文档,手册,开发手册,使用手册,参考手册 # 使用方法: 解压 【***.jar中文文档.zip】,再解压其中的 【***-...
该项目采用了springboot框架,具有高度的灵活性和扩展性,同时还集成了Spring Security进行用户权限控制、Spring Data JPA进行数据持久化,以及Thymeleaf模板引擎进行页面呈现。整体架构清晰,代码结构清晰,便于...
ORM框架用的 Spring Data JPA,权限管理用的是 Spring Security。 以 MySQL 作为数据库,同时用 Redis 数据库缓存几个排行榜。模板引擎使用的是官方推荐的 Thymeleaf,告别JSP吧。 图片上传使用第三方上传——七牛云...
参考文档:gradle的官方userguide.pdf文档的chapter 55和chapter 56. gradle的多模块或项目开发一定不会比maven差,在我看来!大的项目分成多个模块来开发是...core主要使用spring+spring data jpa(hibernate实现)+mysql
java ...Introduction 集结最新主流时尚开源技术的面向企业级Web应用的基础开发框架,提供一个J2EE相关主流开源技术架构整合及一些企业应用基础通用功能和组件的设计...引入JPA、Spring-Data-JPA提升持久层架构规范性和开
通过阅读源代码,可以深入了解Spring Boot的各项特性,如Spring MVC、Spring Data JPA、Spring Security等的使用方法和最佳实践。同时,项目也融入了一些前端开发的技巧,使得整个网站的用户体验非常出色。 除了源...
* Dao层(Data Access Object数据访问对象)使用Spring Data JPA来维护数据读写操作,Spring Data JPA的底层是基于Hibernate的,其JpaRepository、PageAndSortingRepository、CrudRepository等组件能够实现快速单表...
* Spring Data Jpa * MySQL * Redis * Shiro ### 前端 * Vue * ElementUI * Axios ### 三方服务 * 阿里云对象存储 # 项目部署 **bookshop文件夹为打包了前端静态资源的后端项目文件,可以独立运行,端口为8443。**...
该项目使用了Spring框架的核心技术,如SpringBoot、SpringMVC、Spring Data JPA等,以及Thymeleaf模板引擎进行页面渲染。同时,还使用了MySQL数据库进行数据存储,实现了用户信息、简历、招聘信息等数据的持久化存储...
使用Spring Data JPA和Mongo仓库 x. 67.10. 将Spring Data仓库暴露为REST端点 vii. 68. 数据库初始化 i. 68.1. 使用JPA初始化数据库 ii. 68.2. 使用Hibernate初始化数据库 iii. 68.3. 使用Spring JDBC初始化数据库 ...
实现的第一个导出器是 JPA 存储库导出器。 这需要您的 JPA 存储库并使用 HTTP 将它们作为前端,从而允许您对实体进行完整的 CRUD 功能,包括管理关联。 安装 安装说明在文档中: 执照 Spring Data REST 是。 为 ...