Spring Boot中使用Spring Data JPA示例


JPA是Java Persistence API的簡稱,是sun公司早期推出的Java持久層規范,目前實現JPA規范的主流框架有Hibernate、OpenJPA等。Hibernate框架是當前較為流行的JPA實現之一,在Spring Data JPA中,默認底層實現也是使用的Hibernate。

目錄:

 

Spring Data JPA示例搭建

Spring Boot 提供了一個"spring-boot-starter-data-jpa"模塊,在項目中使用這個模塊,就可以簡單的整合Spring Data JPA、Hibernate及其他依賴所需模塊。

新建一個名為spring-jpa的Maven工程,修改其pom.xml文件。

    <!-- Spring Boot父工程 -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.3.RELEASE</version>
    </parent>

    <dependencies>
        <!-- Web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- Spring Data JPA -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <!-- MySQL 驅動 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
    </dependencies>

在src/main/resource目錄下新建一個名為application.yml的配置文件:

spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://192.168.170.129:3306/spring-jpa
    username: root
    password: root

在application.yml配置文件中簡單配置了數據庫連接必要的參數。從中可以看出,我們項目使用的數據庫名:spring-jpa

接下來我們就可以編寫項目的數據訪問層和業務層了。

實體類Book:

package com.hrvy.entity;

@Entity
public class Book {

    /** 主鍵ID */
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    /** 圖書名稱 */
    @Column
    private String bookName;

    /** 圖書封面 */
    @Column
    private String bookCover;

    /** 圖書作者 */
    @Column
    private String bookAuthor;

    /** 圖書價格 */
    @Column
    private BigDecimal bookPrice;

    /** 圖書狀態:0=false(未刪除狀態)1=true(已刪除狀態) */
    @Column
    private Boolean isDelete;

    /** getter/setter 方法。。。 */
}

 

數據訪問接口BookRepository:

package com.hrvy.dao;

public interface BookRepository extends JpaRepository<Book, Integer> {

}

該接口繼承JpaRepository接口,且無任何接口方法和實現類。JpaRepository接口中定義有很多數據訪問方法,Spring會默認使用JDK代理來生成BookRepository接口的代理類,從而就擁有了JpaRepository的功能實現,進行數據CRUD操作。

服務層BookService:

package com.hrvy.service;

public interface BookService {
    /**
     * 獲取所有圖書信息
     * 
     * @return
     */
    List<Book> getBooks();

    /**
     * 保存圖書
     * 
     * @param book 圖書實體
     */
    void saveBook(Book book);
}
package com.hrvy.service.impl;

@Service
public class BookServiceImpl implements BookService {

    @Autowired
    private BookRepository bookRepository;

    @Override
    public List<Book> getBooks() {
        return bookRepository.findAll();
    }

    @Override
    public void saveBook(Book book) {
        bookRepository.save(book);
    }
}

控制層BookController:

package com.hrvy.controller;

@RestController
public class BookController {

    @Autowired
    private BookService bookService;

    /**
     * 獲取全部圖書
     * 
     * @return
     */
    @RequestMapping("/getbooks")
    public List<Book> getBooks() {
        return bookService.getBooks();
    }

    /**
     * 添加圖書
     * 
     * @return
     */
    @RequestMapping("/addbook")
    public String AddBook() {
        Book book = new Book();
        book.setBookName("Spring Data JPA");
        book.setBookAuthor("Hrvy");
        bookService.saveBook(book);
        return "添加成功";
    }
}

運行App.java,瀏覽器輸入http://localhost:8080/addbook進行圖書添加測試,輸入http://localhost:8080/getbooks進行圖書查詢測試。

 

自定義數據存儲邏輯

Spring幫我們生成的代理類,雖然可以完成很多工作,但在實際應用中,有時仍需要實現我們自己的數據存儲邏輯。

新建一個BookRepositoryCustom接口,在BookRepositoryCustom接口中加入需要自定義的接口方法。

BookRepositoryCustom代碼如下:

package com.hrvy.dao;

public interface BookRepositoryCustom {

    List<Book> findBooksCustom();
}

修改原來的BookRepository接口,讓其同時繼承BookRepositoryCustom和JpaRepository。

BookRepository代碼如下:

package com.hrvy.dao;

public interface BookRepository extends BookRepositoryCustom, JpaRepository<Book, Integer> {

}

新建一個名為BookRepositoryCustomImpl的實現類,實現BookRepositoryCustom接口,使用EntityManger接口進行數據操作(該接口具體使用可查看JPA相關文檔)。在此特別注意:該實現類的名字必須為BookRepositoryImpl或BookRepositoryCustomImpl,否則Spring會報錯。原因:Spring默認會在包下查找名為“BookRepository接口名+Impl”或“BookRepositoryCustom接口名+Impl”的實現類,若查找不到,則會將接口方法findBooksCustom()命名查詢規則來代理生成實現,此時就會拋出以下異常:

org.springframework.data.mapping.PropertyReferenceException: No property findBooksCustom found for type Book!

BookRepositoryCustomImpl代碼如下:

package com.hrvy.dao;

public class BookRepositoryCustomImpl implements BookRepositoryCustom {

    @PersistenceContext
    private EntityManager em;

    @Override
    public List<Book> findBooksCustom() {
        StringBuilder sql = new StringBuilder();
        sql.append("select ");
        sql.append("* ");// 拼接表字段,這里使用"*"來代替所有字段
        sql.append("from book ");

        Query query = em.createNativeQuery(sql.toString(), Book.class);

        return (List<Book>) query.getResultList();
    }
}

 運行App.java,瀏覽器輸入http://localhost:8080/getbookscustom進行圖書查詢測試。

 

方法名命名查詢

如果想根據Book的某個字段進行查詢,實現類似“from book where book_name = ?”這樣的查詢,則可以直接在BookRepository接口中定義一個bookName方法(方法名=屬性名),代碼如下:

package com.hrvy.dao;

public interface BookRepository extends BookRepositoryCustom, JpaRepository<Book, Integer> {
    /** 方法名命名查詢:根據bookName獲取Book */
    List<Book> bookName(String bookName);
}

Spring會自動生成相應的查詢方法,不需要我們自己編寫任何邏輯實現。不僅如此,還可以使用接口的方法名,通過特定的關鍵字來實現不同的查詢功能。例如要查詢bookname和bookAuthor等於某值的Book時,則可以使用以下的方法名:

List<Book> findByBookNameAndBookAuthor(String bookName, String bookAuthor);

Spring通過定制方法名來實現相關查詢,目前支持20多個關鍵字,如下表所示:

命名查詢關鍵字
關鍵字 例子 對於的SQL
And findByNameAndAge where name=? and age=?
Is,Equals findByName, findByNameIs, findByNameEquals where name=?
Between findByAgeBetween where age between ? and ?
LessThan findByAgeLessThan where age<?
...    


免責聲明!

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



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