전체 글

매일 발전하는 백엔드 개발자
개발로그

[개발로그] Srping Event, Async

Spring에서 Event가 왜 필요한가 ?Spring Event는 Spring의 3대요소 중 하나인 관점을 분리하기 위한 하나의 방법이다.예를 들어 유저가 회원가입을 할 때 인증을 위한 이메일을 보내는 로직이 어디에 존재해야할까 고민해볼 수 있다. @Service@RequiredArgsConstructor@Transactionalpublic class AccountService implements UserDetailsService { private final AccountRepository accountRepository; private final EmailService emailService; public Account signUp(SignUpForm signUpForm) { ..

개발로그

[개발로그] 패키지 의존성(단방향 연관관계) 테스트 ArchUnit, TestContainers for JAVA

패키지 의존성 테스트 간단한 글, 댓글, 유저만 있는 CRUD를 만들때도 모두 양방향 연관관계 맵핑 이후에 DTO로 만들 때 순환참조를 막았었는데 서비스에 필요한 단방향 연관관계만으로 이런 과정을 생략할 수 있다. 단방향으로 참조를 하고 있는지 확인 할 수 있는 ArchUnit 라이브러리를 사용해 패키지 간 의존성 참조받는 것과 하는 것, 순환참조 여부를 눈이 아니라 테스트 코드로 확인할 수 있다. 기준 버젼은 자바 17, 스프링부트 2.7.11 이다. gradle testImplementation group: 'com.tngtech.archunit', name: 'archunit-junit5', version: '0.13.1' code public class PackageDependencyTests {..

Computer Science/Database

[DB] 소소한 DB 꿀팁

COUNT count함수는 null을 세지 않는다. count(*)와 count(null이 있는 속성)시에는 결과가 다르다. CASE SQL에서의 case문은 조건 충족 시 break 없어도 멈춘다. SELECT CASE WHEN false THEN '참입니다' ELSE '거짓입니다' END as 대신 then 사용한다. EXTRACT hour, dayofweek, minute, second 등 다양한 정보를 빼낼 수 있다. select extract(YEAR FROM created_at) as year from `thelook_ecommerce.users` Join 없이 where로 Join인척 하기 select from a, b where a.user_id = b.id select from a joi..

JPA

[JPA] 연관관계 맵핑 이후 조회 쿼리 시 생각해야할 것

가장 중요한 것은 필요한 정보만큼의 쿼리를 날리는 것이다. 조인을 하지 않고 너무 적은 정보를 가져와 발생하는 예상하기 어려운 N+1 문제도, 서비스 동작시에 필요없는 정보도 조인으로 가져오는 것도 문제다. 같은 객체를 DB에서 가져오더라도, 필요한 정보의 양이 다르면 메소드를 분리해야 한다. EntityGraph를 사용하든 Fetch Join을 사용하든 서비스에서 필요한 정보의 양은 서비스의 동작 마다 다르다. 코드 예시를 보자 Team Entity @Entity @Getter @NamedEntityGraph(name = "Team.withAll", attributeNodes = { @NamedAttributeNode("tags"), @NamedAttributeNode("zones"), @NamedAt..

개발로그

[개발로그] Google SMTP, 서비스 추상화,Thymeleaf Context

SMTP 콘솔로 찍던 javaMailSendor 대신 구글의 SMTP를 이용해 실제 메일을 보낸다. 먼저 구글 계정이 필요하다. 가입 완료했으면 계정관리 > 보안에 들어가 2단계 인증을 한다. 이후 2단계 인증 탭을 클릭하고 스크롤을 아래로 내리면 앱 비밀번호를 만들 수 있는 탭이 있다. 2021년부터 앱 비밀번호는 구글에서 권장하지 않는 방법이고 실제 이메일 서비스보다는 제한이 있지만 설정이 간단해서 사용한다. // application.yml spring: mail: host: smtp.gmail.com port: 587 username: ${mail.username} password: ${mail.password} properties: mail: smtp: auth: true timeout: 500..

개발로그

[개발로그] SpringBoot + Ajax, CSRF

Ajax(Asynchronous Javascript and XML) 웹 페이지 전체를 새로고침하지 않고 웹 페이지의 일부만을 갱신할 수 있게한다. CSRF(Cross Site Request Forgery) 사용자가 이미 로그인해서 들고있는 세션정보를 악의적인 링크를 클릭하게 해서 사용자가 자신의 의지와는 무관하게 공격자가 의도한 행위(등록, 수정, 삭제)를 특정 웹 사이트에 요청하게 만드는 공격이고, 이를 막기위해 csrf 토큰을 사용한다. Spring MVC를 사용하면 디폴트로 csrf 토큰 관리를 제공하고, Spring Security를 사용하면 디폴트로 csrf 보호가 시작된다. Thymeleaf 템플릿 엔진은 프론트 엔드단에서의 csrf 토큰 관리를 지원해줘 별다른 추가 없이도 POST 요청을 보..

개발로그

[개발로그, Spring MVC] View에서 접근 가능한 유저정보를 컨트롤러에서 Model로 넘겨주는 이유

UserDetails @Getter public class UserAccount extends User { private Account account; public UserAccount(Account account) { super(account.getNickname(), account.getPassword(), List.of(new SimpleGrantedAuthority("ROLE_USER"))); this.account = account; } } 해당 UserDetails를 Principal로 AuthenticationToken을 Security Context에 저장하고 Thyemleaf Extras를 통해 Security Context에 접근할 수 있다. View에서 Context 바로 접근 Con..

개발로그

[개발로그] Security Context 유저 정보와 DB 유저 정보 동기화

Security Context의 정보와 DB의 정보가 다를 때? Spring Security를 세션방식과 함께 이용한다면 로그인 시에 Security Context에 AuthenticationToken(UserDetails, Password, Granted)를 저장하고 세션이 만료되거나 로그아웃 될 때까지 전역적으로 사용할 수 있다. 하지만 로그인 중에 유저 정보가 변해도 Security Context가 들고있는 정보는 업데이트가 되지 않기 때문에 동기화를 시켜줘야한다. 코드 예시 유저 Entity와 Entity를 필드로 갖는 UserDetails를 정의한다. @Entity @Getter @EqualsAndHashCode(of = "id") @NoArgsConstructor public class Acc..

비오베베
우당탕탕 개발