-
Notifications
You must be signed in to change notification settings - Fork 0
/
spring.txt
329 lines (258 loc) · 14.8 KB
/
spring.txt
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
CSR패턴 실행구조
Controller - 외부요청 받음(View를 반환하기 위함)
Service - 비즈니스 로직 만듦
Repository - 데이터 저장
이 것들의 의존성을 @Configration 으로 관리 (SpringConfig 클래스 따로 생성)
db실행
*****버전오류시 – project structure (SDK) or gradle 둘 다 버전확인 후 맞추기*****
단축키
(cntr shift a) - 전체검색
(cntr shift t) - main 클래스에서 test 틀 만들기
(cntr Alt v) - 함수만 적어도 자동으로 변수
(cntr shift Enter) - 문장 알아서 완성해줌 ‘);’
(shift f10) - 이전에 실행했던 것 다시 실행
(Alt ins) - generate(사용잦은 단축키 모음)
(Alt Enter) - 빨간 줄 해결
예외
IllegalStateException
특정 메서드가 호출되거나 작업이 수행될 때, 현재 객체의 상태가 허용되지 않는 상태일 경우에 발생시키는 예외 (이미 존재하는 회원)
어노테이션
@beforeEach – 실행전에 실행(
@AfterEach – 실행 후에 실행(변수값 초기화 등)
@Autowired - 의존성 주입을 위함 ex)@Service와 연결해줌(생성자1개면 생략가능)
@Controller - 외부요청 받음(View를 반환하기 위함)
@Service - 비즈니스 로직 만듦
@Repository - 데이터 저장
Controller, Service, Repository 가 무엇일까? (velog.io)
@GetMapping("/members/new")
public String creatFome() {
return "members /creat"; //members /creat위치의 코드 띄워라
}
@PostMapping("/members/new")
public String create(MemberForm form) {
//코드실행
return "redirect:/"; //“/”로 이동하라
}
@SpringBootTest – spring 컨테이너와 테스트를 함께 실행
@Transactional – springtest시 test가 끝나면 test전으로 롤백 (Test한개당 한번씩 롤백)
(일반적인 경우에서는 성공시 커밋(저장) 실패시만 롤백)
(Jpa는 모든 데이터 저장,변경을 트랜잭션 안에서 해야함)
Map - 키와 벨류로 이루어진 값(딕셔너리)
HashMap - 해시함수를 나머지연산한 값을 키 값으로
public static Map<키의 타입, 벨류의 타입> a = new HashMap<>()
(Map 인터페이스를 HashMap으로 구현)
Optional.ofNullable() -이걸로 감싸면 null이 반환되어도 처리할 수 있음
람다식 - 반환타입과 이름을 지움 ex) (a, b) -> a > b ? 1 : 2
메타데이터 – 데이터의 정보를 담고있는 데이터 ex) 사진.class ==사진의 정보
컬렉션 -자료구조 클레스의 모음
ex) List<String> names = new ArrayList<>
(List 인터페이스를 ArrayList로 구현)
stream - 데이터 처리를 위한 소스에서 추출된 연속된 요소
다른 형의 데이터를 스트림으로 변환하면 같은 방식으로 사용가능(재사용성↑)
원하는 형태로
데이터 가공
원하는 형태로 반환
(Crew::getName -> Crew클레스의 메서드 getName)
생성
컬렉션 : 객체.stream()
배열 : Arrays.stream(객체)
중간연산
distinct() : 중복 데이터 있으면 예외 반환
filter() : 조건에 만족하는 데이터만 남김
sort() : 기본 기준 정렬
map() : 원하는 필드만 뽑아내거나 특정 형태로 변환
flatMap() : 평탄화 작업
최종연산
forEach : 스트림의 데이터를 소모하며 출력 .forEach(System.out::println)
allMatch : 모두일치 true
anyMatch : 하나라도 일치 true .anyMatch(a -> a.equals(b))
nonMatch : 모두 불일치 true
findFirst : 조건에 일치하는 첫 번째 요소 반환 .findFirst()
findAny : 조건에 일치하는 요소 한 개 반환
collect : 스트림의 요소를 수집해 원하는 형태로 반환
Collectors – 정의된 컬렉터를 제공하는 클래스
collect(Collectors.groupingBy(person->person.contry()))
reduce : 데이터를 줄여나가며 연산 수행 후 최종결과 반환(합계 등 구할 때)
ifPresent() - optional내에 값이 있으먼 꺼내라
ex) optionalValue.ifPresent(value -> System.out.println(value));
Test – 프로그램이 정상 작동할 수 있는지(코드 길어지면 필요함) (단축키 cntr shift t)
test를 누적기록 삭제
public void clearStore(){
store.clear();
}
@AfterEach
public void aftereach(){
repository.clearStore();
}
예외검증
assertThrows(ExpectedException.class, () -> {
// 예외가 발생할 수 있는 코드
});
값을 검증
assertThat(실제 값).equalTo(“비교 값”);
(검증조건)
1. Client가 요청을 보낸다.(Ajax, Axios, fetch등..)
2. 요청한 URL에 알맞은 Controller가 수신 받는다. (@Controller , @RestController)
3. Controller 는 넘어온 요청을 처리하기 위해 Service 를 호출한다.
4. Service는 알맞은 정보를 가공하여 Controller에게 데이터를 넘긴다.
5. Controller 는 Service 의 결과물을 Client 에게 전달해준다.
query() - JDBC 사용하여 데이터베이스에서 데이터를 검색
query(sql구문, (전달할 값(가변인자)), (ResultSetExtractor<T>r or RowMapper<T>r)
ResultSetExtractor<T>
ResultSet의 모든 행을 반복하며 데이터를 추출하여 T 타입 변환, 최종 결과를 반환() RowMapper<T>
(sql쿼리 실행결과 T로 변환)
-----------------------------------
(예외처리)
public hi() throws SQLException{A}
==
public hi() {
try{A}
catch{throws SQLException}
-----------------------------------
제네릭 – 클래스의 외부에서 클래스 내부의 타입지정
class Person<T, S>{
public T a;
public S b;
Person(T a, S b){
this.a = a;
this.b = b;
}
Integer e = new Integer(2);
Man man = new man(“boy”);
Person p1 = new Person(e, man);
//Person<Integer, Man> p1 = new Person<Integer, Man>(e, man);
//메서드에도 제네릭 적용가능
//Person<T extends Object> ->Object의 자식클래스 이외 제한(래퍼클래스만 가능)
래퍼클래스 – 기본타입 데이터를 객체로 다루기 위함 ex)Integer
spring ioc 컨테이너
객체를 생성,관리하고 의존성 주입(애플리케이션이 실행됨과 동시에 생성)
spring bean - spring ioc 컨테이너가 사용하는 객체
spring bean에서 가져옴
@Autowired – 컨테이너 내부의 값을 가져와서 주입함
@RequiredArgsConstructor - 변수생성하면 자동주입입
spring bean에 등록
@Service, @Repository, @Controller, @Component 등의 어노테이션 아래 메서드의 매개변수는 @Bean으로 등록한 객체에서 가져온다
Spring data Jpa
JpaRepository를 상속받으면 springdatajpa가 같이 상속받은 인터페이스의
오버라이드한 메서드의 이름을 토대로 목적성에 맞게 메서드를 구현
Aop - aop는 여러 곳에서 공통으로 반복하는 기능(시간측정 등)을 핵심로직과 분리하여 적용
aop를 이용해서 메서드의 동작 시간을 확인하면 A메서드의 동작시간을 직접 찍어보지 않고 A메서드의 프록시에 찍어봐서 시간을 보여준 후 다시 그 메서드를 실행, A메서드는 B메서드의 프록시 호출
===============================================================================================================================================================================================
spring 심화
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
스레드
스레드는 멀티 태스킹에서 쓰이는 워크플로우의 최소 단위
thread = new Thread(Runnable target);
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
@Builder
User user = User.builder()
.name("Alice")
.age(30)
.email("alice@example.com")
.build();
위와 같은 패턴으로 Setter를 쉽게 대체할 수 있다.
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
findById 팁
Posts posts = postsRepository.findById(id).orElseThrow(() ->
new IllegalArgumentException("해당 게시글이 존재하지 않습니다. id=" + id));
//위 방식으로 쉽게 예외처리 가능
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
=============================================================================================================================================================================
ORM (Object-Relational Mapping) 프레임워크
오브젝트와 DB를 매핑해주는 프레임워크
JPA
-Hibernate : jpa의 구현체 중 하나
-1차캐시
-2차캐시
-spring Data JPA
-엔티티 매니저의 역할을 대신해줌 (복잡한 쿼리에서는 필요에 따라 엔티티매니저를 직접 사용)
영속상태
-비영속상태 : 영속성 컨텍스트와 관련이 없는 상태
-영속상태 : 영속성 컨텍스트에 저장된 상태
-준영속 상태 : 영속성 컨텍스트에 저장되었다가 분리된 상태 //em.detach(entity) : 특정엔티티만, em.clear() : 전체, em.close() 종료
-영속성 컨택스트내부에 존재하지 않아 비영속과 다를거 없으나 식별자 값만 가지고있음
-merge()를 통해 영속상태인 새로운 객체를 만들 수 있음
-삭제 : 삭제예정 (다음 flush 작업때 지연저장소에 delete쿼리가 저장되고, db에서삭제됨)
JPA의 요소
-엔티티 매니저 팩토리 (엔티티 매니저 생성)
-엔티티 매니저 (엔티티를 관리, 영속성 컨택스트의 작업수행)
-엔티티 (DB에 매핑될 객체)
-영속성 콘텍스트 (엔티티를 관리할 공간)
-1차캐시 (영속상태의 엔티티를 저장)
-@ID
-Entity
-스냅샷 : 최초 엔티티 상태를 복사해서 저장
-영속성 유닛 (DB연결을 설정) //yml파일
***************영속성 컨택스트를 쓰는 이유 : 1차캐시, 쓰기지연, 변경감지를 통해서 DB접근을 줄여준다****************
**영속성 컨텍스트에 저장방법
-em.persist(entity) : 직접저장
-em.merge(entity)
-em.find(entity,entity.getId()) : 조회시 자동저장
-em.flush()
-@Transactional
-repository.save()
-@OneToMany(cascade = CascadeType.PERSIST) : 엔티티 생성과 동시에 컨텍스트에 저장
**엔티티 매니저 사용법
@PersistenceContext
private EntityManager em;
--------------------------------------------------------------------------------------------
@Transactional
public void update(Long id, PostsDto.Request dto) {
Posts posts = postsRepository.findById(id).orElseThrow(() ->
new IllegalArgumentException("해당 게시글이 존재하지 않습니다. id=" + id));
posts.update(dto.getTitle(), dto.getContent());
}
//위 코드 리뷰
-비영속상태의 postEntity를 findById(id)로 인해 영속성 컨택스트에 저장
-post.update() 로 변경된 부분이 변경감지에 의해 변경사항 추적
-트랙잭션 커밋으로 DB에 저장됨
--------------------------------------------------------------------------------------------
**flush : 영속성 컨텍스트의 변경 내용을 DB에 반영
flush(@Transactional) 호출시
-변경감지
-영속성 컨텍스트에 있는 모든 엔티티를 스냅샷과 비교
-수정된 엔티티의 수정된 쿼리를 만들어 쓰기 지연 sql 저장소에 저장
-쓰기 지연 저장소의 sql을 db에 반영
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
@Transactional 구조
@Transactional 하위 메서드가 시작됨과 영속성컨택스트 생성
해당 메서드가 커밋되어 종료될 때 영속성 컨택스트는 삭제됨
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
cascade = CascadeType.REMOVE //부모 엔티티 삭제 시 자식엔티티도 삭제
cascade = CascadeType.PERSIST //엔티티 생성과 동시에 영속성 컨택스트에 등록
fetch = FetchType.LAZY : 매핑한 엔티티를 실제 사용될 때까지 로딩(DB에서 가져오지)하지 않음
// 처음에는 해당엔티티(childEntity를 프록시 객체로 영속성 컨텍스트에 저장 ->실제 사용시 영속성 컨텍스트가 DB에서 가져옴
//프록시 객체가 저장돼있기때문에 저장시에는 영속성 컨택스트가 열려있어야함 (@Transactional 하위에서만 사용 가능)
//해당 엔티티의 실제사용예시 : parent.getChild()
//해당 엔티티에만 적용( 해당엔티티와 연관관계 맺고있는 다른엔티티는 적용되지 않음)
fetch = FetchType.EAGER : 연관된 모든 엔티티를 함께 불러옴
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
프록시 객체 (가짜객체)
-사용될 때 DB에서 진짜 객체 가져옴
-영속성 콘텍스트가 열려있는 동안만 사용가능
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
@Embeddable
엔티티 클래스 내에 다른 클래스의 속성을 포함시키고자 할 때 사용
클래스위에 사용하고 다른 클래스에 변수로 추가할 때 사용하면 DB에 하나의 테이블로 들어감
ex)
@Embeddable
public class Address {
private String street;
private String city;
private String zipcode;
}
public class User {
@Embedded
private Address address; // Address를 포함
}
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
@ResponseBody, @RestController : 객체를 json으로 반환
직렬화 : 객체를 json으로 반환
역직렬화 : json을 객체로 반환
@JsonProperty : json 객체 매핑, 안써도 기본적으로 매핑하나, 쓰면 이름도 설정 가능
@JsonIgnore : 역,직렬화 무시(매핑안함)
=============================================================================================================================================================================
DTO 대신 Recode를 사용하는 것에 대해
가변성이 필요하거나 커스텀 로직을 추가해야 한다면, DTO가 더 적합
간결하고 불변적인 구조를 선호하고 Java 16 이상을 사용한다면, Record가 더 적합할 수 있음, 특히 모바일기기, iot에서 사용시 멀티쓰레드의 성능차이 있음
[출처] https://yozm.wishket.com/magazine/detail/2814/