0%

Spring Data JPA 在 Spring Boot 中的应用

1.JPA

JPA (Java Persistence API) 是 Sun 官方提出的 Java 持久化规范。它为 Java 开发人员提供了一种对象 / 关联映射工具来管理 Java 应用中的关系数据。他的出现主要是为了简化现有的持久化开发工作和整合 ORM 技术,结束现在 Hibernate,TopLink,JDO 等 ORM 框架各自为营的局面。值得注意的是,JPA 是在充分吸收了现有 Hibernate,TopLink,JDO 等 ORM 框架的基础上发展而来的,具有易于使用,伸缩性强等优点。JPA 是一套规范,不是一套产品,那么像 Hibernate,TopLink,JDO 他们是一套产品,如果说这些产品实现了这个 JPA 规范,那么我们就可以叫他们为 JPA 的实现产品。

2. 项目搭建

本文采用 IDEA 搭建 Spring Boot 的 JPA 应用,Demo 结构图如下:

jpa-1.png

3. 具体实现

3.1 配置文件

  • pom.xml 里加入 spring-boot-starter-data-jpa 以及 mysql-connector-java 的依赖,如下所示。
1
2
3
4
5
6
7
8
9
10
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>6.0.6</version>
</dependency>
  • application.yml 里加入 hibernate、jpa 的配置,以及返回 json 对日期字段的特殊处理配置,注意 time-zone 的设置,须与 mysql 的 url 配置一致,否则会引起时间相差 8 小时的问题。jpa 里的 show-sql 作用,如果设置为 true,执行程序后可以看在控制台里看到 sql 语句,如下所示。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
spring:
profiles:
active: product
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/saascrm?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC
username: root
password: snail123
jpa:
hibernate:
ddl-auto: update
show-sql: true
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: UTC

3.2 分层

为了区别各个模块,为项目建立几个包:controller、Entity、respository、service,这是典型的 MVC 架构,各个层次的代表意义在此不再赘述。

3.3 Respository 层

spring data jpa 让我们解脱了 DAO 层的操作,基本上所有 CRUD 都可以依赖于它来实现,需要实现 JpaRepository 接口

1
2
public interface UserRepository extends JpaRepository<UserInfo,Long> {
}

3.4 Entity 层

定义了用户信息表实体 UserInfo,通过 Hibernate 与数据库形成映射关系,如下:

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
43
44
45
46
47
48
@Entity
@Component
public class UserInfo {
public UserInfo() {
}

@Id
@GeneratedValue
public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}


public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}


public String getJobNumber() {
return jobNumber;
}

public void setJobNumber(String jobNumber) {
this.jobNumber = jobNumber;
}

public Date getCreateTime() {
return createTime;
}

public void setCreateTime(Date createTime) {
this.createTime = createTime;
}

private Long id; //ID
private String name; //姓名
private String jobNumber; //工号
private Date createTime; //创建时间

}

3.5 service 层

定义了服务层接口以及服务层接口实现类,如下:

  • UserService.java
1
2
3
4
5
6
7
8
9
public interface UserService {
List<UserInfo> getUserList();
UserInfo getUserByName(String name);
UserInfo addUserInfo(UserInfo userInfo);
UserInfo updateUserInfoById(UserInfo userInfo);
void deleteUserInfoById(Long Id);
List<UserInfo>getCurrentUserList();
Page<UserInfo> getPageUserList();
}
  • UserServiceImpl.java
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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
@Service
public class UserServiceImpl implements UserService{
@Autowired
private UserRepository userRepository;

/**
* 获取所有用户列表
* @return
*/
public List<UserInfo> getUserList(){
List<UserInfo> userList=new ArrayList<UserInfo>();
userList=userRepository.findAll();
return userList;
}

/**
* 通过姓名获取用户信息
* @param name 用户姓名
* @return
*/
public UserInfo getUserByName(String name) {
return userRepository.findByName(name);
}

/**
* 新增用户信息
* @param userInfo 用户信息
* @return
*/
public UserInfo addUserInfo(UserInfo userInfo) {
return userRepository.save(userInfo);
}

/**
* 更新用户信息
* @param userInfo 用户信息
* @return
*/
public UserInfo updateUserInfoById(UserInfo userInfo) {
return userRepository.save(userInfo);
}

/**
* 删除用户信息
* @param id 主键Id
*/
public void deleteUserInfoById(Long id) {
userRepository.delete(id);
}

/**
* 获取最新的用户
* @return
*/
public List<UserInfo> getCurrentUserList() {
Sort sort=new Sort(Sort.Direction.DESC,"createTime");
return userRepository.findAll(sort);

}

/**
* 获取分页的用户
* @return
*/
public Page<UserInfo> getPageUserList() {
Sort sort=new Sort(Sort.Direction.DESC,"createTime");
Pageable pageable=new PageRequest(0,5,sort);
return userRepository.findAll(pageable);
}

}

3.6 Controller 层

其中,日期格式需要做转换,在需要日期转换的 Controller 中使用 SpringMVC 的注解 @initbinder 和 Spring 自带的 WebDateBinder 类来操作。WebDataBinder 是用来绑定请求参数到指定的属性编辑器。由于前台传到 controller 里的值是 String 类型的,当往 Model 里 Set 这个值的时候,如果 set 的这个属性是个对象,Spring 就会去找到对应的 editor 进行转换,然后再 SET 进去。

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
43
44
45
46
47
48
49
50
51
52
53
54
55
@RestController
@RequestMapping(value = "/test")
public class TestController {

@Autowired
private UserInfo userInfo;

@Resource
private UserService userService;

/**
* 获取所有用户
* @return
*/
@GetMapping(value = "/getUserList")
public List<UserInfo> getUserList() {
return userService.getUserList();
}

@GetMapping(value = "/getUserInfo")
public UserInfo getUserInfoByName(@RequestParam("name") String name) {
return userService.getUserByName(name);
}

@GetMapping(value = "/getCurrentUserList")
public List<UserInfo> getCurrentUserList(){
return userService.getCurrentUserList();
}

@GetMapping(value="/getPageUserList")
public Page<UserInfo> getPageUserList(){
return userService.getPageUserList();
}

@PutMapping(value = "/addUserInfo")
public UserInfo addUserInfo(UserInfo userInfo) {
return userService.addUserInfo(userInfo);
}

@PostMapping(value ="/updateUserInfo")
public UserInfo updateUserInfo(UserInfo userInfo){
return userService.updateUserInfoById(userInfo);
}

@PostMapping(value="/deleteUserInfo")
public void deleteUserInfo(@RequestParam("id") Long id){
userService.deleteUserInfoById(id);
}

@InitBinder
protected void init(HttpServletRequest request, ServletRequestDataBinder binder) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));/*TimeZone时区,解决差8小时的问题*/
binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false));
}

4. 测试

  1. Http 定义了与服务器交互的不同方法,最基本的方法有 4 种,分别是 GET,POST,PUT,DELETE。URL 全称是资源描述符,我们可以这样认为:一个 URL 地址,它用于描述一个网络上的资源,而 HTTP 中的 GET,POST,PUT,DELETE 就对应着对这个资源的查,改,增,删 4 个操作。

  2. 本文借助 PostMan 工具进行测试,如下图所示。(注意事项,如果选择 PUT 请求,那么只能选 x-www-form-urlencoded)

jpa-2.png

Powered By Valine
v1.5.2