天天看點

JPA快速開發之查詢接口Repository

作者:蘋果蘋果開花吧

什麼是JPA

SpringData是Spring提供的一個資料操作架構,而SpringData JPA則是該架構下基于JPA标準進行資料操作的子產品。

SpringData JPA簡化了持久層代碼的操作,隻需編寫接口即可實作。

JPA,全稱Java Persistence API,是Spring Data的子項目之一。它是JDK 5.0的注解或XML描述對象與關系表映射關系的工具,可以将運作時的實體對象持久化到資料庫中。

JPA和Mybatis都是持久層架構,具有相同的功能。然而,由于Mybatis的廣泛使用,現在了解和使用JPA的人較少。

JPQL 是從 Hibernate 的 HQL 演變而來的,其文法與 HQL 非常相似。HQL,即 Hibernate Query Language(Hibernate查詢語言),而 SQL 是 Structure Query Language(結構化查詢語言)。

它們的主要差別在于:SQL 直接操作資料庫中的表和字段,而 HQL 則操作實體對象和屬性。

需要注意的是,我們編寫的 JPQL 最終仍會被轉換成 SQL 語句進行執行。

接口繼承關系

JPA快速開發之查詢接口Repository

Repository<T, ID>接口 最頂層接口 作用自定義JPQL語句

java複制代碼/**
 * 使用@Query注解,自定義JPQL語句
 * JPQL語句中,使用的不是表名,而是實體類名,不是列名,而是屬性名,
 * 例如SQL語句:select * from user  JPQL語句是:select User from User
 * 如果是條件查詢,之前語句中的占位符?可以使用(:xxx)進行表示
 * 此時xxx會根據方法中同名的形參自動綁定值
 */
public interface UsersRepositoryByQuery extends Repository<User, Integer> {
    //如果是查詢所有列,可以省略select ....,從from開始寫
    @Query("from User where name=:name")
    List<User> selectByName(String name); //select * from user where name=?

    @Query("select u from User u where name=:name and age=:age")
    List<User> selectByNameAndAge(String name, Integer age); //select * from user where name=? and age=?

    @Query("from User where name=:name and age=:age")
    List<User> selectByNameLike(String name);//select * from user  where name like ?

    //除了使用JPQL語句,也是可以使用sql原生語句,在注解中設定參數nativeQuery = true,不推薦!
    @Query(value = "select * from user where name=:name",nativeQuery = true)
    List<User> selectByNameSQl(String name);//select * from user where name=?
}
           

CrudRepository接口 繼承了Repository接口,内置類增删改查的方法

PagingAndSortingRepository接口繼承了CrudRepository接口 增加了分頁和排序方法

java複制代碼 @Autowired
    private UserRepositoryPage userRepositoryPage;
    /**
     * 分頁
     */
    @Test
    void testPage(){
        //第一個參數是頁碼數,0表示第一頁;第二參數是分頁機關;
        Pageable Pageable = PageRequest.of(0, 2);
        Page<User> page = userRepositoryPage.findAll(Pageable);
        System.out.println("總資料量"+page.getTotalElements());
        System.out.println("總頁數"+page.getTotalPages());
        List<User> content = page.getContent();
        for (User user : content) {
            System.out.println(user);
        }
    }
    /**
     * 排序
     */
    @Test
    void testSort(){
        //根據id排序
        Sort sort = Sort.by(Sort.Order.desc("id"));
        Iterable<User> all = userRepositoryPage.findAll(sort);
        for (User user : all) {
            System.out.println(user);
        }
    }
           

JpaRepository<T, ID> 接口

繼承了 PagingAndSortingRepository<T, ID>

和查詢接口 QueryByExampleExecutor

特點是可以幫助我們将其他接口的方法的傳回值做适配處理。可以使得我們在開發時更友善的使用這些方法

JpaSpecificationExecutor 接口 主要提供了多條件查詢的支援,并且可以在查詢中添加分頁與排序

JpaSpecificationExecutor接口與以上接口沒有關系,完全獨立。 不能單獨使用,需要配合着JPA 中的其他接口一起使用。
java複制代碼//接口  
public interface UserRepositoryExJPA extends JpaRepository<User,Integer>,JpaSpecificationExecutor<User> {
}

  
//使用  
@Autowired
    private UserRepositoryExJPA userRepositoryExJPA;

    /**
     * 自定義規則,可以多條件查詢
     */
    @Test
    void testExJPA2() {
        Specification<User> specification = new Specification<User>() {
            @Override
            public Predicate toPredicate(Root<User> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                //模糊查詢
                Predicate predicate = criteriaBuilder.like(root.get("name"), "張%");
                //模糊查詢+性别篩選+年齡篩選
                Predicate predicate2 = criteriaBuilder.and(criteriaBuilder.like(root.get("name"), "張%"),
                        criteriaBuilder.equal(root.get("sex"), "男"), criteriaBuilder.gt(root.get("age"), 24));
                return predicate2;
            }
        };
        //進行排序年齡進行倒序排列
        Sort sort = Sort.by(Sort.Order.desc("age"));
        //分頁+追加排序
        Pageable pageable = PageRequest.of(0, 2, sort);
        Page<User> page = userRepositoryExJPA.findAll(specification, pageable);
        System.out.println("根據條件查詢到" + page.getTotalElements() + "條資料");
        System.out.println("根據條件查詢到" + page.getTotalPages() + "頁資料");
        System.out.println("當頁資料");
        for (User user : page) {
            System.out.println(user);
        }
    }  
           

JpaRepositoryImplementation<T, ID> 接口

繼承了 JpaRepository<T, ID>, JpaSpecificationExecutor 接口

實作類為SimpleJpaRepository<T, ID> 接口 功能最強大

關鍵命名查詢

根據 Spring Data 的規範,查詢方法應以 find、read 或 get 開頭(例如 find、findBy、read、readBy、get、getBy)。當涉及到查詢條件時,應使用條件關鍵字連接配接屬性,并確定條件屬性的首字母大寫。在解析方法名時,架構會先去除多餘的字首,然後對剩餘部分進行解析。

你可以直接在接口中定義查詢方法,隻要符合規範,就無需編寫實作或 SQL。目前支援的關鍵字寫法如下:

JPA快速開發之查詢接口Repository
JPA快速開發之查詢接口Repository

繼續閱讀