文章使用版本為 Spring Boot 2.1.x
前言
JPA是Java Persistence API的簡稱,是一種標(biāo)準(zhǔn)鳖悠,具體實(shí)現(xiàn)交由各個(gè)廠商實(shí)現(xiàn)。Spring Data JPA 對其提供支持聋涨,內(nèi)部實(shí)現(xiàn)是Hibernate芙扎。
使用JPA開發(fā)代碼非常方便,只要寫一個(gè)接口繼承 JpaRepository
就可以實(shí)現(xiàn)基本的增刪改查的功能胚宦,比如下面這樣
public interface UserRepository extends JpaRepository<User, String> {
}
在大部分情況下都是使用單表操作時(shí)首有,使用JPA也是一個(gè)不錯(cuò)的選擇,下面我們就來一起學(xué)習(xí)下吧枢劝。
添加依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
application.yml
spring:
datasource:
url: jdbc:mysql://127.0.0.1:3306/spring_boot_learn?useUnicode=true&characterEncoding=utf8&allowMultiQueries=true&autoReconnect=true&useSSL=true
driver-class-name: com.mysql.jdbc.Driver
username: root
password: root
hikari:
minimum-idle: 2
maximum-pool-size: 5
jpa:
show-sql: true
hibernate:
ddl-auto: update
datasource的部分就不多講了井联,我們主要來看一下jpa的配置部分
- jpa.show-sql:這個(gè)很明顯是控制是否顯示SQL語句的,開發(fā)時(shí)我們可以選擇true
-
jpa.hibernate.ddl-auto:這個(gè)是用來控制數(shù)據(jù)庫表的生成策略您旁,有以下幾種值
- create:每次加載hibernate時(shí)都會刪除上一次的生成的表烙常,然后根據(jù)你的model類再重新來生成新表,哪怕兩次沒有任何改變也要這樣執(zhí)行鹤盒,這就是導(dǎo)致數(shù)據(jù)庫表數(shù)據(jù)丟失的一個(gè)重要原因蚕脏。
- create-drop:每次加載hibernate時(shí)根據(jù)model類生成表侦副,但是sessionFactory一關(guān)閉,表就自動刪除。
- update:最常用的屬性蝗锥,第一次加載hibernate時(shí)根據(jù)model類會自動建立起表的結(jié)構(gòu)(前提是先建立好數(shù)據(jù)庫)跃洛,以后加載hibernate時(shí)根據(jù)model類自動更新表結(jié)構(gòu),即使表結(jié)構(gòu)改變了但表中的行仍然存在不會刪除以前的行终议。要注意的是當(dāng)部署到服務(wù)器后,表結(jié)構(gòu)是不會被馬上建立起來的葱蝗,是要等應(yīng)用第一次運(yùn)行起來后才會穴张。
- validate:每次加載hibernate時(shí),驗(yàn)證創(chuàng)建數(shù)據(jù)庫表結(jié)構(gòu)两曼,只會和數(shù)據(jù)庫中的表進(jìn)行比較皂甘,不會創(chuàng)建新表,但是會插入新值悼凑。
雖然可以讓程序自動生成表結(jié)構(gòu)偿枕,但是我還是建議手寫建表語句。
CREATE SCHEMA IF NOT EXISTS `spring_boot_learn` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;
CREATE TABLE IF NOT EXISTS `spring_boot_learn`.`user` (
`id` VARCHAR(37) NOT NULL COMMENT 'UUID',
`username` VARCHAR(128) NOT NULL COMMENT '用戶名',
`age` INT(10) unsigned NOT NULL COMMENT '年齡',
PRIMARY KEY (`id`) COMMENT ''
)
ENGINE = InnoDB
COMMENT = '用戶表';
創(chuàng)建實(shí)體
package org.schhx.springbootlearn.entity;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.persistence.Entity;
import javax.persistence.Id;
@Data
@Accessors(chain = true)
@Entity
public class User {
@Id
private String id;
private String username;
private Integer age;
}
@Entity 表明是一個(gè)實(shí)體類
@Id 用來指明主鍵户辫,如果使用自增主鍵渐夸,可以在主鍵上加上@GeneratedValue
創(chuàng)建數(shù)據(jù)訪問接口
package org.schhx.springbootlearn.dao;
import org.schhx.springbootlearn.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
public interface UserRepository extends JpaRepository<User, String> {
List<User> findByUsername(String username);
}
通過查看 JpaRepository 的源碼我們可以發(fā)現(xiàn),通用的增刪改查的方法都已經(jīng)有了渔欢,當(dāng)然你也可以自己寫一些方法墓塌,比如 List<User> findByUsername(String username)
,JPA會自動根據(jù)方法名來創(chuàng)建實(shí)現(xiàn)奥额。
測試
package org.schhx.springbootlearn.dao;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.schhx.springbootlearn.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.Example;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.UUID;
import static org.junit.Assert.*;
@RunWith(SpringRunner.class)
@SpringBootTest
public class UserRepositoryTest {
@Autowired
private UserRepository userRepository;
@Test
@Transactional
public void create() throws Exception {
String id = UUID.randomUUID().toString();
User user = new User().setId(id).setUsername("張三").setAge(20);
User result = userRepository.save(user);
System.out.println(result);
Assert.assertNotEquals(null, result);
}
@Test
@Transactional
public void findByUserName() throws Exception {
String id = UUID.randomUUID().toString();
User user = new User().setId(id).setUsername("張三").setAge(20);
userRepository.save(user);
List<User> result = userRepository.findByUsername("張三");
System.out.println(result);
Assert.assertNotEquals(null, result);
}
@Test
@Transactional
public void findByExample() throws Exception {
String id = UUID.randomUUID().toString();
User user = new User().setId(id).setUsername("張三").setAge(20);
userRepository.save(user);
List<User> result = userRepository.findAll(Example.of(new User().setUsername("張三")));
System.out.println(result);
Assert.assertNotEquals(null, result);
}
}