全部課程
發(fā)布時(shí)間: 2020-07-13 10:34:37
?一、 Spring Data JPA簡(jiǎn)介
Spring Data JPA 是 Spring 基于 ORM 框架、JPA 規(guī)范的基礎(chǔ)上封裝的一套 JPA 應(yīng)用框架,底層使用了Hibernate 的 JPA 技術(shù)實(shí)現(xiàn),可使開(kāi)發(fā)者用極簡(jiǎn)的代碼即可實(shí)現(xiàn)對(duì)數(shù)據(jù)的訪問(wèn)和操作。
它提供了包括增刪改查等在內(nèi)的常用功能接口,且易于擴(kuò)展!學(xué)習(xí)并使用 Spring Data JPA 可以極大提高開(kāi)發(fā)效率!
由于微服務(wù)系統(tǒng)的廣泛應(yīng)用,服務(wù)粒度逐漸細(xì)化,多表關(guān)聯(lián)查詢的場(chǎng)景一定程度減少。單表查詢和單表的數(shù)據(jù)操作正是JPA的優(yōu)勢(shì)。
二、 Spring Data JPA特點(diǎn)
1. 標(biāo)準(zhǔn)化 JPA 是 JCP 組織發(fā)布的 Java EE 標(biāo)準(zhǔn)之一,因此任何聲稱符合 JPA 標(biāo)準(zhǔn)的框架都遵循同樣的架構(gòu),提供相同的訪問(wèn)API,這保證了基于JPA開(kāi)發(fā)的企業(yè)應(yīng)用能夠經(jīng)過(guò)少量的修改就能夠在不同的JPA框架下運(yùn)行。
2. 容器級(jí)特性的支持 JPA框架中支持大數(shù)據(jù)集、事務(wù)、并發(fā)等容器級(jí)事務(wù),這使得 JPA 超越了簡(jiǎn)單持久化框架的局限,在企業(yè)應(yīng)用發(fā)揮更大的作用。
3. 簡(jiǎn)單方便 JPA的主要目標(biāo)之一就是提供更加簡(jiǎn)單的編程模型:在JPA框架下創(chuàng)建實(shí)體和創(chuàng)建Java類一樣簡(jiǎn)單,沒(méi)有任何的約束和限制,只需要使用javax.persistence.Entity進(jìn)行注釋,JPA的框架和接口也都非常簡(jiǎn)單,沒(méi)有太多特別的規(guī)則和設(shè)計(jì)模式的要求,開(kāi)發(fā)者可以很容易地掌握。JPA基于非侵入式原則設(shè)計(jì),因此可以很容易地和其它框架或者容器集成。
4. 查詢能力 JPA的查詢語(yǔ)言是面向?qū)ο蠖敲嫦驍?shù)據(jù)庫(kù)的,它以面向?qū)ο蟮淖匀徽Z(yǔ)法構(gòu)造查詢語(yǔ)句,可以看成是Hibernate HQL的等價(jià)物。JPA定義了獨(dú)特的JPQL(Java Persistence Query Language),JPQL是EJB QL的一種擴(kuò)展,它是針對(duì)實(shí)體的一種查詢語(yǔ)言,操作對(duì)象是實(shí)體,而不是關(guān)系數(shù)據(jù)庫(kù)的表,而且能夠支持批量更新和修改、JOIN、GROUP BY、HAVING 等通常只有 SQL 才能夠提供的高級(jí)查詢特性,甚至還能夠支持子查詢。
5. 高級(jí)特性 JPA 中能夠支持面向?qū)ο蟮母呒?jí)特性,如類之間的繼承、多態(tài)和類之間的復(fù)雜關(guān)系,這樣的支持能夠讓開(kāi)發(fā)者較大限度的使用面向?qū)ο蟮哪P驮O(shè)計(jì)企業(yè)應(yīng)用,而不需要自行處理這些特性在關(guān)系數(shù)據(jù)庫(kù)的持久化。
三、 在SpringBoot項(xiàng)目中引入JPA依賴實(shí)現(xiàn)對(duì)數(shù)據(jù)庫(kù)的操作
1. 引入必須的依賴包
<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>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
2. 修改application.yml編寫配置文件
server:
port: 9004
spring:
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
datasource:
url: jdbc:mysql://localhost:3306/springbootjpa?serverTimezone=UTC
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: 123456aB
jpa:
hibernate:
ddl-auto: validate # 自動(dòng)建表用update 成功后換成validate
database: mysql
show-sql: true
# create:每次加載hibernate時(shí)都會(huì)刪除上一次的生成的表,然后根據(jù)你的model類再重新來(lái)生成新表,哪怕兩次沒(méi)有任何改變也要這樣執(zhí)行,這就是導(dǎo)致數(shù)據(jù)庫(kù)表數(shù)據(jù)丟失的一個(gè)重要原因。
# create-drop:每次加載hibernate時(shí)根據(jù)model類生成表,但是sessionFactory一關(guān)閉,表就自動(dòng)刪除。
# update:最常用的屬性,第一次加載hibernate時(shí)根據(jù)model類會(huì)自動(dòng)建立起表的結(jié)構(gòu)(前提是先建立好數(shù)據(jù)庫(kù)),以后加載hibernate時(shí)根據(jù)model類自動(dòng)更新表結(jié)構(gòu),即使表結(jié)構(gòu)改變了但表中的行仍然存在不會(huì)刪除以前的行。
#要注意的是當(dāng)部署到服務(wù)器后,表結(jié)構(gòu)是不會(huì)被馬上建立起來(lái)的,是要等應(yīng)用第一次運(yùn)行起來(lái)后才會(huì)。
# validate:每次加載hibernate時(shí),驗(yàn)證創(chuàng)建數(shù)據(jù)庫(kù)表結(jié)構(gòu),只會(huì)和數(shù)據(jù)庫(kù)中的表進(jìn)行比較,不會(huì)創(chuàng)建新表,但是會(huì)插入新值。
3. 編寫與數(shù)據(jù)庫(kù)對(duì)應(yīng)的實(shí)體類
@Data
@Entity
@Table(name="tb_user")
public class TbUser {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@NotEmpty(message = "不能為空,不能為null")
@Column(name = "username",nullable = false, length = 20)
private String username;
@Column(name = "password",nullable = false, length = 100)
private String password;
@Column(name = "role",nullable = false, length = 100)
private String role;
private Date createTime;
}
4. 編寫dao接口
public interface TbUserDao extends JpaRepository<TbUser,Integer> {
}
5. 編寫service接口
public interface TbUserService {
TbUser addUser(TbUser tbUser);
void deleteUserById(Integer id);
TbUser findUserById(Integer id);
List<TbUser> users();
}6. 編寫service實(shí)現(xiàn)類
@Service
public class TbUserServiceImpl implements TbUserService {
@Resource
TbUserDao userDao;
@Override
public TbUser addUser(TbUser tbUser){
TbUser user = userDao.save(tbUser);
return user;
}
@Override
public void deleteUserById(Integer id) {
userDao.deleteById(id);
}
@Override
public TbUser findUserById(Integer id) {
TbUser user = userDao.findById(id).get();
return user;
}
@Override
public List<TbUser> users() {
List<TbUser> users = userDao.findAll();
return users;
}
}
7. 編寫controller
@RestController
public class TbUserController {
@Resource
TbUserService userService;
@PostMapping("/add")
public TbUser addUser(TbUser tbUser){
TbUser user = userService.addUser(tbUser);
user.setCreateTime(new Date());
System.out.println("user = " + user);
return user;
}
@PostMapping("/delete/{id}")
public void deleteUserById(@PathVariable(value = "id") Integer id){
userService.deleteUserById(id);
}
@GetMapping("/user/{id}")
public TbUser findUserById(@PathVariable(value = "id") Integer id){
TbUser user = userService.findUserById(id);
return user;
}
@GetMapping("/findAll")
public List<TbUser> users(){
List<TbUser> users = userService.users();
System.out.println("users = " + users);
return users;
}
}
上一篇: SQL語(yǔ)句的分類之DDL