Spring Data JPA 提供了很多强大的数据操作,本示例以Spring Boot + JPA + My SQL 来演示默认提供最基础的接口和方法对数据的操作。

演示的版本:

  1. Spring Boot 2.0.4.RELEASE
  2. My SQL 5.*

1、简介

Spring 在数据的操作上,提供以 Repository 为基础接口,CrudRepositoryPagingAndSortingRepositoryJpaRepository 为子接口,作为Spring Data JPA操作的核心。
其中继承关系是 Repository <-CrudRepository <- PagingAndSortingRepository <- JpaRepository.

2、依赖

添加相关的JPA 和 数据库的连接jar包 :

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>
<scope>runtime</scope>
</dependency>

3、配置

application.yml/application.properties 配置我们的数据连接信息:

1
2
3
4
5
6
7
8
9
10
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf8
username: root
password: #password
jpa:
hibernate:
ddl-auto: update
show-sql: true

4、 实体Entity

以但表Person作为实体类:

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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
package com.devnp.entity ;

import java.util.Date;

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

@Entity
public class Person {

@Id
@GeneratedValue
private int id ;

@Column(name = "LastName")
private String lastName ;

@Column(name = "FirstName")
private String firstName ;

@Column(name = "Age")
private int age ;

@Column(name = "Birth")
@Temporal(TemporalType.DATE)
private Date birth ;

@Column(name = "Salary")
private double salary ;

public Person() {
super();
}


public Person(int id) {
super();
this.id = id;
}

public Person(String lastName, String firstName, int age, Date birth, double salary) {
super();
this.lastName = lastName;
this.firstName = firstName;
this.age = age;
this.birth = birth;
this.salary = salary;
}

public int getId() {
return id;
}

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

public String getLastName() {
return lastName;
}

public void setLastName(String lastName) {
this.lastName = lastName;
}

public String getFirstName() {
return firstName;
}

public void setFirstName(String firstName) {
this.firstName = firstName;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

public Date getBirth() {
return birth;
}

public void setBirth(Date birth) {
this.birth = birth;
}

public double getSalary() {
return salary;
}

public void setSalary(double salary) {
this.salary = salary;
}

@Override
public String toString() {
return "Person [id=" + id + ", lastName=" + lastName + ", firstName=" + firstName + ", age=" + age + ", birth="
+ birth + ", salary=" + salary + "]";
}


}

5、CrudRepository

CrudRepository 为我们常用的增删查改提供相应的功能,CrudPersonRepository 继承 CrudPersonRepository接口:

1
2
3
4
5
6
7
8
9
package com.devnp.repository;

import org.springframework.data.repository.CrudRepository;

import com.devnp.entity.Person;

public interface CrudPersonRepository extends CrudRepository<Person, Integer> {

}

利用单元测试对其常用的方法进行测试:
CrudPersonRepositoryTests:

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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
package com.devnp.repository;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import com.devnp.entity.Person;

@RunWith(SpringRunner.class)
@SpringBootTest
public class CrudPersonRepositoryTests {

@Autowired
private CrudPersonRepository crudPersonRepository;

/**
* 保存或者更新单个对象
* 根据ID判断对象是否存在,然后决定进行更新或者保存
*/
@Test
public void testSave() {
System.out.println(crudPersonRepository.save(new Person("DU", "LIU" , 18, new Date(), 55522.12)));
}

/**
* 保存或者更新多个对象
* 根据ID判断对象是否存在,然后决定进行更新或者保存
*/
@Test
public void testSaveAll() {
List<Person> list = new ArrayList<>();

list.add(new Person("NAME-1", "JACK" , 20, new Date(), 6000.00));
list.add(new Person("NAME-2", "TOME" , 18, new Date(), 7000.12));

crudPersonRepository.saveAll(list).forEach(System.out::println);
}

/**
* 根据主键进行查询
*/
@Test
public void testFindById() {
System.out.println(crudPersonRepository.findById(10).get());
}

/**
* 根据查询全部数据
*/
@Test
public void testFindAll() {
Iterable<Person> persons = crudPersonRepository.findAll();

persons.forEach(System.out::println);
}

/**
* 根据主键判断是否存在
*/
@Test
public void testExistsById() {
System.out.println(crudPersonRepository.existsById(10));
}

/**
* 根据主键删除记录
* 先会根据ID去查询对象,然后在进行删除操作
*/
@Test
public void testDeleteById() {
crudPersonRepository.deleteById(11);
}

/**
* 根据对象进行删除
*/
@Test
public void testDelete() {
crudPersonRepository.delete(new Person(12));
}



}

6、PagingAndSortingRepository

PagingAndSortingRepositoryCrudRepository 的基础上还提供了排序和分页查询方法,PagingPersonRepository 继承 PagingAndSortingRepository

```java
package com.devnp.repository;

import org.springframework.data.repository.PagingAndSortingRepository;

import com.devnp.entity.Person;

public interface PagingPersonRepository extends PagingAndSortingRepository<Person, Integer> {

}

编写测试类,对相应的排序和分页进行测试 PagingPersonRepositoryTests.java

```java
package com.devnp.repository;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest
public class PagingPersonRepositoryTests {

@Autowired
private PagingPersonRepository pagingPersonRepository ;

/**
 * 查询有数据,并根据条件进行排序
 */
@Test
public void testFindAllBySort() {

    pagingPersonRepository.findAll(new Sort(Direction.DESC, "id")).forEach(System.out::println);
}

/**
 * 查询有数据,并根据条件进行分页
 */
@Test
public void testFindAllByPaging() {
    pagingPersonRepository.findAll(PageRequest.of(0, 2)).forEach(System.out::println);
}

}

7、JpaRepository

继承了 PagingAndSortingRepositoryCrudRepository 的方法同时,还引进了flushdelete*batch 这样的操作,同时也改写一个方法的参数类型。

参考

https://projects.spring.io/spring-data-jpa/

代码

spring-boot-jpa-basic