LHJ's Blog

💠 SpringBoot JPA

💬 JPA简介

JPA(Java Persistence API)是由Sun公司提出的Java持久层规范,为Java开发人员提供了一套对象/关系映射规范工具来操作关系数据,它的意义在于简化现有的持久层开发以及整理ORM技术,结束各个ORM框架各自一套的局面。

JPA仅仅是一种规范,不是一套产品,Hibernate就是实现了JPA规范的一套产品

Spring Data JPA是Spring在ORM框架和JPA规范上开发出来的一款产品,是基于Hibernate之上构建的一款操作关系数据的工具,以更为简介的代码实现CRUD操作。

🎄 使用JPA

♻ 引入必要的依赖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.48</version>
</dependency>

📑 修改配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
server:
port: 8080
servlet:
context-path: /

spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/springboot?useSSL=false&serverTimezone=UTC&characterEncoding=utf-8
username: root
password: root
jpa:
hibernate:
ddl-auto: update
show-sql: true

ddl-auto一共有四个值,分别是:createcreate-dropupdatevalidate

🔹 create: 每次启动应用的时候都会删除表,然后根据Model重新生成表,即使Model没有变化也会这么做。有 可能会导致数据丢失

🔹 create-drop: 每次启动的时候会根据Model生成表,应用停止后就会立刻删除表

🔹 update: 第一次运行的时候根据Model生成表(前提是数据库存在),应用结束或重启不会删除表,如果Model发生变化会自动更新表(不会删除表中已有的数据)。需要注意的是,部署以后表并不会立刻创建好,二是需要等第一次访问操作的时候才会开始建表

🔹 validate: 每次启动的时候会验证数据库表结构,不会创建和删除表

🐶 创建实体类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
package com.longhujing.springboot.study.jpa.entity;

import lombok.Data;

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

/**
* @author longhujing
*/
@Data
@Entity
public class UserEntity {

/**
* 主键id
*/
@Id
@GeneratedValue
private Long id;

/**
* 用户名
*/
@Column(nullable = false, unique = true)
private String name;

/**
* 年龄
*/
@Column(nullable = false)
private int age;

/**
* 邮箱
*/
@Column(nullable = false, unique = true)
private String email;

}

☕ 创建数据库访问层

1
2
3
4
5
6
7
8
9
10
11
12
package com.longhujing.springboot.study.jpa.dao;

import com.longhujing.springboot.study.jpa.entity.UserEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

/**
* @author longhujing
*/
@Repository
public interface UserRepository extends JpaRepository<UserEntity, Long> {
}

🃏 测试使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package com.longhujing.springboot.study.jpa;

import com.longhujing.springboot.study.jpa.dao.UserRepository;
import com.longhujing.springboot.study.jpa.entity.UserEntity;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;

@SpringBootTest
class SpringbootStudyJpaApplicationTests {

@Autowired
private UserRepository userRepository;

@Test
void contextLoads() {
userRepository.save(new UserEntity(1L, "zhangsan", 13, "zhangsan@longhujing.com"));
userRepository.save(new UserEntity(2L, "lisi", 13, "lisi@longhujing.com"));
userRepository.save(new UserEntity(3L, "wangwu", 13, "wangwu@longhujing.com"));
userRepository.save(new UserEntity(4L, "zhaoliu", 13, "zhaoliu@longhujing.com"));

List<UserEntity> users = userRepository.findAll();
Assertions.assertEquals(4, users.size());
}

}

🎯 自定义查询

JPARepository提供了很多通用的接口,但有的时候并不能完全满足我们的需求,比如提供的接口里面就没有通过用户名/邮箱查找用户的。

Spring Data JPA提供了通过属性名来实现数据库操作,其主要的语法规则是find***Byread***Byquery***Bycount***Byget***By,后面接上在Entity中的属性名称,Spring Data JPA会自动帮我们实现。

expample:

UserRepository中添加以下接口

1
UserEntity findUserEntityByEmail(String email);

测试使用

1
2
3
4
5
6
@Test
void testDIYQuery(){
UserEntity userEntity = userRepository.findUserEntityByEmail("lisi@longhujing.com");

Assertions.assertEquals("lisi", userEntity.getName());
}

当然这种方法也有很大的限制,对于比较复杂的情况就不得不自己写SQL实现了。

example:

UserRepository中添加以下接口

1
2
3
4
@Transactional
@Modifying
@Query("DELETE FROM user_entity WHERE name = ?1")
void deleteUserEntityByName(String name);

其中的?1,?表示的是占位符,1是第几个参数

测试使用

1
2
3
4
5
6
7
@Test
void testDIYDelete(){
userRepository.deleteUserEntityByName("lisi");

List<UserEntity> users = userRepository.findAll();
Assertions.assertEquals(3, users.size());
}

📑 源码地址

Github



 评论