전체 글 562

[스프링부트] 순환 참조 문제란?

순환 참조 문제란 정확히 무엇일까요? A 클래스가 B 클래스의 Bean을 주입받고, B 클래스가 A 클래스의 Bean을 주입받는 상황으로 서로 순환되어 참조할 경우, 발생하는 문제입니다. 이 문제가 왜 일어나죠? 필드 주입 방식과 수정자 주입 방식에서는 위 같은 상황이 일어나더라도 애플리케이션 실행 과정에서 예외가 발생하지 않습니다. 당장에는 문제가 생기지 않지만, 문제가 되는 순간은 실제로 해당 메소드가 호출되었을 때 입니다. 하지만 위 상황은 순환참조 문제가 아닙니다. 서로 다른 메소드가 서로 호출을 할 때 생기는 순환호출 문제입니다. 생성자 주입 방식에서의 순환참조 문제에 대해 다뤄보기 전, 생성자 주입 방식의 동작원리에 대해 알아봐야합니다. A클래스가 B클래스를 의존하고, B클래스가 C클래스를 의..

[스프링부트] 트랜잭션의 의미와 사용 이유

트랜잭션이란? > 데이터베이스의 상태를 변경시키기 위해 수행하는 작업의 단위를 의미합니다. 데이터베이스의 상태를 변경시킨다는 의미는 select, update, delete, insert와 같은 행동을 의미합니다. 이러한 트랜잭션은 상황에 따라 여러개가 만들어질 수 있습니다. 그 하나의 트랜잭션은 commit(저장)되거나 rollback(철회) 될 수 있습니다. A가 B에게 만원을 송금한다고 가정하면, A는 먼저 통장에서 만원을 인출하고, B의 통장에 만원을 입금해야합니다. 이때 인출과 입금의 두 가지 작업이 합쳐져서 '송금'이라는 하나의 논리적인 기능을 이루게 됩니다. A의 통장에서 만원이 인출이 되었는데, B의 통장으로 입금하는 과정이 실패하면? 다시 송금 기능을 수행해야 합니다. 잘못된 처리니까요 ..

[스프링부트] 실제로 실행된 쿼리 보는 방법

실제로 실행된 쿼리를 보는 방법에 대해 알아보겠습니다. application.properties 파일에 들어가서 spring.jpa.show_sql=true 위 코드를 복붙해줍니다. 그리고 다시 테스트를 실행하면? 위와 같이 콘솔에서도 쿼리 로그를 확인할 수 있습니다!! insert 구문이 실행되었구나, 라는 걸 알 수 있고 cleanup() 메소드를 통해 모든 내용이 테이블에서 지워졌구나를 짐작할 수 있습니다. https://eboong.tistory.com/521?category=958623 [스프링부트] Spring boot JPA 테스트 코드 작성하기 Posts.java -> Entity 클래스입니다. package com.yeony.web.springbootwebproject.domain.pos..

[스프링부트] Spring boot JPA 테스트 코드 작성하기

Posts.java -> Entity 클래스입니다. package com.yeony.web.springbootwebproject.domain.posts; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; import javax.persistence.*; @Getter @NoArgsConstructor @Entity public class Posts { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(length = 500,nullable = false) private String title; @Column(columnDe..

[스프링부트] Spring 웹 계층

1. Web ( Controller, View ) - 컨트롤러와 뷰 템플릿 영역입니다. - 필터, 인터셉터, 컨트롤러 어드바이스 등 외부 요청과 응답에 대한 영역을 의미합니다. 2. Service - @Service에 사용되는 서비스 영역입니다. - 일반적으로 Controller와 Dao 중간 영역에서 사용됩니다. - @Transactional이 사용되는 영역입니다. 트랜잭션과 도메인 간의 순서만 보장해줍니다. 3. Repository -> interface로 생성 - Database와 같이 DB 저장소에 접근하는 영역입니다. - DAO(Data Access Object) 영역이라고 생각하면 됩니다. JpaRepository을 상속해주면, 기본적인 CRUD가 생성됩니다. (자동으로) Entity 클래스와..

[스프링부트] JPA가 무엇이고, 왜 써야 하는가!?

JPA는 자바 표준 ORM입니다. ORM ( Object Relational Mapping) : 객체-관계 매핑의 줄임말입니다. 객체라는 개념을 구현한 클래스와 테이블을 자동으로 매핑(연결)하는 것을 의미합니다. 1. 단순 반복 작업 : 수십, 수백개의 테이블의 SQL을 만들고 유지보수 해야하는 단순 반복 작업을 하게 되는 걸 ORM이 해결해줍니다. 2. 패러다임 불일치 문제 그러나 클래스와 테이블이 애초에 호환가능성을 염두해두고 만들어진 것이 아니기 때문에 불일치가 발생하게 됩니다. 이를 ORM을 통해 해결할 수 있습니다. 객체 간의 관계를 바탕으로 SQL 문을 자동으로 생성하기 때문입니다. ORM을 사용하면 직접 따로 SQL문을 짤 필요 없이 클래스의 메서드를 통해, 객체를 통해서 간접적으로 DB를 ..

[스프링부트] MockMvc 관련 메소드

private MockMvc mvc : 웹 API 테스트(GET,POST 등) 진행시 사용합니다. 스프링 MVC 테스트의 시작점입니다. mvc.perform(get("/hello")) : MockMVC를 통해 /hello 주소로 HTTP GET 요청을 합니다. 체이닝이 지원됩니다. .andExpect() : 응답 결과를 검증합니다. - 상태코드 : status() .isOk() : 200 .isNotFound() : 404 .isMethodNotAllowed() : 405 .isInternalServerError() : 500 .is(int status) : status 상태코드 - 리턴하는 뷰 이름 검증 : view() .name("example") > 리턴하는 뷰 이름이 example인가! - 리다이..

[스프링부트] 값 넘겨주는 유닛 테스트코드 작성하기(RequestParam)

@RequestParam은 외부에서 API로 넘긴 파라미터를 가져오는 어노테이션입니다. @RequestParam("가져올 데이터의 이름") [데이터타입] [가져온 데이터를 담을 변수] HelloResponseDto.java 응답 데이터를 받을 dto 클래스입니다. package com.yeony.web.springbootwebproject.web.dto; import lombok.Getter; import lombok.RequiredArgsConstructor; @Getter @RequiredArgsConstructor public class HelloResponseDto { private final String name1; private final int amount1; } HelloResponseDt..

[스프링부트] error: variable name not initialized in the default

테스트 코드를 돌렸더니 위와 같은 에러가 떴습니다. @Getter를 이용해서 선언된 모든 필드의 get 메서드를 생성해줬습니다. 그리고 @RequiredArgsConstructor를 이용해서 선언된 모든 final 필드가 모함된 생성자를 생성해줍니다. 물론 final이 안 붙어있으면 생성해주지 않습니다. 위와 같이 오류가 나는 이유는 그래들 버전이 5로 올라가면서 lombok을 프로젝트에 추가해주는 방법이 달라졌기 때문입니다. 책에 적혀 있는대로만 하면 안되더라구요.. 롬북을 사용하려면 아래와 같이 총 4개의 구문을 적어주어야합니다. 테스트 성공!

[스프링부트] assertThat 인식 안되는 문제 해결

AssertJ란? : 자바 JUnit의 테스트코드에 사용되어, 테스트코드의 가독성과 편의성을 높여주는 라이브러리입니다. 메서드 체이닝을 지원해서 더 직관적이고 읽기 쉬운 테스트코드 작성이 가능합니다. 참고로 자바 8 이상은 AssertJ 3.x버전을 사용해야 합니다. static import를 통해 AssertJ의 다양한 API를 클래스 이름 없이 사용이 가능합니다. AssertJ에서 모든 테스트 코드는 assertThat()으로 시작합니다. assertThat(테스트타겟).메소드1().메소드2(). ... 다양한 메소드를 확인할 수 있는 사이트! https://www.javadoc.io/doc/org.assertj/assertj-core/latest/org/assertj/core/api/package-..

[스프링부트] 롬북(lombok)의 개념, 설치 방법 | maven repository

참고서적 : 스프링 부트와 AWS로 혼자 구현하는 웹 서비스 롬북을 사용하는 이유가 뭔지 궁금했습니다. 일단 그래서 롬북의 개념에 대해 알아봤습니다. 롬북을 사용하지 않으면 모델 객체마다 반복적으로 getter나 setter 메소드를 생성해줘야합니다. 변수명이 바뀌게 되는 경우에도 다시 만들어줘야하는 번거로움이 있습니다. 그래서 롬북을 사용하게 되면 @annotation으로 위 역할을 대신 해줍니다. 즉 정리하자면 롬북은 어노테이션을 통해 특정 메서드를 자동으로 생성해주는 라이브러리입니다. 참고로 롬북은 프로젝트마다 설정해줘야합니다. 물론 플러그인은 한 번만 하면 됩니다. (2번 과정) 1번과 3번 과정을 프로젝트마다 해줘야합니다. 1. build.gradle 파일에 아래와 같이 ..

[스프링부트] 롬북 플러그인 설치 & compile, compileOnly,implementation

책에서는 compile('org..')를 사용하라고 했으나 프로젝트에서 사용하면 글씨가 회색으로 변하면서 비활성화가 됩니다. 그래서 compile과 compileOnly가 무슨 차이가 있는건지 알아봤습니다. https://hack-jam.tistory.com/13 [Gradle] implementation vs compile 서론 Gradle dependency 관련해서 검색을 하다보면, 어떤 글에서는 implementation을 사용하고 어떤 글에서는 compile을 사용하는 경우가 있다. 사실 어떻게 사용해도 돌아가긴 해서, 음... 무슨 차이지?하고 bluayer.com compileOnly는 의존성 옵션입니다. compile 시에만 빌드하고, 빌드 결과물에는 포함되지 않습니다. compile은 A..

[스프링부트] 테스트코드 작성하기, hello 출력하기

HelloController.java package com.yeony.web.springbootwebproject.web; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController public class HelloController { @GetMapping("/hello") public String hello(){ return "hello"; } } HelloControllerTest.java package c..

[스프링부트] 어노테이션 모음

@SpringBootApplication : 스프링 부트의 자동설정, 스프링 Bean 읽기와 생성을 모두 자동으로 설정됩니다. 특히 @SpringBootApplication이 있는 위치부터 설정을 읽어가기 때문에 항상 이 클래스는 프로젝트의 최상단에 위치해있어야 합니다. @SpringBootApplication public class SpringbootWebprojectApplication { public static void main(String[] args) { SpringApplication.run(SpringbootWebprojectApplication.class, args); } // SpringApplication.run으로 내장 WAS(웹 애플리케이션 서버)를 실행합니다. // 내장 WAS란..

[인텔리제이] 프로젝트 깃허브 저장소에 올리기

인텔리제이에서 프로젝트를 깃허브 저장소에 올리는 방법에 대해 작성해보려고 합니다. 깃허브 액션을 활용할 겁니다. Command + Shift + A 단축키를 누르면 깃허브 액션 검색창이 활성화됩니다. share project on github를 타이핑하면 깃허브 로그인 창이 나옵니다. 깃허브 저장소에 등록하면 깃허브 사이트에 들어가지 않고도 바로 깃허브 저장소를 만들 수 있게 됩니다.

[스프링부트] Maven과 Gradle의 차이점

현재 공부중인 책과 강의에서는 gradle을 선택하여 프로젝트를 생성했습니다. 그런데, 회원가입 구현을 하면서 찾다 보니 gradle 대신 maven을 사용하는 프로젝트를 종종 보았고, 어떤 차이가 있는지 궁금해서 조사를 해보았습니다. 참고로 Maven과 Gradle은 빌드 관리 도구입니다. 빌드 : 빌드란 소스코드 파일들을 컴퓨터에서 실행이 가능한 소프트웨어로 변환하는 일련의 과정을 의미합니다. 따라서 컴파일, 테스팅, 배포 등이 빌드 과정의 집합에 속합니다. Maven과 Gradle 같은 빌드 관리 도구를 왜 사용해야 할까요? 빌드 관리 도구가 어떤 역할을 수행할까요? 빌드 관리 도구 : 빌드 자동화를 수행해 실행가능한 프로그램으로 바꿔주는 도구입니다. 빌드 관리 도구를 쓰면 뭐가 좋은건데?라는 의문..

[2138] 전구의 스위치 in python

https://www.acmicpc.net/problem/2138 2138번: 전구와 스위치 N개의 스위치와 N개의 전구가 있다. 각각의 전구는 켜져 있는 상태와 꺼져 있는 상태 중 하나의 상태를 가진다. i(1 < i < N)번 스위치를 누르면 i-1, i, i+1의 세 개의 전구의 상태가 바뀐다. 즉, 꺼져 www.acmicpc.net 시간 복잡도를 생각하지 못하고 bfs로 탐색을 진행했다가 메모리초과 뜸.. 아래 코드의 시간복잡도는 O(N^2) 1초에 N의 범위가 2000 이하여야 쓸 수 있는 코드! 하지만 주어진 데이터 개수는 10만 시간 복잡도를 계산하면 10만 *. 10만 =. 100만 결국 O(N)으로 작성을 해야 함! 시간 제한은 2초 # import sys # from collection..

[1463] 1로 만들기 in python

https://www.acmicpc.net/problem/17626 17626번: Four Squares 라그랑주는 1770년에 모든 자연수는 넷 혹은 그 이하의 제곱수의 합으로 표현할 수 있다고 증명하였다. 어떤 자연수는 복수의 방법으로 표현된다. 예를 들면, 26은 52과 12의 합이다; 또한 42 + 32 + 1 www.acmicpc.net > dp i%2로 나눠지고 i%3으로 나눠지면 min함수를 이용해서 어떤 경우를 선택해야 최솟값으로 나오는 지 확인해야한다. 위에서 구한 값과 -1을 뺀 값중에서도 어떤 경우를 선택해야 최솟값으로 나오는 지 확인해야 한다. import sys n = int(sys.stdin.readline()) dp = [0 for _ in range(n + 1)] dp[0],..

[17626] Four Squares in python

> dp https://www.acmicpc.net/problem/17626 17626번: Four Squares 라그랑주는 1770년에 모든 자연수는 넷 혹은 그 이하의 제곱수의 합으로 표현할 수 있다고 증명하였다. 어떤 자연수는 복수의 방법으로 표현된다. 예를 들면, 26은 52과 12의 합이다; 또한 42 + 32 + 1 www.acmicpc.net 총 4개 이하의 자연수 제곱수들의 합으로 모든 자연수를 정의내릴 수 있다. N = a^2 + b^2 + c^2 + d^2 dp를 푸는 문제는 항상 규칙이 존재한다. n이 6일때를 생각해보자. i가 1일땐 1이라고 초기화 진행 i=2일때, 2는 1의 제곱수들의 합으로 정의할 수 있음. 2 = 1^2 + 1^2 2 - 1^2 = 1이다. 따라서 dp[1]과..

[1735] 분수합 in python

> 유클리드 호제법 최대 공약수를 구할 땐 유클리드 호제법을 이용해야 한다. * 유클리드 알고리즘 * : a, b의 최대 공약수는 (a-b),b의 최대공약수와 같다. 1. 임의의 두 자연수 a,b가 주어졌다. 2. 두 자연수 중에 큰 값을 a라고 가정한다. 3. 큰 수 a 자리에는 a-b와 b값 중에 큰 값을 넣는다. 작은 수 b 자리에는 a-b와 b값 중에 작은 값을 넣는다. 그리고 재귀함수를 호출한다. import sys sys.setrecursionlimit(100000) def gcd(a, b): if b == 0: return a return gcd(max(a - b, b), min(a - b, b)) c1, p1 = map(int, input().split()) c2, p2 = map(int,..

[1010] 다리놓기 in python

> 다이나믹 > 조합 일단 조합으로 먼저 푼 문제 해당 문제는 서로 다리가 교차되는 일은 허용되지 않으므로 순열(중복허용)대신 조합(중복불허)을 사용함. 조합은 팩토리얼 함수를 이용해서 구할 수도 있고, permutation 함수를 이용할 수도 있음. 해당 문제에서는 팩토리얼을 재귀함수로 구현 ex) 6C3 = 6 * 5 * 4 // 3! 8C3 = 8 * 7 * 6 // (3!) -> ( factorial(8) // factorial(8-3) ) // factorial(3) t=int(input()) def factorial(n): if n==0 or n==1: return 1 return factorial(n-1)*n for _ in range(t): w,e=map(int,input().split()..