📢 mybatis parameter가 2개 이상일 경우 사용방법

💡 parameterType="map"를 이용하면 된다.

    <select id="findById" parameterType="map" resultType="Member">
        SELECT
        <include refid="memberColumns" />
        FROM member
        WHERE id = #{id, jdbcType=BIGINT}
          and member_id = #{memberId, jdbcType=VARCHAR}
    </select>


@Param 이용 

Controller

memberService.findById(Long id, String memberId)

Service

memberMapper.findById(Long id, String memberId)

Mapper

Member findById(@Param("id") Long id, @Param("memberId") Long memberId);


Map 이용 

Controller

Map<String, Object> param = new HashMap<>();
param.put("id", id);
param.put("memberId", memberId);

memberService.findById(id, memberId);

✔ Service

memberMapper.findById(Map<String, Object> param)

Mapper

Member findById(Map<String, Object> param)

 

📌 [mybatis] resultType이 String인 경우 경고 메시지가 뜨네요


Mybatis에서 DB정보를 이용하여 가공된 텍스트값을 받으려고 합니다. 

    <select id="getInfo" resultType="String">
        select 'abc'
    </select>


그런데 mapper interface에서 다음과 같은 경고메세지가 빨간줄과 함께 표시됩니다.

@Mapper 
public interface InfoMapper {
	String getInfo();
}

===============================================
Result type not match for select id="getInfo" 

srcType: java. lang. String 
targetType: java. lang. String
===============================================

분명 같은 타입인데도 말이죠. 

MyBatis에서 resultType="String"을 지정하면 "Result Maps collection does not have a type handler for result object" 또는 비슷한 경고 메시지가 발생할 수 있습니다. 이는 MyBatis가 반환할 데이터 타입을 명확하게 매핑하는 과정에서 발생하는 경고입니다.

📝 해결 방법

resultType="java.lang.String"으로 명시

경고가 단순한 매핑 이슈라면 resultType="java.lang.String"처럼 패키지명을 명확하게 적어주는 것만으로도 해결되는 경우가 있습니다. 

    <select id="getInfo" resultType="java.lang.String">
        select 'abc'
    </select>

이 방법으로 해결이 안된다면..

✅ resultType="String" 대신 resultMap 사용

MyBatis의 resultMap을 정의하고, 이를 select 문에서 참조하는 방식으로 해결할 수 있습니다.

<resultMap id="StringResultMap" type="java.lang.String"/>
<select id="getInfo" resultMap="StringResultMap">
    select 'abc'
</select>

저는 이방법으로 해결했습니다.  🤔

 

 

📌 [mariadb / mysql / mybatis ] Like문 사용방법 

회원테이블에서 김씨 성을 검색하는 방법입니다. 

select *
  from 회원테이블
 where member_id like '김%'

 Mybatis에서 변수로 처리하기 위해서 검색부분을 분리하면 검색이 안됩니다. 

select *
  from 회원테이블
 where member_id like '김' + '%'

concat 함수를 이용하여 분리해야 합니다. 

select *
  from 회원테이블
 where member_id like concat('김', '%')

✅ 이제 Mybatis에서 parameter로 검색어를 받아서 조회할 수 있습니다. 

    <select id="findByMember" parameterType="String" resultType="Member">
        select member_id, member_name
        from member
        where member_name like concat(#{searchTxt},'%')
    </select>

 

📌 mariadb / mysql 함수

📝 문자열 함수

left(문자열,자리수) : 왼쪽에서 문자열 자르기
✅ right(문자열,자리수) : 오른쪽에서 문자열 자르기
✅ substring(문자열,시작위치,길이) : 시작위치부터 길이만큼 문자 반환, 길이가 생략되면 문자열의 끝까지 반환

select left('abcdefg',3);
결과 : abc

select right('abcdefg',3);
결과 : efg

select substring('abcdefg', 3, 2);
결과 : cd

LPAD(str, len [,padstr])
✔ str의 값을 len에서 설정한 숫자만큼 표시한다. 
✔ str의 값의 길이가 len에서 설정한 값보다 크면 str이 일부분 표시된다.
✔ str의 값의 길이가 len에서 설정한 값보다 작으면 차이만큼 padstr이 표시된다. (생략하면 space가 표시됨)

 select lpad('abcde',3,'0')
 결과 : abc 
 
 select lpad('abcde',10,'0')
 결과 : 00000abcde 

 select lpad('abcde',10)
 결과 :      abcde


📝 형변환 함수

✅ 문자를 숫자로 변환 

SELECT CAST("001" AS INTEGER);
결과 : 1


📝 null 처리 

✅ ifnull(값1, 값2)
  값1이 null이면 값2로 치환한다

select ifnull(10, 0)
결과 : 10

select ifnull(null, 0)
결과 : 0

 

 

📢 무료 Rest API data 제공 사이트 - JSONPlaceholder

    JSONPlaceholder는 프론트엔드 개발자API 테스트를 원하는 개발자를 위해 무료로 제공되는 REST API 서비스입니다. 실제 서버를 구축하지 않고도 가상의 데이터를 사용하여 API 호출을 테스트할 수 있도록 도와줍니다.

💻 JSONPlaceholder 사이트 바로가기 

 

JSONPlaceholder - Free Fake REST API

{JSON} Placeholder Free fake and reliable API for testing and prototyping. Powered by JSON Server + LowDB. Serving ~3 billion requests each month.

jsonplaceholder.typicode.com

📝 JSONPlaceholder를 사용하는 이유

 프론트엔드 개발자가 백엔드 없이 API 테스트 가능
 백엔드 개발자가 API 구조를 설계하고 샘플 데이터로 테스트 가능
 단순하고 빠르게 가짜 데이터를 활용하여 개발 환경 구축 가능
 무료이면서도 강력한 REST API 제공

📝 게시글 목록 조회 (GET /posts)

👉 요청 : 

// command line, 또는 bash 
curl https://jsonplaceholder.typicode.com/posts

// 브라우저에서는 url만 입력합니다.
https://jsonplaceholder.typicode.com/posts

👉 응답 (JSON 데이터):

[
  {
    "userId": 1,
    "id": 1,
    "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
    "body": "quia et suscipit..."
  },
  {
    "userId": 1,
    "id": 2,
    "title": "qui est esse",
    "body": "est rerum tempore vitae..."
  }
]

 

📝 사용 가능한 엔드포인트 (API)

JSONPlaceholder에서 제공하는 주요 API 엔드포인트는 다음과 같습니다.

엔드포인트 설명
/posts 게시글 목록 조회
/posts/{id} 특정 게시글 조회
/comments 댓글 목록 조회
/comments?postId={id} 특정 게시글의 댓글 조회
/albums 앨범 목록 조회
/photos 사진 목록 조회
/users 사용자 목록 조회
/todos 할 일 목록 조회

👉 요청 예 : 

https://jsonplaceholder.typicode.com/albums

https://jsonplaceholder.typicode.com/todos/3


📝 
주요 특징

✅ 무료(Mock API) 제공
  API 개발이나 프론트엔드 연동을 테스트할 때 실제 백엔드 없이도 사용할 수 있는 무료 서비스입니다.

 RESTful API 지원
 GET, POST, PUT, PATCH, DELETE 등의 HTTP 요청을 지원하여 실제 API처럼 활용할 수 있습니다.

 샘플 데이터 제공
 가상의 사용자, 게시글, 댓글, 사진 등의 JSON 데이터를 미리 제공해줍니다.

 CORS & JSON 지원
 CORS(Cross-Origin Resource Sharing)를 지원하여, 다양한 환경에서 테스트할 수 있습니다.

 빠르고 간편한 사용
 회원가입이나 인증 없이 API 호출만으로 바로 사용할 수 있습니다.

 

 

[Java(자바)] 현재 날짜, 현재 시간 구하기 

LocalDate 사용 (날짜만 필요할 때)

import java.time.LocalDate;

public class Main {
    public static void main(String[] args) {
        LocalDate today = LocalDate.now();
        System.out.println("현재 날짜: " + today);
        
        // 포맷 적용하기 
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd");
        String nowString = now.format(formatter);
        
        System.out.println("포맷팅 날짜: " + nowString);
        
    }
}


👉
  
출력 결과 

현재 날짜: 2025-03-04
포맷팅 날짜: 2025/03/04

 LocalDateTime 사용 (날짜와 시간 필요할 때)

import java.time.LocalDateTime;

public class Main {
    public static void main(String[] args) {
        LocalDateTime now = LocalDateTime.now();
        System.out.println("현재 날짜와 시간: " + now);
    }
}

👉  출력 결과 

현재 날짜와 시간: 2025-03-04T14:30:45.123

ZonedDateTime 사용 (시간대 포함)

import java.time.ZonedDateTime;
import java.time.ZoneId;

public class Main {
    public static void main(String[] args) {
        ZonedDateTime seoulTime = ZonedDateTime.now(ZoneId.of("Asia/Seoul"));
        System.out.println("서울 시간: " + seoulTime);
    }
}

👉  출력 결과 

서울 시간: 2025-03-04T14:30:45.123+09:00[Asia/Seoul]

Date 클래스 사용 (구버전(버전 8 이전), 권장X)

import java.util.Date;

public class Main {
    public static void main(String[] args) {
        Date date = new Date();
        System.out.println("현재 날짜와 시간: " + date);
    }
}

👉  출력 결과 

현재 날짜와 시간: Tue Mar 04 14:30:45 KST 2025



📢  IntelliJ IDEA Community Edition에서 한글 언어팩을 사용하는 방법은 다음과 같습니다

플러그인 설치:

    🟠 상단 메뉴에서 File > Settings(Windows/Linux) 또는 IntelliJ IDEA > Preferences(Mac)를 선택합니다.
    🟠 Settings 창에서 왼쪽 메뉴에서 Plugins를 클릭합니다.
    🟠 Marketplace 탭을 선택한 후, 검색창에 Korean Language Pack 또는 Korean을 입력하여 한글 언어팩을 검색합니다.
    🟠 검색 결과에서 Korean Language Pack 플러그인을 선택하고, Install 버튼을 클릭합니다.
    🟠 플러그인 설치가 완료되면, Restart 버튼을 눌러 IntelliJ IDEA를 재시작합니다.


언어 설정 (플러그인설치만으로 안되는 경우) 

    🟠 상단 메뉴에서 File > Settings(Windows/Linux) 또는 IntelliJ IDEA > Preferences(Mac)를 선택합니다.
    🟠  Settings 창에서 Appearance & Behavior > System Settings > Language and Region를 선택합니다.
    🟠  Language를 Korean 한국어로 선택하고 IntelliJ IDEA를 재시작합니다

📌 MultipartFile이란?

MultipartFile은 Spring Framework에서 제공하는 인터페이스로, HTTP 요청을 통해 업로드된 파일을 다룰 때 사용됩니다. multipart/form-data 타입의 요청을 처리할 수 있도록 설계되어 있으며, 이를 활용하면 이미지, 문서 등 다양한 파일을 서버로 업로드할 수 있습니다.


1️⃣ MultipartFile 기본 개념

Spring에서는 클라이언트가 파일을 업로드할 때 multipart/form-data 형식으로 요청을 보내야 합니다. 이때 Spring의 MultipartResolver가 요청을 해석하고, MultipartFile 객체를 생성하여 컨트롤러에서 이를 받을 수 있도록 합니다.

MultipartFile 인터페이스 주요 메서드

메서드 설명
getName() 요청 파라미터의 이름 반환
getOriginalFilename() 업로드된 파일의 원본 이름 반환
getContentType() 파일의 MIME 타입 반환 (image/png, application/pdf 등)
getSize() 파일 크기(byte 단위) 반환
isEmpty() 파일이 비어있는지 확인
getBytes() 파일을 바이트 배열로 변환
getInputStream() 파일을 스트림 형태로 변환
transferTo(File dest) 파일을 지정한 위치로 저장

2️⃣ 하나의 파일 업로드 예제 (Spring Boot)

Spring Boot에서 MultipartFile을 이용하여 파일을 업로드하는 예제를 만들어 보겠습니다.

import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;

@RestController
@RequestMapping("/upload")
public class FileUploadController {

    @PostMapping
    public String uploadFile(@RequestParam("file") MultipartFile file) {
        if (file.isEmpty()) {
            return "파일이 비어 있습니다.";
        }

        // 파일 저장 경로 (예제: 로컬 디렉토리)
        String filePath = "C:/upload/" + file.getOriginalFilename();

        try {
            file.transferTo(new File(filePath)); // 파일 저장
            return "파일 업로드 성공: " + file.getOriginalFilename();
        } catch (Exception e) {
            return "파일 업로드 실패: " + e.getMessage();
        }
    }
}

 

📝 파일 업로드 테스트 (Postman)

위의 컨트롤러를 실행한 후 Postman을 사용하여 파일 업로드를 테스트할 수 있습니다.

  1. Postman 실행
  2. POST 요청을 보낼 URL: http://localhost:8080/upload
  3. Body → form-data 선택
  4. key 값을 file로 설정 (컨트롤러에서 @RequestParam("file")로 받으므로)
  5. Type을 File로 선택 후 업로드할 파일 추가
  6. Send 버튼 클릭 → 응답 확인

💡 첨부파일 앞에 느낌표가 있다면 Working Directory를 설정해야 합니다.

🔧 Postman의 작업 디렉토리 설정 변경

  1. Postman 실행
  2. Settings(설정) → General(일반) 탭으로 이동
  3. Working Directory(작업 디렉토리) 항목 찾기
  4. "Change Directory"(디렉토리 변경) 버튼 클릭
  5. 업로드할 파일이 있는 폴더를 선택하여 작업 디렉토리로 설정
  6. 설정 저장 후 Postman 재시작

 👉  이렇게 하면 Postman이 해당 폴더 내 파일을 정상적으로 참조할 수 있습니다. (느낌표시가 사라짐~)

👉  Send 버튼을 누르면 정상적으로 파일이 업로드됩니다.

 

3️⃣ 여러 개의 파일 업로드

파일을 여러 개 업로드하고 싶다면 List<MultipartFile>을 사용하면 됩니다.

import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.List;

@RestController
@RequestMapping("/multiple")
public class MultiFileUploadController {

    @PostMapping
    public String uploadMultipleFiles(@RequestParam("files") List<MultipartFile> files) {
        if (files.isEmpty()) {
            return "파일이 없습니다.";
        }

        String uploadPath = "C:/upload/";
        StringBuilder responseMessage = new StringBuilder();

        for (MultipartFile file : files) {
            try {
                file.transferTo(new File(uploadPath + file.getOriginalFilename()));
                responseMessage.append("파일 업로드 성공: ").append(file.getOriginalFilename()).append("\n");
            } catch (IOException e) {
                responseMessage.append("파일 업로드 실패: ").append(file.getOriginalFilename()).append("\n");
            }
        }
        return responseMessage.toString();
    }
}

✔ @RequestParam("files") List<MultipartFile> files를 사용하여 여러 개의 파일을 받습니다.
✔ 반복문을 사용하여 각 파일을 저장합니다.

🔧 Postman 테스트 방법

  1. POST 요청을 보낼 URL: http://localhost:8080/upload/multiple
  2. Body → form-data 선택
  3. key 값을 files로 설정
  4. Type을 File로 선택 후 여러 개의 파일 추가
  5. Send 버튼 클릭 → 응답 확인

👉 테스트 결과입니다.

 

4️⃣ 파일 크기 제한

application.properties파일에서 업로드할 파일 크기를 설정할 수 있습니다.

spring.servlet.multipart.enabled=true
spring.servlet.multipart.max-file-size=5MB      # 개별 파일 크기 제한
spring.servlet.multipart.max-request-size=20MB  # 전체 요청 크기 제한

 

5️⃣ 업로드 파일 확장자 제한 (예: 이미지만 허용)

파일 확장자를 검사하여 특정 유형의 파일만 업로드하도록 설정할 수도 있습니다.

@RestController
@RequestMapping("/limit")
public class LimitUploadController {

    @PostMapping
    public String limitUpload(@RequestParam("file") MultipartFile file) {
        if (file.isEmpty()) {
            return "파일이 없습니다.";
        }

        // 허용할 확장자 목록
        List<String> allowedExtensions = List.of("jpg", "jpeg", "png", "gif");

        // 파일 확장자 추출
        String originalFilename = file.getOriginalFilename();
        assert originalFilename != null;
        String fileExtension = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);

        if (!allowedExtensions.contains(fileExtension.toLowerCase())) {
            return "허용되지 않은 파일 형식입니다.";
        }

        try {
            file.transferTo(new File("C:/upload/" + originalFilename));
            return "파일 업로드 성공: " + originalFilename;
        } catch (IOException e) {
            return "파일 업로드 실패: " + e.getMessage();
        }
    }
}

 

 

 
 

-- 끝 --

📌 와이어프레임(Wireframe)이란?

와이어프레임(Wireframe)은 웹사이트나 애플리케이션의 구조 및 레이아웃을 시각적으로 표현한 설계도입니다. UI/UX 디자인의 초기 단계에서 사용되며, 페이지의 기본적인 배치와 기능을 정리하는 역할을 합니다.


🔹 와이어프레임의 특징

흑백 또는 단순한 도형으로 구성됨
디자인 요소(색상, 이미지, 아이콘 등) 최소화
페이지의 핵심 기능과 구조를 정의
개발자, 디자이너, 기획자 간의 원활한 소통 도구


🏗 와이어프레임의 유형

와이어프레임은 디테일 수준에 따라 로우 피델리티(Lo-Fi)와 하이 피델리티(Hi-Fi)로 나뉩니다.

1️⃣ 로우 피델리티(Lo-Fi) 와이어프레임

✔ 종이나 디지털 스케치 도구를 이용해 간단한 박스와 선으로 구성
✔ 텍스트보다는 자리 표시자(Placeholder) 사용
✔ 웹사이트의 기본적인 구조와 레이아웃을 빠르게 정리할 때 유용

✏️ 예시: 손으로 그린 스케치, Balsamiq을 활용한 간단한 와이어프레임

2️⃣ 하이 피델리티(Hi-Fi) 와이어프레임

✔ 상세한 디자인 요소가 포함됨 (폰트, 버튼 스타일, 아이콘 등)
✔ 실제 콘텐츠를 반영하여 좀 더 완성된 모습
✔ UI/UX 검토 및 개발 전에 구체적인 방향을 설정하는 데 사용

✏️ 예시: Figma, Adobe XD, Sketch 등을 활용한 정밀한 와이어프레임


🛠 와이어프레임 제작 도구

  • Figma: 협업 기능이 강력한 클라우드 기반 디자인 툴
  • Adobe XD: 프로토타이핑까지 가능한 강력한 UX/UI 설계 도구
  • Sketch: Mac 사용자를 위한 UI/UX 디자인 툴
  • Balsamiq: 빠른 스케치 스타일 와이어프레임 제작
  • Whimsical: 직관적인 UI 설계 도구

🎯 와이어프레임이 중요한 이유

개발 및 디자인 비용 절감 → 초기에 레이아웃을 확정하여 불필요한 수정 방지
팀원 간의 원활한 협업 → 기획자, 디자이너, 개발자 간의 명확한 소통 가능
사용자 경험(UX) 최적화 → 페이지의 흐름과 기능을 미리 점검


📌 와이어프레임 vs 목업(Mockup) vs 프로토타입(Prototype) 차이점

개념설명활용 목적

와이어프레임 기본적인 레이아웃과 구조를 설계한 스케치 초기 기획 단계에서 레이아웃 정리
목업(Mockup) 색상, 이미지, 타이포그래피 등을 포함한 정적인 디자인 UI 디자인 검토 및 피드백 반영
프로토타입(Prototype) 클릭, 애니메이션 등 상호작용이 가능한 동적인 시뮬레이션 사용자 테스트 및 실제 기능 검토

🎨 정리하면?

와이어프레임은 UI/UX 디자인 과정에서 기본적인 레이아웃을 빠르게 구상하는 단계입니다.
본격적인 디자인 및 개발에 들어가기 전에 기획을 명확하게 정리하고, 팀원과의 원활한 협업을 위해 필수적인 작업이죠! 😊

💡 언제든지 Copilot Pro 구독을 취소할 수 있습니다. 구독 취소는 현재 청구 주기가 끝날 때 적용됩니다. 
만일 3월 5일에 구독 신청 후 3월 25일에 취소했다면, 4월 4일까지 사용이 가능합니다. 

📌 github copilot 구독 취소 방법

1️⃣ GitHub의 페이지 오른쪽 상단에서 프로필 사진을 선택한 다음,  설정 (Settings) 을 선택합니다.

2️⃣ 사이드바의 "액세스(Access)" 섹션에서  청구 및 플랜(Billing and plans)을 클릭한 다음 플랜 및 사용량(Plans and usage)을 클릭합니다.

3️⃣ ‘추가 기능(Add-ons)’의 ‘GitHub Copilot’ 섹션에서 오른쪽에 있는 구독 관리(Manage subscription) 드롭다운을 선택한 다음 취소(Cancel subscription)를 클릭합니다.

4️⃣ "Cancel GitHub Copilot Pro" 팝업창에서 Cancel GitHub Copilot Pro 버튼을 클릭합니다.

🎉  상단에 취소되었다는 알림판이 표시됩니다. 

 

💻 참고페이지 

 

개별 사용자로 Copilot Pro 취소 - GitHub Docs

더 이상 Copilot Pro를 사용하지 않으려면 Copilot Pro 구독을 취소할 수 있습니다.

docs.github.com

 

- 끝 -

 

 

 

 

'Tool > 일반' 카테고리의 다른 글

github copilot 구독 방법  (0) 2025.03.17

[도커(docker)] docker-compose를 이용하여 react app 서버 설치 및 개발 환경 구성하기

 

🖥️ Dockerfile를 이용하여 react app 서버 설치 및 개발 환경 구성하기

 

 

[도커(docker)] Dockerfile를 이용하여 react app 서버 설치 및 개발 환경 구성하기

[도커(docker)] Dockerfile를 이용하여 react app 서버 설치 및 개발 환경 구성하기📢  작성순서 📌 로컬에서 react app 설치 및 환경구성   📌 Dockerfile 파일 작성📌 Docker image 빌드📌 Do

happyldh.tistory.com

💡이전글에서 Dockerfile 파일과 docker build 명령어와 docker run 명령어를 이용하여  서버 설치 및 환경 구성했는데 docker-compose를 이용하면 한번에 설치 및 구성을 할 수 있습니다. 

📌docker-compose를 이용하여 react app 서버 설치 및 개발 환경 구성하기

📝 docker-compose.yml 파일 생성

version: '3'
services:
  react:
    build: 
      context: .
      dockerfile: Dockerfile.dev
    ports:
      - "3000:3000"
    volumes:
      - /usr/src/app/node_modules
      - .:/usr/src/app
    stdin_open: true

 

👉  파일내용에 대한 설명입니다. 

version: '3'  # 사용할 Docker Compose 파일의 버전 (v3)

services:
  react:  # 'react'라는 이름의 서비스 정의
    build: 
      context: .  # 현재 디렉터리를 빌드 컨텍스트로 사용
      dockerfile: Dockerfile  # React 개발을 위한 Dockerfile 지정 (Dockerfile)

    # 포트 매핑으로 로컬에서 React 개발 서버 접속 가능
    ports:
      - "3000:3000"  # 호스트의 3000번 포트를 컨테이너의 3000번 포트와 연결 (React 개발 서버용)

    # 로컬 코드 변경 사항을 컨테이너에 자동 반영
    # volumes 설정 덕분에 이미지 빌드를 하지 않고 코드를 수정하면 바로 반영됩니다.
    # 단, 서버는 재실행해야 반영됩니다.
    volumes:
      # 컨테이너 내부의 node_modules 폴더는 유지하여, 로컬 파일과 충돌 방지
      - /usr/src/app/node_modules  
      # 현재 디렉터리의 모든 파일을 컨테이너의 /usr/src/app에 마운트 (소스 코드 실시간 반영)
      - .:/usr/src/app  

	# 컨테이너를 실행할 때 표준 입력을 열어 인터랙티브 모드 활성화
    # react 서버 구성시 사용
    stdin_open: true


📝 이미지 빌드 및 서버 실행

docker-compose up


👉 실행결과입니다.

 

🚀 지금까지 docker compose를 이용한 방법에 대해 알아봤습니다. 


 

 

 

 

[도커(docker)] Dockerfile를 이용하여 react app 서버 설치 및 개발 환경 구성하기

📢  작성순서 

📌 로컬에서 react app 설치 및 환경구성   

📌 Dockerfile 파일 작성

📌 Docker image 빌드

📌 Docker에서 react app 실행

 

📌로컬에서 react app 설치 및 환경구성  

 

[react] react 설치하기 - Create React App

[react] react 설치하기 - Create React App📢  작업순서 📌 Node.js 및 npm 설치📌 Create React App 설치📌 React 앱 실행📌 Node.js 및 npm 설치  💡 React 앱을 개발하려면 Node.js가 필요합니다. Node.js에

happyldh.tistory.com

 

📌  Dockerfile 파일 작성

루트 폴더에서  Dockerfile 파일을 작성한다. 

FROM node:alpine

WORKDIR /usr/src/app

COPY package*.json ./

RUN npm install

COPY . .

CMD ["npm", "start"]

 

📌  Docker image 빌드 

docker build 명령을 이용하여 image를 생성한다. 

# react-app 이름으로 이미지를 빌드한다. 
docker build -t react-app .

 

📌  Docker에서 react app 실행

 docker run 명령을 이용하여 react app를 실행한다.

docker run -it -p 3000:3000 -v /usr/src/app/node_modules -v %cd%:/usr/src/app react-app

👉 명령에 대한 설명입니다.

docker run 
  # 인터랙티브 모드(-i)와 터미널(-t)을 활성화하여 컨테이너 내에서 명령어 입력 가능하게 함
  -it   
  
  # 호스트의 3000번 포트를 컨테이너의 3000번 포트에 연결
  -p 3000:3000   
  
  # 컨테이너의 node_modules 디렉터리를 볼륨으로 유지하여 로컬파일을 참조하지 않도록 함
  # 로컬 파일과 충돌 방지
  -v /usr/src/app/node_modules  
  
  # 현재 디렉터리(%cd%)를 컨테이너의 /usr/src/app에 마운트하여 실시간 코드 변경 반영
  -v %cd%:/usr/src/app 
  
  # 실행할 도커 이미지 (React 앱을 포함한 이미지)
  react-app



👉 실행결과입니다.

 

 

 

 

 

 

 

[도커(docker)] docker build 명령어 사용법 - Dockerfile 

⚙ docker build 명령어는 Docker 이미지를 빌드하는 데 사용됩니다. 보통 Dockerfile을 기반으로 하며, 해당 디렉터리에서 지정된 명령어를 실행하여 이미지를 생성합니다.

🟢  기본 명령어 

# 해당 폴더의 Dockerfile파일을 이용하여 이미지를 생성합니다.
docker build .


🟢  이미지 이름 지정 ( -t)

# 이미지 이름을 myapp으로 지정
docker build -t myapp .


🟢  Dockerfile 이름 및 경로 지정 ( -f)

# Dockerfile의 이름이 다르거나 경로가 다른경우 
docker build -f ./app/Dockerfile.dev .



 

 

 

 

 

 

 

 

[react] react 설치하기 - Create React App

📢  작업순서 

📌 Node.js 및 npm 설치

📌 Create React App 설치

📌 React 앱 실행

📌 Node.js 및 npm 설치 

💡 React 앱을 개발하려면 Node.js가 필요합니다. Node.js에는 JavaScript 런타임과 함께 패키지 관리자(npm)가 포함되어 있습니다.
다운로드: Node.js 공식 홈페이지에서 LTS(Long Term Support) 버전을 다운로드하여 설치합니다.
설치 확인: 터미널(또는 명령 프롬프트)에서 아래 명령어를 입력하여 설치가 제대로 되었는지 확인합니다.

node -v
npm -v

 

📌 Create React App 설치

💡 Create React App은 React 프로젝트를 쉽게 생성하고 기본적인 빌드 설정을 자동으로 구성해주는 도구입니다.

📝 폴더 생성

터미널(명령 프롬프트)에서 폴더를 생성후 이동합니다.

mkdir react-app
cd react-app

📝 react 앱 설치 

✔ 터미널(명령 프롬프트)에서 실행합니다.

npx create-react-app .

 

📌 React 앱 실행

✔ 터미널(명령 프롬프트)에서 실행합니다.

npm start

👉 실행결과입니다.

 

 

[도커(docker)] Docker Compose로 Node.js Express 서버와 Redis 연동하기

📢  작성순서 

📌 Express 서버 구성

📌 Express 서버용 Dockerfile 만들기

📌 Docker Compose 설정
📌 Docker Compose 실행

 

💻 참고 페이지 

📝 [도커(docker)] Dockerfile를 이용하여 nodejs & express 서버 설치 및 개발 환경 구성하기

 

[도커(docker)] Dockerfile를 이용하여 nodejs & express 서버 설치 및 개발 환경 구성하기

[도커(docker)] Dockerfile를 이용하여 nodejs & express 서버 설치 및 개발 환경 구성하기  📢  작성순서 📌 Node.js Express 서버 코드 작성📌 Docker 설정 파일 작성📌 Docker 컨테이너 실행 📌  Node.j

happyldh.tistory.com


📌  프로젝트 디렉터리 구조

📝 프로젝트 폴더 아래처럼 구성하겠습니다.

express-redis-app/
│── docker-compose.yml    # Docker Compose 설정 파일
│── app/                  # Node.js Express 서버 코드
│   ├── Dockerfile        # dockerfile
│   ├── server.js         # Express 서버 코드
│   ├── package.json      # Node.js 패키지 설정 파일

📌  Express 서버 구성 

📝 package.json 파일 생성 

/app 폴더에서 아래의 명령어를 이용해서 package.json 파일을 생성한다.

npm init -y

생성된 파일 내용을 아래와 같이 변경한다.

{
  "name": "express-redis-app",  // 프로젝트 이름
  "version": "1.0.0",  // 프로젝트 버전
  "main": "index.js",  // 기본 실행 파일 (사용되지 않음, "start" 스크립트에서 server.js 사용)
  "scripts": {
    "start": "node server.js",  // 서버 실행 명령어 (server.js 파일을 실행)
    "test": "echo \"Error: no test specified\" && exit 1"  // 테스트 스크립트 (현재 테스트 없음)
  },
  "keywords": [],  // 프로젝트 관련 키워드 (비어 있음)
  "author": "",  // 작성자 정보 (비어 있음)
  "license": "ISC",  // 오픈소스 라이선스 (ISC 라이선스 적용)
  "description": "",  // 프로젝트 설명 (비어 있음)
  "dependencies": {
    "express": "^4.21.2",  // Express.js 최신 버전 (4.21.2 이상)
    "redis": "^4.7.0"  // Redis 클라이언트 최신 버전 (4.7.0 이상)
  }  
}

🙌 local에서 구현하는 방법은 상단에 Dockerfile를 이용하여 nodejs & express 서버 설치 및 개발 환경 구성하기 링크를 이용하여 확인하세요

📝 server.js 파일 생성 

/app 폴더에 editor(vscode등)을 이용하여 Redis 연동코드를 server.js파일에 작성한다. 

const express = require('express'); // Express.js 프레임워크 모듈 불러오기
const redis = require('redis'); // Redis 클라이언트 모듈 불러오기

const app = express();
const PORT = 3000; // 서버가 실행될 포트 번호

// Redis 클라이언트 설정
const redisClient  = redis.createClient({
    socket: {
        host: 'redis', // Docker Compose에서 정의한 Redis 컨테이너의 이름
        port: 6379 // Redis 기본 포트
    }
});

// Redis 서버에 연결
redisClient.connect()
    .then(() => console.log('Redis connected')) // 연결 성공 시 메시지 출력
    .catch((err) => console.error("❌ Redis 연결 실패:", err)); // 연결 실패 시 오류 출력

// 기본 라우트 설정
app.get('/', async (req, res) => {     
    let count = await redisClient.get('count'); // Redis에서 'count' 키의 값을 가져옴
    if (!count) {
        count = 0; // 값이 없으면 기본값 0으로 설정
    } 

    count = parseInt(count) + 1; // 방문자 수 증가
    await redisClient.set('count', count); // 증가된 값을 Redis에 저장
    res.send(`Hello World! ${count}`); // 응답으로 방문 횟수 출력
});

// 서버 실행
app.listen(PORT, () => {
    console.log(`Server is running on port ${PORT}`); // 서버 실행 메시지 출력
});

 

📌  Express 서버용 Dockerfile 만들기

📝 /app 폴더에 Dockerfile를 생성한다. 

# Node.js 18 버전의 공식 이미지를 기반으로 함
FROM node:18

# 작업 디렉터리 설정
WORKDIR /usr/src/app

# package.json과 package-lock.json을 복사
COPY package*.json .

# 의존성 설치
RUN npm install 

# 모든 파일을 컨테이너로 복사
COPY . .

# 애플리케이션 실행
CMD ["npm", "start"]

 

📌  Docker Compose 설정

📝 Root 폴더에 docker-compose.yml을 작성해서 Express와 Redis 서버를 하나의 네트워크에서 실행하자

version: '3'  # Docker Compose 파일의 버전 지정

services:
  redis:
    image: "redis:latest"  # 최신 Redis 이미지를 사용하여 컨테이너 실행
    container_name: "redis-server"  # 컨테이너의 이름을 "redis-server"로 지정
    ports:
      - "6379:6379"  # 호스트의 6379 포트를 컨테이너의 6379 포트에 매핑 (Redis 기본 포트)

  app:
    build: ./app  # ./app 디렉터리에 있는 Dockerfile을 기반으로 애플리케이션 빌드
    container_name: "express-server"  # 컨테이너의 이름을 "express-server"로 지정
    ports:
      - "3000:3000"  # 호스트의 3000 포트를 컨테이너의 3000 포트에 매핑
    depends_on:
      - redis  # "redis" 서비스가 먼저 실행된 후 "app" 서비스가 실행됨
    volumes:
      - ./app:/usr/src/app  # 로컬의 "./app" 디렉터리를 컨테이너의 "/usr/src/app"에 매핑
      - /usr/src/app/node_modules  # "node_modules" 디렉터리는 호스트와 공유하지 않음 (컨테이너 내부에서만 유지)
    environment:
      - REDIS_HOST=redis  # Redis 서버의 호스트명을 "redis"로 설정 (Docker Compose 내 서비스 이름 사용 가능)
      - REDIS_PORT=6379  # Redis 포트를 6379로 설정

 

📌  Docker Compose 실행

📝 docker-compose up 명령을 실행해서 Redis와 Express 서버를 함께 실행하자.

docker-compose up --build

👉 터미널 출력결과

👉 docker images 화면

👉 docker containers 화면

👉 브라우저 접속 화면

👉 새로고침을 할때마다 숫자가 1씩 증가합니다.

🚀 지금까지 Docker Compose를 이용하여 Node.js Express 서버와 Redis서버 두개의 docker를 연동하는 방법을 알아보았습니다 

 

 



 

 

 

+ Recent posts