Spring data JPA的簡單用法

1、導(dǎo)入jar包。

org.springframework.boot

spring-boot-starter-data-jpa

2、配置文件

#spring data jpa

spring.jpa.generate-ddl=true

spring.jpa.show-sql=true

spring.jpa.hibernate.ddl-auto=update

3、實體的定義


4、定義Repository接口,繼承Repository接口。

/**

* 1、Repository是一個空接口,即是一個標(biāo)記接口

* 2、若我們定義的接口繼承了Repository,則該接口會被IOC容器識別為一個Repository Bean,納入到IOC容器中,

* 進(jìn)而可以在該接口中定義滿足一些規(guī)范的方法。

*3、實際上,也可以通過@RepositoryDefinition()注解的方式來替代繼承Repository接口

*@RepositoryDefinition(domainClass= Person.class,idClass = Integer.class)

*/

public interfacePersonRepositoryextendsRepository {

Person findByLastName(String lastName);

}

說明:Repository接口中,泛型是對應(yīng)的實體,類型是對應(yīng)實體的主鍵。

5、Repository的子接口。

CrudRepository接口:繼承Repository接口,實現(xiàn)了增刪改查方法。

JpaRepository接口:繼承PagingAndStoringRepository,實現(xiàn)了一組JPA規(guī)范的相關(guān)方法。

PagingAndStoringRepository接口:繼承CrudRepository接口,實現(xiàn)了分頁排序相關(guān)的方法。

SimpleJpaRepository接口:

JpaSpecificationExcutor接口:不屬于Repository體系,實現(xiàn)一組Criteria查詢相關(guān)方法。

6、Repository接口中聲明方法的規(guī)范

1、查詢方法以 find | read | get 開頭;

2、涉及條件查詢時,條件的屬性用條件關(guān)鍵字連接,要注意的是:條件屬性以首字母大寫

例如:定義一個 Entity 實體類?class User{

private String firstName;

private String lastName;?}

使用And條件連接時,應(yīng)這樣寫:?findByLastNameAndFirstName(String lastName,String firstName);?條件的屬性名稱與個數(shù)要與參數(shù)的位置與個數(shù)一一對應(yīng)

3、直接在接口中定義查詢方法,如果是符合規(guī)范的,可以不用寫實現(xiàn),目前支持的關(guān)鍵字寫法如下:


4、支持級聯(lián)查詢

若當(dāng)前類有符合條件的屬性,則優(yōu)先使用,而不使用級聯(lián)屬性。若要使用級聯(lián)屬性,則屬性之間使用下劃線進(jìn)行分割。


使用關(guān)鍵字進(jìn)行查詢例子:

//where lastName like ?%

List findByLastNameStartingWith(String lastName);

//where lastName like ?% and id< ?

List getByLastNameStartingWithAndIdLessThan(String lastName,Integer id);

//where lastName in (?,?) or birth

List findByEmailIOrBirthLessThan(List email, Date birth);

//where a.id>?

List findByAddress_IdGreaterThan(Integer id);

5、@Query注解(查詢)

//查詢Id最大的那個Person(注意:from后面跟著的實體名Person)

//使用@Query注解可以自定義JPQL,語句實現(xiàn)更靈活的查詢

@Query("select p from Person p where p.id=(select max(p2.id) from Person p2)")

Person findMaxIdPerson();;

//為Query注解傳遞參數(shù)方式1:使用占位符(參數(shù)有順序)

@Query("select p from Person p where p.lastName=?1 and p.email=?2")

List testQueryAnnotationParams(String lastName,String email);

//為Query注解傳遞參數(shù)方式2:命名參數(shù)的方式(參數(shù)無順序)

@Query("select p from Person p where p.lastName=:lastName and p.email=:email")

List testQueryAnnotationParams2(@Param("email") String email,@Param("lastName") String lastName);

//Like參數(shù)的傳遞(在占位符上使用%)

@Query("select p from Person p where p.lastName like %?1% or p.email like %?2%")

List testQueryAnnotationLikeParam(String lastName,String email);

//Like參數(shù)的傳遞(在占位符上使用%)

@Query("select p from Person p where p.lastName like %?% or p.email like %?%")

List testQueryAnnotationLikeParam2(@Param("lastName") String lastName,@Param("email ") String email);

//使用原生的SQL注解

@Query(value ="select count(id) from person",nativeQuery =true)

intgetPersonCount();

6、Modifying注解

//可以通過自定義的JPQL完成update和delete操作,注意:JPQL不支持插入語句(insert)

//在Query注解中,編寫JPQL語句,但必須使用@Modiying進(jìn)行修飾,以通知spring data,這是一個update或者是delete

//update或者是delete操作需要使用事物,此時需要定義Service層,在Service層上添加事物操作

//默認(rèn)情況下,springdata的每個方法上都是有事物的,但都是一個只讀事物,他們不能完成修改操作

@Modifying

@Query("update Person p set p.email=?1 where id=?2")

intupdatePersonLastName(String email,Integer id);

Service層的事物:

@Service

public classPersonServiceImplimplementsPersonService {

@Autowired

privatePersonRepositorypersonRepository;

@Override

@Transactional

public intupdateLastName(String email, Integer id) {

intcount=personRepository.updatePersonLastName("dd",1);

returncount;

}

}

7、CrudRepository子接口

public interfacePersonRepositoryextendsCrudRepository

Service接口:

public interfacePersonService {

intupdateLastName(String email,Integer id);

voidsavePersons(List list);

}

Service接口實現(xiàn):

@Service

public classPersonServiceImplimplementsPersonService {

@Autowired

privatePersonRepositorypersonRepository;

@Override

@Transactional

public intupdateLastName(String email, Integer id) {

intcount=personRepository.updatePersonLastName("dd",1);

returncount;

}

@Transactional

@Override

public voidsavePersons(List list) {

personRepository.save(list);

}

}

批量添加測試:

@Test

public voidtestSave() {

List persons =newArrayList<>();

for(inti ='a'; i >='z'; i++) {

Person person =newPerson();

person.setBirth(newDate());

person.setLastName("彩虹"+(char)i);

person.setEmail((char)i+"836908728@qq.com"+(char)i);

person.setId(i +10);

persons.add(person);

}

personService.savePersons(persons);

}

8、PageAndSortingRepository子接口

(是一個只讀操作,不需要事物)

//pageNo的記錄是從1開始

intpageNo =6-1;

intpageSize =5;

//Pageable接口通常使用的其PageRequest實現(xiàn)類,其中封裝了分頁的相關(guān)信息(page,size,sort)

//排序相關(guān),Sort封裝了排序的信息

//Order是針對于某一個屬性進(jìn)行升序還是降序

Order order1=newSort.Order(Direction.DESC,"id");

Order order2=newSort.Order(Direction.ASC,"email");

//sort可以包含多個

Sort sort=newSort(order1,order2);

PageRequest pageable =newPageRequest(pageNo, pageSize,sort);

Page page =personRepository.findAll(pageable);

System.out.println("總記錄數(shù):"+ page.getTotalElements());

System.out.println("當(dāng)前第幾頁:"+ (page.getNumber()+1));

System.out.println("總頁數(shù):"+ page.getTotalPages());

System.out.println("當(dāng)前頁面的list:"+ page.getContent());

System.out.println("當(dāng)前頁面的記錄數(shù):"+ page.getNumberOfElements());

9、JpaRepository接口:是PagingAndSortingRepository的子接口

public interfacePersonRepositoryextendsJpaRepository

@Test

public voidtestJpaRepository() {

Person person =newPerson();

person.setBirth(newDate());

person.setLastName("云南");

person.setEmail("836908728@qq.com");

person.setId(27);

Person person1 =personRepository.saveAndFlush(person);

System.out.println(person == person1);

}

9、JpaSpecificationExecutor接口,不屬于Repository體系

(實現(xiàn)帶查詢條件的分頁)

public interfacePersonRepositoryextendsJpaRepository,JpaSpecificationExecutor

@Test

/**

* 實現(xiàn)帶查詢條件的分頁:

* 使用JpaSpecificationExecutor的PagefindAll(Specificationspec,Pageable pageable)

* Specification:封裝了JPA Criteria查詢的查詢條件

* Pageable:封裝了請求分頁的信息,例如:pageNo,pageSize,Sort

*/

public voidtestJpaSpecificationExecutor(){

intpageNo=3-1;

intpageSize=5;

PageRequest pageRequest=newPageRequest(pageNo,pageSize);

Specification specification=newSpecification() {

/**

*

*@paramroot:代表查詢的實體類

*@paramcriteriaQuery:可以從中得到root對象,即告知JPA Criteria查詢要查詢哪一個實體類,還可以添加查詢條件

*? ? ? ? ? ? ? ? ? ? 還可以結(jié)合EntityManager對象得到最終查詢的TypeQuery對象

*@paramcriteriaBuilder:CriteriaBuilder 用于創(chuàng)建Criteria相關(guān)對象的工廠,當(dāng)然可以從中獲取到Predicate對象

*@returnPredicate類型,代表一個查詢條件

*/

@Override

//如:實現(xiàn)id>5

publicPredicate toPredicate(Root root, CriteriaQuery criteriaQuery, CriteriaBuilder criteriaBuilder) {

Path path=root.get("id");

Predicate predicate=criteriaBuilder.gt(path,5);

returnpredicate;

}

};

Page page=personRepository.findAll(specification,pageRequest);

System.out.println("總記錄數(shù):"+ page.getTotalElements());

System.out.println("當(dāng)前第幾頁:"+ (page.getNumber() +1));

System.out.println("總頁數(shù):"+ page.getTotalPages());

System.out.println("當(dāng)前頁面的list:"+ page.getContent());

System.out.println("當(dāng)前頁面的記錄數(shù):"+ page.getNumberOfElements());

}

10、自定義Repository接口

?步驟:

–定義一個接口: 聲明要添加的, 并自實現(xiàn)的方法

–提供該接口的實現(xiàn)類: 類名需在要聲明的 Repository 后添加 Impl, 并實現(xiàn)方法

–聲明 Repository 接口, 并繼承 1) 聲明的接口

–使用.

–注意: 默認(rèn)情況下, Spring Data 會在 base-package 中查找 "接口名Impl" 作為實現(xiàn)類. 也可以通過 repository-impl-postfix 聲明后綴.

如:定義一個接口:


2、實現(xiàn)接口


3、繼承自定義接口

public interfacePersonRepositoryextendsJpaRepository,JpaSpecificationExecutor,TestRepository

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容