日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

分享Spring Data JPA的一些技巧和優秀實踐

來源: 責編: 時間:2023-10-08 07:05:01 287觀看
導讀在現代軟件開發中,Spring Boot已成為構建穩健和可擴展應用程序的主要框架。當涉及到與數據庫的交互時,Java持久化API(JPA)提供了一種方便高效的方式來管理關系型數據。為了確保Spring Boot應用程序的可維護性、可讀性和可

在現代軟件開發中,Spring Boot已成為構建穩健和可擴展應用程序的主要框架。當涉及到與數據庫的交互時,Java持久化API(JPA)提供了一種方便高效的方式來管理關系型數據。為了確保Spring Boot應用程序的可維護性、可讀性和可擴展性,在創建使用JPA進行數據訪問的Repository接口時,遵循最佳實踐至關重要。Ykc28資訊網——每日最新資訊28at.com

Ykc28資訊網——每日最新資訊28at.com

命名規范

遵循Spring Data的Repository接口命名慣例。命名慣例應為EntityNameRepository或
EntityNameRepositoryCustom(用于自定義Repository方法)。
Ykc28資訊網——每日最新資訊28at.com

public interface UserRepository extends JpaRepository<User, Long> {    // 此處可以自定義方法}

領域特定的Repository接口

在軟件工程中,關注點分離是一個核心原則,強調每個組件應具有明確定義的責任。在Spring Boot應用程序的上下文中,使用領域特定的存儲庫接口與該原則一致,允許在不同實體類型及其相應數據訪問操作之間保持清晰的區分。Ykc28資訊網——每日最新資訊28at.com

好處Ykc28資訊網——每日最新資訊28at.com

  1. 模塊化和清晰性:每個存儲庫接口專注于一個實體類型。這種模塊化確保存儲庫方法簡潔且與其處理的實體類型相關,使代碼庫更具可讀性和可理解性。
  2. 封裝性:領域特定的存儲庫接口封裝了與特定實體相關的數據訪問操作。這種隔離減少了意外誤用或在錯誤的實體上執行不適當查詢的可能性。
  3. 類型安全性:通過為每個實體使用接口,可以獲得強類型的好處。這有助于在編譯期間捕獲錯誤,而不是在運行時。
  4. 維護性:當需要對特定實體的數據訪問方法進行更改或增強時,你知道要去找哪個相應的Repository接口。這種有針對性的方法簡化了維護和調試過程。

考慮一個示例,有一個電子商務應用程序,其中有兩個主要實體:產品和分類。通過使用領域特定的Repository接口,我們可以將每個實體的數據訪問邏輯保持分離并組織良好。Ykc28資訊網——每日最新資訊28at.com

public interface ProductRepository extends JpaRepository<Product, Long> {    List<Product> findByCategory(Category category);}

在此示例中,該ProductRepository接口包括一個查詢方法findByCategory,該方法根據產品的關聯類別來檢索產品。Ykc28資訊網——每日最新資訊28at.com

類似地,該CategoryRepository接口可以只關注與類別相關的數據訪問操作。Ykc28資訊網——每日最新資訊28at.com

public interface CategoryRepository extends JpaRepository<Category, Long> {    Category findByName(String name);}

通過利用領域特定的Repository接口,我們可以創建一個更有組織且易于理解的數據訪問層,該層與應用程序的實體結構保持一致。這種關注點分離不僅提高了代碼質量,而且隨著應用程序隨著時間的推移而發展,也有利于維護和擴展。Ykc28資訊網——每日最新資訊28at.com

查詢方法

Spring Data JPA 提供了一種遵循命名約定來定義Repository方法的便捷方法,稱為“查詢方法”。這種方法通過方法名稱表達查詢,從而無需為常見操作編寫顯式 SQL 或 JPQL 查詢。利用查詢方法可以增強代碼庫的可讀性和可維護性。Ykc28資訊網——每日最新資訊28at.com

查詢方法的命名約定基于實體的屬性名稱。通過將findBy、getBy、readBy或 queryBy等前綴與屬性名稱組合,可以創建有意義的查詢方法。Ykc28資訊網——每日最新資訊28at.com

@Entitypublic class Book {    @Id    @GeneratedValue(strategy = GenerationType.IDENTITY)    private Long id;        private String title;    private String author;    private int publicationYear;    private String genre;    // Getters and setters}public interface BookRepository extends JpaRepository<Book, Long> {    List<Book> findByAuthorAndPublicationYearAndGenre(String author, int publicationYear, String genre);}

也可以通過向查詢方法添加可選參數來進一步擴展。比如需要按作者和流派搜索書籍,而不指定出版年份:Ykc28資訊網——每日最新資訊28at.com

public interface BookRepository extends JpaRepository<Book, Long> {    List<Book> findByAuthorAndGenreAndPublicationYear(String author, String genre, int publicationYear);        List<Book> findByAuthorAndGenre(String author, String genre);}

Spring Data JPA 根據方法名稱和參數名稱自動生成相應的 SQL 查詢,使復雜的查詢場景變得更加容易,而無需編寫原生 SQL 查詢。Ykc28資訊網——每日最新資訊28at.com

自定義查詢方法

雖然查詢方法提供了一種強大的機制,可以根據命名約定從方法名稱生成查詢,但在某些情況下需要更復雜的查詢。對于這些場景,Spring Data JPA 可以使用@Query注解定義自己的自定義查詢方法。Ykc28資訊網——每日最新資訊28at.com

@Query注解能夠直接在Repository接口中定義 JPQL(Java 持久性查詢語言)或原生 SQL 查詢。這種方法可以更加靈活地構建涉及多個實體、復雜聯接或其他非標準操作的查詢。Ykc28資訊網——每日最新資訊28at.com

public interface UserRepository extends JpaRepository<User, Long> {    @Query("SELECT u FROM User u WHERE CONCAT(u.firstName, ' ', u.lastName) LIKE %:keyword%")    List<User> findUsersByFullNameKeyword(@Param("keyword") String keyword);}

在使用 JPQL 還無法實現的特定于數據庫的功能時,還可以使用原生 SQL 查詢。以下是自定義原生 SQL 查詢方法的示例:Ykc28資訊網——每日最新資訊28at.com

public interface ProductRepository extends JpaRepository<Product, Long> {    @Query(value = "SELECT * FROM products p WHERE p.price > :minPrice", nativeQuery = true)    List<Product> findProductsAboveMinPrice(@Param("minPrice") BigDecimal minPrice);}

在此示例中,@Query 注解使用 nativeQuery = true來表示查詢是用原生 SQL 編寫的。該查詢的意圖是檢索價格高于指定最低價格的產品。Ykc28資訊網——每日最新資訊28at.com

自定義查詢方法有幾個好處:Ykc28資訊網——每日最新資訊28at.com

  • 靈活性:可以創建更適合特定要求的查詢。
  • 復雜操作:自定義查詢適合復雜的連接操作或需要使用特定于數據庫的函數。
  • 性能:在某些情況下,原生 SQL 查詢可能會為特定場景提供更好的性能。

使用原生 SQL 查詢時必須謹慎,因為如果處理不當,可能會導致特定于數據庫的代碼和潛在的安全漏洞(例如 SQL 注入)。Ykc28資訊網——每日最新資訊28at.com

通過使用自定義查詢方法,我們可以在查詢方法命名約定的便利性和處理更復雜或專門的數據檢索場景的靈活性之間取得平衡。Ykc28資訊網——每日最新資訊28at.com

自定義Repository接口

在Repository層中分離關注點是一個好習慣,這意味著需要將標準 Spring Data JPA 方法與自定義方法分開。這種分離增強了代碼組織、可讀性和可維護性,并促進了單一職責原則。Ykc28資訊網——每日最新資訊28at.com

首先創建一個自定義Repository接口來保存專用方法。該接口不應直接擴展JpaRepository,因為這會導致自定義方法與標準方法混雜在一起。Ykc28資訊網——每日最新資訊28at.com

public interface UserRepositoryCustom {    List<User> findActiveUsers();}

接下來,為自定義Repository接口創建一個實現類。實現類遵循命名規范<EntityName>RepositoryImpl,并且應該放置在與Repository接口相同的包中。Ykc28資訊網——每日最新資訊28at.com

@Repositorypublic class UserRepositoryImpl implements UserRepositoryCustom {    @PersistenceContext    private EntityManager entityManager;    @Override    public List<User> findActiveUsers() {        TypedQuery<User> query = entityManager.createQuery("SELECT u FROM User u WHERE u.active = true", User.class);        return query.getResultList();    }}

最后,通過擴展標準 Spring Data JPA Repository接口 ( JpaRepository) 和自定義Repository接口 ( UserRepositoryCustom) 來創建主Repository接口。Ykc28資訊網——每日最新資訊28at.com

public interface UserRepository extends JpaRepository<User, Long>, UserRepositoryCustom {    // Spring Data JPA 方法與自定義方法}

通過遵循這種方法,我們可以在 Spring Data JPA 提供的常見 CRUD 操作與自定義專用方法之間保持清晰的分離。使代碼更加模塊化且更易于理解。Ykc28資訊網——每日最新資訊28at.com

分頁和排序

在處理大型數據集時,高效的分頁和排序機制對于提供流暢的用戶體驗和優化查詢性能至關重要。Ykc28資訊網——每日最新資訊28at.com

分頁涉及將結果集劃分為較小的頁面,以避免一次獲取所有數據。Spring Data JPA 的Pageable接口提供了一種定義分頁參數的方法,包括所需的頁碼、每頁的條目數(頁面大小)和排序方式。Ykc28資訊網——每日最新資訊28at.com

public interface ProductRepository extends JpaRepository<Product, Long> {    Page<Product> findByCategory(Category category, Pageable pageable);}

在此示例中,該方法findByCategory返回一個Page<Product>.Ykc28資訊網——每日最新資訊28at.com

排序可以根據一個或多個字段以特定順序排列查詢結果。Spring Data JPA 的Sort類能夠為Repository方法指定排序方式。Ykc28資訊網——每日最新資訊28at.com

public interface ProductRepository extends JpaRepository<Product, Long> {    List<Product> findByCategoryOrderByPriceAsc(Category category);}

在此示例中,findByCategoryOrderByPriceAsc方法根據給定類別檢索產品,并按價格升序,后綴OrderByPriceAsc表示排序順序。Ykc28資訊網——每日最新資訊28at.com

可以結合分頁和排序來按特定順序檢索分頁結果。例如:Ykc28資訊網——每日最新資訊28at.com

public interface ProductRepository extends JpaRepository<Product, Long> {    Page<Product> findByCategoryOrderByPriceAsc(Category category, Pageable pageable);}

通過提供Pageable參數,可以指定頁碼、頁面大小和排序標準。Spring Data JPA 負責生成適當的查詢來獲取請求的數據。Ykc28資訊網——每日最新資訊28at.com

@Servicepublic class ProductService {    @Autowired    private ProductRepository productRepository;    public Page<Product> getProductsByCategoryWithPaginationAndSorting(Category category, int pageNumber, int pageSize) {        // 創建 Pageable 對象來進行分頁和排序        Pageable pageable = PageRequest.of(pageNumber, pageSize, Sort.by(Sort.Direction.ASC, "price"));                return productRepository.findByCategoryOrderByPriceAsc(category, pageable);    }}

最后,我們可以在 Controller 中使用Service方法來檢索分頁和排序的結果,如下所示:Ykc28資訊網——每日最新資訊28at.com

@RestController@RequestMapping("/products")public class ProductController {    @Autowired    private ProductService productService;    @GetMapping    public ResponseEntity<Page<Product>> getProductsByCategory(            @RequestParam("category") Long categoryId,            @RequestParam("page") int pageNumber,            @RequestParam("size") int pageSize) {        Category category = new Category();        category.setId(categoryId);        Page<Product> products = productService.getProductsByCategoryWithPaginationAndSorting(category, pageNumber, pageSize);        return ResponseEntity.ok(products);    }}

冪等方法

在設計和實現Repository方法時,特別是那些修改數據的方法時,遵循冪等原則非常重要,以確保多次調用具有相同參數的相同方法不會導致意外行為。Ykc28資訊網——每日最新資訊28at.com

例如,在電子商務應用程序中,如果多次下具有相同詳細信息的訂單,則應該產生相同的結果,并且不會創建多個重復訂單。Ykc28資訊網——每日最新資訊28at.com

使用事務性操作

修改數據時,使用事務操作是一個很好的做法。Spring Data JPA 提供開箱即用的事務管理。使用事務確保操作期間發生錯誤,則回滾更改,從而保持數據的完整性。Ykc28資訊網——每日最新資訊28at.com

@Servicepublic class OrderService {    @Autowired    private OrderRepository orderRepository;    @Transactional    public void placeOrder(User user, Product product) {        // 檢查訂單是否已存在        Order existingOrder = orderRepository.findByUserAndProduct(user, product);        if (existingOrder == null) {            // 創建一個新訂單            Order newOrder = new Order();            newOrder.setUser(user);            newOrder.setProduct(product);            newOrder.setOrderDate(LocalDateTime.now());            orderRepository.save(newOrder);        } else {            // 如果訂單已存在,在不需要操作        }    }}

冪等性檢查

對于某些操作,我們可能需要實施冪等性檢查。意味著在執行某個操作之前,需要檢查該操作是否已經執行過,以防止多余的操作。Ykc28資訊網——每日最新資訊28at.com

@Servicepublic class OrderService {    @Autowired    private OrderRepository orderRepository;    @Transactional    public void processOrder(Long orderId) {        Order order = orderRepository.findById(orderId).orElse(null);        if (order != null && !order.isProcessed()) {            // 執行處理邏輯            order.setProcessed(true);        }    }}

在此示例中,processOrder方法檢查訂單是否已被處理,以防止多次處理同一訂單。Ykc28資訊網——每日最新資訊28at.com

通過遵循這些實踐,可以確保Repository方法保持冪等性。這不僅可以防止意外的副作用,還可以使應用程序更加健壯和可預測,特別是在處理意外錯誤或故障時。Ykc28資訊網——每日最新資訊28at.com

單元測試

為Repository接口編寫單元測試對于確保其正確性至關重要。使用JUnit和Mockito等工具來模擬數據庫交互并驗證Repository方法是否按預期運行。Ykc28資訊網——每日最新資訊28at.com

// User.java@Entitypublic class User {    @Id    @GeneratedValue(strategy = GenerationType.IDENTITY)    private Long id;    private String username;    private String email;    // getters and setters}// UserRepository.javapublic interface UserRepository extends JpaRepository<User, Long> {    User findByUsername(String username);}import static org.junit.jupiter.api.Assertions.assertEquals;import static org.mockito.Mockito.when;@RunWith(MockitoJUnitRunner.class)public class UserRepositoryTest {    @InjectMocks    private UserService userService;    @Mock    private UserRepository userRepository;    @Test    public void testFindByUsername() {        // Arrange        String username = "zhangsan";        User user = new User();        user.setId(1L);        user.setUsername(username);        user.setEmail("zhangsan@example.com");        when(userRepository.findByUsername(username)).thenReturn(user);        // Act        User foundUser = userService.findByUsername(username);        // Assert        assertEquals(username, foundUser.getUsername());    }}

@DataJpaTest是一個專門用于JPA測試的 Spring Boot 注解。當使用 @DataJpaTest 時,Spring Boot 會設置一個最小的 Spring 應用程序上下文,其中僅包含 JPA 測試所需的組件。這樣測試就可以訪問已配置的內存數據庫,并且 Spring 將自動配置和管理 EntityManager 和Repository,這樣可以以更集成的方式進行測試。Ykc28資訊網——每日最新資訊28at.com

@DataJpaTestpublic class UserRepositoryTest {    @Autowired    private TestEntityManager entityManager;    @Autowired    private UserRepository userRepository;    @Test    public void testFindByUsername() {        // Arrange        String username = "zhangsan";        User user = new User();        user.setUsername(username);        user.setEmail("zhangsan@example.com");        entityManager.persist(user);        // Act        User foundUser = userRepository.findByUsername(username);        // Assert        assertEquals(username, foundUser.getUsername());    }}

使用@DataJpaTest優點:Ykc28資訊網——每日最新資訊28at.com

  1. 為JPA相關組件提供輕量級、針對性的測試環境。
  2. 它使用必要的配置設置 Spring 應用程序上下文,從而更容易編寫Repository測試。
  3. 自動配置內存數據庫,確保測試的隔離性和速度。

錯誤處理

在進行數據訪問操作時,可能會發生異常,例如數據庫連接問題、約束違規和數據完整性問題。Spring Data JPA 通過自動將 JPA 特定的異常轉換為 Spring 的DataAccessException來簡化錯誤處理,這樣就可以在整個應用程序中以一致的方式處理異常。Ykc28資訊網——每日最新資訊28at.com

考慮一個示例,嘗試將重復的用戶名插入數據庫,這時會發生唯一約束沖突。Ykc28資訊網——每日最新資訊28at.com

@Entitypublic class User {    @Id    @GeneratedValue(strategy = GenerationType.IDENTITY)    private Long id;    @Column(unique = true)    private String username;    private String email;    // getters and setters}public interface UserRepository extends JpaRepository<User, Long> {    User findByUsername(String username);}

在這種情況下,如果嘗試插入具有重復用戶名的新用戶名,則會拋出ConstraintViolationException異常。Ykc28資訊網——每日最新資訊28at.com

@Servicepublic class UserService {    @Autowired    private UserRepository userRepository;    public User createUser(User user) {        try {            return userRepository.save(user);        } catch (DataAccessException ex) {            // 處理異常            throw new CustomDataAccessException("An error occurred while saving the user.", ex);        }    }}

在UserService中,我們使用一個try-catch塊來捕獲DataAccessException。Spring Data JPA 自動將底層 JPA 異常轉換為更通用的DataAccessException. 然后,我們可以根據應用程序的要求處理此異常。Ykc28資訊網——每日最新資訊28at.com

為了使錯誤處理的信息更豐富,我們可以創建擴展 SpringDataAccessException或其子類的自定義異常類。例如:Ykc28資訊網——每日最新資訊28at.com

public class CustomDataAccessException extends DataAccessException {    public CustomDataAccessException(String msg, Throwable cause) {        super(msg, cause);    }}

接下來,在Controller中處理異常:Ykc28資訊網——每日最新資訊28at.com

@RestController@RequestMapping("/users")public class UserController {    @Autowired    private UserService userService;    @PostMapping    public ResponseEntity<?> createUser(@RequestBody User user) {        try {            User createdUser = userService.createUser(user);            return ResponseEntity.status(HttpStatus.CREATED).body(createdUser);        } catch (CustomDataAccessException ex) {            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ex.getMessage());        }    }}

總結

在 Spring Boot 應用程序中使用 JPA 創建Repository接口時遵循最佳實踐對于實現可維護、可擴展和有組織的代碼至關重要。通過遵循最佳實踐,開發人員可以構建強大的數據訪問層,與更廣泛的應用程序架構無縫集成。這種方法促進了模塊化,增強了可測試性,確保了明確的職責分離,并最終有助于開發高質量的 Spring Boot 應用程序。Ykc28資訊網——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-12271-0.html分享Spring Data JPA的一些技巧和優秀實踐

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 十個超級高效的IntelliJ IDEA插件

下一篇: 掌握C/C++中的靜態變量與靜態成員!

標簽:
  • 熱門焦點
  • 盧偉冰長文解析K60至尊版 對Redmi有著里程碑式的意義

    在今天的Redmi后性能時代戰略發布會結束之后,Redmi總經理盧偉冰又帶來了一篇長文,詳解了為什么 Redmi 要開啟后性能時代?為什么選擇和 MediaTek、Pixelworks 深度合作?以及后性
  • 官方承諾:K60至尊版將會首批升級MIUI 15

    全新的MIUI 15今天也有了消息,在官宣了K60至尊版將會搭載天璣9200+處理器和獨顯芯片X7的同時,Redmi給出了官方承諾,K60至尊重大更新首批升級,會首批推送MIUI 15。也就是說雖然
  • 7月安卓手機性能榜:紅魔8S Pro再奪榜首

    7月份的手機市場風平浪靜,除了紅魔和努比亞帶來了兩款搭載驍龍8Gen2領先版處理器的新機之外,別的也想不到有什么新品了,這也正常,通常6月7月都是手機廠商修整的時間,進入8月份之
  • Golang 中的 io 包詳解:組合接口

    io.ReadWriter// ReadWriter is the interface that groups the basic Read and Write methods.type ReadWriter interface { Reader Writer}是對Reader和Writer接口的組合,
  • .NET 程序的 GDI 句柄泄露的再反思

    一、背景1. 講故事上個月我寫過一篇 如何洞察 C# 程序的 GDI 句柄泄露 文章,當時用的是 GDIView + WinDbg 把問題搞定,前者用來定位泄露資源,后者用來定位泄露代碼,后面有朋友反
  • 自律,給不了Keep自由!

    來源 | 互聯網品牌官作者 | 李大為編排 | 又耳 審核 | 谷曉輝自律能不能給用戶自由暫時不好說,但大概率不能給Keep自由。近日,全球最大的在線健身平臺Keep正式登陸港交所,努力
  • “又被陳思誠騙了”

    作者|張思齊 出品|眾面(ID:ZhongMian_ZM)如今的國產懸疑電影,成了陳思誠的天下。最近大爆電影《消失的她》票房突破30億斷層奪魁暑期檔,陳思誠再度風頭無兩。你可以說陳思誠的
  • 機構稱Q2國內智能手機銷量同比下滑4% vivo份額重回第1

    7月29日消息,根據市場調查機構Counterpoint Research公布的最新報告,2023年第2季度中國智能手機銷量同比下降4%,創新自2014年以來第2季度銷量新低。報
  • 聯想的ThinkBook Plus下一版曝光,鍵盤旁邊塞個平板

    ThinkBook Plus 是聯想的一個特殊筆記本類別,它在封面放入了一塊墨水屏,也給人留下了較為深刻的印象。據有人爆料,聯想的下一款 ThinkBook Plus 可能更特殊,它
Top 主站蜘蛛池模板: 汽车| 寿宁县| 瓦房店市| 罗甸县| 元谋县| 贡山| 阜康市| 黄冈市| 铜山县| 科尔| 福泉市| 东乡| 耿马| 荥阳市| 凭祥市| 滦平县| 长春市| 永吉县| 苏尼特左旗| 澜沧| 昆明市| 梨树县| 松江区| 沅陵县| 新兴县| 仲巴县| 大名县| 沁源县| 若尔盖县| 蓬溪县| 封开县| 石台县| 海城市| 蒲城县| 平度市| 永吉县| 青岛市| 苍溪县| 开阳县| 崇文区| 龙门县|