day58 πŸŒ•

μž₯λ―ΈΒ·2022λ…„ 8μ›” 10일
0

였늘의 μ„±κ³Ό

λͺ©λ‘ 보기
58/129

μŠ€ν”„λ§ MVC 2편 - λ°±μ—”λ“œ μ›Ή 개발 ν™œμš© 기술 μ„Ήμ…˜ 8 μ΄μ–΄μ„œ μˆ˜κ°•

+) 22. 08. 13. day57 πŸŒ• 에 정리 및 μΆ”κ°€ μ™„λ£Œ!


ν† ν”½ 1개 - DDL, DML, DCL

DDL(Data Define Language, 데이터 μ •μ˜μ–΄)

DDL은 λ°μ΄ν„°λ² μ΄μŠ€ 객체(λ°μ΄ν„°λ² μ΄μŠ€, ν…Œμ΄λΈ”)λ₯Ό 생성해쀀닀.
λ°μ΄ν„°λ² μ΄μŠ€ κ΄€λ¦¬μžλ‚˜ λ°μ΄ν„°λ² μ΄μŠ€ μ„€κ³„μžκ°€ μ‚¬μš©ν•œλ‹€.

CREATE TABLE 사원 (
	μ‚¬λ²ˆ INTEGER NOT NULL;
	이름 CHAR(10) NOT NULL;
	λΆ€μ„œ CHAR(10)
	PRIMARY KEY(μ‚¬λ²ˆ),
	FOREIGN KEY(λΆ€μ„œ)
		REFERENCES λΆ€μ„œλͺ©λ‘(λΆ€μ„œμ½”λ“œ)
		ON DELETE SET NULL
		ON UPDATE CASCADE
);
⬆️ CREATE μ˜ˆμ‹œ

ν…Œμ΄λΈ”λΏλ§Œ μ•„λ‹ˆλΌ μŠ€ν‚€λ§ˆ, 도메인, λ·°, 인덱슀 등을 생성할 수 μžˆλ‹€.

μœ„ μ½”λ“œλ₯Ό 잠깐 μ„€λͺ…ν•˜μžλ©΄, λΆ€μ„œλͺ©λ‘μ—μ„œ μ˜μ—…λΆ€κ°€ μ‚­μ œ(DELETE)λœλ‹€λ©΄ 사원 ν…Œμ΄λΈ”μ˜ μ˜μ—…λΆ€λŠ” μ „λΆ€ 빈칸으둜 λŒ€μ²΄(SET NULL)되고, μ˜μ—…λΆ€κ°€ νŒλ§€λΆ€λ‘œ λ³€κ²½(UPDATE)λœλ‹€λ©΄ 사원 ν…Œμ΄λΈ”μ˜ μ˜μ—…λΆ€λŠ” μ „λΆ€ νŒλ§€λΆ€λ‘œ λŒ€μ²΄(CASCADE β†’ μ—°κ΄€λœ 것듀도 ν•¨κ»˜ μ‹€ν–‰)λœλ‹€.

DDL은 생성 외에 λ³€κ²½(ALTER), 제거(DROP) λ“±μ˜ κΈ°λŠ₯도 μžˆλ‹€.

  • ALTER: ν…Œμ΄λΈ” λ³€κ²½
  • DROP: λ°μ΄ν„°λ² μ΄μŠ€, ν…Œμ΄λΈ” 제거
  • TRUNCATE: ν…Œμ΄λΈ” μ΄ˆκΈ°ν™”

DML(Data Manipulation Language, 데이터 μ‘°μž‘μ–΄)

DML은 ν…Œμ΄λΈ”μ˜ 데이터λ₯Ό 쑰회, μ‚½μž…, μ‚­μ œ, κ°±μ‹ ν•˜λŠ” μž‘μ—…μ„ ν•œλ‹€.
λ°μ΄ν„°λ² μ΄μŠ€ μ‚¬μš©μžμ™€ λ°μ΄ν„°λ² μ΄μŠ€ 관리 μ‹œμŠ€ν…œ κ°„μ˜ μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ œκ³΅ν•œλ‹€.

SELECT 속성 FROM ν…Œμ΄λΈ” WHERE 쑰건
INSERT INTO ν…Œμ΄λΈ”(속성) VALUES(κ°’)
DELETE FROM ν…Œμ΄λΈ” WHERE 쑰건
UPDATE ν…Œμ΄λΈ” SET 속성=κ°’ WHERE 쑰건
⬆️ DML μ˜ˆμ‹œ
  • SELECT: ν…Œμ΄λΈ”μ˜ νŠΉμ • μ†μ„±λ“€λ§Œ μ‘°νšŒν•œλ‹€. WHERE μ ˆμ„ 뢙이면 쑰건에 λ§žλŠ” λ°μ΄ν„°λ§Œ μ‘°νšŒν•  수 μžˆλ‹€.
    SELECT 문을 μ„œλΈŒ 쿼리둜 ν•˜μ—¬ VIEWλ₯Ό μƒμ„±ν•˜λ©΄ μ’€ 더 κ°„νŽΈν•˜κ²Œ 쑰회 μž‘μ—…μ„ λ°˜λ³΅ν•  수 μžˆλ‹€.
     CREATE VIEW μ˜μ—…λΆ€μ‚¬μ›(μ‚¬λ²ˆ, 사원λͺ…)
         AS SELECT μ‚¬λ²ˆ, 사원λͺ…
         FROM 사원
         WHERE λΆ€μ„œλͺ…='μ˜μ—…λΆ€';
    ⬆️ SELECT 문을 μ„œλΈŒ 쿼리둜 ν•œ VIEW 생성 μ˜ˆμ‹œ
  • INSERT: 데이터λ₯Ό μΆ”κ°€ν•œλ‹€.
  • DELETE: 데이터λ₯Ό μ‚­μ œν•œλ‹€.
  • UPDATE: 데이터λ₯Ό κ°±μ‹ ν•œλ‹€.

DCL(Data Control Language, 데이터 μ œμ–΄μ–΄)

DCL은 λ°μ΄ν„°μ˜ 관리 및 λ³΄μ•ˆ, μ œμ–΄μ‚¬ν•­ 등을 μ •μ˜ν•œλ‹€.

GRANT CONNECT TO ROSE; //κΆŒν•œ λΆ€μ—¬
REVOKE CONNECT FROM ROSE; //κΆŒν™˜ 회수

//νŠΉμ • κΈ°λŠ₯(쑰회, μ‚½μž…, μ‚­μ œ λ“±)을 λΆ€μ—¬ν•  μˆ˜λ„ μžˆλ‹€.
GRANT SELECT ON 사원 TO ROSE WITH GRANT OPTION;
REVOKE GRANT OPTION FOR SELECT ON 사원 FROM ROSE CASCADE;
⬆️ DCL μ˜ˆμ‹œ
  • GRANT: μ–΄λ–€ κΆŒν•œμ„ λˆ„κ΅¬(TO)μ—κ²Œ 뢀여할지 μ •μ˜ν•œλ‹€.
    WITH GRANT OPTION: λΆ€μ—¬ 받은 κΆŒν•œμ„ λ‹€λ₯Έ μ‚¬λžŒμ—κ²Œ λΆ€μ—¬ν•  수 μžˆλ‹€.

    κΆŒν•œ ROLE

    • DBA: λͺ¨λ“  DB κΆŒν•œ 가짐 β†’ DB κ΄€λ¦¬μžμ—κ²Œλ§Œ λΆ€μ—¬
    • RESOURCE: 객체(CREATE, ALTER, DROP), 데이터(SELECT, INSERT, UPDATE, DELETE) κΆŒν•œ
    • CONNECT: λ‹¨μˆœ 접속 κΆŒν•œ
  • REVOKE: λΆ€μ—¬λœ κΆŒν•œμ„ λˆ„κ΅¬λ‘œλΆ€ν„°(FROM) νšŒμˆ˜ν• μ§€ μ •μ˜ν•œλ‹€.

TCL(Transaction Control Language, νŠΈλžœμž­μ…˜ μ œμ–΄μ–΄)

  • COMMIT: νŠΈλžœμž­μ…˜μ΄ μ„±κ³΅μ μœΌλ‘œ μ™„λ£Œλ˜μ—ˆμ„ λ•Œ κ²°κ³Όλ₯Ό λ°˜μ˜ν•œλ‹€.
  • ROLLBACK: νŠΈλžœμž­μ…˜ μˆ˜ν–‰ 쀑 λ¬Έμ œκ°€ 생겼을 λ•Œ 초기 μƒνƒœλ‘œ λ³΅κ·€ν•œλ‹€.
  • SAVEPOINT: 볡귀 지점을 μ§€μ •ν•œλ‹€.

참고 자료

  1. ai_researcher.log, β€œλ°μ΄ν„°λ² μ΄μŠ€(3) SQL - DDL, DML, DCL”, https://velog.io/@cha-suyeon/λ°μ΄ν„°λ² μ΄μŠ€3-SQL-DDL-DML-DCL

  2. 주간컴곡, β€œ47. DDL/DML/DCL 2μž₯. 물리DB섀계 3κ³Όλͺ©. DBꡬ좕 _ μ •λ³΄μ²˜λ¦¬κΈ°μ‚¬(2020) 필기”, https://youtu.be/3UygoMorzrw


베이슀볼 PR 올리기

+) 22. 08. 12. 7μ°¨ PR μΆ”κ°€!

Input Class

μ‚¬μš©μžμ—κ²Œ 값을 μž…λ ₯ λ°›λŠ” 클래슀

import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

public class Input {

    public String input() {
        System.out.println("\n1~9 μ‚¬μ΄μ˜ 숫자 3개λ₯Ό μž…λ ₯ν•΄ μ£Όμ„Έμš”.");
        return new Scanner(System.in).nextLine();
    }

    public List<Integer> toNumbers(String str) {
        List<Integer> numbers = Pattern.compile("")
                .splitAsStream(str)
                .map(Integer::parseInt)
                .collect(Collectors.toList());

        validateForNumberLength(numbers);
        validateForNumberRange(numbers);
        validateForDuplication(numbers);

        return numbers;
    }

    public void validateForNumberLength(List<Integer> numbers) {
        if(numbers.size() != 3) {
            throw new RuntimeException("3자리 숫자λ₯Ό μž…λ ₯ν•΄ μ£Όμ„Έμš”.");
        }
    }

    public void validateForNumberRange(List<Integer> numbers) {
        if(numbers.contains(0)) {
            throw new RuntimeException("1~9 λ²”μœ„μ˜ 숫자λ₯Ό μž…λ ₯ν•΄ μ£Όμ„Έμš”.");
        }
    }

    public void validateForDuplication(List<Integer> numbers) {
        int count = (int) numbers.stream().distinct().count();

        if (count < 3) {
            throw new RuntimeException("쀑볡값이 μžˆμŠ΅λ‹ˆλ‹€.");
        }
    }
}
  • input()
    μ‚¬μš©μžμ—κ²Œ 값을 μž…λ ₯ λ°›λŠ”λ‹€.

  • toNumbers()
    μž…λ ₯ 받은 값을 ν•œ κΈ€μžμ”© λΆ„λ¦¬ν•˜μ—¬ λ¦¬μŠ€νŠΈμ— λ„£κ³  μ •μˆ˜ν˜•μœΌλ‘œ λ°˜ν™˜ν•œλ‹€.

  • validateForNumberLength()
    3자리 μˆ˜κ°€ λ§žλŠ”μ§€ κ²€μ‚¬ν•œλ‹€.

  • validateForNumberRange() (μƒˆλ‘œ μΆ”κ°€λœ λΆ€λΆ„)
    1~9 λ²”μœ„μ˜ μˆ˜μΈμ§€ κ²€μ‚¬ν•œλ‹€.

  • validateForDuplication()
    쀑볡값이 μžˆλŠ”μ§€ κ²€μ‚¬ν•œλ‹€.


RandomNumber Class

λžœλ€ν•œ μ •μˆ˜λ₯Ό μƒμ„±ν•˜λŠ” 클래슀

import lombok.extern.slf4j.Slf4j;

import java.util.*;

@Slf4j
public class RandomNumber {

    private final Set<Integer> randomNumber;

    public RandomNumber() {
        randomNumber = new HashSet<>();
    }

    public List<Integer> createRandomNumber() {
        Random random = new Random(System.currentTimeMillis());

        while(randomNumber.size() < 3) {
            randomNumber.add(random.nextInt(9) + 1);
        }

        log.info("λžœλ€κ°’ = {}", randomNumber);
        return new ArrayList<>(randomNumber);
    }
}
  • createRandomNumber()
    쀑볡값이 없도둝 Set으둜 값을 μ €μž₯ν•œλ‹€. λ¦¬μŠ€νŠΈμ— 3κ°œκ°€ λ“€μ–΄κ°ˆ λ•ŒκΉŒμ§€ λ°˜λ³΅ν•΄μ„œ λžœλ€κ°’μ„ μƒμ„±ν•˜κ³  λ„£λŠ”λ‹€.

μ΄λ²ˆμ—” Math.random λŒ€μ‹  java.util의 Random을 μ‚¬μš©ν–ˆλ‹€.


Ball Class

Ball인지 ν™•μΈν•˜λŠ” 클래슀

import java.util.List;

import static java.util.stream.IntStream.range;

public class Ball implements Baseball {

    private final int ball;

    public Ball() {
        this.ball = 0;
    }

    @Override
    public int compare(List<Integer> randomNumber, List<Integer> userNumber) {
        return (int) range(0, 3)
                .filter(n -> randomNumber.contains(userNumber.get(n)))
                .count();
    }
}
  • compare()
    λžœλ€κ°’ λ¦¬μŠ€νŠΈμ— μ‚¬μš©μžκ°€ μž…λ ₯ν•œ 값이 ν¬ν•¨λ˜μ–΄ μžˆλŠ”(contains) 개수λ₯Ό λ°˜ν™˜ν•œλ‹€.

IntStream.rangeλ₯Ό μœ„μ— static으둜 뺌.
그리고 객체지ν–₯ μƒν™œμ²΄μ‘° 원칙 쀑 <ν•œ 쀄에 점을 ν•˜λ‚˜λ§Œ μ°λŠ”λ‹€.>λ₯Ό 지킀기 μœ„ν•΄ μ λ§ˆλ‹€ μ—”ν„° 찍음... 이게 원칙을 지킨 건진 λͺ¨λ₯΄κ² μŒ.


Strike Class

Strike인지 ν™•μΈν•˜λŠ” 클래슀

import java.util.List;

import static java.util.stream.IntStream.range;

public class Strike implements Baseball {

    private final int strike;

    public Strike() {
        this.strike = 0;
    }

    @Override
    public int compare(List<Integer> randomNumber, List<Integer> userNumber) {
        return (int) range(0, 3)
                .filter(n -> randomNumber.get(n).equals(userNumber.get(n)))
                .count();
    }
}
  • compare()
    λžœλ€κ°’ λ¦¬μŠ€νŠΈμ— μžˆλŠ” μˆ˜μ™€ μ‚¬μš©μžκ°€ μž…λ ₯ν•œ μˆ˜κ°€ 값도 κ°™κ³  μœ„μΉ˜λ„ 같은(equals) 개수λ₯Ό λ°˜ν™˜ν•œλ‹€.

바뀐 건 Ball Class와 κ°™μŒ.


Main Class

μ‹€ν–‰ν•˜λŠ” 클래슀

import java.util.List;

public class Main {

    public static void main(String[] args) {
        Input input = new Input();
        Output output = new Output();
        RandomNumber randomNumber = new RandomNumber();
        List<Integer> randomNumbers = randomNumber.createRandomNumber();

        Ball ball = new Ball();
        Strike strike = new Strike();

        output.printPlayBaseballGame();

        while(true) {
            List<Integer> userNumbers = input.toNumbers(input.input());

            int totalStrike = strike.compare(randomNumbers, userNumbers);
            int totalBall = ball.compare(randomNumbers, userNumbers) - totalStrike;

            output.output(totalBall, totalStrike);

            if(totalStrike == 3) {
                break;
            }
        }
    }
}

바뀐 점은 λΆˆν•„μš”ν•œ int totalStrike = 0, int totalBall = 0을 λΉΌκ³  while(totalStrike != 3)을 while(true)둜 λ°”κΎΈμ—ˆλ‹€.
그리고 while λ¬Έ μ•ˆμ— if(totalStrike == 3)을 μ£Όμ–΄μ„œ λ°˜λ³΅λ¬Έμ„ νƒˆμΆœν•˜λ„λ‘ 함.

이와 κ΄€λ ¨ν•΄μ„œ λ‚΄κ°€ κΆκΈˆν–ˆλ˜ 것...

이 방법이 μ’€ 더 객체지ν–₯적인 방법이 μ•„λ‹κΉŒ? μƒκ°ν–ˆλ‹€.
κ·Έλž˜μ„œ μœ„μ™€ 같이 κ΅¬ν˜„ν•˜κ³  μ‹Άμ—ˆλŠ”λ° 그건;; Strike 값을 μ–΄λ–»κ²Œ λ°›μ•„μ˜¬μ§€μ— λŒ€ν•œ κ΅΄λ ˆκ°€ μƒκ²¨μ„œ... 일단 포기함.
getStrikeλ₯Ό μ“°λ©΄ getter/setterλ₯Ό 쓰지 μ•ŠλŠ”λ‹€λŠ” 객체지ν–₯ μƒν™œμ²΄μ‘° 원칙에 μœ„λ°°λ˜λŠ” 것이 μ•„λ‹Œκ°€ ν•΄μ„œ.

음... μ•„λ¬΄νŠΌ μ’€ 더 객체지ν–₯적인 μ½”λ“œλ‘œ 짜고 μ‹Άμ—ˆλŠ”λ° 지식이 λΆ€μ‘±ν•˜λ‹ˆ νž˜λ“€μ—ˆλ‹€. κ·Έλž˜λ„ 계산기 λ•Œλ³΄λ‹¨ μ’€ 더 λ‚˜μ•„μ§„ 것 κ°™μŒ... 응...

profile
김뉴비

0개의 λŒ“κΈ€

κ΄€λ ¨ μ±„μš© 정보