学习Spring-Data-Jpa(六)---05、spring-data-commons中的repository

时间:2019-11-10
本文章向大家介绍学习Spring-Data-Jpa(六)---05、spring-data-commons中的repository,主要包括学习Spring-Data-Jpa(六)---05、spring-data-commons中的repository使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

1、spring-data-commons项目

  spring-data-commons项目是所有spring-data项目的核心,我们来看一下该项目下的repository包中的接口和注解。

    

 2、Repository接口和@RepositoryDefinition注解

  当中最重要的就是Repository接口了。它是做数据库操作的最底层的抽象接口、最顶级的父类,打开Repository接口看其源码,发现里面其实什么方法都没有,仅仅起到一个标识作用。捕获要管理的域类型和域类的id类型。用途是保存类型信息,并能够在类路径扫描期间发现继承该接口的接口,帮助我们创建代理类。

@Indexed
public interface Repository<T, ID> {

}

  @Indexed 我们发现在Repository接口上有一个@Indexed 注解,是Spring5提供的注解,用于提升应用启动性能。这个注解单独存在不起作用,要想使其生效的话,要添加spring-context-indexer依赖。在编译时会将@CompoentScan扫描指定package中要生成的bean写在METE-INF/spring.components文件中,当项目启动时,就会读取这个文件,不会再扫描指定的package了,从而提升性能。

  我们只要继承Repository接口,并根据它的规则来命名接口方法,就可以进行数据库操作。(与继承Repository接口相等价的就是,在接口上添加@RepositoryDefinition注解)

示例:

/**
* 书籍持久层
* @author caofanqi
* 使用@RepositoryDefinition注解与继承Repository具有相同的效果
*/
//@RepositoryDefinition(domainClass = Book.class,idClass = Long.class)
public interface BookRepository extends Repository<Book,Long>{

/**
* 根据书名查找书籍
* @param bookName 书籍名称
* @return 该书籍名称的书列表
*/
List<Book> findBooksByBookNameContains(String bookName);

}
@Transactional
@Rollback(false) @SpringBootTest
class BookRepositoryTest { @Resource private BookRepository bookRepository; @Test void findBooksByBookNameContains() { System.out.println("bookRepository : " + bookRepository.getClass().getName()); List<Book> books = bookRepository.findBooksByBookNameContains("Java"); System.out.println(books); } }

  这样就会根据我们传入的参数去like查询符合条件的书籍,生成的sql语句如下:

     

3、CrudRepository接口与注解@NoRepositoryBean

  CrudRepository是Repository接口的子接口,提供了一套通用的CRUD方法。接口上的@NoRepositoryBean注解的意思是,不让Spring生成该类的代理类。

@NoRepositoryBean //不让Spring为该类生成代理类,仅仅提供一套通用的CRUD方法。
public interface CrudRepository<T, ID> extends Repository<T, ID> {

    /**
   * 保存方法*/
    <S extends T> S save(S entity);

    /**
   * 保存*/
    <S extends T> Iterable<S> saveAll(Iterable<S> entities);

    /**
     * 根据id进行查询*/
    Optional<T> findById(ID id);

    /**
     * 判断给定id的数据是否存在*/
    boolean existsById(ID id);

    /**
     * 查询全部,数据量很大的时候,谨慎使用*/
    Iterable<T> findAll();

    /**
     * 根据给定ids查询符合条件的数据
     */
    Iterable<T> findAllById(Iterable<ID> ids);

    /**
     * 统计条数*/
    long count();

    /**
     * 根据id删除*/
    void deleteById(ID id);

    /**
     * 删除给定实体*/
    void delete(T entity);

    /**
     * 删除给定实体*/
    void deleteAll(Iterable<? extends T> entities);

    /**
     * 删除全部
     */
    void deleteAll();
}

  我们要想使用这些方法,只需自己的Repository继承该接口即可。

4、PagingAndSortingRepository接口

  是CrudRepository的子接口,也不会生成代理,只是提供分页和排序的方法。

@NoRepositoryBean
public interface PagingAndSortingRepository<T, ID> extends CrudRepository<T, ID> {

    /**
     * 根据sort去所有对象排序的集合*/
    Iterable<T> findAll(Sort sort);

    /**
     * 根据pageable进行分页,pageable中可以包含sort*/
    Page<T> findAll(Pageable pageable);
}

  分页相关对象:

  Sort查询的排序选项,至少提供一个属性列表来进行排序,不能是null或空,默认是升序ASC;
  可以通过Sort.by 来构建Sort对象:
    public static Sort by(String... properties) 根据给定的属性列表进行升序排序;
    public static Sort by(Direction direction, String... properties) 指定属性和排序方向,Direction.ASC(升序)、Direction.DESC(降序);
    public static Sort by(Order... orders)/public static Sort by(List<Order> orders) 根据给定的一组order进行排序。

  Order,实现一个排序对,提供方向和属性,为sort提供输入。也就是说,可以针对每一个属性设置不同的升序或降序。
  可以通过一下方式来构建Order对象:
    public static Order by(String property) ,指定属性返回order对象,默认使用升序。
    public static Order asc(String property),返回指定属性升序的order对象。
    public static Order desc(String property),返回指定属性降序的order对象。

  Pageable分页信息的抽象接口,实现类是PageRequest;
  可以通过一下方式来构建Pageable对象:
    public static PageRequest of(int page, int size),创建一个未排序的PageRequest,page从0开始;
    public static PageRequest of(int page, int size, Direction direction, String... properties),创建一个根据给定方向和属性排序的分页对象。
    public static PageRequest of(int page, int size, Sort sort),创建一个根据sort进行排序的分页对象。

  Page,封装分页结果信息,可以通过如下方法获取分页信息。
    page.getContent() ,分页查询结果列表;
    page.getNumberOfElements(),当前分页结果列表中的元素个数;
    page.getTotalElements(),当前条件下总条数;
    page.getTotalPages(),总页数;
    page.getNumber(),我们自己传的page;
    page.getSize(),我们自己传入的size。

 代码示例:

    @Test
    void testPagingAndSortingRepository(){

        Sort.Order id = Sort.Order.by("id");
        Sort.Order bookName = Sort.Order.desc("bookName");
        Sort sort = Sort.by(id,bookName);

        Pageable pageable = PageRequest.of(2,2, sort);

        Page<Book> page = bookRepository.findAll(pageable);

        System.out.println("分页查询结果列表:" + page.getContent());
        System.out.println("当前分页结果列表中的元素个数:" + page.getNumberOfElements());
        System.out.println("当前条件下总条数:" + page.getTotalElements());
        System.out.println("总页数:" +page.getTotalPages());
        System.out.println("我们自己传的page:" +page.getNumber());
        System.out.println("我们自己传入的size:" +page.getSize());

        
    }
源码地址:https://github.com/caofanqi/study-spring-data-jpa

 



 

原文地址:https://www.cnblogs.com/caofanqi/p/11831362.html