1. 程式人生 > >spring-data-jpa簡單使用(二)

spring-data-jpa簡單使用(二)

1:使用spring-data-jpa很簡單,只需要在dao層繼承repository介面即可。那麼repository介面是什麼呢?

 可以看到repository介面下面什麼都沒有,這表明它是一個標記介面。標記介面的作用的什麼?標記介面的作用是把當前類納入到spring的容器中,繼承了這個類你會發現

這個標記我想使用idea的同志們都不會陌生的,因為這個表明,當前的類已經被納入到spring容器中,可以被spring掃描到。那麼,除了繼承Repository這個介面,還可以怎麼做 -> 在介面上加上@RepositoryDefinition註解

RepositoryDefinition註解中有兩個屬性(domainClass,idClass)一個標識實體類的位元組碼型別和主鍵的位元組碼型別

但是我們一般不用這個註解,這裡我們瞭解一下知道他是怎麼搞的就行:無非就是用了spring的aop和反射來實現的。

 

下面我們來看看spring-data-jpa有哪些介面

那麼查詢方法的規則和使用又是怎麼樣的呢?

在介面下面定義的方法必須遵循這些規則

上程式碼:

     1:查詢出名字以胡開頭,並且年齡小於25

    @Test
    public void test1(){
        // 查詢出名字以胡開頭,並且年齡小於25
        List<User> users = userRepository.findByNameLikeAndAgeLessThan("胡%",25);
        users.forEach(p -> System.out.println(p.getName() + " ,年齡" + p.getAge()));
    }

    2:使用原生的sql進行查詢

    @Query(value = "select * from user u where u.name like ?1% and age > ?2",nativeQuery = true)
    List<User> findUser(String name,int age);

      需要使用@Query註解和nativeQuery屬性

   3: 不使用原生的sql進行查詢

    @Query(value = "select u from User u where u.salary > ?1")
    List<User> findSalary(double salary);

     from後面就不能寫表名了,只能寫表對應的對映名稱   ?1代表佔位符,當前你也可以使用:如下

    @Query(value = "select u from User u where u.id = :id")
    User findUser(@Param("id")long id);

   這有一個誤區:就是冒號後面對應的值應該和@Param裡面的值一致,否則或報錯

    @Query(value = "select u from User u where u.id = :idd")
    User findUser(@Param("idd")long id);

這是正確的,註解裡面的值和冒號後面的值對應。下面是錯誤的:

    @Query(value = "select u from User u where u.id = :idd")
    User findUser(@Param("id")long idd);

4:修改查詢

    @Modifying
    @Query(nativeQuery = true,value = "update user u set u.address = ?2 where u.id = ?1")
    void update(Long id,String address);

     需要@Modifying註解和@Query註解和@Transactional註解(放在service層) 缺一不可.

5:關聯查詢什麼之類的就不用我多嘴了吧 直接@Query註解加上nativeQuery屬性搞起來,原生sql別說你不會哈!!!

 

分頁排序:

     這裡需要兩個物件:Sort和PageRequest

程式碼如下:

    public List<User> getUsers(){
        // 安裝薪資降序
        Sort sort = new Sort(Sort.Direction.DESC,"salary");

        // 每頁大小十頁
        PageRequest pageRequest = PageRequest.of(0,10,sort);
        List<User> users = userRepsoitory.findAll(pageRequest).getContent();

        return users;
    }

 具體方法點進去看api需要什麼引數

 

那麼?更復雜點的動態sql分頁排序查詢,spring-data-jpa能解決嗎?我們知道mybatis可以在xml檔案中使用if,for之類的標籤來判斷,構造動態sql;那spring-data-jpa怎麼構建:

這個時候就需要一個強大的物件出馬:

   Specification 和JpaSpecificationExecutor<T>

程式碼如下:

   public List<User> conditionalQuery(User user){
        Specification<User> specification = new Specification<User>() {
            @Override
            public Predicate toPredicate(Root<User> root, CriteriaQuery<?> cq, CriteriaBuilder cb) {
                // root:可用從root中拿到User的屬性
                // cq:用來查詢
                // cb:用來構造查詢條件
                List<Predicate> predicates = new ArrayList<>();
                if (!StringUtils.isBlank(user.getName())) {
                    predicates.add(cb.like(root.get("name"),user.getName() + "%"));
                }

                if (user.getAge() > 0) {
                    predicates.add(cb.gt(root.get("age"),user.getAge()));
                }

                if (user.getSalary() > 0) {
                    predicates.add(cb.gt(root.get("salary"),user.getSalary()));
                }

                Predicate result = cb.and(predicates.toArray(new Predicate[predicates.size()]));

                return result;
            }
        };
        // 這個排序分頁還記得怎麼操作嗎?
        PageRequest pageRequest = PageRequest.of(0,10,Sort.Direction.DESC,"salary");

        List<User> users = userRepsoitory.findAll(specification, pageRequest).getContent();
        return users;
    }
}

dao層需要繼承JpaSpecificationExecutor<User>,然後用JpaSpecificationExecutor<User>的findAll方法;

結果如下:

     按薪水降序:

[
    {
        "id": 5,
        "name": "胡歌",
        "age": 30,
        "salary": 2100000,
        "address": "上海"
    },
    {
        "id": 17,
        "name": "胡歌",
        "age": 27,
        "salary": 2100000,
        "address": "上海"
    },
    {
        "id": 18,
        "name": "胡歌",
        "age": 30,
        "salary": 2100000,
        "address": "上海"
    },
    {
        "id": 21,
        "name": "胡歌",
        "age": 27,
        "salary": 2100000,
        "address": "上海"
    },
    {
        "id": 19,
        "name": "胡歌",
        "age": 26,
        "salary": 21000,
        "address": "上海"
    },
    {
        "id": 20,
        "name": "胡歌",
        "age": 19,
        "salary": 18000,
        "address": "上海"
    }
]

 

總結:

   1:簡單的查詢可以直接呼叫JpaRepository的方法和其命名規範查詢

   2:關聯查詢可以使用@Query註解加nativeQuery屬性

   3:動態sql分頁排序查詢可以使用Specification和JpaSpecificationExecutor介面