RetroTV's Dev Blog

RetroTV's Dev Blog

나의 배움에 대한 기록

Docker

Docker에서 MariaDB UTF-8 설정하기

MySQL/MariaDB를 써본 적이 있다면, 기본 문자열 셋이 latin1으로 되어 있다는 것을 알고 있을 것이다. (참고로 MySQL은 8 버전부터 기본 UTF-8로 설정되어 있다.) 일반적으로 my.cnf 혹은 my.ini 파일에서 UTF-8 설정을 해줌으로써 해결할 수 있지만, Docker를 사용할 경우 컨테이너 배포 과정에서 미리 문자열 셋을 설정해 줌으로써 번거로운 작업을 건너
1 min read
JAVA

객체지향 언어에 인터페이스가 존재하는 이유

코드의 결합도가 높으면 생기는 문제 어떤 개발자가 고객으로부터 계정의 패스워드를 암호화 해서 저장을 해야하니, 패스워드를 암호화 하는 기능을 만들어야 한다는 요청을 받았다. 개발자는 금방 암호화 기능을 추가해 고객에게 보여주었다. @Test public void encryptMD5() throws NoSuchAlgorithmException { // 외부에서 입력받은 패스워드 String password = "this is password"; // MD5 알고리즘으로 문자열을 인코딩 한다
15 min read
Raspberry Pi

라즈베리 파이 SSH 모니터/키보드 없이 활성화 하기

더 이상 ssh 파일을 추가하는 방법이 안 먹힌다! 언제부터 인지는 잘 모르겠지만, 몇몇 국가에서 보안을 위해 운영체제에 기본 계정 생성을 금지하는 법안을 도입했다고 한다. 라즈베리 파이에서도 이런 트랜드를 반영하여 2022년 초에 배포된 Raspberry Pi OS (Bullseye)부터는 기본 계정이 생성되지 않도록 바뀌었다고 한다. 즉, 기존에 Raspberry Pi OS를 올린 sd
4 min read
JAVA

Spring Data JPA 3부터 바뀐 SEQUENCE(시퀀스) 기본키 생성 전략

마이그레이션을 진행합니다... 안되잖아? Spring Boot 3이 공식적으로 배포되기 시작하면서, 이 참에 2.7.X 버전으로 개발중이던 프로젝트를 3.0.0으로 업그레이드 했다. 마이그레이션을 진행 하면서, 하나하나 발생한 문제를 손수 뜯어 고치고 프로젝트를 실행 했더니 이게웬걸! 뜬금없이 JPA 쪽에서 문제가 발생했다. 알고보니 기존의 Spring Data JPA 2에서 Hibernate 5를 사용하다 Spring
3 min read
Podman

Podman의 개념과 설치방법

Podman 이란? Podman(Pod manager tool)은 리눅스 시스템에서 컨테이너를 개발, 관리, 실행하기 위한 오픈소스 툴이다. 기존의 Docker와 같은 컨테이너 엔진이지만, Docker와는 몇가지 다른 점이 존재한다. 대표적으로는 아래와 같이 2가지 차이점을 들 수 있다. daemonless Docker는 Docker daemon을 통해 Docker client의 모든 명령어를 처리하게 된다. 이러한 방식은 작업을 처리할 때
6 min read
JAVA

스프링 부트 Kafka 연동하기

개발환경 * OpenJDK 17 * Docker Spring Boot 프로젝트 생성 1. https://start.spring.io 접속. 2. 아래 사진과 같이 설정하고 프로젝트 생성. 프로젝트 불러오기 1. 생성된 프로젝트 압축파일 풀기. 2. 압축이 풀린 폴더를 IDE에서 폴더 열기로 프로젝트를 불러오기. 프로젝트 구조 application.yml 생성 1. src/main/resources 디렉토리에 존재하는 application.properties
4 min read
Spring

스프링을 쓰는 이유

왜 스프링을 쓸까? 국내에서 가장 많이 쓰이는 백엔드 프레임워크는 단연 Spring Framework(이하 스프링)일 것이다. 그런데 왜 스프링을 사용했냐고 물어보면 이 질문에 대해 답할 수 있는 사람은 별로 없다는 것을 깨닫게 될 것이다. 이는 스프링이 제시하는 핵심 가치나 특징을 모르기 때문에 그런 것이다. 그렇다면 위의 질문에 대답할 수 있도록,
6 min read
Database

트랜잭션(Transaction)과 ACID

트랜잭션이란? 정보처리기사 데이터베이스 과목을 공부했거나, 웹 프레임워크(Spring, Express.js, Django 등)을 사용해 봤다면 트랜잭션이라는 용어는 무조건 들어보게 될 것이다. 그만큼 데이터베이스에서 트랜잭션이란 개념은 상당히 중요하다. 트랜잭션은 데이터베이스에서 하나의 논리적인 기능을 수행하기 위한 작업의 최소 단위를 의미한다. 데이터베이스에 접근하는 방법은 질의(Query) 이므로, 달리 말하자면 여러 개의 질의를 하나로
5 min read
JAVA

함수와 메소드의 차이

함수랑 메소드가 같은게 아니라고? 내가 JAVA를 주로 하면서 함수와 메소드를 구분해서 썼던 기억은 없었던 것으로 기억한다. 그랬으니 나는 당연히 함수와 메소드의 차이에 대해서도 잘 모르고 대충 뭉뚱그려서 전부 함수라고 불렀었다. 함수와 메소드를 구분 짓는 가장 큰 차이점은 '함수가 단독으로 존재하느냐, 아니면 클래스 내부에 포함되어 있느냐' 로 구별된다. 이제부터
4 min read
JAVA

객체지향 설계의 5가지 원칙

SOLID 원칙? 객체지향 설계를 할 때, SOLID 원칙을 지켜줘야 한다는 얘기는 정보처리기사 공부를 했다면 한번쯤은 들어봤을 것이다. (그리고 자격증을 취득하면 귀신같이 잊어버린다.) SOLID 용어는 다음과 같이 1. 단일 책임 원칙(Single Responsibility) 2. 개방-폐쇄 원칙(Open Closed Principle) 3. 리스코프 치환 원칙(Liskov Substitutuib Principle) 4. 인터페이스 분리 원칙(Interface
6 min read
Gradle

Gradle을 이용해 하나의 클래스 및 함수만 테스트 하기

하나의 클래스 테스트하기 Spring Boot 2 프로젝트를 진행하면서, JUnit 5을 이용해 테스트 주도 개발을 하고 있다. 그러던 중 한 가지 문제에 봉착하게 되었다. 테스트 규모가 커지기 시작하면서 테스트 실행 시, 모든 테스트를 실행하는 데에 부담이 생기기 시작한 것이다. 따라서 테스트 할 때, 클래스 혹은 함수 단위로 테스트를 할 필요가 생긴
7 min read
Gradle

*-plain.jar 빌드되지 않게 하기

Spring Boot 2에 포함된 Gradle(이하 그레이들) 플러그인이 2.5 버전부터 두 개의 jar 파일을 빌드하도록 변경되었다고 한다. 구글링을 해보니, 끝에 -plain이 붙는 jar 파일은 애플리케이션 실행에 필요한 런타임 의존성이 제거된 jar 파일이라고 한다. 런타임 의존성이 제거가 됐기 때문에, 우리가 jar 파일을 실행할 때 쓰는 명령어인 java -jar 로 실행이
2 min read
Gradle

jar 파일 이름 변경해서 빌드하기

스프링 부트 2 프로젝트를 빌드 한다면 보통, Gradle(이하 그레이들)이나 Maven을 이용해 빌드하게 될 것이다. 나 같은 경우에는 그레이들을 사용해서 빌드하고 있는데, 문제는 빌드 결과물인 jar 파일의 이름이 불필요 할 정도로 길다는 점이었다. 일반적으로 프로젝트를 빌드하면, 다음과 같은 규칙으로 jar 파일 명이 결정된다. <프로젝트 명>-<
4 min read
Jenkins

Jenkins로 Spring Boot 2 + Vue 3 프로젝트를 리눅스 서버에 배포하기 (3)

새로운 빌드 Item 생성하기 Jenkins 메인 화면 좌측에 새로운 Item 이라는 버튼을 클릭하자. Item을 식별할 이름을 지정 해준 뒤, Freestyle project를 선택하고 OK 버튼을 클릭한다. 나는 Book Management App 이라는 이름으로 지정해 주었다. 가장 위, 설명에 이 Item이 어떤 것인지 알려주는 문구를 적어주자. (EX. 이 Item은 나의 프로젝트를 빌드하는 Item
10 min read
Jenkins

Jenkins로 Spring Boot 2 + Vue 3 프로젝트를 리눅스 서버에 배포하기 (2)

Jenkins로 프로젝트 자동 배포하기 지난 글에서는 나의 프로젝트를 배포할 서버를 세팅하는 과정에 대해 다루었다. 이번 글에서는 Jenkins를 통해 Spring Boot 2 + Vue 3 프로젝트를 자동 배포하는 방법에 대해 다루도록 하겠다. Jenkins를 사용할 것이기 때문에, 당연히 Jenkins가 배포되어 있는 서버가 필요하다. 만약 Jenkins 서버가 없다면 아래의 글을 참조해 하나 만들도록 하자.
7 min read
AWS

AWS Lightsail 인스턴스 생성하고 PuTTY로 접속하기

AWS Lightsail 인스턴스 생성하기 AWS Lightsail의 특징 원래 AWS 하면 가장 먼저 떠올리는 서비스는 EC2일 것이다. EC2 서비스의 특징은 사용한 시간에 따라 과금이 된다는 점이다. 따라서 EC2 인스턴스는 24/7(항상 가동되는) 서비스를 사용하는 데에 부적합하다. (그리고 뭣보다 EC2 인스턴스를 계속 켜두면 지갑이 위험해질 것이다...) 이 점을 아마존도 알고 있어서,
12 min read
Docker

리눅스에서 sudo 없이 도커 사용하기

sudo 쓰기 귀찮은데... Windows나 MacOS에서는 Docker(이하 도커)를 설치할 때, 일반 계정 권한으로 설치하게 된다. 그렇기 때문에 도커를 사용할 때, 관리자 권한으로 도커를 실행할 필요가 없다. 그러나 Linux 에서는 root 권한으로 도커를 설치하기 때문에 root 외의 사용자가 docker 명령어를 사용하면 권한 오류가 발생한다. 이 때문에 도커를 실행하고 docker 명령어를
2 min read
Jenkins

Jenkins로 Spring Boot 2 + Vue 3 프로젝트를 리눅스 서버에 배포하기 (1)

시작하기에 앞서... 이 글은 내가 만든 도서 관리 앱을 AWS Lightsail에 Jenkins로 자동 배포하는 과정을 정리한 글임을 먼저 밝힌다. 이 글을 정독하기 전에, 먼저 아래의 글을 읽고 AWS Lightsail 인스턴스를 생성하고 PuTTY 사용법에 대해서 알아보는 것을 권장한다. 만약 본인이 이미 VPS를 통해 인스턴스를 생성하고 PuTTY로 원격 접속하는 방법에 대해 알고
11 min read
Docker

Docker로 Jenkins 서버 구축하기

준비사항 * Docker가 설치되고 사용할 수 있는 환경 이 글의 내용은 Linux/MacOS/Windows 운영체제에서 적용이 가능 하지만, 각 운영체제 별로 적용 방법이 조금씩 상이할 수 있다. 여기서는 기본적으로 MacOS를 기반으로 작성했음을 알린다. 운영체제 별로 몇 가지 차이점에 대해 미리 설명하자면 다음과 같다. 사전설명 * Linux의 경우 sudo 권한을 이용해 Docker를 설치하기
9 min read
JAVA

Spring Data JPA에서 Specification으로 엔티티 JOIN하기

엔티티 쪼개기 혹시나 정보처리기사 자격증을 땄거나 혹은 따기 위해 정보처리기사 공부를 했다면 알고 있겠지만, 관계형 데이터베이스는 정규화라는 과정을 거치면서 데이터의 중복을 제거해 나간다. 이 과정에서 중복된 데이터는 중복을 제거한 뒤 다른 테이블로 쪼개지고, 기존 테이블의 컬럼 값은 FK(이하 외래 키)로 대체된다. [JPA] 스프링 데이터 JPA에서 Specification으로 동적 WHERE절
9 min read
JAVA

객체지향 쿼리 언어 (JPQL)

JPQL(Java Persistence Query Language) 이란? 지난 [JPA] 스프링 데이터 JPA에서 Specification으로 동적 WHERE절 구현하기 (1) 글에서 'JPA에서 사용하는 SQL과 비슷한 언어라고 만 생각하면 될 것 같다.' 라고 남겨 놨었는데, 사실 Specification을 제대로 쓰기 위해선 JPQL을 먼저 알아야 한다. JPA는 기존의 SQL 중심적인 개발을 타파하고 엔티티라는 객체를 중심으로
9 min read
JAVA

스프링 데이터 JPA에서 Specification으로 동적 WHERE절 구현하기

책 조회를 위해서는 동적 WHERE절 기능을 구현해야 할 것 같은데... 개인적으로 진행했던 도서 장부 프로젝트에서 외부에서 입력 받은 조회 조건들의 존재 여부에 따라 동적으로 WHERE절을 생성할 필요가 있었다. -- 이해를 돕기위해 간략화 된 책 조회 쿼리입니다 SELECT * FROM BOOK WHERE TITLE = '제목' AND AUTHOR_NAME = '저자명'
10 min read