
객체에 분류와 구현에 대해 공부하다보면 VO(Value Object)라는 용어를 알게되고, VO를 공부하면 대표적으로 등장하는 예시가 Money 클래스이다. long이나 BigDecimal 같은 숫자를 다루는 타입으로 통화를 표현하게 되는데 이런 타입을 사용하지 말고 직접 통화를 의미하는 타입을 만들어서 표현력을 올리고, 통화의 책임을 다루라는 의미다. 테스트주도개발이라는 책에서도 Money 클래스를 TDD로 만들어가는걸로 책을 시작한다. java에서는 JDK 안에 time 패키지를 제공함으로써 날짜에 대한 표준 구현 클래스들을 제공한다. 언어표준이기 때문에 대부분의 라이브러리에서도 지원하고 있어 날짜나 시간을 직접 구현하거나 String같은 타입으로 표현하는 경우는 드물다. 미처 몰랐는데 통화에 대해서..
요즘은 처음 자바 환경에서 개발 공부를 시작할때도 프레임워크 기반에서 시작해서 순수하게 JDBC 를 이용한 DB 접근 코드는 거의 작성할 일이 없는 것 같지만, JDBC 를 이용해서 코드를 작성하면 보통 이런 코드가 나온다.Connection conn = DriverManager.getConnection(jdbcUrl, id, pw);PreparedStatement pstmt = conn.prepareStatement("SELECT * FROM car WHERE car_id = ?");pstmt.setLong(1);ResultSet rs = pstmt.executeQuery();rs.close();pstmt.close();conn.close();DB의 Connection 객체를 가져와서 해당 객체를 이용..
spring boot 버전을 올리면서 3.4.x 버전을 사용하게 됐고, 동작을 확인하던 도중 기존 코드에서 에러가 발생했다.Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect)해당 로우가 다른 트랜잭션에서 업데이트되거나 삭제되었다는 메시지인데, 버전을 올리지 않으면 해당 에러는 발생하지 않았다. 해당 문제가 발생할 수 있는 상황은 이렇다.// 엔티티 정의@Entity@Table(name = "person")@AllArgsConstructor@NoArgsConstructor(access = AccessLevel.PROTECTED)public class Person { @Id @Generated..
spring 은 전통적으로 http client 로 RestTemplate 을 제공해왔다. 그러다가 webflux 의 등장과 함께 비동기로 동작하는 http client 인 WebClient 라는 모던 http client 를 제공하기 시작했는데, 초기엔 mvc 에서도 이 WebClient 를 이용하는걸 권장했다. 하지만 WebClient 를 이용하기 위해선 webflux 전체에 의존해야하고, reactive 라이브러리인 proejct reactor API 를 사용해야하는 불편함이 있었다. 불편함이라고 썼지만 개인적으론 최악의 경험이었다. 그러다가 spring boot 3.2 에 신규 동기 http client 가 들어왔으니 그게 RestClient 이다. 오늘은 RestClient 를 잘 사용하기 위한..
이번엔 예외처리에 대한 이야기를 해보려한다. 실무에서도 흔히 보이는 방식과 그 방식에서 아쉬웠던 부분도 함께 정리해보고자 한다. # 1개의 Exception 클래스와 error enum실무에서 가장 많이 본 예외처리 방식이다. 대다수가 이런 방식을 사용하고 있을거라고 생각한다.// 예외 클래스 정의@Getterpublic class ApiException extends RuntimeException { private ErrorCode errorCode;}// 에러 코드를 담는 상수 정의, 사용자노출 메시지와 http status 코드를 관리@AllArgsConstructor@Getterpublic enum ErrorCode { ENTITY_NOT_FOUND("엔티티를 찾지 못했습니다.", 40..
이번엔 특별히 무언가 주제가 있다기보다 실무에서도 쉽게 접하는 상황에서 어떻게 인터페이스를 설계하는게 올바른지 예제를 통해 알아가보려 한다. 지난 포스팅의 후속작정도 될 것 같다. # 요구사항소셜 로그인 로직을 구현해야한다. 소셜 로그인은 네이버, 카카오, 구글을 지원할 예정이다. 소셜 로그인을 할때 각 플랫폼들이 필요로 하는 정보는 아래에 적어놨다. 실제 플랫폼들의 소셜 로그인을 구현하는건 아니어서 아래 필요정보들은 실제 플랫폼 소셜 로그인과는 상관없이 가상의 필요정보다. 네이버: client-key, 사용자 id, 사용자 동의여부카카오: client-key, 사용자 id구글: client-key, 사용자 토큰 # 인터페이스 정의소셜 로그인과 각 플랫폼들의 관계는 딱봐도 개발자로 하여금 뭔가 추상화를..
기존 spring boot 3.0.13 버전에서 3.1.12 로 버전업을 시도했다. 하위호환을 잘 보장해준 덕에 큰 이슈없이 빌드에 성공했는데 엔티티 조회시 ArrayIndexOutOfBoundsException 이 발생하는걸 확인했다. 해당 엔티티는 크게 복잡하지 않은 보통의 엔티티였는데 왜 문제가 발생한건지 정리하려한다. 문제가 발생하는 환경을 간단한 엔티티로 표현하면 이렇다.@Entity@Table(name = "car")public class Car { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "car_id") private Long id; @Column(name = "car_type") ..
spring batch 를 이용할때 어떤 reader 를 이용할지 항상 고민되는 편이다. DB 접근을 JPA 로 하고 있다면 대표적으로 JpaCursorItemReader, JpaPagingItemReader 중에 고민하게 된다. 보통 이 둘을 고민하는 상황이 오면 성능적으론 JpaCursorItemReader 가 더 좋다는걸 알게 된다. 하지만 대량의 데이터를 조회한 후 커서를 이동시키는 이 방식은 타임아웃을 유발할 수 있기에 데이터가 많을땐 조심해야해서, 이런 문제에 대해 안전한 JpaPagingItemReader 를 선택하는 경우가 많다. 하지만 페이징 기반의 리더를 쓰게되면 몇가지 곤란한 부분이 있는데 대표적으로 특정 상태를 이용해 조회한 후 상태를 변경하는 방식의 배치 잡을 만들때다. 1페이지를..
spring batch 4.3 부터 JpaCursorItemReader 가 추가됐다. 이게 추가되기 이전에는 배치에서 JPA 를 쓸땐 JpaPagingItemReader 를 사용하거나 cursor 방식이 필요하다면 HibernateCursorItemReader 를 써야했다. JpaCursorItemReader 가 추가된지 비교적 얼마 안됐기때문에 아직 HibernateCursorItemReader 를 이용해 돌아가고있는 배치가 많을 것으로 예상한다. 하지만 HibernateCursorItemReader 는 spring batch 5.0 부터 Deprecate 되었고, 5.2 부터는 아예 삭제될 예정이므로 최신 spring batch 에서 배치 로직을 작성하거나 기존 spring batch 프로젝트의 버전..
spring 을 공부하면 가장 먼저 배우는 키워드 중 하나가 DI 이다. DI 란 무엇인가? 의존성을 직접 해결하지 않고 외부로부터 주입받는 것이다. 더군다나 주입받는 대상을 구현 클래스가 아닌 인터페이스로 지정하면 확장에 열려있는 설계가 되며, DI 는 스트레티지 패턴에 기초하고 있다는걸 공부하게 된다. 그럼 spring 을 사용하고 있는 우리는 공부한걸 잘 이해하고, spring 으로 애플리케이션을 개발할때 다형성을 잘 이용하고 있을까?@Componentpublic class DataGetter { public String get() { // SQL 을 이용해 데이터 조회 }}@Componentpublic class DataAggregator { @Autowired ..
- Total
- Today
- Yesterday
- servlet
- Spring
- JavaScript Core
- java
- Git
- frontend개발환경
- Design Pattern
- backend개발환경
- TEST
- generics
- DesignPattern
- programming
- Kotlin
- code
- toby
- clean code
- javascript
- OOP
- go-core
- Jackson
- http
- JPA
- MySQL
- java8
- spring cloud
- db
- EffectiveJava
- 정규표현식
- frontcode
- mariadb
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |