一. JPA簡介## **一. JPA簡介**一. JPA簡介
1. JPA概念
JPA是Sun官方提出的Java持久化規(guī)范,是Java Persistence API的簡稱刻帚,中文名‘Java持久層API’湾笛,它本質上是一種ORM規(guī)范壳炎。
JPA通過 JDK 5.0 的 注解或XML 兩種形式來描述 ‘對象--關系表’ 的映射關系,并將運行期的實體對象持久化到數據庫中诊沪。
2. JPA出現的原因
Sun引入 JPA 規(guī)范是出于兩個原因:
1. 簡化現有Java EE和Java SE的開發(fā)工作;
2. Sun希望整合ORM技術蹂空,實現天下歸一舰始。
也就是說,Sun提出JPA規(guī)范的目的就是想以官方身份來統一各種ORM框架的規(guī)范峻堰,包括著名的Hibernate讹开、TopLink等。這樣就可以避免開發(fā)者為了使用Hibernate捐名,要學習一套ORM框架旦万;為了使用TopLink框架,又要再學習一套ORM框架镶蹋,免去了重復學習的過程成艘!
3. JPA涵蓋的技術
JPA的總體思想和現有的Hibernate、TopLink贺归、JDO淆两、Mybatis等ORM框架大體一致。
總的來說牧氮,JPA包括以下3方面的技術:
(1).ORM映射元數據
JPA支持XML和JDK 5.0中的注解兩種形式琼腔,通過元數據描述對象和表之間的映射關系,框架據此將實體對象持久化到數據庫表中踱葛。
(2).JPA的API
用來操作實體對象丹莲,執(zhí)行CRUD操作光坝,框架在后臺替我們完成所有的事情,開發(fā)者從繁瑣的JDBC和SQL代碼中解脫出來甥材。
(3).查詢語言
通過面向對象而非面向數據庫的查詢語言查詢數據盯另,避免程序的SQL語句緊密耦合。
4. JPA與其他ORM框架的關系
JPA的本質是一種ORM規(guī)范(不是ORM框架洲赵,因為JPA并未提供ORM實現鸳惯,只是制定了規(guī)范),而非實現叠萍。
它只提供了一些相關的接口芝发,但是這些接口并不能直接使用,JPA的底層需要某種JPA實現苛谷,而Hibernate等框架則是對JPA的一種具體實現辅鲸。
也就是說JPA僅僅是一套規(guī)范,不是一套產品, Hibernate, TopLink等都是實現了JPA規(guī)范的一套產品。
Hibernate 從3.2開始腹殿,就開始兼容JPA独悴。Hibernate3.2獲得了Sun TCK的 JPA(Java Persistence API)兼容認證。
所以JPA和Hibernate之間的關系锣尉,可以簡單的理解為JPA是標準接口刻炒,Hibernate是實現,他們之間并不是對標的關系自沧,下圖可以表明他們之間的關系坟奥。
Hibernate屬于遵循JPA規(guī)范的一種實現,但是Hibernate還有其他要實現的規(guī)范拇厢。所以它們的關系更類似于是:JPA是一種做面條的標準規(guī)范筏勒,而Hibernate是一種遵循做面條規(guī)范的具體的湯面;它不僅遵循了做面條的規(guī)范旺嬉,同時也會遵循做湯和調料的其他規(guī)范管行。
5. JPA中的注解
二. Spring Boot整合JPA實現過程
1. 創(chuàng)建web程序
我們按照之前的經驗,創(chuàng)建一個web程序邪媳,并將之改造成Spring Boot項目捐顷,具體過程略。
2. 添加依賴包
org.springframework.boot
spring-boot-starter-data-jpa
mysql
mysql-connector-java
com.alibaba
druid
1.1.10
3. 添加配置文件
創(chuàng)建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的配置屬性雨效,其主要作用是:自動創(chuàng)建迅涮、更新、驗證數據庫表結構徽龟。
該參數的幾種配置如下:
·create:每次加載hibernate時都會刪除上一次的生成的表叮姑,然后根據你的model類再重新來生成新表,哪怕兩次沒有任何改變也要這樣執(zhí)行,這就是導致數據庫表數據丟失的一個重要原因传透。
·create-drop:每次加載hibernate時根據model類生成表耘沼,但是sessionFactory一關閉,表就自動刪除。
·update:最常用的屬性朱盐,第一次加載hibernate時根據model類會自動建立起表的結構(前提是先建立好數據庫)群嗤,以后加載hibernate時根據model類自動更新表結構,即使表結構改變了但表中的行仍然存在不會刪除以前的行兵琳。要注意的是當部署到服務器后狂秘,表結構是不會被馬上建立起來的,是要等應用第一次運行起來后才會躯肌。
·validate:每次加載hibernate時者春,驗證創(chuàng)建數據庫表結構,只會和數據庫中的表進行比較清女,不會創(chuàng)建新表碧查,但是會插入新值。
4. 創(chuàng)建實體類
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@Entitypublic 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. 創(chuàng)建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. 創(chuàng)建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 {
}
7. 創(chuàng)建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 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. 創(chuàng)建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
*/@SpringBootApplicationpublic class JpaApplication { ? ?public static void main(String[] args) {
SpringApplication.run(JpaApplication.class, args);
}
}
完整項目結構:
9. 測試接口
在瀏覽器中進行get查詢:
在postman中執(zhí)行添加操作:
在postman中執(zhí)行刪除操作:
10. JPA實現原理
JPA會根據方法名來生成sql查詢語句校仑,它遵循的是Convention over configuration(約定大約配置)的原則,遵循Spring 以及JPQL定義的方法命名传惠。Spring提供了一套可以通過命名規(guī)則進行查詢構建的機制迄沫,這套機制會把方法名首先過濾一些關鍵字,比如 find…By, read…By, query…By, count…By 和 get…By...
然后系統會根據關鍵字將命名解析成2個子語句卦方,第一個 By 是區(qū)分這兩個子語句的關鍵詞羊瘩。這個 By 之前的子語句是查詢子語句(指明返回要查詢的對象),后面的部分是條件子語句盼砍。
如果直接就是 findBy… 返回的就是定義Respository時指定的領域對象集合尘吗,同時JPQL中也定義了豐富的關鍵字:and、or浇坐、Between等等睬捶,下面我們來看一下JPQL中有哪些關鍵字: