일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 스프링
- Transaction
- Spring Security
- RestControllerAdvice
- exception
- 트랜잭션
- 스프링부트
- 객체지향프로그래밍
- Filter
- response
- 인터셉터
- 스프링 시큐리티
- Spring
- proxy pattern
- 관점지향프로그래밍
- Interceptor
- aspect
- http
- network
- SQL
- MYSQL
- OOP
- java
- request
- spring boot
- 자바
- 디자인패턴
- git
- aop
- mybatis
- Today
- Total
목록분류 전체보기 (64)
장쫄깃 기술블로그
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/QN1Xy/btrLLyLHZGA/ayL22jp8yn7XqbvjbDqRWk/img.jpg)
STRAIGHT_JOIN MySQL에는 STRAIGHT_JOIN 이라고 하는 JOIN이 있다. STRAIGHT_JOIN is similar to JOIN, except that the left table is always read before the right table. This can be used for those (few) cases for which the join optimizer processes the tables in a suboptimal order. 왼쪽 테이블을 강제로 먼저 읽는 JOIN이라고 보면 될 것 같다. 간혹 explain을 이용하여 쿼리 실행계획을 보면 index가 적용되지 않고 쿼리 타입이 ALL로 실행되는 경우가 있다. 이는 MySQL의 옵티마이저(optimizer)가..
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/n2SwK/btrLgTOOsQU/Q0nIqFA4xKwcxTYpWvQwgK/img.jpg)
INSERT IGNORE 중복키 제약조건에 위배되면 INSERT를 무시한다. 기본적으로 PRIMARY KEY를 기준으로 한다. INSERT IGNORE INTO USER (id, name, salary) VALUES ("user", "장쫄깃", 20000) REPLACE INTO 중복키 제약조건에 위배되면 해당 레코드를 삭제하고 다시 삽입한다. 기본적으로 PRIMARY KEY를 기준으로 한다. REPLACE INTO USER (id, name, salary) VALUES ("user", "장쫄깃", 20000)
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/cQxaue/btrLechPiKD/6jCIq2wSr9FubBMu2y1rn1/img.jpg)
DUPLICATE ON KEY UPDATE 데이터 삽입 시, PRIMARY KEY나 UNIQUE KEY가 중복되었을 경우 UPDATE, 중복이 아닌 경우 INSERT를 수행하는 구문이다. INSERT INTO [TABLE] (COLUMN1, COLUMN2, ...) VALUES (VALUE1, VALUE2, ...) ON DUPLICATE KEY UPDATE (COLUMN1 = VALUE1, COLUMN2 = VALUE2, ...) 기존 INSERT INTO 구문 뒤에 추가해서 사용하면 된다. 성능면에서도 괜찮은 구문이라는 말이 많다. 예) PK = id INSERT INTO USER (id, name, salary) VALUES("user", "장쫄깃", 20000) ON DUPLICATE KEY UP..
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/dyHqt5/btrGlUEAMbJ/M0irhfVh3dKyMlomCafYI1/img.jpg)
MyBatis란? MyBatis는 객체 지향 언어인 Java의 관계형 데이터베이스 프로그래밍을 좀 더 쉽게 도와주는 퍼시스턴스 프레임워크(Persistence Framework, 데이터를 다루는 클래스 및 설정파일 집합)이다. MyBatis는 JDBC를 통해 RDBMS에 액세스하는 작업을 캡슐화하고 기존 JDBC의 중복작업을 간소화해준다. 또한, XML 파일의 형태인 mapper를 통해 프로그램 코드로부터 SQL 쿼리를 분리되는 환경을 제공하고 Java 객체와 매핑하는 작업을 도와준다. 추가적인 특징은 다음과 같다. 기존 JDBC보다 사용하기 편리 다른 ORM(Object Relational Mapping) 프레임워크에 비해 추가적인 학습의 부담이 적음 복잡한 쿼리 또는 다이나믹한 쿼리를 지원 프로그램 ..
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/cvuVJv/btrGjbU8IO7/qsTnxscykQlaKR4O5fGAIk/img.jpg)
들어가며 대규모 서비스 개발 시에 가장 기본적으로 하는 튜닝은 바로 DB에서 Write와 Read DB를 Replication(레플리케이션, 복제)하고, 쓰기 작업은 Master(Write)로 보내고 읽기 작업은 Slave(Read)로 보내어 부하를 분산 시키는 것이다. 특히, 대부분의 서비스는 읽기가 압도적으로 많기 때문에 Slave는 여러 대를 두어 읽기 부하를 분산 시킨다. 그런데 또 하나 기억해야 할 것이 Replication은 비록 짧더라고 딜레이가 존재하는 것이다. 따라서 정합성이 굉장히 중요한 데이터는 비록 Read 작업이더라도 Slave에서 읽지 않고 Master에서 읽어야만 하는 경우도 있다. 때문에, 해당 게시글에서는 Transaction Read-Only인 경우 Slave에서 Read..
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/bGt3hb/btrFTO65VEp/PUNkKmsSHRWlOPwumkBS1k/img.jpg)
들어가며 기존에 SpringBoot에선 tomcat-jdbc를 기본 DataSource로 제공했다. 하지만 2.0부터 HikariCP가 기본으로 변경되었다.(참고) HikariCP는 이전 버전에서도 많은 사람들이 설정을 변경해서 사용했을 정도로 인기가 많았다. 이번 게시글에선 HikariCP의 DataSource 정보를 설정하는 방법에 대해서 알아보려고 한다. 더 나아가 다음 게시글에선 HikariCP를 이용하여 Transaction Read-Only 적용 시 Master / Slave DB 라우팅하는 방법까지 가보려고 한다. 1. Dependency 추가 dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' im..
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/0ze8Z/btrFGOlLsuH/7xvSbZK5qDvZeFg3tAzwkK/img.jpg)
들어가며 Spring 에서는 Annotation 사용에 대한 기능을 많이 제공하고 있다. @Controller, @Service, @Component, @Repository 등 많은 Annotation이 존재한다. 해당 Annotation은 각 기능에 필요한 만큼 많은 기능을 내포하고 있으며, 이러한 내용을 잘 알지 못해도 필요한 기능만 쉽게 사용할 수 있도록 제공되어지고 있다. 하지만 이러한 Annotation에 대해 불필요한 내용이 포함되거나 새롭게 필요한 내용이 있는 경우 Custom을 하기도 한다. 그 중 주로 사용되는 @Target과 @Retention에 대해 알아보도록 하겠다. Meta-Annotation meta-annotation은 다른 annotation 에서도 사용되는 annotatio..
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/5gSrC/btrFKGN0pgf/vy205gADUyranuoKqxf7Xk/img.jpg)
들어가며 스프링 프레임워크로 개발시 빈을 등록할 때 빈의 의존관계로 인해 빈들이 등록되는 순서를 지정할 필요가 있다. (예를 들어, C 빈은 A빈과 B빈 등록 후에 등록되어야 한다.) 이 때 사용하는 어노테이션은 @DependsOn 에 대해 알아보려고 한다. @DependsOn @DependsOn 은 어떤 빈이 다른 빈보다 먼저 초기화되도록 강제하며, 에러가 발생하더라도 개발자가 원인을 찾을 수 있도록 메시지를 보여준다. @Component("A") public class ComponentA { // ... } @Component("B") public class ComponentB { // ... } @Component("C") @DependsOn(value={"A", "B"}) public class ..
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/bRLczU/btrFKH0n8SZ/wu88HPhR8QtNSkHYhksYZk/img.jpg)
들어가며 @Autowired는 Component Scan + @Component로 스프링 빈에 등록된 객체를 찾아서 필요한 의존관계를 설정한다. (우선적으로, 타입(Type)으로 해당 빈(Bean)을 찾는다.) 만약 @Autowired를 통한 자동 의존관계 주입 시 여러개의 빈이 존재한다면 어떻게 될까? 어떤 빈을 의존주입을 해야할 지 판단하지 못하는 경우 UnsatisfiedDependencyException 이 발생한다. UnsatisfiedDependencyException은 예외명에서도 알 수 있듯이 스프링 빈 객체들이 생성되는 과정에서 의존주입을 하게 되는데, 필드에 해당하는 의존관계를 만족시킬 수 없을 때 발생하는 예외이다. 그 중에서 대표적으로 NoUniqueBeanDefinitionExce..
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/cpFSlG/btrFBIyhFxI/eDqtVtFMeKdPRwMq7Xrre0/img.jpg)
Atomic 변수란 Atomic 변수는 원자성을 보장하는 변수이다. 멀티스레드 환경에서 동기화 문제를 해결하기 위해 synchronized 키워드를 사용하여 락을 걸곤 한다. 그런데 synchronized는 특정 스레드가 해당 블럭 전체를 lock 하기 때문에 낭비가 심하다. 이러한 문제를 해결하기 위해 고안된 방법이 Atomic 변수이다. Atomic 변수는 CAS(Compare And Swap) 알고리즘을 사용하여 NonBlocking하면서 동기화 문제를 해결할 수 있다. CAS(Compare And Swap) 알고리즘 멀티스레드 환경, 멀티코어 환경에서 각 CPU는 메인 메모리에서 변수값을 참조하는 것이 아니라, 각 CPU의 개시 영역에서 메모리를 참조하게 된다. (그림 2 참조) 이 때, 메인 메..