SpringBoot2.x系列教程42--整合使用JPA

一. JPA簡介

1. JPA概念

JPA是Sun官方提出的Java持久化規範,是Java Persistence API的簡稱,中文名‘Java持久層API’,它本質上是一種ORM規範。

JPA通過 JDK 5.0 的 註解或XML 兩種形式來描述 ‘對象--關係表’ 的映射關係,並將運行期的實體對象持久化到數據庫中。

2. JPA出現的原因

Sun引入 JPA 規範是出於兩個原因:

  • 1. 簡化現有Java EE和Java SE的開發工作;
  • 2. Sun希望整合ORM技術,實現天下歸一。

也就是說,Sun提出JPA規範的目的就是想以官方身份來統一各種ORM框架的規範,包括著名的Hibernate、TopLink等。這樣就可以避免開發者爲了使用Hibernate,要學習一套ORM框架;爲了使用TopLink框架,又要再學習一套ORM框架,免去了重複學習的過程!

3. JPA涵蓋的技術

JPA的總體思想和現有的Hibernate、TopLink、JDO、Mybatis等ORM框架大體一致。

總的來說,JPA包括以下3方面的技術:

(1).ORM映射元數據

JPA支持XML和JDK 5.0中的註解兩種形式,通過元數據描述對象和表之間的映射關係,框架據此將實體對象持久化到數據庫表中。

(2).JPA的API

用來操作實體對象,執行CRUD操作,框架在後臺替我們完成所有的事情,開發者從繁瑣的JDBC和SQL代碼中解脫出來。

(3).查詢語言

通過面向對象而非面向數據庫的查詢語言查詢數據,避免程序的SQL語句緊密耦合。

4. JPA與其他ORM框架的關係

JPA的本質是一種ORM規範(不是ORM框架,因爲JPA並未提供ORM實現,只是制定了規範),而非實現。

它只提供了一些相關的接口,但是這些接口並不能直接使用,JPA的底層需要某種JPA實現,而Hibernate等框架則是對JPA的一種具體實現。

也就是說JPA僅僅是一套規範,不是一套產品, Hibernate, TopLink等都是實現了JPA規範的一套產品。

Hibernate 從3.2開始,就開始兼容JPA。Hibernate3.2獲得了Sun TCK的 JPA(Java Persistence API)兼容認證。

所以JPA和Hibernate之間的關係,可以簡單的理解爲JPA是標準接口,Hibernate是實現,他們之間並不是對標的關係,下圖可以表明他們之間的關係。

Hibernate屬於遵循JPA規範的一種實現,但是Hibernate還有其他要實現的規範。所以它們的關係更類似於是:
JPA是一種做麪條的標準規範,而Hibernate是一種遵循做麪條規範的具體的湯麪;它不僅遵循了做麪條的規範,同時也會遵循做湯和調料的其他規範。

5. JPA中的註解

二. Spring Boot整合JPA實現過程

1. 創建web程序

我們按照之前的經驗,創建一個web程序,並將之改造成Spring Boot項目,具體過程略。

2. 添加依賴包

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.1.10</version>
</dependency>

3. 添加配置文件

創建application.yml配置文件

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/db4?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true
    type: com.alibaba.druid.pool.DruidDataSource
    username: root
    password: syc
    driver-class-name: com.mysql.jdbc.Driver #驅動
  jpa:
    hibernate:
      ddl-auto: update #自動更新
    show-sql: true  #日誌中顯示sql語句

jpa.hibernate.ddl-auto是hibernate的配置屬性,其主要作用是:自動創建、更新、驗證數據庫表結構。

該參數的幾種配置如下:

  • ·create:每次加載hibernate時都會刪除上一次的生成的表,然後根據你的model類再重新來生成新表,哪怕兩次沒有任何改變也要這樣執行,這就是導致數據庫表數據丟失的一個重要原因。
  • ·create-drop:每次加載hibernate時根據model類生成表,但是sessionFactory一關閉,表就自動刪除。
  • ·update:最常用的屬性,第一次加載hibernate時根據model類會自動建立起表的結構(前提是先建立好數據庫),以後加載hibernate時根據model類自動更新表結構,即使表結構改變了但表中的行仍然存在不會刪除以前的行。要注意的是當部署到服務器後,表結構是不會被馬上建立起來的,是要等應用第一次運行起來後纔會。
  • ·validate:每次加載hibernate時,驗證創建數據庫表結構,只會和數據庫中的表進行比較,不會創建新表,但是會插入新值。

4. 創建實體類

package com.yyg.boot.domain;

import lombok.Data;
import lombok.ToString;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

/**
 * @Author 一一哥Sun
 * @Date Created in 2020/3/30
 * @Description Description
 */
@Data
@ToString
@Entity
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column
    private String username;

    @Column
    private String birthday;

    @Column
    private String sex;

    @Column
    private String address;

}

5. 創建DataSource配置類

package com.yyg.boot.config;

import com.alibaba.druid.pool.DruidDataSource;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;

/**
 * @Author 一一哥Sun
 * @Date Created in 2020/3/30
 * @Description 第二種配置數據源的方式
 */
@Data
@ComponentScan
@Configuration
@ConfigurationProperties(prefix="spring.datasource")
public class DbConfig {

    private String url;
    private String username;
    private String password;

    @Bean
    public DataSource getDataSource() {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setUrl(url);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        return dataSource;
    }

}

6. 創建JPA實體倉庫

package com.yyg.boot.repository;

import com.yyg.boot.domain.User;
import org.springframework.data.jpa.repository.JpaRepository;

/**
 * @Author 一一哥Sun
 * @Date Created in 2020/3/31
 * @Description Description
 */
public interface UserRepository extends JpaRepository<User, Long> {
}

7. 創建Controller測試接口

package com.yyg.boot.web;

import com.yyg.boot.domain.User;
import com.yyg.boot.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * @Author 一一哥Sun
 * @Date Created in 2020/3/31
 * @Description Description
 */
@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserRepository userRepository;

    @GetMapping("")
    public List<User> findUsers() {
        return userRepository.findAll();
    }

   /**
     * 注意:記得添加@RequestBody註解,否則前端傳遞來的json數據無法被封裝到User中!
     */
    @PostMapping("")
    public User addUser(@RequestBody User user) {
        return  userRepository.save(user);
    }

    @DeleteMapping(path = "/{id}")
    public String deleteById(@PathVariable("id") Long id) {
        userRepository.deleteById(id);
        return "success";
    }

}

8. 創建Application啓動類

package com.yyg.boot;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * @Author 一一哥Sun
 * @Date Created in 2020/3/31
 * @Description Description
 */
@SpringBootApplication
public class JpaApplication {

    public static void main(String[] args) {
        SpringApplication.run(JpaApplication.class, args);
    }

}

完整項目結構:

9. 測試接口

在瀏覽器中進行get查詢:

在postman中執行添加操作:

在postman中執行刪除操作:

10. JPA實現原理

JPA會根據方法名來生成sql查詢語句,它遵循的是Convention over configuration(約定大約配置)的原則,遵循Spring 以及JPQL定義的方法命名。
Spring提供了一套可以通過命名規則進行查詢構建的機制,這套機制會把方法名首先過濾一些關鍵字,比如 find…By, read…By, query…By, count…By 和 get…By...

然後系統會根據關鍵字將命名解析成2個子語句,第一個 By 是區分這兩個子語句的關鍵詞。這個 By 之前的子語句是查詢子語句(指明返回要查詢的對象),後面的部分是條件子語句。

如果直接就是 findBy… 返回的就是定義Respository時指定的領域對象集合,同時JPQL中也定義了豐富的關鍵字:and、or、Between等等,下面我們來看一下JPQL中有哪些關鍵字:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章