SpringDataJPA對數據庫的操作的幾種方式


1:SpringDataJPA是JPA規范的再次封裝抽象,底層還是使用了HibernateJPA技術實現,是屬於Spring的生成體系中的一部分

2:SpringData的結構(七個接口)

 

 

操作數據庫的方式一:繼承JpaRepository口后操作數據庫

 

  1:在Repository層新建一個基礎接口

 

 

 
1 @NoRepositoryBean //告訴JPA不要創建對應接口的bean對象
2 public interface BaseReposittory <T,ID extends Serializable> extends JpaRepository<T,ID>{
3 }

  2:再建一個你所要操作的類型的接口去繼承 這里以實體類Employee舉例  這里Long是數據庫中主鍵的類型   完成后就已經具備了基礎的CRUD 和分頁排序的功能

 1 public interface EmployeeRepository extends BaseReposittory<Employee,Long>{ 

  注意:在操作數據庫時 添加和修改所使用的都是save()方法 ;可以自行測試   這里測試一個分頁排序

1 @Test//分頁排序
2     public void pageAndSort() throws Exception{
3         Sort sort = new Sort(Sort.Direction.DESC,"age");
4          Pageable page = new PageRequest(0,10,sort);
5         Page<Employee> employees = employeeRepository.findAll(page);
6         employees.forEach(e->{
7             System.out.println(e);
8         });
9     }

  基礎查詢和分頁排序底層已經定義好可以直接使用 現在我們來自定義查詢; 查詢方法寫在EmployeeRepository

自定義查詢

方式一:按照規范創建查詢方法,一般按照java駝峰式書寫規范加一些特定關鍵字

  例:  

1  //根據名稱模糊查詢
2     List<Employee> findByUsernameLike(String username);
3     //根據名稱進行查詢
4     List<Employee> findByUsername(String username);

 

查詢規則如下:

表達式

例子

hql查詢語句

And

findByLastnameAndFirstname

… where x.lastname = ?1 and x.firstname = ?2

Or

findByLastnameOrFirstname

… where x.lastname = ?1 or x.firstname = ?2

Is,Equals

findByFirstname,findByFirstnameIs,findByFirstnameEqual

… where x.firstname = 1?

Between

findByStartDateBetween

… where x.startDate between 1? and ?2

LessThan(lt)

findByAgeLessThan

… where x.age < ?1

LessThanEqual(le)

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 age)

… 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)

 

 

方式二:@Query注解查詢

 

EmployeeRepository 按照查詢方法的命名規則,其實是比較麻煩的如果我們想不遵循 查詢方法的命名規則,還可以使用@Query的方法進行查詢。只需要將@Query定義在Respository的方法之上即可

 

 

  1:使用jpql語句操作數據庫

  例:

 

1    //根據用戶名查詢(這里寫必需在問號后加順序)
2     @Query("select e from Employee e where e.username = ?1")
3     Employee query01(String name);
4     //根據用戶名模糊查詢(這里寫必需在問號后加順序)
5     @Query("select e from Employee e where e.username like ?1")
6     List<Employee> query02(String name);
7     //根據用戶名與郵件進行模糊查詢(這里寫必需在問號后加順序)
8     @Query("select e from Employee e where e.username like ?1 and e.email like ?2")
9     List<Employee> query03(String name, String email);

 

  2:如果想用原生sql操作數據庫只需在注解@Query中加nativeQuery =true 

  例:

 

1   //查詢所有
2     @Query(nativeQuery =true,value = "select * from employee where username=?;")
3     Employee query04(String name);

 

 

 

 

 

 

 方式三:繼承接口JpaSpecificationExecutor

    JpaSpecificationExecutor的認識  

    JpaSpecificationExecutor(JPA規則執行者)JPA2.0提供的Criteria API的使用封裝,可以用於動態生成Query來滿足我們業務中的各種復雜場景。

 

    Spring Data JPA為我們提供了JpaSpecificationExecutor接口,只要簡單實現toPredicate方法就可以實現復雜的查詢。所有查詢都要求傳入一個Specification對象

  1:BaseReposittory的操作

@NoRepositoryBean //告訴JPA不要創建對應接口的bean對象
public interface BaseReposittory <T,ID extends Serializable> extends JpaRepository<T,ID>,JpaSpecificationExecutor<T> {
}

 

  2:測試:直接來個多條件查詢

  

 1 /**
 2      * 根據相應的規則(Specification) 查詢對應數據
 3      *  Predicate: where username=? and email =?
 4      *      root : 根 -> 可以獲取到類中的屬性(username,email)
 5      *      criteriaQuery: 如select,from,where,group by ,order by 等
 6      *      criteriaBuilder:解決 username=? / username like ? / age > ?
 7      *                      多個條件結合 username=?  and/or  age > ?
 8      */
 9     @Test//多條件查詢+分頁+排序
10     public void testJpaSpecificationExecutor() throws Exception{
11         //先定義規范
12         Specification spec= new Specification<Employee>() {
13             @Override
14             public Predicate toPredicate(Root<Employee> root, CriteriaQuery<?> cq, CriteriaBuilder cd) {
15                 Path usernamePath = root.get("username");
16                 Predicate p1 = cd.like(usernamePath, "%1%");
17                 Path emailPath = root.get("email");
18                 Predicate p2 = cd.like(emailPath, "%2%");
19                 Path agePath = root.get("age");
20                 Predicate p3 = cd.ge(agePath, 18);//le 表示小於 ge表示大於
21                 //多個條件連接起來
22                 Predicate p = cd.and(p1, p2, p3);
23                 return p;
24             }
25         };
26         //進行排序
27         Sort sort = new Sort(Sort.Direction.ASC,"username");
28         //進行分頁
29         Pageable page=new PageRequest(0,10,sort);
30         //查詢數據庫
31         Page p = employeeRepository.findAll(spec, page);
32         p.forEach(e->{
33             System.out.println(e);
34         });
35     }

Root:查詢哪個表(定位到表和字段-> 用於拿到表中的字段)
 *            可以查詢和操作的實體的根
 *              Root接口:代表Criteria查詢的根對象,Criteria查詢的查詢根定義了實體類型,能為將來導航獲得想要的結果,它與SQL查詢中的FROM子句類似
 *             Root<Employee> 相當於 from Employee
 *             Root<Product> 相當於  from Product
 *        CriteriaQuery:查詢哪些字段,排序是什么(主要是把多個查詢的條件連系起來)
 *        CriteriaBuilder:字段之間是什么關系,如何生成一個查詢條件,每一個查詢條件都是什么方式
 *                      主要判斷關系(和這個字段是相等,大於,小於like等)
 *        PredicateExpression):單獨每一條查詢條件的詳細描述 整個 where xxx=xx and yyy=yy ...

 

 

方式四:使用jpa-spec插件的前提是要實現JpaSpecificationExecutor接口(我這里是接口繼承了接口)

  1:在Maven項目中pom.xml引入包

 

<!--  jpa的SpecificationSpecification功能封裝 -->
<dependency>
  <groupId>com.github.wenhao</groupId>
  <artifactId>jpa-spec</artifactId>
  <version>3.1.1</version>
  <!-- 把所有依賴都過濾 -->
  <exclusions>
    <exclusion>
      <groupId>*</groupId>
      <artifactId>*</artifactId>
    </exclusion>
  </exclusions>
</dependency>

  2:功能測試:

 

 1 @Test// 多個條件查詢 +分頁+排序
 2     public void testSpec() throws Exception{
 3         Specification<Employee> spec = Specifications.<Employee>and()
 4                 .like("username","%1%")
 5                 .like("email","%2%")
 6                 .ge("age", 20)
 7                 .build();
 8         Sort sort = new Sort(Sort.Direction.DESC,"age");//根據年齡排序
 9         Pageable page = new PageRequest(0,10,sort);
10         Page<Employee> list = employeeRepository.findAll(spec, page);
11         list.forEach(e->{
12             System.out.println(e);
13         });
14     }

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM