阅读 19

02.【Spring Data专题】 - Repository接口

Repository接口概述

Repository 接口是 Spring Data 的一个核心接口,它不提供任何方法(空接口),开发者需要在自己定义的接口中声明需要的方法

public interface Repository<T, ID extends Serializable> { } 
复制代码

那么,没有提供方法,怎么就完成了数据库方面的操作呢?

回答:若我们定义的接口继承了 Repository, 则该接口会被 IOC 容器识别为一个 Repository Bean (BooDao接口),纳入到 IOC 容器中,从而可以在该接口中定义遵循 Spring Data的规范的方法(约定优于配置),就无需写实现类。


第二种方案:可以通过 @RepositoryDefinition 注解来替代继承 Repository 接口

//第一個屬性domainClass的值是實體類對象類,第二個屬性的對象的主鍵類型
@RepositoryDefinition(domainClass = Book.class,idClass = Integer.class)
public interface BookDao /*extends Repository<Book,Integer>*/ {
    Book getByBookName(String bookName);
}
复制代码

1.Repository的子接口

基础的 Repository 提供了最基本的数据访问功能,其几个子接口则扩展了一些功能。它们的继承关系如下:

  • Repository: 仅仅是一个标识,表明任何继承它的均为仓库接口类

  • CrudRepository: 继承 Repository,实现了一组 CRUD 相关的方法

    public interface CrudRepository<T, ID extends Serializable> extends Repository<T, ID> {
      <S extends T> S save(S entity);           //保存这个实体
      Optional<T> findById(ID primaryKey);      //使用给定的ID返回实体 
      Iterable<T> findAll();                    //返回所有实体 
      long count();                             //返回实体的个数 
      void delete(T entity);                    //删除给定的实体 
      boolean existsById(ID primaryKey);        //检查指定ID的实体是否存在
      // … more functionality omitted.
    }
    复制代码

    我们还提供基于持久技术特性的一些抽象,比如JpaRepository,或者 MongoRepository.这些接口继承了CrudRepository的一些功能,并暴露一些基于持久层的不太通用的额外功能.

  • PagingAndSortingRepository: 继承 CrudRepository,实现了一组分页排序相关的方法

    public interface PagingAndSortingRepository<T, ID extends Serializable> extends CrudRepository<T, ID> {
      Iterable<T> findAll(Sort sort);
      Page<T> findAll(Pageable pageable);
    }
    复制代码
  • JpaRepository: 继承 PagingAndSortingRepository,实现一组 JPA 规范相关的方法

  • 自定义的 XxxxRepository 需要继承 JpaRepository,这样的 XxxxRepository 接口就具备了通用的数据访问控制层的能力。

  • JpaSpecificationExecutor不属于Repository体系,实现一组 JPA Criteria 查询相关的方法

2.Repository定义方法

个人不是很喜欢这种方式,因为方法名称有时过长,还有不是很灵活

定义方法的规则如下

  • 不是随便声明的. 而需要符合一定的规范

  • 查询方法以 find | read | get 开头

  • 涉及条件查询时,条件的属性用条件关键字连接
  • 要注意的是:条件属性以首字母大写。
  • 支持属性的级联查询. 若当前类有符合条件的属性, 则优先使用, 而不使用级联属性.
  • 若需要使用级联属性, 则属性之间使用_进行连接.

具体案例代码

(1)准备的测试表格数据

Snap1.jpg

(2)Repository定义的简单方法

public interface BookDao extends Repository<Book,Integer> {
    Book getByBookName(String bookName);

    //条件语句:WHERE book_name LIKE ?% AND book_id<?
    List<Book> getByBookNameStartingWithAndBookIdLessThan(String bookName,Integer bookId);

    //条件语句:WHERE book_name LIKE %? AND book_id<?
    List<Book> findByBookNameEndingWithAndBookIdLessThan(String bookName,Integer bookId);

    //条件语句:WHERE book_name LIKE %?% AND book_id<?
    List<Book> findByBookNameContainingAndBookIdLessThan(String bookName,Integer bookId);

    //条件语句:WHERE price IN (?,?,?) OR author=?
    List<Book> getByPriceInOrAuthor(List<Double> priceList,String author);
}
复制代码

规则附录表格

Keyword Sample JPQL snippet
And findByLastnameAndFirstname … where x.lastname = ?1 and x.firstname = ?2
Or findByLastnameOrFirstname … where x.lastname = ?1 or x.firstname = ?2
Is,Equals findByFirstname,
findByFirstnameIs,findByFirstnameEquals
… where x.firstname = ?1
Between findByStartDateBetween … where x.startDate between ?1 and ?2
LessThan findByAgeLessThan … where x.age < ?1
LessThanEqual findByAgeLessThanEqual … where x.age <= ?1
GreaterThan findByAgeGreaterThan … where x.age > ?1
GreaterThanEqual findByAgeGreaterThanEqual … 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 not null
Like findByFirstnameLike … where x.firstname like ?1
NotLike findByFirstnameNotLike … where x.firstname not like ?1
StartingWith findByFirstnameStartingWith … where x.firstname like ?1 (parameter bound with appended %)
EndingWith findByFirstnameEndingWith … where x.firstname like ?1 (parameter bound with prepended %)
Containing findByFirstnameContaining … where x.firstname like ?1 (parameter bound wrapped in %)
OrderBy findByAgeOrderByLastnameDesc … where x.age = ?1 order by x.lastname desc
Not findByLastnameNot … where x.lastname <> ?1
In findByAgeIn(Collection ages) … where x.age in ?1
NotIn findByAgeNotIn(Collection ages) … where x.age not in ?1
True findByActiveTrue() … where x.active = true
False findByActiveFalse() … where x.active = false
IgnoreCase findByFirstnameIgnoreCase … where UPPER(x.firstame) = UPPER(?1)
关注下面的标签,发现更多相似文章
评论