-
JPA ORM으로 테이블 복잡도 줄이기 성능 상의 이점을 보기 위해서 두 테이블로 나누지않고 하나의 테이블에 관련 정보를 모음 : JOIN 하지않고 그냥 SELECT 하기위해서 @Embedded와 @Embeddable로 복잡도 줄이기 : 객체 분리해서 모듈 형태로 관리하기 - 하나의 큰 판(CarInfo)과 여러 모듈(Car, Owner) 테이블 mysql> desc carinfo; +-------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+-------------+------+-----+---------+-------+ | id | int(11) | NO | PRI | NULL | | | name |...
-
데이터 캐시하기(2) - 스프링 캐시 추상화, redis 글로벌 캐시 스프링 캐시 추상화 - AOP, 캐시 매니져 AOP : @Cacheable, @CacheEvict 캐시 관련 코드를 비즈니스 로직에서 덜어낼 수 있도록 어노테이션(포인트컷)을 설정해두면 프록시? CGLib? 어찌되었건 캐시 동작(read, write) @Cacheable : 캐시 서비스를 메소드 단위로 설정 어노테이션 name : 캐시 이름 메소드 파라미터(key), 리턴 데이터(value) : 파라미터가 없을 경우 기본 키 값을 생성, 파라미터가 여러개인 경우 key=”#파라미터명” 으로 설정, 객체일 경우 key=”#객체.필드명” (SpEL) @Cacheable("item") public Item findByName(String name)...
-
JPA, Spring lazy loading 실제 사용할 때까지 연관관계에 있는 객체를 실제로 데이터 찾고(커넥션) 초기화 하지않음 : 메모리를 아낄 수 있고, 커넥션을 하지않으니 효율적(쓸데 없이 테이블 JOIN을 하지않아도 되는 것임) 대신 원 타입을 상속받은 프록시 객체(가짜)가 할당되어있음 : 해당 객체를 처음 사용(최초 1회 - 메모리 상)하려고할 때 그제서야 데이터베이스에서 데이터를 찾고 객체 초기화를 함 컬렉션을 그대로 get받아도 초기화하지않다가 컬렉션.get(idx)를 할 떄 초기화 : 아래 예시를 보면 hibernate에서 만들어낸 컬렉션 이름이 나옴 - 쿼리도 여전히 날리지않음 영속성...
-
정리해보기 객체지향 객체지향 : 분업화, 하나의 세상을 이루기위해서 하나의 존재만이 있는 것이 아니라 여러 존재들이 협업하면서 세상을 이룸, 협업이 필요하다면 필요한 객체가 다른 객체에 메세지를 보내 요청함, 파일로 코드를 분리한 것과는 전혀 다른 개념임(저장 공간만 달리할 뿐 하나로 처리하는건 마찬가지) 객체지향의 장점 : 역할 별로 객체를 나누다보니 어떤 한 기능을 수정할 때 담당 객체의 코드만 수정해주면 됨 - 변경점이 하나로 모임, 변경사항이 생기더라도 유연하게 대처할 수 있음(코드 간의 의존성이 적기때문에 - 물론 객체지향적인 프로그래밍을 했다면),...
-
Spring-data-JPA 상태 기본적으로 트랜잭션 내에서 JPA/Hibernate가 관리하냐 마냐의 상태 - 관리 대상이 아니면 영속화와는 상관없이 gc 대상 객체일 뿐, 중간 계층이 존재함(성능적인 장점이 있음 - 커넥트를 여러번 하지않음) transient : 관리한 적이 없는 상태, 일반 객체(ID가 없음) persistence : 관리하고 있는 상태, 1차 캐시 대상, 트랜잭션 내에서 얘를 찾으면 SELECT 쿼리 날리는 대신 캐시한 객체를 리턴해줌 detached : 트랜잭션이 끝나고 Persistence Context가 제거된 상태, 관리한 흔적으로 맵핑 데이터는 있으나 일반 객체 removed : 트랜잭션 내에서...
-
스프링부트 환경설정 알아보고 dev/prod 환경에 따른 설정하기 외부에서 어플리케이션 환경설정하기 주로 사용되는 방법은 application.properties 파일에 설정을 함 key-value 형태로 정의해두면 어플리케이션 내에서 사용할 수 있음 : 설정값 가져오는 방법(1) - @Value로 다양한 외부에서 환경설정 방법이 있어서 적용 우선순위가 있음 스프링부트가 기본적으로 어플리케이션 구동 시 필요한 설정을 이미 해둔 것이 있음 : 우선순위가 가장 낮음 - 기본 설정된 key-value 살펴보기 jar 실행 시 커맨드라인으로도 환경설정을 할 수 있음 : properties 파일로 선언하는 것보다 적용 우선순위가 높음(훠어어얼씬...
-
sql 테이블 생성, 수정하기 TINYINT와 INT 타입 : 가격 데이터를 저장해야하는데, TINYINT는 -127 ~ 128까지 저장가능함 -> 데이터 타입을 변경해야함, INT(21억) 늘릴 수 있지만 줄일 수 없음 > CREATE TABLE ITEM ( ITEM_ID INT AUTO_INCREMENT, NAME VARCHAR(50) NOT NULL, PRICE TINYINT DEFAULT 0, QUANTITY INT DEFAULT 0 PRIMARY KEY (ITEM_ID); ); > ALTER TABLE ITEM MODIFY COLUMNN PRICE INT DEFAULT 0; SELECT - ORDER BY 정렬하기 : ORDER BY 열 DESC ASC 복수열 정렬 가능...
-
JPA 연관관계 맵핑 - 객체지향과 데이터베이스의 패러다임 불일치 인식하기 객체의 관계는 단방향이지만, 데이터베이스의 테이블은 fk 하나로 양방향 관계를 맺을 수 있음 반대쪽에 객체 참조 필드를 생성하기 전까지 단방향 관계임 : 테이블은 SQL FK로 JOIN을 사용하면 둘다 조회가능하지만 객체는 .get()과 같은 메소드를 사용해야하는데 참조 필드가 없으면 할 수가 없음(패러다임의 불일치) - .get()을 해야 내부적으로 SQL을 생성할텐데 없으면 그렇지도 못함(이 부분은 없애고 올리기) /****** 단방향 ******/ public class Member { private Long id; private Team team; }...
-
java-ims 내부 flow Request 메세지 파싱 Request 객체 생성 Request에 핸들러(컨트롤러) 요청 : path를 가지고 있기때문에 위임 컨트롤러에 Request 넘겨주며 처리 요청 ResponseEntity(HttpMethod, Header, Body) 생성 Response 객체 응답하기 Response 작성할 때 필요한 데이터를 가진 ResponseEntity 만들기 빌더 패턴으로 만들기 장점 : 조립하듯이 객체를 생성할 수 있음, 객체 생성 시 설정해야할 필드가 많아지면서 선택적으로 필드를 설정할 수 있게할 때 좋음(유연성), 특정 필드만 깔끔하게 기본값을 설정해둘 수 있음, 필드 각각의 할당 조건이 생길 때 분리해두면 코드가...
-
java-was 기존 코드 분석하기 서버 소켓(8080 - 웹서버가 80을 사용하고, WAS는 8080 리버스 프록시)을 만들어두고 클라이언트 소켓의 연결 요청을 기다림 클라이언트 소켓이 연결되면 클라이언트의 요청을 처리할 핸들러(쓰레드)를 실행시킴 : 클라이언트 연결 Request 만들기 Request 담당 오브젝트 테스트하면서 만들기 Request 생성자 설계 : InputStream을 인자로 받음 매번 브라우저로 요청을 보내고 HTTP 메세지를 읽지않기위해 모의 HTTP 메세지로 내용이 구성된 파일(request.txt)로도 읽을 수 있게) request.txt 읽기 gradle, maven은 정해진 디렉토리에 정해진 파일을 넣어야함 : resource를 class path에 넣어두고...
-
java-ims ControllerAdvice, RestControllerAdvice @RestController와 @Controller의 차이 : 응답 데이터가 json이냐 뷰(.html)냐 차이 @RestControllerAdvice : response를 json으로 변환해주는 역할, rest api 구현할 때 사용 컨트롤러의 타입에 따른 예외처리 분기 같은 타입의 예외지만 각기 다른 처리를 할 수 있음 : json 응답, redirect 혹은 특정 view 응답 /* RestController */ @RestControllerAdvice(annotations = RestController.class) @Order(1) public class SecurityRestControllerAdvice { ... } /* Controller */ @ControllerAdvice(annotations = Controller.class) @Order(2) public class SecurityControllerAdvice { ... } ResponseEntity static 메소드 ResponseEntity의...
-
JPA DDL : 테이블 생성, 변경 등의 쿼리, 테스트 서버에서는 자동 변경하도록 설정하는 것이 괜찮지만 실서버에서는 그러면 안됨 스키마 : 데이터베이스 테이블 정보를 집약해서 하나 만들어두고, 레퍼런스 삼아서 JPA(정확히는 구현체) 작업을 함 키(pk) 생성할 때 : 대리키를 사용하라 키 생성 전략(자동 - 대리키) : 엔티티에 키를 할당하는 전략, 데이터베이스 마다 각각 다른 전략을 취하고 있음 IDENTITY : 키 생성부터 할당까지 데이터베이스에서 함, auto_increment 전략을 사용하려면 해당 전략을 사용해야함 SEQUENCE : 키 생성은 데이터베이스 시퀀스(키 생성...
-
JPA - 영속성 컨텍스트 영속성 컨텍스트란 순수 객체와 데이터베이스의 중간에 위치한 계층 : 중간 계층(레이어)을 둠으로써 얻는 이점이 있기때문에, JPA는 영속성 컨텍스트라는 레이어를 둠 엔티티 매니져를 통해서 접근한다고 생각하면 됨 J2EE 환경 : 엔티티매니져 당 하나의 영속성 컨텍스트를 가지고 있음 스프링 사용 환경 : 트랜잭션 내에서 여러 엔티티매니져가 하나의 영속성 컨텍스트에 접근(사용), 영속성 컨텍스트는 트랜잭션 끝나면 삭제 영속성 컨텍스트 특징 @Id로 엔티티 식별 : 식별자 값이 없으면 안됨(에러 발생) /* 엔티티를 영속성 컨텍스트에 저장해두고 관리...
-
스프링 프로젝트 - java-ims Mockito를 통한 Service 단위테스트와 도메인 단위테스트 다른 의미의 테스트임 : 같아보이지만 Service 계층을 테스트 하는 것과 도메인에 대한 단독 테스트는 다름 서버 자원을 사용하는 것과 일반 자바 객체를 테스트 하는 것에서 차이 삭제 기능 바로 삭제를 하지않고, 삭제 상태로 만들어놓음 : 삭제 상태로 변경된 엔티티를 또다른 엔티티(히스토리)로 만들어서 보관함 일정 기간이 지났을 때 엔티티를 실제로 삭제함 기록 또한 일정기간 보관 @Entity public class DeleteHistory { @Id @GeneratedValue(strategy = GenerationType.IDENTIFY) private long...
-
스프링과 스프링모듈 하나(이상)씩 알아(만)가기 Spring J2EE로 자바 어플리케이션을 개발할 때 편하게 개발할 수 있도록 제공하는 프레임워크 모듈 형태로 개발 편의를 제공함 : Spring MVC, Spring Data 등 흔히들 하는 착각 : Spring == Spring MVC <– 아닙니다! 모듈과 함께 스프링빈 컨테이너를 제공함 컨테이너 : 어떤 것의 라이프사이클을 관리해주는 역할, 여기서 어떤 것은, 라이프사이클은 인스턴스의 생성부터 소멸까지를 말함, 인스턴스는 기본적으로 싱글톤으로 관리됨 스프링빈 : 스프링 컨텍스트에서 사용되는 인스턴스(스프링 빈)을 말함, 스프링 컨테이너에서 관리되는 인스턴스 즉 스프링빈이...
-
REST API ATDD REST API REST 디자인 원칙을 지켜서 만든 Web/HTTP API : 여기서 API는 원격에서 다른 시스템의 메소드를 콜하는 인터페이스를 말함(리소스 핸들링을 위한 - 기본적으로 CRUD) REST 등장 배경 : 현재 형성된 웹 환경을 파괴하지않으면서도 HTTP를 발전 시킬 수 없을까? 웹서버에 변경이 생기더라도 클라이언트에는 아무런 영향을 미치지않도록 발전시킬 수 없을까? 궁극적으로 서버와 클라이언트의 디펜던시를 제거함으로서 얻을 수 있는 이점을 얻기위해서 원칙을 만들게 됨 어떻게 디펜던시를 제거하나? 일관된 URI 디자인(요청), 요청에 대한 응답 결과의 메세지만으로도...
-
테스트 코드 중복 없애기 테스트 코드 중복을 없애기 위해서 2가지 방법(+@)이 있음 @Before 메소드를 사용 : 모든 테스트메소드가 거치기때문에 필요없는 메소드도 호출하는 단점이 있음 일반 메소드(prehandle 개념 메소드)를 정의해두고 prehandle을 거쳐야하는 @Test에서 호출하는 방법 : 코드양은 늘어나지만 필요한 메소드에만 적용시킬 수 있음 +@ 방법은 2번째에서 상속을 사용해서 중복을 제거하는 것 테스트 코드 또한 중복을 제거하지않으면 테스트 케이스가 늘어날수록 중복 제거한 코드보다 코드양이 훨씬 더 늘어남 2번째 방법으로 중복 제거하기 public class QnaAcceptanceTest extends AcceptanceTest {...
-
스프링 @RestController와 @Controller의 내부 동작 차이 @Controller : 선언한 컨트롤러는 뷰 이름을 리턴하고, 뷰 리졸버가 뷰를 찾아 응답하는 형태 : text/html @RestController : @Controller 선언과 @ResponseBody 선언을 합쳐둔 어노테이션 @ResponseBody : Http response message body에 컨버팅된 리턴 데이터를 써서 응답함 리턴 데이터가 MessageConverter를 거쳐 요청자의 요청 형태로 컨버팅(json, xml)하여 응답 메세지 바디에 입력해서 응답함 MessageConverter 라이브러리 : Jacson(json), Marshalling(xml) @RestController 적용 코드 @RestController @RequestMapping("/api/questions/{questionId}/answers") public class ApiAnswerController { @PostMapping public Answer create(@PathVariable Long questionId, String...