两张表(多对多关联)操作 with Spring Boot, Spring Data JPA, H2
2017-03-21 10:25
651 查看
转自:http://blog.csdn.net/lewis_007/article/details/53006602
这里通过一个完整的例子展示如何通过
JDK 8+
Maven 3+
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
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
[/code]
2
3
4
5
1
2
3
4
5
[/code]
2
3
4
5
6
7
8
9
10
11
12
13
1
2
3
4
5
6
7
8
9
10
11
12
13
[/code]
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
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
[/code]
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
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
[/code]
2
3
4
5
6
7
8
9
10
11
1
2
3
4
5
6
7
8
9
10
11
[/code]
2
3
4
5
6
7
8
9
10
11
1
2
3
4
5
6
7
8
9
10
11
[/code]
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
110
111
112
113
114
115
116
117
118
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
110
111
112
113
114
115
116
117
118
[/code]
1
[/code]
源码地址: https://github.com/lewis007/jpa-manytomany-springboot-h2.git
博客地址: http://blog.csdn.net/lewis_007/article/details/53006602
参考网址: http://www.cnblogs.com/luxh/archive/2012/05/30/2527123.html
这里通过一个完整的例子展示如何通过
JPA对两张表(多对多关联)进行增删改查操作。
前提
JDK 8+Maven 3+
表结构
例子
创建 Maven 项目
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.lewis.demos</groupId> <artifactId>jpa-manytomany-springboot-h2</artifactId> <version>0.0.1-SNAPSHOT</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.4.1.RELEASE</version> </parent> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>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
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
[/code]
src/main/resources/application.properties
## JPA Settings spring.jpa.generate-ddl: true spring.jpa.hibernate.ddl-auto: create-drop spring.jpa.properties.hibernate.format_sql: true spring.jpa.show-sql: true1
2
3
4
5
1
2
3
4
5
[/code]
src/main/Java/hello/Application.java
package hello; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }1
2
3
4
5
6
7
8
9
10
11
12
13
1
2
3
4
5
6
7
8
9
10
11
12
13
[/code]
创建实体
src/main/java/hello/domain/Book.java
package hello.domain; import java.io.Serializable; import java.util.Set; import javax.persistence.CascadeType; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.JoinTable; import javax.persistence.ManyToMany; @Entity public class Book implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue private Integer id; private String name; @ManyToMany(cascade = CascadeType.ALL) @JoinTable(name = "BOOK_AUTHOR", joinColumns = { @JoinColumn(name = "BOOK_ID", referencedColumnName = "ID") }, inverseJoinColumns = { @JoinColumn(name = "AUTHOR_ID", referencedColumnName = "ID") }) private Set<Author> authors; public Book() { super(); } public Book(String name) { super(); this.name = name; } public Book(String name, Set<Author> authors) { super(); this.name = name; this.authors = authors; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Set<Author> getAuthors() { return authors; } public void setAuthors(Set<Author> authors) { this.authors = authors; } @Override public String toString() { return String.format("Book [id=%s, name=%s, authors=%s]", id, name, authors); } }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
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
[/code]
src/main/java/hello/domain/Author.java
package hello.domain; import java.io.Serializable; import java.util.Set; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.ManyToMany; @Entity public class Author implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue private Integer id; private String name; @ManyToMany(mappedBy = "authors") private Set<Book> books; public Author() { super(); } public Author(String name) { super(); this.name = name; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Set<Book> getBooks() { return books; } public void setBooks(Set<Book> books) { this.books = books; } @Override public String toString() { return String.format("Author [id=%s, name=%s, books=%s]", id, name, books); } }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
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
[/code]
创建 Repository
src/main/java/hello/repository/BookRepository.java
package hello.repository; import org.springframework.data.jpa.repository.JpaRepository; import hello.domain.Book; public interface BookRepository extends JpaRepository<Book, Integer> { public Book findByName(String name); }1
2
3
4
5
6
7
8
9
10
11
1
2
3
4
5
6
7
8
9
10
11
[/code]
src/main/java/hello/repository/AuthorRepository.java
package hello.repository; import org.springframework.data.jpa.repository.JpaRepository; import hello.domain.Author; public interface AuthorRepository extends JpaRepository<Author, Integer> { public Author findByName(String name); }1
2
3
4
5
6
7
8
9
10
11
1
2
3
4
5
6
7
8
9
10
11
[/code]
单元测试
编写单元测试
src/test/java/hello/BookTests.java
package hello; import static org.assertj.core.api.Assertions.assertThat; import java.util.Arrays; import java.util.HashSet; import java.util.Set; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; import org.springframework.test.context.junit4.SpringRunner; import hello.domain.Author; import hello.domain.Book; import hello.repository.AuthorRepository; import hello.repository.BookRepository; @RunWith(SpringRunner.class) @DataJpaTest public class BookTests { @Autowired private BookRepository bookRepository; @Autowired private AuthorRepository authorRepository; @Before public void save() { Author lewis = new Author("Lewis"); Author mark = new Author("Mark"); Author peter = new Author("Peter"); Set<Author> springs = new HashSet<>(); springs.addAll(Arrays.asList(lewis, mark)); Book spring = new Book("Spring in Action", springs); Set<Author> springboots = new HashSet<>(); springboots.addAll(Arrays.asList(lewis, peter)); Book springboot = new Book("Spring Boot in Action", springboots); bookRepository.save(Arrays.asList(spring, springboot)); } @After public void deleteAll() { bookRepository.deleteAll(); } @Test public void findAll() { assertThat(bookRepository.findAll()).hasSize(2); assertThat(authorRepository.findAll()).hasSize(3); } @Test public void findByName() { assertThat(bookRepository.findByName("Spring in Action")).isNotNull(); assertThat(authorRepository.findByName("Lewis")).isNotNull(); } @Test public void deleteBook() { Book springboot = bookRepository.findByName("Spring Boot in Action"); assertThat(springboot).isNotNull(); bookRepository.delete(springboot); assertThat(bookRepository.findAll()).hasSize(1); assertThat(authorRepository.findAll()).hasSize(2); assertThat(authorRepository.findByName("Peter")).isNull(); } @Test public void removeAuthor() { Book springboot = bookRepository.findByName("Spring Boot in Action"); assertThat(springboot).isNotNull(); Author peter = authorRepository.findByName("Peter"); assertThat(peter).isNotNull(); springboot.getAuthors().remove(peter); bookRepository.save(springboot); assertThat(authorRepository.findByName("Peter")).isNotNull(); assertThat(bookRepository.findByName("Spring Boot in Action").getAuthors()).hasSize(1); } @Test public void marge() { Book springboot = bookRepository.findByName("Spring Boot in Action"); assertThat(springboot).isNotNull(); springboot.setName("Spring Boot in Action (1st Edition)"); Author lewis = authorRepository.findByName("Lewis"); assertThat(lewis).isNotNull(); Author jacob = new Author("Jacob"); Set<Author> springboots = new HashSet<>(); springboots.addAll(Arrays.asList(lewis, jacob)); springboot.setAuthors(springboots); bookRepository.save(springboot); assertThat(bookRepository.findByName("Spring Boot in Action")).isNull(); assertThat(bookRepository.findByName("Spring Boot in Action (1st Edition)").getAuthors()).hasSize(2); assertThat(authorRepository.findAll()).hasSize(4); assertThat(authorRepository.findByName("Peter")).isNotNull(); assertThat(authorRepository.findByName("Jacob")).isNotNull(); } }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
110
111
112
113
114
115
116
117
118
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
110
111
112
113
114
115
116
117
118
[/code]
执行测试用例
mvn clean test1
1
[/code]
资源
源码地址: https://github.com/lewis007/jpa-manytomany-springboot-h2.git博客地址: http://blog.csdn.net/lewis_007/article/details/53006602
参考网址: http://www.cnblogs.com/luxh/archive/2012/05/30/2527123.html
相关文章推荐
- Spring boot结合Spring-Data-JPA操作MySQL数据库
- SpringBoot入门(三)--数据库操作&&Spring-data-jpa的使用
- springboot学习-springboot使用spring-data-jpa操作MySQL数据库
- Spring Boot with Spring Data JPA (1) - Concept
- Spring-boot中使用Spring-data-jpa操作DB
- Spring Boot (五)Spring Data JPA 操作 MySQL 8
- 在spring Boot中使用Spring-data-jpa操作数据库
- • Spring Boot 进 阶- 数 据 访 问-使用spring-data-jpa 操作数据库
- SpringBoot项目 使用Sprin Data Jpa 实现数据库的 增 ,删, 改, 查操作
- Distributed transactions with multiple databases, Spring Boot, Spring Data JPA and Atomikos
- SpringBoot操作之Spring-Data-Jpa(二)CRUD实现
- SpringBoot项目 使用Sprin Data Jpa 操作数据库
- spring data jpa boot thymeleaf hibernate manytoone 双向关联 java.lang.StackOverflowError: null
- springboot使用spring-data-jpa操作MySQL数据库
- SpringBoot Data JPA 关联表查询的方法
- SpringBoot使用Spring-Data-Jpa实现CRUD操作
- SpringBoot操作之Spring-Data-Jpa(一)
- 在spring Boot中使用Spring-data-jpa操作数据库
- SpringBoot学习(五)操作数据库Spring-Data-JPA
- Distributed transactions with multiple databases, Spring Boot, Spring Data JPA and Atomikos