SpringBoot 學習筆記_整合持久層——Spring Boot JPA

SpringBoot 學習筆記_整合持久層——Spring Boot JPA

聲明:

本次學習參考 《SpringBoot + Vue 開發實戰》 · 王松(著) 一書。

本文的目的是記錄我學習的過程和遇到的一些問題以及解決辦法,其內容主要來源於原書。

如有侵權,請聯繫我刪除

SpringBoot 整合持久層開發

整合 Spring Boot JPA

JPA 是一種 ORM 規範。 Spring DataSpring 的一個子項目,致力於簡化數據的訪問,通過規範的方法名稱來分析開發者的意圖,進而減少數據庫訪問層的代碼。

  • 創建數據庫(表會根據實體類自動創建)

  • 創建 SpringBoot 項目,添加依賴

    <!-- 添加 Spring Boot JPA 依賴 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
    	<groupId>com.alibaba</groupId>
    	<artifactId>druid</artifactId>
    	<version>1.1.9</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <scope>runtime</scope>
    </dependency>
    
  • 數據庫配置(application.properties)

    ### 數據庫基本配置 ###
    spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
    #spring.datasource.url=jdbc:mysql:///chapter05?serverTimezone=GMT
    spring.datasource.url=jdbc:mysql://localhost:3306/chapter05?serverTimezone=GMT
    spring.datasource.username=root
    spring.datasource.password=root
    #### 數據庫配置 —— JPA 相關 ####
    # 表示是否在控制檯打印 JPA 打印過程生成的 SQL
    spring.jpa.show-sql=true
    # 表示 JPA 對應的數據庫是 MySQL
    spring.jpa.database=mysql
    # 表示在項目啓動時根據實體類更新數據庫中的表(可選:create、create-drop、validate、no)
    spring.jpa.hibernate.ddl-auto=update
    # 表示使用的數據庫方言是 MySQL57Dialect
    spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL57Dialect
    
  • 創建實體類

    // @Entity 表示該類是一個實體類。在項目啓動時會根據該類自動生成一個數據表,表名稱即 @Entity 的 name 值,如果不配置,默認爲類名。
    @Entity(name = "t_book")
    public class BookJPA {
        // @Id 表示該實體類的主鍵。所有實體類都要有主鍵
        @Id
        // @GeneratedValue 表示主鍵自動生成,strategy 表示生成策略
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Integer id;
    
        // @Column 表示表中字段名稱和實體類中屬性名稱的映射。如果不配置,默認生成字段名就是屬性名。nullable 表示是否可爲空
        @Column(name = "book_name", nullable = false)
        private String name;
    
        private String author;
        private Float price;
    
        // @Transient 表示生成數據表時,忽略該字段
        @Transient
        private String description;
    }
    
  • 創建數據庫訪問層

    /**
     * 整合 JPA 的 BookDao
     *
     * 自定義 Dao 繼承 JpaRepository。JpaRepository 中提供了一些基本的數據操作方法,有增刪改查、分頁查詢、排序查詢等。
     */
    public interface BookJPADao extends JpaRepository<BookJPA, Integer> {
    
        //Spring Data JPA 支持既定規範命名查詢(方法名複合既定規範,自動生成對應 SQL)
    
        /**
         *     keyWords             示例                                對應 SQL
         *     And                  findByNameAndAge                    where name=? and age=?
         *     Or                   findByNameOrAge                     where name=? or age=?
         *     Is/Equals            findByAgeIs/findByAgeEquals         where age=?
         *     Between              findByAgeBetween                    where age between ? and ?
         *     LessThan/Before      findByAgeLessThan/findByAgeBefore   where age < ?
         *     LessThanEquals       findByAgeLessThanEquals             where age <= ?
         *     GreaterThan/After    findByAgeGreaterThan/findByAgeAfter where age > ?
         *     GreaterThanEquals    findByAgeGreaterThanEquals          where age >= ?
         *     IsNull               findByNameIsNull                    where name is null
         *     IsNotNull/NotNull    findByNameNotNull                   where name is not null
         *     Not                  findByNameNot                       where name <> ?
         *     In                   findByAgeIn                         where age in(?)
         *     NotIn                findByAgeNotIn                      where age not in(?)
         *     NotLike              findByNameNotLike                   where name not like ?
         *     StartingWith         findByNameStartingWith              where name like '?%'
         *     EndingWith           findByNameEndingWith                where name like '%?'
         *     Containing/Contains  findByNameContains                  where name like '%?%'
         *     True                 findByEnabledTrue                   where enabled = true
         *     False                findByEnabledFalse                  where enabled = false
         *     IgnoreCase           findByNameIgnoreCase                where UPPER(name)=UPPER(?)
         *
         *     OrderBy              findByAgeGreaterThanOrderByIdDesc   where age > ? order by id desc
         */
    
        // 查詢作者名以某字符開頭的所有書
        List<BookJPA> getBooksByAuthorStartingWith(String author);
        // 查詢價格大於某值得所有書
        List<BookJPA> getBooksByPriceGreaterThan(Float price);
    
        // Spring Data JPA 支持原生 SQL。 nativeQuery = true 表示使用原生 SQL 語句
        @Query(value = "select * from t_book where id=(select max(id) from t_book)", nativeQuery = true)
        BookJPA getMaxIdBook();
    
        // Spring Data JPA 支持默認的 JPQL。JPQL 是一種可移植的面向對象表達式語言。
        // 通過類名和屬性(並非數據庫列名)來進行參數綁定。參數需要使用 @Param 綁定。
        @Query("select b from t_book b where b.id > :id and b.author=:author")
        List<BookJPA> getBookByIdAndAuthor(@Param("author") String author, @Param("id") Integer id);
    
        // Spring Data JPA 支持默認的 JPQL。
        // 通過佔位符進行參數傳遞。參數順序有嚴格要求。
        @Query("select b from t_book b where b.id < ?2 and b.name like %?1%")
        List<BookJPA> getBooksByIdAndNameAnd(String name, Integer id);
    
        // 如果方法涉及修改操作,需要添加 @Modifying 註解並添加事務
    }
    
  • 創建 Service 和 Controller

    /**
     *  整合 Spring Data JPA 的 Service 層
     */
    @Service
    public class BookJPAService {
        @Autowired
        BookJPADao bookDao;
    
        public void addBook(BookJPA book){
            bookDao.save(book);
        }
    
        public Page<BookJPA> getBookByPage(Pageable pageable){
            return bookDao.findAll(pageable);
        }
    
        public List<BookJPA> getBooksByAuthorStartingWith(String author){
            return bookDao.getBooksByAuthorStartingWith(author);
        }
    
        public List<BookJPA> getBooksByPriceGreaterThan(Float price){
            return bookDao.getBooksByPriceGreaterThan(price);
        }
    
        public BookJPA getMaxIdBook(){
            return bookDao.getMaxIdBook();
        }
    
        public List<BookJPA> getBookByIdAuthor(String author, Integer id){
            return bookDao.getBookByIdAndAuthor(author, id);
        }
    
        public List<BookJPA> getBooksByIdAndName(String name, Integer id){
            return bookDao.getBooksByIdAndName(name, id);
        }
    }
    
    /**
     * 整個 Spring Data JPA 的 Controller 層
     */
    
    @RestController
    public class BookJPAController {
        @Autowired
        BookJPAService bookService;
    
        @GetMapping("/jpa/findAll")
        public void findAll(){
            PageRequest pageable = PageRequest.of(2, 3);
            Page<BookJPA> page = bookService.getBookByPage(pageable);
    
            System.out.println(" 總頁數: " + page.getTotalPages());
            System.out.println(" 總記錄: " + page.getTotalElements());
            System.out.println(" 查詢結果: " + page.getContent());
            System.out.println(" 當前頁數: " + page.getNumber() + 1);
            System.out.println(" 當前頁記錄數: " + page.getNumberOfElements());
            System.out.println(" 每頁記錄數: " + page.getSize());
        }
    
        @GetMapping("/jpa/search")
        public void search(){
            List<BookJPA> bs1 = bookService.getBookByIdAndAuthor("吳承恩", 1);
            List<BookJPA> bs2 = bookService.getBooksByAuthorStartingWith("施");
            List<BookJPA> bs3 = bookService.getBooksByPriceGreaterThan(0.1F);
            BookJPA book = bookService.getMaxIdBook();
    
            System.out.println(bs1);
            System.out.println(bs2);
            System.out.println(bs3);
            System.out.println(book);
        }
    
        @GetMapping("/jpa/save")
        public void save(){
            BookJPA book = new BookJPA();
            book.setAuthor("臥龍");
            book.setName("臥龍鍋巴");
            book.setPrice(3.5F);
    
            bookService.addBook(book);
        }
    }
    
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章