네로개발일기

개발자 네로의 개발 일기, 자바를 좋아합니다 !

'2021/11'에 해당되는 글 16건


반응형

🐳 docker run 명령어 사용법

Docker를 실행하기 위해 docker run 명령어를 자주 사용하게 된다.

⛵️ 기본 포맷

docker run 명령어의 기본 포맷은 다음과 같다. 여기서 이미지 식별자는 필수이다.

$ docker run [OPTIONS] IMAGE[:TAG|@DIGEST] [COMMAND] [ARGS...]
$ docker run [옵션] IMAGE [명령어] [인자]

⛵️ -d 옵션

컨테이너를 백그라운드에서 실행하고 싶을 때 쓰는 명령어이다. -d 옵션을 사용하면 컨테이너가 detached 모드에서 실행된다.
아래는 python:3.8-alpine 이미지로 python -m http.server 명령어를 백그라운드로 실행시킨 명령어이다.

$ docker run -d python:3.8-alpine python -m http:server

⛵️ -it 옵션

-i 옵션과 -t 옵션은 같이 쓰는 경우가 흔하다. 컨테이너를 종료하지 않은 채 터미널에서 입력을 계속해서 컨테이너로 전달하기 위해 이 두 옵션을 사용한다. -it 옵션은 컨테이너의 쉘(shell)이나 CLI 도구로 사용할때 유용하게 사용된다.

$ docker run -it python:3.8-alpine
Python 3.8.2 (default, Mar 24 2020, 02:56:01)
[GCC 9.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> print("Hi!")
Hi!
>>>
=======================================================================
$ docker run -it mysql:5.7
# ls
bin		home	lib		tmp
dev		etc		usr		var

⛵️ --name 옵션

docker 컨테이너를 제어할 때 컨테이너 ID를 사용하기엔 불편하게 느껴질 수 있다. 이런 경우, --name 옵션을 사용해서 컨테이너에 이름을 부여해 해당 이름으로 컨테이너를 식별할 수 있다.
아래는 my-server라는 이름의 컨테이너를 실행하고 docker kill 커맨드로 해당 컨테이너를 종료하거나 docker run 명령어로 해당 컨테이너를 삭제할 때 컨테이너 ID 대신에 이름을 사용하는 것을 보여주는 예시다.

$ docker run -d --name my-server python:3.8-alpine python -m http.server
7899108d467cc423e20a3d6cb250070baae01fa541b037707afbbe8d1e9e3000
$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
7899108d467c        python:3.8-alpine   "python -m http.serv…"   2 seconds ago       Up 3 second                             my-server
$ docker kill my-server
my-server
$ docker rm my-server
my-server

⛵️ -e 옵션

Docker 컨테이너의 환경변수를 설정하기 위해 -e 옵션을 사용한다. -e 옵션을 사용하면 Dockerfile의 ENV 설정도 덮어써지게 된다.
아래는 FOO 환경변수를 bar로 세팅하고 환경변수를 출력하는 명령어이다.

$ docker run -e FOO=bar python:3.8-alpine env
PATH=/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=92ebed448fb3
FOO=bar
LANG=C.UTF-8
GPG_KEY=E3FF2839C048B25C084DEBE9B26995E310250568
PYTHON_VERSION=3.8.2
PYTHON_PIP_VERSION=20.0.2
PYTHON_GET_PIP_URL=https://github.com/pypa/get-pip/raw/d59197a3c169cef378a22428a3fa99d33e080a5d/get-pip.py
PYTHON_GET_PIP_SHA256=421ac1d44c0cf9730a088e337867d974b91bdce4ea2636099275071878cc189e
HOME=/root

⛵️ -p 옵션

-p 옵션은 호스트와 컨테이너 간의 포트(Port) 배포(publish)/바인드(bind)를 위해 사용된다. 호스트(host) 컴퓨터에서 컨테이너에서 리스닝하고 있는 포트로 접속할 수 있도록 설정해준다.
아래는 컨테이너 내부에서 3306 포트로 리스닝하고있고 호스트 컴퓨터에서 3306 포트로 접속할 수 있도록 하는 명령어이다.

$ docker run -d --name mysql5.7_lower_case -p 3306:3306 mysql:5.7

⛵️ --rm 옵션

--rm 옵션은 컨테이너를 일회성으로 실행할 때 주로 쓴다. 컨테이너가 종료될 때 컨테이너와 관련된 리소스(파일 시스템, 볼륨)까지 깨끗하게 제거해준다.

$ docker run --rm -it wernight/funbox nyancat


[참고]
=> Docker CLI 레퍼런스
https://docs.docker.com/engine/reference/run/

Docker run reference

docs.docker.com

=> MySQL 5.7 도커로 설치하기
https://frogand.tistory.com/89
=> 출처
https://www.daleseo.com/docker-run/

docker run 커맨드 사용법

Engineering Blog by Dale Seo

www.daleseo.com

728x90
반응형

'programming language > Docker' 카테고리의 다른 글

[Docker] MySQL 5.7 컨테이너 설치 명령어  (0) 2021.11.29
blog image

Written by ner.o

개발자 네로의 개발 일기, 자바를 좋아합니다 !

반응형

🐳 [Docker] MySQL 5.7 컨테이너 설치 명령어

💻 OS: mac m1

🌵 lower_case_table_name = 1 로 설정

🌷 character-set: UTF-8 로 설정

$ docker run -d \
--name [컨테이너 이름] \
-p 3306:3306 \
-e MYSQL_ALLOW_EMPTY_PASSWORD=true \
-e TZ=Asia/Seoul \
--character-set-server=utf8 \
--collation-server=utf8_general_ci \
--lower_case_table_names=1 \
--platform linux/amd64 \
mysql:5.7
# 예시

$ docker run -d \
--name mysql5.7_lower_case \
-p 3306:3306 \
-e MYSQL_ALLOW_EMPTY_PASSWORD=true \
-e TZ=Asia/Seoul \
--character-set-server=utf8 \
--collation-server=utf8_general_ci \
--lower_case_table_names=1 \
--platform linux/amd64 \
mysql:5.7

🌼 명령어의 의미

-d 백그라운드로 실행(detached mode)

--name 컨테이너의 이름 설정

-p [외부접근포트]:[내부포워딩포트] 외부에서 접근하는 포트와 내부에서 포워딩하는 포트를 설정

-e Mysql컨테이너에서 사용할 환경변수 설정

    MYSQL_ALLOW_EMPTY_PASSWORD=true 패스워드 없이 접속이 가능하도록 설정

    MYSQL_ROOT_PASSWORD=[password] root 사용자의 password를 설정

--character-set-server 컨테이너의 인코딩 설정

--collation-server 컨테이너의 인코딩 설정

--lower_case_table_names=1 MySQL 테이블명 대소문자 구분하지 않도록 설정

--platform linux/amd64 macOS m1 인 경우 intel 칩이 아니기 때문에 amd64로 설정

 

 

[참고] lower_case_table_names 가 1로 설정되어 있는지 확인하는 방법

- 데이터 베이스에서 아래의 쿼리를 실행시킨다.

> show variables like 'lower_case_table_names';
728x90
반응형

'programming language > Docker' 카테고리의 다른 글

[Docker] docker run 명령어  (1) 2021.11.30
blog image

Written by ner.o

개발자 네로의 개발 일기, 자바를 좋아합니다 !

반응형

1. Department DTO

Department 테이블에서 조회한 데이터를 채울 DTO(Data Transfer Object)이다.

 

dto/Department.java

package dto;

public class Department {
	
    int id;
    String name;
    
    public int getId() {
    	return id;
    }
    
    public void setId(int id) {
    	this.id = id;
    }
    
    public String getName() {
    	return name;
    }
    
    public void setName(String name) {
    	this.name = name;
    }
}

2. Department mapper 구현

mapper/DepartmentMapper.java

package mapper;

import java.util.List;

import org.apache.ibatis.annotations.Delete; 
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Options;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;

import dto.Department;

@Mapper 
public interface DepartmentMapper { 
	
    @Select("SELECT * FROM department")
    List<Department> findAll();
    
    @Select("SELECT * FROM department WHERE id = #{id}") 
    Department findOne(int id); 
    
    @Insert("INSERT department (name) VALUES (#{name})") 
    @Options(useGeneratedKeys=true, keyProperty="id") 
    void insert(Department department); 
    
    @Update("UPDATE department SET name = #{name} WHERE id = #{id}") 
    void update(Department department); 
    
    @Delete("DELETE FROM department WHERE id = #{id}") 
    void delete(int id); 
}

@Mapper

mybatis mapper에는 @Mapper 어노테이션이 붙어있어야 한다.

 

findAll

@Select("SELECT * FROM Department")
List<Department> findAll();

findAll 메서드는 department 테이블의 모든 레코드를 조회해서 리턴한다. findAll 메서드를 호출하면, "SELECT * FROM Department" SQL 명령이 MySQL 엔진에서 실행된다. 이 메서드의 조회 결과 레코드 한 개당 Department 객체 한 개가 생성되어 조회 결과 레코드의 칼럼들이 Department 객체의 속성에 채워진다. 이 때 컬럼명과 객체의 속성명이 일치하는 것만 채워지고 일치하지 않는 것은 무시된다. 이렇게 생성된 Department 객체들이 List 타입의 객체에 채워져 리턴된다.

 

- 조회 결과 칼럼명 일치

SELECT SQL 명령의 조회 결과가 Java 객체에 자동으로 채워질 때 조회 결과 칼럼명과 Java 객체의 setter 이름이 일치해야 한다.

 

findOne

@Select("SELECT * FROM department WHERE id = #{id}")
Department findOne(int id);

findOne 메서드는 department 테이블의 레코드 한개를 조회해서 리턴한다. findOne 메서드를 호출하면 "SELECT * FROM department WHERE id = #{id}" 명령이 MySQL 엔진에서 실행된다. 이때, 이 메소드의 파라미터 id 변수의 값이, #{id} 부분에 채워진 후 실행된다. Department 객체를 한 개 생성해서, 조회 결과 레코드의 각 컬럼의 값을, 이 Department 객체에 채워서 리턴한다. 이때 컬럼명과 객체의 속성명이 일치하는 것만 채워지고, 일치하지 않는 것은 무시된다. 조회 결과가 없을 경우에, 이 메소드는 null을 리턴한다.

 

insert

@Insert("INSERT department (name) VALUES (#{name})")
@Options(useGeneratedKeys=true, keyProperty="id")
void insert(Department department);

insert 메서드의 파라미터 변수가 Department 객체이다. 이 Java 객체의 속성값이 INSERT SQL 명령의 #{...} 부분에 채워져서 실행된다. Java 객체의 속성명과 #{...} 부분의 이름이 일치해야 속성값이 채워질 수 있다.

 

@Options(useGeneratedKeys=true, keyProperty="id")

INSERT할 테이블의 기본키(primary key) 필드 이름이 "id"이고, 이 필드의 값은 자동으로 생성된다는 선언이다. (Auto Increment 필드)

 

update

@Update("UPDATE department SET name = #{name} WHERE id = #{id}")
void update(Department department);

 

delete

@Delete("DELETE FROM department WHERE id = #{id}")
void delete(int id);

 

3. Department Controller

controller/DepartmentController.java

package controller;

import java.util.List; 

import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.stereotype.Controller; 
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import dto.Department; 
import mapper.DepartmentMapper;

@Controller
@RequestMapping("department")
public class DepartmentController {

    @Autowired
    DepartmentMapper departmentMapper; 
    
    @RequestMapping("list")
    public String list(Model model) { 
    	List<Department> departments = departmentMapper.findAll();
        model.addAttribute("departments", departments); 
        return "department/list";
    }
    
    @GetMapping("create")
    public String create(Model model) { 
    	model.addAttribute("department", new Department()); 
    	return "department/edit";
    } 
    
    @PostMapping("create") 
    public String create(Model model, Department department) {
    	departmentMapper.insert(department); 
    	return "redirect:list";
    } 
    
    @GetMapping("edit")
    public String edit(Model model, @RequestParam("id") int id) { 
    	Department department = departmentMapper.findOne(id); 
    	model.addAttribute("department", department); 
    	return "department/edit";
    } 
    
    @PostMapping("edit")
    public String edit(Model model, Department department) {
    	departmentMapper.update(department);
    	return "redirect:list";
    } 
    
    @RequestMapping("delete")
    public String delete(Model model, @RequestParam("id") int id) { 
	    departmentMapper.delete(id);
    	return "redirect:list";
    } 
}

 

@Autowired

@Autowired
DepartmentMapper departmentMapper;

DepartmentMapper 인터페이스를 구현한 Java 클래스를 spring mybatis가 자동으로 구현해주고, 그 클래스의 객체를 하나 생성하여 departmentMapper 멤버 변수에 자동으로 대입해준다.

 

4. request parameter 전달

액션 메서드의 파라미터에 request parameter 값이 채워져서 액션 메서드에 전달된다.

 

값을 하나씩 전달 받을 때 - @RequestParam

@GetMapping("edit")
public String edit(Model model, @RequestParam("id") int id)

값을 여러 개 전달 받을 때 - 파라미터 객체

@PostMapping("edit")
public String edit(Model model, Department department)

request parameter 데이터가 Department 객체에 자동으로 채워진다. request parameter 데이터의 이름과 액션 메서드의 파라미터 객체의 속성이름이 일치할 경우에 (setter 메서드 이름이 일치할 경우에) request parameter 데이터가 그 속성에 자동으로 채워진다.

 

 

 

728x90
반응형
blog image

Written by ner.o

개발자 네로의 개발 일기, 자바를 좋아합니다 !

반응형

JSP에서 숫자나 날짜를 정해진 포맷으로 출력할 때, formatNumber, formatDate 확장 태그를 사용한다. 

 

JSTL

이 확장 태그들은 JSTL 라이브러리에 들어있다.

따라서 프로젝트 pom.xml 파일에 JSTL dependency가 들어있어야 한다.

<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>

위 확장 태그들을 사용하기 위해 필요한 선언이다. 이 선언이 JSP 파일 선두에 있어야 한다.

 

formatNumber

<fmt:formatNumber value="${ weight }" pattern="#.#" />

weight 값이 소숫점 한자리까지 출력된다. 그 아래 자리는 반올림된다.

 

<fmt:formatNumber value="${ weight * 1000 }" pattern="#,###" />

weight * 1000 식의 값이 출력된다. 3자리마다 콤마(,)가 출력된다 (1,234,567)

formatNumber 확장 태그의 pattern은 Java의 DecimalFormat 클래스의 그것과 같다.

 

formatDate

<fmt:formatDate pattern="yyyy-MM-dd" value="${ birthday }" />

birthday 값을 "yyyy-MM-dd" 형태로 출력한다. birthday 값은 Date 타입이어야 한다. formatDate 확장 태그의 pattern은 Java의 SimpleDateFormat 클래스의 그것과 같다. 

 

728x90
반응형
blog image

Written by ner.o

개발자 네로의 개발 일기, 자바를 좋아합니다 !

반응형

1. 컨트롤러 클래스

HomeController.java

import org.springframework.streotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class HomeController {
	
    @RequestMapping("/")
    public String index(Model model) {
    	model.addAttribute("message", "좋은 아침!");
        return "index";
    }
}

컨트롤러 클래스는 웹 브라우저의 URL 요청을 받아서, 웹 서버에서 실행되는 자바 클래스이다. 웹 브라우저가 웹서버에 어떤 URL을 요청을 하면 그 URL에 해당하는 컨트롤러의 메소드가 자동으로 호출되어 실행된다.

 

@Controller 어노테이션

컨트롤러 클래스에 이 어노테이션(Annotation)을 붙여줘야 한다. 

 

액션 메서드

웹 브라우저가 어떤 URL을 웹서버에 요청하면, 그 요청된 URL에 해당하는 컨트롤러의 어떤 메서드가 자동으로 호출된다. 웹 브라우저의 요청에 의해서 자동으로 호출되는 컨트롤러의 메서드를 액션메서드라 한다.

 

@RequestMapping 어노테이션

액션 메서드에 붙은 @RequestMapping("/") 어노테이션의 "/" 부분은 그 액션 메서드를 호출하기 위한 URL이다. 자동으로 호출할 액션 메서드를 찾을 때 컨트롤러 클래스의 이름이나 액션 메서드의 이름은 상관없고 @RequestMapping 어노테이션에 등록되어 있는 URL만 일치하면 된다.

 

컨트롤러 액션 메서드의 리턴값

컨트롤러의 액션 메서드는 문자열을 리턴한다. 컨트롤러의 액션 메서드가 리턴하는 문자열은 View 파일의 이름이다. 컨트롤러의 액션 메서드가 리턴된 후, 뷰 파일이 실행된다. 액션 메서드가 리턴한 이름의 뷰 파일이 실행된다.

 

Model 객체

public String index(Model model)

컨트롤러의 액션 메서드는 Spring Web MVC 엔진에 의해 호출된다. 대부분의 액션 메서드의 파라미터에 Model model 객체가 포함된다. 컨트롤러의 액션 메서드가 뷰 파일에 전달할 데이터를 Model 객체에 넣어 전달한다. 즉, Model 객체는 데이터를 전달하는 객체라고 보면 된다.

 

model의 attribute

model.addAttribute("message", "좋은 아침!");

뷰 파일에 전달할 데이터를 Model 객체에 넣는 코드이다. 전달되는 데이터의 이름은 "message"이고 값은 "좋은 아침!" 문자열이다. 이렇게 모델에 담겨서 뷰에 전달되는 데이터는 model attribute라고 한다. 

뷰에서 model attribute를 출력하는 코드는

${message}

위와 같다. model attribute 이름이 정확히 일치해야 한다.

2. 뷰 (view)

index.jsp

<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>

<!DOCTYPE html> 
<html> 
<head>
<meta charset="utf-8"> 
</head>
<body>
	<h1>안녕하세요</h1> 
	<h3>${ message }</h3> 
</body>
</html>

웹 브라우저의 요청(http request)에 대한 응답(http response)으로, 웹 서버에서 웹 브라우저로 전송되는 것들은 http 태그가 대부분이다. 

 

실행 순서

웹 브라우저에서 웹 서버에 요청(http request)이 전달되면, 요청된 URL과 일치하는 컨트롤러의 액션 메서드가 실행된다. 그리고 액션 메서드의 뒤를 이어서 뷰(view) 파일이 실행된다. 뷰 파일의 실행 결과, 출력된 html 태그들이 웹 브라우저로 전송된다.

 

728x90
반응형
blog image

Written by ner.o

개발자 네로의 개발 일기, 자바를 좋아합니다 !