Spring Data JPA 之 JpaRepository的使用
- SpringBoot版本:2.3.2.RELEASE
- SpringBoot Data JPA版本:2.3.2.RELEASE
JpaRepository是SpringBoot Data JPA提供的非常強(qiáng)大的基礎(chǔ)接口。
1 JpaRepository
1.1 JpaRepository接口定義
JpaRepository接口的官方定義如下:
@NoRepositoryBean public interface JpaRepository<T, ID> extends PagingAndSortingRepository<T, ID>, QueryByExampleExecutor<T>
可以看出JpaRepository繼承了接口PagingAndSortingRepository和QueryByExampleExecutor。而PagingAndSortingRepository又繼承CrudRepository。因此,JpaRepository接口同時(shí)擁有了基本CRUD功能以及分頁功能。
當(dāng)我們需要定義自己的Repository接口的時(shí)候,我們可以直接繼承JpaRepository,從而獲得SpringBoot Data JPA為我們內(nèi)置的多種基本數(shù)據(jù)操作方法,例如:
public interface UserRepository extends JpaRepository<User, Integer> { }
1.2 內(nèi)置方法
1.2.1 CrudRepository<T, ID>提供的方法
/** * 保存一個(gè)實(shí)體。 */ <S extends T> S save(S entity); /** * 保存提供的所有實(shí)體。 */ <S extends T> Iterable<S> saveAll(Iterable<S> entities); /** * 根據(jù)id查詢對應(yīng)的實(shí)體。 */ Optional<T> findById(ID id); /** * 根據(jù)id查詢對應(yīng)的實(shí)體是否存在。 */ boolean existsById(ID id); /** * 查詢所有的實(shí)體。 */ Iterable<T> findAll(); /** * 根據(jù)給定的id集合查詢所有對應(yīng)的實(shí)體,返回實(shí)體集合。 */ Iterable<T> findAllById(Iterable<ID> ids); /** * 統(tǒng)計(jì)現(xiàn)存實(shí)體的個(gè)數(shù)。 */ long count(); /** * 根據(jù)id刪除對應(yīng)的實(shí)體。 */ void deleteById(ID id); /** * 刪除給定的實(shí)體。 */ void delete(T entity); /** * 刪除給定的實(shí)體集合。 */ void deleteAll(Iterable<? extends T> entities); /** * 刪除所有的實(shí)體。 */ void deleteAll();
1.2.2 PagingAndSortingRepository<T, ID>提供的方法
/** * 返回所有的實(shí)體,根據(jù)Sort參數(shù)提供的規(guī)則排序。 */ Iterable<T> findAll(Sort sort); /** * 返回一頁實(shí)體,根據(jù)Pageable參數(shù)提供的規(guī)則進(jìn)行過濾。 */ Page<T> findAll(Pageable pageable);
1.2.3 JpaRepository<T, ID>提供的方法
/** * 將所有未決的更改刷新到數(shù)據(jù)庫。 */ void flush(); /** * 保存一個(gè)實(shí)體并立即將更改刷新到數(shù)據(jù)庫。 */ <S extends T> S saveAndFlush(S entity); /** * 在一個(gè)批次中刪除給定的實(shí)體集合,這意味著將產(chǎn)生一條單獨(dú)的Query。 */ void deleteInBatch(Iterable<T> entities); /** * 在一個(gè)批次中刪除所有的實(shí)體。 */ void deleteAllInBatch(); /** * 根據(jù)給定的id標(biāo)識符,返回對應(yīng)實(shí)體的引用。 */ T getOne(ID id);
JpaRepository<T, ID>還繼承了一個(gè)QueryByExampleExecutor<T>,提供按“實(shí)例”查詢的功能。
2 方法測試
下面對以上提供的所有內(nèi)置方法進(jìn)行測試,給出各方法的用法。
首先定義實(shí)體類Customer:
package com.tao.springboot.hibernate.entity; import lombok.Data; import lombok.NoArgsConstructor; import lombok.NonNull; import lombok.RequiredArgsConstructor; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; @Entity @Table(name = "tb_customer") @Data @NoArgsConstructor @RequiredArgsConstructor public class Customer { @Id @GeneratedValue(strategy = GenerationType.AUTO) @Column(nullable = false) private Long id; @Column(nullable = false) private String name; @Column(nullable = false) private Integer age; }
然后定義接口CustomerRepository:
package com.tao.springboot.hibernate.repository; import com.tao.springboot.hibernate.entity.Customer; import org.springframework.data.jpa.repository.JpaRepository; public interface CustomerRepository extends JpaRepository<Customer, Long> { }
接下來對各個(gè)方法進(jìn)行測試~
2.1 save
/** * 保存一個(gè)實(shí)體。 */ <S extends T> S save(S entity);
測試代碼:
@GetMapping("/customer/save") public Customer crudRepository_save() { // 保存一個(gè)用戶michael Customer michael = new Customer("Michael", 26); Customer res = customerRepository.save(michael); return res; }
測試結(jié)果:
2.2 saveAll
/** * 保存提供的所有實(shí)體。 */ <S extends T> Iterable<S> saveAll(Iterable<S> entities);
測試代碼:
@GetMapping("/customer/saveAll") public List<Customer> crudRepository_saveAll() { // 保存指定集合的實(shí)體 List<Customer> customerList = new ArrayList<>(); customerList.add(new Customer("Tom", 21)); customerList.add(new Customer("Jack", 21)); List<Customer> res = customerRepository.saveAll(customerList); return res; }
測試結(jié)果:
2.3 findById
/** * 根據(jù)id查詢對應(yīng)的實(shí)體。 */ Optional<T> findById(ID id);
測試代碼:
@GetMapping("/customer/findById") public Customer crudRepository_findById() { // 根據(jù)id查詢對應(yīng)實(shí)體 Optional<Customer> customer = customerRepository.findById(1L); if(customer.isPresent()) { return customer.get(); } return null; }
測試結(jié)果:
2.4 existsById
/** * 根據(jù)id查詢對應(yīng)的實(shí)體是否存在。 */ boolean existsById(ID id);
測試代碼:
@GetMapping("/customer/existsById") public boolean crudRepository_existsById() { // 根據(jù)id查詢對應(yīng)的實(shí)體是否存在 return customerRepository.existsById(1L); }
測試結(jié)果:
2.5 findAll
/** * 查詢所有的實(shí)體。 */ Iterable<T> findAll();
測試代碼:
@GetMapping("/customer/findAll") public List<Customer> crudRepository_findAll() { // 查詢所有的實(shí)體 List<Customer> customerList = customerRepository.findAll(); return customerList; }
測試結(jié)果:
2.6 findAllById
/** * 根據(jù)給定的id集合查詢所有對應(yīng)的實(shí)體,返回實(shí)體集合。 */ Iterable<T> findAllById(Iterable<ID> ids);
測試代碼:
@GetMapping("/customer/findAllById") public List<Customer> crudRepository_findAllById() { // 根據(jù)給定的id集合查詢所有對應(yīng)的實(shí)體,返回實(shí)體集合 List<Long> ids = new ArrayList<>(); ids.add(2L); ids.add(1L); List<Customer> customerList = customerRepository.findAllById(ids); return customerList; }
測試結(jié)果:
2.7 count
/** * 統(tǒng)計(jì)現(xiàn)存實(shí)體的個(gè)數(shù)。 */ long count();
測試代碼:
@GetMapping("/customer/count") public Long crudRepository_count() { // 統(tǒng)計(jì)現(xiàn)存實(shí)體的個(gè)數(shù) return customerRepository.count(); }
測試結(jié)果:
2.8 deleteById
/** * 根據(jù)id刪除對應(yīng)的實(shí)體。 */ void deleteById(ID id);
測試代碼:
@GetMapping("/customer/deleteById") public void crudRepository_deleteById() { // 根據(jù)id刪除對應(yīng)的實(shí)體 customerRepository.deleteById(1L); }
測試結(jié)果:
刪除前~~
刪除后~~
2.9 delete(T entity)
/** * 刪除給定的實(shí)體。 */ void delete(T entity);
測試代碼:
@GetMapping("/customer/delete") public void crudRepository_delete() { // 刪除給定的實(shí)體 Customer customer = new Customer(2L, "Tom", 21); customerRepository.delete(customer); }
測試結(jié)果:
刪除前~~
刪除后~~
2.10 deleteAll(Iterable<? extends T> entities)
/** * 刪除給定的實(shí)體集合。 */ void deleteAll(Iterable<? extends T> entities);
測試代碼:
@GetMapping("/customer/deleteAll(entities)") public void crudRepository_deleteAll_entities() { // 刪除給定的實(shí)體集合 Customer tom = new Customer(2L,"Tom", 21); Customer jack = new Customer(3L,"Jack", 21); List<Customer> entities = new ArrayList<>(); entities.add(tom); entities.add(jack); customerRepository.deleteAll(entities); }
測試結(jié)果:
刪除前~~
刪除后~~
2.11 deleteAll
/** * 刪除所有的實(shí)體。 */ void deleteAll();
測試代碼:
@GetMapping("/customer/deleteAll") public void crudRepository_deleteAll() { // 刪除所有的實(shí)體 customerRepository.deleteAll(); }
測試結(jié)果:
刪除前~~
刪除后~~
2.12 findAll(Sort sort)
/** * 返回所有的實(shí)體,根據(jù)Sort參數(shù)提供的規(guī)則排序。 */ Iterable<T> findAll(Sort sort);
測試代碼:
@GetMapping("/customer/findAll(sort)") public List<Customer> pagingAndSortingRepository_findAll_sort() { // 返回所有的實(shí)體,根據(jù)Sort參數(shù)提供的規(guī)則排序 // 按age值降序排序 Sort sort = new Sort(Sort.Direction.DESC, "age"); List<Customer> res = customerRepository.findAll(sort); return res; }
測試結(jié)果:
格式化之后發(fā)現(xiàn),確實(shí)是按照age的值降序輸出的?。?!
2.13 findAll(Pageable pageable)
/** * 返回一頁實(shí)體,根據(jù)Pageable參數(shù)提供的規(guī)則進(jìn)行過濾。 */ Page<T> findAll(Pageable pageable);
測試代碼:
@GetMapping("/customer/findAll(pageable)") public void pagingAndSortingRepository_findAll_pageable() { // 分頁查詢 // PageRequest.of 的第一個(gè)參數(shù)表示第幾頁(注意:第一頁從序號0開始),第二個(gè)參數(shù)表示每頁的大小 Pageable pageable = PageRequest.of(1, 5); //查第二頁 Page<Customer> page = customerRepository.findAll(pageable); System.out.println("查詢總頁數(shù):" + page.getTotalPages()); System.out.println("查詢總記錄數(shù):" + page.getTotalElements()); System.out.println("查詢當(dāng)前第幾頁:" + (page.getNumber() + 1)); System.out.println("查詢當(dāng)前頁面的集合:" + page.getContent()); System.out.println("查詢當(dāng)前頁面的記錄數(shù):" + page.getNumberOfElements()); }
測試結(jié)果:
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java HttpURLConnection超時(shí)和IO異常處理
這篇文章主要介紹了Java HttpURLConnection超時(shí)和IO異常處理的相關(guān)資料,需要的朋友可以參考下2016-09-09Springboot配置suffix指定mvc視圖的后綴方法
這篇文章主要介紹了Springboot配置suffix指定mvc視圖的后綴方法,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-07-07java微信企業(yè)號開發(fā)之發(fā)送消息(文本、圖片、語音)
這篇文章主要為大家詳細(xì)介紹了java微信企業(yè)號開發(fā)之發(fā)送消息,發(fā)送類型包括文本、圖片、語音,感興趣的小伙伴們可以參考一下2016-06-06淺談PrintStream和PrintWriter的區(qū)別和聯(lián)系
這篇文章主要介紹了淺談PrintStream和PrintWriter的區(qū)別和聯(lián)系,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-03-03