Skip to content

Commit eba83c6

Browse files
committed
learning spring data jpa
1 parent 6390c30 commit eba83c6

File tree

7 files changed

+298
-5
lines changed

7 files changed

+298
-5
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package datajpa.dto;
2+
3+
import lombok.AllArgsConstructor;
4+
import lombok.Data;
5+
6+
@Data
7+
@AllArgsConstructor
8+
public class MemberDto {
9+
10+
private Long id;
11+
private String username;
12+
private String teamName;
13+
}

book/spring-data-jpa/src/main/java/datajpa/entity/Member.java

+10
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import javax.persistence.Id;
88
import javax.persistence.JoinColumn;
99
import javax.persistence.ManyToOne;
10+
import javax.persistence.NamedQuery;
1011

1112
import lombok.AccessLevel;
1213
import lombok.Getter;
@@ -19,6 +20,10 @@
1920
@Setter
2021
@NoArgsConstructor(access = AccessLevel.PROTECTED)
2122
@ToString(of = { "id", "username", "age" })
23+
@NamedQuery(
24+
name = "Member.findWithNamedQuery",
25+
query = "select m from Member m where m.username = :username"
26+
)
2227
public class Member {
2328

2429
@Id
@@ -38,6 +43,11 @@ public Member(String username) {
3843
this.username = username;
3944
}
4045

46+
public Member(String username, int age) {
47+
this.username = username;
48+
this.age = age;
49+
}
50+
4151
public Member(String username, int age, Team team) {
4252
this.username = username;
4353
this.age = age;

book/spring-data-jpa/src/main/java/datajpa/repository/MemberJpaRepository.java

+29
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,33 @@ public List<Member> findAll() {
3838
return em.createQuery("select m from Member m", Member.class)
3939
.getResultList();
4040
}
41+
42+
public List<Member> findByUsernameAndAgeGreaterThan(String username, int age) {
43+
return em.createQuery("select m from Member m where m.username = :username and m.age > :age",
44+
Member.class)
45+
.setParameter("username", username)
46+
.setParameter("age", age)
47+
.getResultList();
48+
}
49+
50+
public List<Member> findWithNamedQuery(String username) {
51+
return em.createNamedQuery("Member.findWithNamedQuery", Member.class)
52+
.setParameter("username", username)
53+
.getResultList();
54+
}
55+
56+
public List<Member> findByPage(int age, int offset, int limit) {
57+
return em.createQuery("select m from Member m where m.age = :age order by m.username desc",
58+
Member.class)
59+
.setParameter("age", age)
60+
.setFirstResult(offset)
61+
.setMaxResults(limit)
62+
.getResultList();
63+
}
64+
65+
public long totalCount(int age) {
66+
return em.createQuery("select count(m) from Member m where m.age = :age", Long.class)
67+
.setParameter("age", age)
68+
.getSingleResult();
69+
}
4170
}
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,50 @@
11
package datajpa.repository;
22

3+
import java.util.Collection;
4+
import java.util.List;
5+
import java.util.Optional;
6+
7+
import org.springframework.data.domain.Page;
8+
import org.springframework.data.domain.Pageable;
39
import org.springframework.data.jpa.repository.JpaRepository;
10+
import org.springframework.data.jpa.repository.Query;
11+
import org.springframework.data.repository.query.Param;
412

13+
import datajpa.dto.MemberDto;
514
import datajpa.entity.Member;
615

716
public interface MemberRepository extends JpaRepository<Member, Long> {
8-
}
17+
18+
List<Member> findByUsernameAndAgeGreaterThan(String username, int age);
19+
20+
// 어노테이션이 없어도 됨
21+
@Query(name = "Member.findWithNamedQuery")
22+
List<Member> findWithNamedQuery(@Param("username") String username);
23+
24+
@Query("select m from Member m where m.username = :username and m.age = :age")
25+
List<Member> findUser(@Param("username") String username, @Param("age") int age);
26+
27+
@Query("select m.username from Member m")
28+
List<String> findUsernameList();
29+
30+
@Query("select new datajpa.dto.MemberDto(m.id, m.username, t.name) from Member m join m.team t")
31+
List<MemberDto> findMemberDto();
32+
33+
@Query("select m from Member m where m.username in :names")
34+
List<Member> findByNames(@Param("names") Collection<String> names);
35+
36+
// 반환 타입 체크
37+
List<Member> findListByUsername(String username);
38+
39+
Member findMemberByUsername(String username);
40+
41+
Optional<Member> findOptionalMemberByUsername(String username);
42+
43+
// 페이징과 정렬
44+
Page<Member> findByAge(int age, Pageable pageable);
45+
// Slice<Member> findByAge(int age, Pageable pageable);
46+
47+
@Query(value = "select m from Member m left join m.team t",
48+
countQuery = "select count(m) from Member m")
49+
Page<Member> findCustomCountQueryByAge(int age, Pageable pageable);
50+
}

book/spring-data-jpa/src/main/resources/application.yaml

+6-4
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,13 @@ spring:
77
jpa:
88
hibernate:
99
ddl-auto: create
10+
#ddl-auto: update
1011
properties:
1112
hibernate:
12-
# show_sql: true
13-
format_sql: true
13+
# show_sql: true
14+
format_sql: true
15+
default_batch_fetch_size: 100
1416

1517
logging.level:
16-
org.hibernate.SQL: debug
17-
org.hibernate.type: trace
18+
org.hibernate.SQL: trace
19+
# org.hibernate.type: trace

book/spring-data-jpa/src/test/java/datajpa/repository/MemberJpaRepositoryTest.java

+50
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
import org.junit.jupiter.api.Test;
88
import org.springframework.beans.factory.annotation.Autowired;
99
import org.springframework.boot.test.context.SpringBootTest;
10+
import org.springframework.data.domain.PageRequest;
11+
import org.springframework.data.domain.Pageable;
1012
import org.springframework.test.annotation.Rollback;
1113
import org.springframework.transaction.annotation.Transactional;
1214

@@ -64,4 +66,52 @@ public void basicCRUD() {
6466

6567
assertThat(repository.count()).isEqualTo(0);
6668
}
69+
70+
@Test
71+
public void testFindByUsernameAndAgeGreaterThan() {
72+
Member m1 = new Member("AAA", 10);
73+
Member m2 = new Member("AAA", 20);
74+
Member m3 = new Member("BBB", 20);
75+
repository.save(m1);
76+
repository.save(m2);
77+
repository.save(m3);
78+
79+
List<Member> finds = repository.findByUsernameAndAgeGreaterThan("AAA", 15);
80+
assertThat(finds.size()).isEqualTo(1);
81+
}
82+
83+
@Test
84+
public void testNamedQuery() {
85+
Member m1 = new Member("AAA", 10);
86+
Member m2 = new Member("AAA", 20);
87+
Member m3 = new Member("BBB", 20);
88+
repository.save(m1);
89+
repository.save(m2);
90+
repository.save(m3);
91+
92+
List<Member> finds = repository.findWithNamedQuery("BBB");
93+
assertThat(finds.size()).isEqualTo(1);
94+
}
95+
96+
@Test
97+
public void paging() {
98+
// given
99+
repository.save(new Member("member1", 10));
100+
repository.save(new Member("member2", 10));
101+
repository.save(new Member("member3", 10));
102+
repository.save(new Member("member4", 10));
103+
repository.save(new Member("member5", 10));
104+
105+
int age = 10;
106+
int offset = 0;
107+
int limit = 3;
108+
109+
// when
110+
List<Member> members = repository.findByPage(age, offset, limit);
111+
long totalCount = repository.totalCount(age);
112+
113+
// then
114+
assertThat(members.size()).isEqualTo(limit);
115+
assertThat(totalCount).isEqualTo(5L);
116+
}
67117
}

book/spring-data-jpa/src/test/java/datajpa/repository/MemberRepositoryTest.java

+147
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,23 @@
22

33
import static org.assertj.core.api.Assertions.assertThat;
44

5+
import java.util.Arrays;
56
import java.util.List;
67
import java.util.Optional;
78

89
import org.junit.jupiter.api.Test;
910
import org.springframework.beans.factory.annotation.Autowired;
1011
import org.springframework.boot.test.context.SpringBootTest;
12+
import org.springframework.data.domain.Page;
13+
import org.springframework.data.domain.PageRequest;
14+
import org.springframework.data.domain.Sort;
15+
import org.springframework.data.domain.Sort.Direction;
1116
import org.springframework.test.annotation.Rollback;
1217
import org.springframework.transaction.annotation.Transactional;
1318

19+
import datajpa.dto.MemberDto;
1420
import datajpa.entity.Member;
21+
import datajpa.entity.Team;
1522

1623
/**
1724
*/
@@ -22,6 +29,8 @@ public class MemberRepositoryTest {
2229

2330
@Autowired
2431
private MemberRepository repository;
32+
@Autowired
33+
private TeamRepository teamRepository;
2534

2635
@Test
2736
public void testSave() {
@@ -70,4 +79,142 @@ public void basicCRUD() {
7079

7180
assertThat(repository.count()).isEqualTo(0);
7281
}
82+
83+
@Test
84+
public void testFindByUsernameAndAgeGreaterThan() {
85+
Member m1 = new Member("AAA", 10);
86+
Member m2 = new Member("AAA", 20);
87+
Member m3 = new Member("BBB", 20);
88+
89+
repository.save(m1);
90+
repository.save(m2);
91+
repository.save(m3);
92+
93+
List<Member> finds = repository.findByUsernameAndAgeGreaterThan("AAA", 15);
94+
assertThat(finds.size()).isEqualTo(1);
95+
}
96+
97+
@Test
98+
public void testNamedQuery() {
99+
Member m1 = new Member("AAA", 10);
100+
Member m2 = new Member("AAA", 20);
101+
Member m3 = new Member("BBB", 20);
102+
103+
repository.save(m1);
104+
repository.save(m2);
105+
repository.save(m3);
106+
107+
List<Member> finds = repository.findWithNamedQuery("BBB");
108+
assertThat(finds.size()).isEqualTo(1);
109+
}
110+
111+
@Test
112+
public void testQuery() {
113+
Member m1 = new Member("AAA", 10);
114+
Member m2 = new Member("AAA", 20);
115+
Member m3 = new Member("BBB", 20);
116+
117+
repository.save(m1);
118+
repository.save(m2);
119+
repository.save(m3);
120+
121+
List<Member> finds = repository.findUser("AAA", 10);
122+
assertThat(finds.size()).isEqualTo(1);
123+
assertThat(finds.get(0)).isEqualTo(m1);
124+
}
125+
126+
@Test
127+
public void testFindUsernameList() {
128+
Member m1 = new Member("AAA", 10);
129+
Member m2 = new Member("AAA", 20);
130+
Member m3 = new Member("BBB", 20);
131+
132+
repository.save(m1);
133+
repository.save(m2);
134+
repository.save(m3);
135+
136+
List<String> usernameList = repository.findUsernameList();
137+
138+
for (String s : usernameList) {
139+
System.out.println("s = " + s);
140+
}
141+
}
142+
143+
@Test
144+
public void testFindMemberDto() {
145+
Team team = new Team("teamA");
146+
teamRepository.save(team);
147+
148+
Member m1 = new Member("AAA", 10);
149+
m1.setTeam(team);
150+
repository.save(m1);
151+
152+
List<MemberDto> dataList = repository.findMemberDto();
153+
for (MemberDto memberDto : dataList) {
154+
System.out.println("MembetDto ==> " + memberDto);
155+
}
156+
}
157+
158+
@Test
159+
public void testFindByNames() {
160+
Member m1 = new Member("AAA", 10);
161+
Member m2 = new Member("AAA", 20);
162+
Member m3 = new Member("BBB", 20);
163+
Member m4 = new Member("CCC", 20);
164+
165+
repository.saveAll(Arrays.asList(m1, m2, m3, m4));
166+
167+
List<Member> members = repository.findByNames(Arrays.asList("AAA", "CCC"));
168+
for (Member member : members) {
169+
System.out.println("Member ==> " + member);
170+
}
171+
}
172+
173+
@Test
174+
public void returnType() {
175+
Member m1 = new Member("AAA", 10);
176+
Member m2 = new Member("BBB", 20);
177+
repository.save(m1);
178+
repository.save(m2);
179+
180+
// NoResultException
181+
Member findMember = repository.findMemberByUsername("AAA");
182+
repository.findOptionalMemberByUsername("AAA");
183+
184+
Member ccc = repository.findMemberByUsername("CCC");
185+
assertThat(ccc).isNull();
186+
System.out.println("## findMemberByUsername ==> " + findMember);
187+
188+
List<Member> result = repository.findListByUsername("AAA");
189+
System.out.println("## findListByUsername ==> " + result.size());
190+
}
191+
192+
@Test
193+
public void paging() {
194+
// given
195+
repository.save(new Member("member1", 10));
196+
repository.save(new Member("member2", 10));
197+
repository.save(new Member("member3", 10));
198+
repository.save(new Member("member4", 10));
199+
repository.save(new Member("member5", 10));
200+
201+
int age = 10;
202+
PageRequest pageRequest = PageRequest.of(0, 3, Sort.by(Direction.DESC, "username"));
203+
204+
// when
205+
// Page<Member> page = repository.findByAge(age, pageRequest);
206+
//Slice<Member> page = repository.findByAge(age, pageRequest);
207+
Page<Member> page = repository.findCustomCountQueryByAge(age, pageRequest);
208+
Page<MemberDto> dtoPage = page.map(m -> new MemberDto(m.getId(), m.getUsername(), null));
209+
210+
// then
211+
assertThat(page.getContent().size()).isEqualTo(pageRequest.getPageSize());
212+
assertThat(page.getTotalElements()).isEqualTo(5L);
213+
assertThat(page.getNumber()).isEqualTo(pageRequest.getPageNumber());
214+
assertThat(page.getTotalPages()).isEqualTo(2);
215+
assertThat(page.isFirst()).isTrue();
216+
assertThat(page.isLast()).isFalse();
217+
assertThat(page.hasNext()).isTrue();
218+
219+
}
73220
}

0 commit comments

Comments
 (0)