`
H.Z
  • 浏览: 16746 次
  • 来自: 长沙
社区版块
存档分类
最新评论

spring之spring data jpa(入门二)

 
阅读更多

Repository:

public interface Repository<T, ID extends Serializable> {
 
}

 这个接口只是一个空的接口,目的是为了统一所有Repository的类型,其接口类型使用了泛型,泛型参数中T代表实体类型,ID则是实体中id的类型。

 

 

CrudRepository:

持久层接口定义的比较多,且每个接口都需要声明相似的CURD的方法,直接继承Repository就比较繁琐.这时就可以继承CrudRepository,它会自动为域对象创建CRUD的方法,供业务层直接调用.

 

public interface CrudRepository<T, ID extends Serializable> extends Repository<T, ID> {
 
    <S extends T> S save(S entity);
 
    <S extends T> Iterable<S> save(Iterable<S> entities);
 
    T findOne(ID id);
 
    boolean exists(ID id);
 
    Iterable<T> findAll();
 
    Iterable<T> findAll(Iterable<ID> ids);
 
    long count();
 
    void delete(ID id);
 
    void delete(T entity);
 
    void delete(Iterable<? extends T> entities);
 
    void deleteAll();
}

 该接口中的方法大多是访问数据库中常用的方法,如果需要,直接继承这个接口即可.但是CrudRepository也有副作用,它可能暴露不希望暴露给业务层的方法.这种情况下,只能退回继承Repository接口,在接口中显示声明需要暴露给业务层的方法.

 

 

PagingAndSortingRepository:

分页查询和排序是持久层常用的功能,Spring Data 为此提供了 PagingAndSortingRepository 接口,它继承自 CrudRepository 接口,在 CrudRepository 基础上新增了两个与分页有关的方法。

 

public interface PagingAndSortingRepository<T, ID extends Serializable> extends CrudRepository<T, ID> {
 
    Iterable<T> findAll(Sort sort);
 
    Page<T> findAll(Pageable pageable);
}

 但是,我们很少会将自定义的持久层接口直接继承自 PagingAndSortingRepository,而是在继承 Repository 或 CrudRepository 的基础上,在自己声明的方法参数列表最后增加一个 Pageable 或 Sort 类型的参数,用于指定分页或排序信息即可,这比直接使用 PagingAndSortingRepository 提供了更大的灵活性.

 

这些Repository都是spring-data-commons提供给我们的核心接口,spring-data-commons是Spring Data的核心包。这个接口中为我们提供了数据的分页方法,以及排序方法.

 

针对spring-data-jpa又提供了一系列repository接口,其中有JpaRepository和JpaSpecificationExecutor.

 

JpaRepository :

 

public interface JpaRepository<T, ID extends Serializable> extends PagingAndSortingRepository<T, ID> {
 
    List<T> findAll();
 
    List<T> findAll(Sort sort);
 
    <S extends T> List<S> save(Iterable<S> entities);
    void flush();
 
    T saveAndFlush(T entity);
 
    void deleteInBatch(Iterable<T> entities);
 
    void deleteAllInBatch();
}

 这个类继承自PagingAndSortingRepository,看其中的方法,可以看出里面的方法都是一些简单的操作,并未涉及到复杂的逻辑。当你在处理一些简单的数据逻辑时,便可继承此接口.

 

其实在业务中往往会涉及到多张表的查询,以及查询时需要的各种条件,此时就需要复杂业务查询了.spring data jpa提供了JpaSpecificationExecutor.

 

JpaSpecificationExecutor:

public interface JpaSpecificationExecutor<T> {
 
    T findOne(Specification<T> spec);
 
    List<T> findAll(Specification<T> spec);
 
    Page<T> findAll(Specification<T> spec, Pageable pageable);
 
    List<T> findAll(Specification<T> spec, Sort sort);
 
    long count(Specification<T> spec);
}

 在这个接口里面出现次数最多的类就是Specification.class,而这个类主要也就是围绕Specification来打造 的,Specification.class是Spring Data JPA提供的一个查询规范,只需围绕这个规范来设置查询条件便可.

 

Specification接口:

 

public interface Specification<T> {
	/**
	 * </pre>
	 * JPA规范中的
	 * @param root  ROOT查询中的条件表达式
	 * @param query 条件查询设计器
	 * @param cb	条件查询构造器
	 * @return
	 * </pre>
	 */
	Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder cb);
}

 在使用复杂对象查询时,实现该方法用JPA去构造对象查询便可.

 

Spring Data JPA 在后台为持久层接口创建代理对象时,会解析方法名字,并实现相应的功能。除了通过方法名字以外,它还可以通过如下两种方式指定查询语句:

 

  1. Spring Data JPA 可以访问 JPA 命名查询语句。只需要在定义命名查询语句时,为其指定一个符合给定格式的名字,Spring Data JPA 便会在创建代理对象时,使用该命名查询语句来实现其功能.
  2. 还可以直接在声明的方法上面使用 @Query 注解,并提供一个查询语句作为参数,Spring Data JPA 在创建代理对象时,便以提供的查询语句来实现其功能.

 三种创建查询的方式

1.通过解析方法名创建查询

框架在进行方法名解析时,会先把方法名多余的前缀截取掉,比如 find、findBy、read、readBy、get、getBy,然后对剩下部分进行解析。并且如果方法的最后一个参数是 Sort 或者 Pageable 类型,也会提取相关的信息,以便按规则进行排序或者分页查询。

 

直接在接口中定义查询方法,如果是符合规范的,可以不用写实现,目前支持的关键字写法如下:

 

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.startData between 1? and 2?
LessThan findByAgeLessThan where  x.age < ?1
GreaterThan findByAgeGreaterThan where   x.age >?1
After findByStartDateAfter where   x.startDate > ?1
Before findByStartDateBefor where   x.startDate < ?1
IsNull findByAgeIsNull where   x.age is  null
IsNotNull,NotNull findByAge(Is)NotNull where   x.age is not null
Like findByFirstnameLike where   x.firstname like ?1
NotLike findByFirstnameNotLike where   x.firstname not like ?1
StartingWith findByFirstnameStartingWith where   x.firstname like ?1(如%?)
EndingWith findByFirstnameEndingWith where   x.firstname like ?1(如?%)
Containing findByFirstnameContaining where   x.fistaname like ?1(如%?%)
OrderBy findByFirstnameOrderByAgeDesc where   x.firstname  =?1 Order by x.age desc
Not findByLastnameNot where   x.lastname <>?1
In findByAgeIn(collegetion<Age> ages where   x.age in ?1
NotIn findByAgeNotIn(collegetion<Age> ages where   x.age  not  in  ?1
True findByActiveTrue where   x.active = true
false findbyActiveFalse where   x.active =false

先去除findBy,剩下UserDepUuid.假设查询实体为Doc.假如创建如下的查询:findByUserDepUuid().

1.POJO规范,首字母小写.userDepUuid是不是Doc的一个属性,是,则根据该属性查询.如果不是,第二步.

2.从右往左截取第一个大写字母(Uuid),剩下userDep.检查userDep是否为Doc的属性,是,则根据该属性查询,如果不是,重复第二步,最后假设user为Doc的一个属性.

3.接着处理剩下(UepUuid),先判断user对应的类型是否有depUuid属性,有,则根据Doc.user.depUuid的取值进行查询. 没有,继续进行第二步,截取掉了Uuid,剩下dep,假设user对于类型有dep属性,最终Doc.user.dep.uuid的值进行查询.

4.可能会有一种特殊情况.比如Doc包含一个user属性,也有一个userDep属性,此时会存在混淆.可以明确在属性之间加上"_"以显示表示.如:findByUser_DepUuid()  或者  findByUserDep_uuid()

 

特殊的参数:还可以直接在方法的参数上加入分页或排序的参数: 比如:

Page<UserModel> findByName(String name,Pageable pageable);
List<UserModeel>  findByName(String name,Sort sort);

 

 

也可以使用JPA的NameQueries,方法如下:

              1:在实体类上使用@NamedQuery,示例如下:
@NamedQuery(name = "UserModel.findByAge",query = "select o from UserModel o where o.age >= ?1")
2:在自己实现的DAO的Repository接口里面定义一个同名的方法,示例如下:
public List<UserModel> findByAge(int age);

 

3:然后就可以使用了,Spring会先找是否有同名的NamedQuery,如果有,那么就不会按照接口定义的方法来解析。

2.使用@Query

     @Query 注解的使用非常简单,只需在声明的方法上面标注该注解,同时提供一个 JP QL 查询语句即可,如下所示: 

 @Query("select o from UserModel o where o.uuid=?1")
public List<UserModel> findByUuidOrAge(int uuid); 

 注意:

               1:方法的参数个数必须和@Query里面需要的参数个数一致

 

2:如果是like,后面的参数需要前面或者后面加“%”,比如下面都对:
 @Query("select o from UserModel o where o.name like ?1%")
public List<UserModel> findByUuidOrAge(String name);
 
@Query("select o from UserModel o where o.name like %?1")
public List<UserModel> findByUuidOrAge(String name);
 
@Query("select o from UserModel o where o.name like %?1%")
public List<UserModel> findByUuidOrAge(String name);
 
//当然,这样在传递参数值的时候就可以不加‘%’了,当然加了也不会错 
 还可以使用@Query来指定本地查询,只要设置nativeQuery为true,比如:
 @Query(value="select * from tbl_user where name like %?1" ,nativeQuery=true)
public List<UserModel> findByUuidOrAge(String name);
//注意:当前版本的本地查询不支持翻页和动态的排序 
使用命名化参数,使用@Param即可,比如:
 @Query(value="select o from UserModel o where o.name like %:nn")
public List<UserModel> findByUuidOrAge(@Param("nn") String name);
//同样支持更新类的Query语句,添加@Modifying即可,比如:
@Modifying
@Query(value="update UserModel o set o.name=:newName where o.name like %:nn")
public int findByUuidOrAge(@Param("nn") String name,@Param("newName") String newName);
/*
注意:
1:方法的返回值应该是int,表示更新语句所影响的行数
2:在调用的地方必须加事务,没有事务不能正常执行 .
*/

 3.JpaRepository的查询功能(创建查询的顺序)

               Spring Data JPA 在为接口创建代理对象时,如果发现同时存在多种上述情况可用,它该优先采用哪种策略呢?
<jpa:repositories> 提供了 query-lookup-strategy 属性,用以指定查找的顺序。它有如下三个取值:
  1. create-if-not-found:如果方法通过@Query指定了查询语句,则使用该语句实现查询;如果没有,则查找是否定义了符合条件的命名查 询,如果找到,则使用该命名查询;如果两者都没有找到,则通过解析方法名字来创建查询。这是 query-lookup-strategy 属性的默认值
  2. create:通过解析方法名字来创建查询。即使有符合的命名查询,或者方法通过 @Query指定的查询语句,都将会被忽略
  3. use-declared-query:如果方法通过@Query指定了查询语句,则使用该语句实现查询;如果没有,则查找是否定义了符合条件的命名查询,如果找到,则使用该命名查询;如果两者都没有找到,则抛出异常                                                     

        

  • 大小: 37.6 KB
  • 大小: 65.8 KB
分享到:
评论

相关推荐

    Spring Data JPA从入门到精通

    'SpringDataJPA从入门到精通'以SpringBoot为技术基础 从入门到精通 由浅入深地介绍SpringDataJPA的使用。有语法 有实践 有原理剖析。'SpringDataJPA从入门到精通'分为12章 内容包括整体认识JPA、JPA基础查询方法、...

    spring注解+spring data jpa文档+JPA文档.rar

    Spring框架的核心特性包括依赖注入(DI)和面向切面编程(AOP),并且它还提供了对数据库操作的支持,这主要通过Spring Data JPA和Java Persistence API(JPA)实现。 Spring注解是Spring框架中的一大特色,它极大...

    Spring Data JPA API(Spring Data JPA 开发文档).CHM

    Spring Data JPA API。 Spring Data JPA 开发文档。 官网 Spring Data JPA API。

    Spring Data JPA 笔记

    Spring Data JPA则是在JPA之上构建的一层抽象,它扩展了JPA的功能,提供了更多的便利。例如,Spring Data JPA支持自动化的查询生成,只需定义Repository接口,无需编写任何实现代码,就可以执行CRUD(创建、读取、...

    spring data jpa入门实例

    【Spring Data JPA 入门实例】 Spring Data JPA 是 Spring 框架的一个模块,它简化了数据库访问层(DAO)的开发,通过提供自动化的 Repository 实现,使得开发者无需编写大量的 CRUD(创建、读取、更新、删除)代码...

    Spring Data JPA入门项目02

    在本项目"Spring Data JPA入门项目02"中,我们将深入探讨如何使用Spring Data JPA进行查询操作,包括排序和分页。Spring Data JPA是Spring Framework的一个模块,它为Java Persistence API (JPA) 提供了一种更加便捷...

    Spring Data JPA中文文档[1.4.3]_springdatajpa_erlang_waitxpf_

    1. **Repository Abstraction**:这是 Spring Data JPA 的核心特性之一。它提供了一种声明式的数据访问接口,允许开发者定义自定义的查询方法,而不需要手动编写 SQL 或者 HQL(Hibernate Query Language)。例如,...

    spring data jpa 入门例子

    本入门例子将帮助你理解并掌握Spring Data JPA的核心概念和常用功能。 1. **什么是Spring Data JPA** Spring Data JPA是Spring框架的一部分,它为JPA提供了一种声明式的方法来处理数据访问层。通过使用Spring Data...

    Spring Boot整合SpringDataJPA

    Spring Data JPA是Spring生态系统中的一个重要组件,它为开发者提供了与JPA(Java Persistence API)交互的简化接口,极大地提高了数据访问的效率。本教程将深入探讨如何在Spring Boot项目中整合Spring Data JPA,...

    spring Data Jpa入门

    Spring Framework对JPA的支持本身就很强大,我们不用理会EntityManager的创建,事务处理等等.Spring又进步了,只需要声明一下方法接口,Spring Data JPA可以帮你完成数据访问层的实现代码,开发者把更多的心思放在业务...

    Spring Data JPA.zip

    **Spring Data JPA 深度解析** Spring Data JPA 是 Spring Framework 的一个重要模块,它为 Java Persistence API (JPA) 提供了便捷的数据访问层。这个框架简化了数据库操作,使得开发人员能够以声明式的方式处理...

    Spring Data JPA入门项目01

    在这个"Spring Data JPA入门项目01"中,我们将探讨如何利用Spring Data JPA来实现基本的CRUD(创建、读取、更新和删除)功能。 首先,我们需要在项目中引入Spring Data JPA的相关依赖。这通常在Maven或Gradle的配置...

    Spring-data-jpa常用教程.pdf

    #### 二、Spring-data-jpa 与 Spring 整合 Spring-data-jpa 与 Spring 的整合非常紧密,它利用 Spring 的依赖注入和事务管理功能,使得开发者可以轻松地在应用程序中集成数据访问逻辑。下面将详细介绍整合的关键...

    spring学习:spring data jpa

    Spring Data JPA是Spring框架的一个模块,主要目的是简化Java企业级应用中数据访问层的开发。这个框架构建在JPA(Java Persistence API)之上,提供了一种声明式的方式来操作数据库,使得开发者无需编写大量的SQL...

    Spring Data JPA的优点和难点.pdf

    Spring Data JPA是Spring生态中的一个强大ORM框架,它极大地提高了Java开发者在处理数据库操作时的效率。Spring Data JPA的主要优点在于其高度的开发效率、成熟的语法结构以及与Spring框架的紧密集成。 1. **开发...

    Spring+Spring MVC+SpringData JPA整合完成增删改查,翻页实例.zip

    在这个"Spring+Spring MVC+SpringData JPA整合完成增删改查,翻页实例"中,我们将深入探讨这三个组件如何协同工作,实现高效的数据管理与用户交互。 首先,Spring MVC是Spring框架的一个模块,专门用于构建Web应用...

    SpringMVC+Spring+Spring Data JPA+Maven

    技术架构:SpringMVC3+Spring3.1.2+Spring Data JPA+Maven 声明:该应用仅仅是技术研究:Spring Data JPA的配置和常见api的使用&maven构建项目,其他技术不在此研究 内涵sql和各种Spring Data JPA测试和案例,导入&...

    spring data jpa 教程

    本教程将详细介绍 Spring Data JPA 的核心概念与使用方法,帮助开发者从基础入门到实现复杂查询的完整过程。 第一章:Spring Data JPA 入门 Spring Data JPA 简化了 JPA(Java Persistence API)的开发,通过约定...

Global site tag (gtag.js) - Google Analytics