Spring Data

Spring Data

一.概述

1.Spring Data 概述

Spring Data:
	Spring 的一个子项目。用于简化数据库访问,支持 NoSQL 和关系数据存储。
	其主要目标是使数据库的访问变得方便快捷。
	
	SpringData 项目所支持的 NoSQL 存储:
		MongoDB(文档数据库)
        Neo4j(图形数据库)
        Redis(/值存储)
        HBase(列族数据库)
        
    SpringData 项目所支持的关系数据存储技术:
    	JDBC
    	JPA

2.JPA Spring Data 概述

JPA Spring Data :
	致力于减少数据访问层(DAO)的开发量。开发者唯一要做的,就只是声明持久层的接口,其他都交给 Spring Data JPA.

二.Spring Data JPA HelloWorld

使用 Spring Data JPA 进行持久层开发需要的四个步骤:
	1.配置 Spring 整合 JPA
	2.在 Spring 配置文件中配置 Spring Data,让 Spring 为声明的接口创建代理对象。配置了<jpa:repositories>,Spring
		初始化容器时将会扫描 base-package 指定的包目录及其子目录,为继承 Repository 或其子接口的接口创建代理对象,并将
		代理对象注册为 Spring Bean,业务层便可以通过 Spring 自动封装的特性来直接使用该对象。
	3.声明持久层的接口,该接口继承 Repository, Repository 是一个标记型接口,它不包含任何方法,如必要,Spring Data 可实现
		Repository 其他子接口,其中定义了一些常用的增删改查,以及分页相关的方法。
	4.在接口中声明需要的方法。Spring Data 将根据给定的策略来为其生成实现代码。

三.Repository 接口

Repository 接口:
	1.Repository 是一个空接口,即是一个标记接口。
	2.若定义的接口继承了 Repository,则该接口会被 IOC 容器识别为一个 Repository Bean.
    	纳入到IOC容器中。进而可以在该接口中定义满足一定规范的方法。
    3.实际上,也可以通过注解的方式 @RepositoryDefinition 注解来替代继承 Repository 接口
    	domainClass=.class
        idClass=Integer.class
         @RepositoryDefinition(domainClass=Person.class,idClass=Integer.class)
            
1.Repository 接口是 Spring Data 的一个核心接口,它不提供任何方法,开发者需要在自己定义的接口中声明需要的方法
	public interface Repository<T,ID extends Serializable>{}
2.Spring Data 可以让我们之定义接口,只要遵循 Spring Data 的规范,就无需实现类。
3.与继承 Repository 等价的一种方式,就是在持久层接口上使用 @RepositoryDefinition 注解,并为其指定 domainClass 和 idClass 属性。
 
 
Repository 子接口
	基础的 Repository 提供了最基本的数据访问功能,其几个子接口则扩展了一些功能。他们的继承关系如下:
		Repository : 仅仅是一个标识,表明任何继承它的均为仓库接口类。
		CrudRepository : 继承 Repository,实现了一组 CRUD 相关的方法
		PagingAndSortingRepository : 继承 CrudRepository, 实现了一组分页排序相关的方法
		JpaRepository : 继承 PagingAndSortingRepository,实现了一组 JPA 规范相关的方法
		自定义的 XxxRepository 需要继承 JpaRepository,这样的 XxxRepository 接口就具备了
			通用的数据访问控制层的能力。
		JpaSpecificationExecutor : 不属于 Repository 体系,实现一组 JPA Criteria 查询相关的方法

四.Spring Data 查询方法定义规范

在 Repository 子接口中声明方法
	1.不是随便声明的。而需要符合一定的规范。
	
规范:
	简单条件查询
	1.简单条件查询:查询某一个实体类或集合
	2.按照 Spring Data 的规范,查询方法以 find | read | get 开头。
		涉及条件查询时,条件的属性用条件关键字链接,要注意的是:条件属性是以首字母大写。
		例如:定义一个 Entity 实体类
		class User {
			private String firstName;
			private String lastName;
		}
		使用 And 条件连接时,应这样写:
			findByLastNameAndFirstName(String lastName, String firstName);
			条件的属性名称与个数要与参数的位置与个数一一对应。
	3.支持级联查询。若当前类有符合条件的属性,则优先使用,而不是用级联属性。
		若需要使用级联属性,则属性之间使用 _ 进行连接。
			
例如:
	//WHERE lastName LIKE ?% AND id < ?
	List<Person> getByLastNameStartingWithAndIdLessThan(String lastName, Integer id);

五.SpringData 支持的关键字

直接在接口中定义查询方法,如果是符合规范的,可以不用写实现,目前支持的关键字写法如下:
keyword sample JPQL snippet
And findByLastnameAndFirstname …where x.lastname = ?1 and x.firstname = ?2
Or findByLastnameOrFirstname …where x.lastname = ?1 or x.firstname = ?2
Between findByStartDateBetween …where x.startDate between ?1 and ?2
LessThan findByAgeLessThan …where x.age < ?1
GreaterThan findByGreaterThan …where x.age > ?1
After findByStartDateAfter …where x.startDate > ?1
Before findByStartDateBefore …where x.startDate < ?1
IsNull findByAgeIsNull …where x.age is null
IsNotNull,NotNull findByAge(is)NotNull …where x.age is not null

六.@Query 注解

使用 @Query 注解可以自定义 JPQL 语句以实现更灵活的查询。
	例如:
	@Query("SELECT p FROM Person p WHERE p.id = (SELECT max(p2.id) FROM Person p2)")
    Person getMaxIdPerson();@Query 注解传递参数的方式1:使用占位符。
	例如:
	@Query("SELECT p FROM Person p WHERE p.lastName = ?1 and p.email = ?2")
    List<Person> testQueryAnnotationParams1(String lastName, String email);@Query 注解传递参数的方式2:命名参数的方式(与参数的顺序无太大关系)
	例如:
	@Query("SELECT p FROM Person p WHERE p.lastName = :lastName AND p.email = :email")
    List<Person> testQueryAnnotationParams2(@Param("email") String email, @Param("lastName") String lastName);

LIKE: SpringData 允许在占位符上添加 %%。
	方式一:
	@Query("SELECT p FROM Person p WHERE p.lastName LIKE ?1 OR p.email LIKE ?2")
	List<Person> testQueryAnnotationLikeParam(String lastName, String email);
	传入的参数:
	List<Person> persons = personRepository.testQueryAnnotationLikeParam("%A%","%bb%");
	
	方式二:
	或者
	@Query("SELECT p FROM Person p WHERE p.lastName LIKE %?1% OR p.email LIKE %?2%")
	List<Person> testQueryAnnotationLikeParam(String lastName, String email);
	传入的参数:
	List<Person> persons = personRepository.testQueryAnnotationLikeParam("A","bb");

	方式三:
	或者
	@Query("SELECT p FROM Person p WHERE p.lastName LIKE %:lastName% OR p.email LIKE %:email%")
	List<Person> testQueryAnnotationLikeParam(@Param("email") String email, @Param("lastName") String lastName);
	传入的参数:
	List<Person> persons = personRepository.testQueryAnnotationLikeParam("bb","A");

设置 nativeQuery=true 即可以使用原生的 SQL 查询。
	@Query(value="SELECT count(id) FROM jpa_persons", nativeQuery=true)
    long getTotalCount();

七.@Modifying 注解和事务

添加在 Service 层。在  application.xml 文件中配置自动扫描。

//可以通过自定义的 JPQL 完成 UPDATE 和 DELETE 操作。注意:JPQL 不支持使用 INSERT
//在 @Query 注解中编写 JPQL 语句。但必须使用 @Modifying 进行修饰。以通知SpringData,这是一个 UPDATE 或 DELETE 操作。
// UPDATE 或 DELETE 操作需要使用事务,此时需要定义Service 层。在Service层的方法上添加事务操作。
//默认情况下,SpringData 的每个方法上有事务,但都是一个只读事务。他们不能完成修改操作。
@Modifying
@Query("UPDATE Person p SET p.email = :email WHERE id = ")
    
事务:
1.Spring Data 提供了默认的事务处理方式,即所有的查询均声明为只读事务。
2.对于自定义的方法,如需改变 Spring Data 提供的事务默认方式,可以在方法上注解 @Transactional 声明。
3.进行多个 Repository 操作时,也应该使他们在同一个事务中处理,按照分层架构的思想,这部分属于业务逻辑层,因此,
	需要在 Service 层实现对多个 Repository 的调用,并在相应的方法上声明事务。

八.CrudRepository 接口


九.PagingAndSortingRepository 接口

public void testPagingAndSortingRepository() {
    int pageNo = 3;
    int pageSize = 5;
    PageRequest pageRequest = new PageRequest(pageNo, pageSize);
    Page<Person> page = personRespository.findAll(pageRequest);
    
    
    	排序相关.Sort 封装了排序的信息
        Order order1 = new Order(Direction.DESC, "id");
    	Order order2 = new Order(Direction.ASC,"email");
        Sort sort = new Sort(order1, order2);
        PageRequest pageable = new PageRequest(pageNo,pageSize,sort);
}

十.JpaRepository 接口


十一.JpaSpecificationExecutor 接口

JpaSpecificationExecutor :
	1.不属于 Repository 体系,实现一组 JPA Criteria 查询相关的方法
	2.Specification : 封装 JPA Criteria 查询条件。通常使用匿名内部类的方式来创建该接口的对象。

十二.自定义 Repository 方法

1.为某一个Repository 上添加自定义的方法
	步骤:
		1.定义一个接口:声明要添加的,并自实现的方法
		2.提供该接口的实现类:类名需在要声明的 Repository 后添加 Impl, 并实现方法。
		3.声明 Repository 接口,并继承 1> 声明的接口
		4.使用
		注意:默认情况下,Spring Data 会在 base-package 中查找"接口名 Impl" 作为实现类。
				也可以通过 repository-impl-postfix 声明后缀。
2.为所有的 Repository 都添加自实现的方法

你可能感兴趣的:(流行框架)