ㄴㅏ랏말ㅆ.ㅁㅣ
article thumbnail

3일차 MySQL과 데이터베이스

  • Database와 MySQL
  • 테이블 만들기
  • Spring에서 DB사용하기

컴퓨터의 핵심부품

CPU : 연산(덧셈, 곱셈)

RAM : 메모리(렘8, 16), 임시기억장치

DISK : 하드디스크, SSD, 장기기억장치

서버를 실행시켜 API동작까지 일어나는 일

  1. 개발하고 있는 서버(코드)는 DISK에 잠들어 있다
  2. 서버를 실행시키면 DISK에 있는 코드 정보가 RAM으로 복사된다
  3. API가 실행되면 '연산'이 수행되며 CPU와 RAM을 왔다갔다 한다
  4. 즉 POST API를 통해 생긴 유저 정보는 RAM(메모리)에 쓰여 있다
  5. 서버가 종로되면 RAM에 있는 모든 정보는 사라진다
  6. 때문에 다시 서버를 시작하면 유저 정보가 없다(그러므로 워드, 엑셀에서 저장은 DISK에 장기기록을 뜻한다)

그렇다면 서버에서 DISK에 저장하는 방법은?

  1. File클래스를 이용해 직접 Disk에 접근할 수도 있음
  2. Database를 이용해 저장

Database : 데이터를 구조화 시켜 저장하는 것

MySQL : RDB(Relational Database)로 표처럼 구조화 시켜 사용

SQL(Structured Query Language) : 표처럼 구조화된 데이터를 조회하는 언어

MySQL 정수타입

 tinyint : 1바이트 정수
 int : 4바이트 정수
 bigint : 8바이트 정수

실수타입

 double : 8바이트 정수
 decimal(A, B) : 소수점을 B개 가지고 있는 전체 A자리 실수
 ex) Decimal(4,2) = 12.23

문자열 타입

 char(A) : A 글자가 들어갈 수 있는 문자열(고정)
 varchar(A) : 최대 A 글자가 들어갈 수 있는 문자열(최대) 

날짜, 시간 타입

 date : 날짜, yyyy-MM-dd
 time : 시간, HH:mm:ss
 datetime : 날짜와 시간을 합친 타입, yyyy-MM-dd HH:mm:ss

데이터를 정의하는 언어로 DDL(Data Definition Language)라 함

데이터 생성, 조회, 수정, 삭제 -> CRUD

  • 데이터 넣기
    INSERT INTO [테이블 이름] (필드1이름, 필드2이름, ....) VALUES (값1, 값2 ..)
  • 데이터 조회
    SELECT * FROM [테이블 이름] WHERE [조건]; 조건에는 =, <=, !=, <, >, >=, between, in, not in등이 있다
  • 데이터 수정
    UPDATE [테이블 이름] SET 필드1이름=값, 필드2이름=값, ... WHERE [조건]; 만약 [조건]을 붙이지 않으면, 모든 데이터가 업데이트 된다
  • 데이터 삭제
    DELETE FROM [테이블 이름] WHERE [조건]; [조건]을 붙이지 않으면, 모든 데이터가 삭제된다

이 4가지는 데이터를 조작하는 언어로 DML(Data Manipulation Language)라 한다

Spring과 데이터베이스 연결하기

yml 설정

spring:
  datasource:
    url: "jdbc:mysql://localhost/library"
    // 자바 데이터베이스 커낵터 db는 mysql 사용할 db는 library
    username: "root"
    password: "aa414802!"
    driver-class-name: com.mysql.cj.jdbc.Driver
      // 데이터 베이스에 접근할때 사용할 프로그램

메모리에 저장하던 유저 정보를 mysql에 저장하도록 바꾸기

UserController에 들어가서 바꿔줌

Jdbc템플릿이 생성자를 만들어두면 자동으로 파라미터를 타고 들어와 설정되게 됨

고정된 sql이 아닌(?, ?)는 입력값에 따라 달라져야 하기에 ?로 처리

GET API 변경

간단히 람다로 변경도 가능

익명 클래스

주로 한 번만 사용되는 객체를 생성할 때 사용. 이름이 없으며, 간단한 인터페이스 구현에 사용됨

- 인터페이스나 추상 클래스를 즉석에서 구현해 사용
- 외부의 final이나 effectively final 변수에 접근가능
button.addActionListener(new ActionListener() { // 익명클래스 사용해 메소드 구성함
    public void actionPerformed(ActionEvent e) {
        // 이곳에 클릭 시 수행할 동작을 정의합니다.
    }
});

람다

자바8부터 도입되어 코드를 간결하게 만들며 함수형 프로그래밍을 지원함,
주로 컬렉션의 요소를 처리하거나 이벤트 리스너 구현에 사용
큰수찾기
@FunctionalInterface
interface MyNumber {
    int getMax(int num1, int num2);
}

public class LambdaExample {
    public static void main(String[] args) {
        MyNumber max = (x, y) -> (x >= y) ? x : y;
        System.out.println(max.getMax(10, 30));
    }
}


Runnable 인스턴스 생성 및 Thread 실행
public class RunnableExample {
    public static void main(String[] args) {
        Runnable runnable = () -> {
            for (int i = 0; i < 30; i++) {
                System.out.println(i);
            }
        };
        Thread thread = new Thread(runnable);
        thread.start();
    }
}

함수형 프로그래밍

자료처리를 수학적 함수계산으로 취급하고, 상태와 가변 데이터를 멀리하는 프로그래밍
명령형 프로그래밍 상태변경과 반대되어 함수의 응용을 강조, 순수함수를 사용해 프로그램 동작 예측가능
public static void main(String[] args) {
    List<Integer> values = Arrays.asList(7, 5, 123, 5, 42, 95, 68, 30, 42);
    List<Integer> result = values.stream()
                                  .filter(number -> number < 50)
                                  .distinct()
                                  .sorted()
                                  .collect(Collectors.toList());
    System.out.println(result);
}

원본 리스트 values는 변경되지 않으며, 각 단계에서 순수 함수를 사용하여 연산을 수행
불변성과 부작용이 없는 연산을 보여줌

@FunctionalInterface

자바8에서 도입된 어노테이션으로, 해당 인터페이스가 함수형 인터페이스임을 나타냄
함수형 인터페이스는 정확히 하나의 추상 메서드를 가져야 하며, 어노테이션은 이러한 인터페이스를 
명시적으로 표시하는데 사용 또한 함수형 인터페이스의 계약 위반시 컴파일러에게 오류 메시지 생성 요구
@FunctionalInterface
public interface SimpleFunctionalInterface {
    void execute();
}
execute 라는 하나의 추상 메서드를 가지고 있음, 람다 표현식, 메서드 참조, 생성자 참조를 통해 인터페이스의 인스턴스 생성 가능

스트림 API

스트림 API를 사용하면 데이터를 필터링, 정렬, 변환, 그룹화하는 등의 작업을 람다식을 이용하여 간단하고 가독성 높은 코드로 작성할 수 있으며, 병렬 처리를 통해 성능을 향상시킬 수 있다

메소드 레퍼런스

자바에서 람다식으로 표현되는 메소드의 실행 로직이 이미 존재하는 메소드와 동일한 경우, 해당 메소드를 직접 참조하는 방식
이를 통해 가독성 향상, 중복 줄임, 간결한 표현 가능하다
public static void main(String[] args) {
    List<String> words = Arrays.asList("hello", "world", "java", "stream");

    // 람다 표현식을 사용한 경우
    words.forEach(word -> System.out.println(word));

    // 메소드 레퍼런스를 사용한 경우
    words.forEach(System.out::println);
}

문제

  1. 자바의 람다식은 왜 등장했을까?
    자바에서 람다를 다루기 위한 노력
    무수한 동작들을 만들어야 함에따라 매소드 생성이 너무 많이 필요했다, 그러한 복잡한 코드를 조금이라도 줄이고자 '익명 클래스', 와 인터페이스를 사용해 매소드 생성을 막을 수 있엇다
    But '익명 클래스'의 사용은 복잡했고 다양한 필터가 필요했다. 이러한 불편함을 완전히 해결하고자 JDK8에서 람다(이름 없는 함수)가 등장했다
    FuitFilter, Predicate, Consumer 등의 인터페이스를 JDK8에서 많이 만들어 놨고 사용할 수 있었다
    또한 if문과 for문을 간결하게 만들고자 stream을 사용하게 되었다(병렬 처리 가능)
private List<Fruit> filterFruits(List<Fruit> fruits, Predicate<Fruit> fruitFilter) {
    List<Fruit> results = new ArrayList<>();
    for (Fruit fruit : fruits) {
        if (fruitFilter.test(fruit)) {
            results.add(fruit);
        }
    }
    return results;
}

filterFruits(fruits, fruit ->fruit.getName(),equals("사과"));
// 변수 -> 변수를 이용한 함수로
// (변수1, 변수2) -> 변수1과 변수 2를 이용한 함수

스트림으로 변환
private List<Fruit> filterFruits(List<Fruit> fruits, Predicate<Fruit> fruitFilter) {
    return fruits.stream()
            .filter(fruitFilter)
            .collect(Collections.toList());
}

메소드 레퍼런스 활용
filterFruits(fruits, Fruit::isApple);
/* 메소드 자체를 직접 넘겨주는 '것처럼' 사용. 왜냐하면 실제 함수를 넘겨주는 것 같지만(Fruit::isApple) 실제 받는 것은
 Predicate 인터페이스여서 '넘겨주는 것처럼' 사용하는 것, 이는 바꿔 말해 Java에서는 함수는 변수에 할당되거나 파라미터로\
 전달할 수 없다. (자바에서 함수는 2급 시민 으로 간주)*/

2. 람다식과 익명 클래스는 어떤 관계가 있을까?


익명클래스는 클래스 선언과 인스턴스가 필요하지만 람다식은 더 간결한 문법으로 직관적이다


(int a, int b) -> a > b ? a : b

// 위(람다식)와 아래(익명 클래스의 객체 내부 메소드)와 같다

new Object(){
int max(int a, int b) {
    return a > b ? a : b;}
}
------------------------------------------

MyFunction f = new MyFunction() {  
@Override  
public int max(int a, int b) {  
    return a > b ? a: b;  
    }  
};


int big = f.max(5, 3);

System.out.println(big);

람다식
MyFunction f = (a, b) -> a > b ? a: b;
람다식도 익명 객체이기에 대체 가능하다

하나의 메서드가 선언된 인터페이스를 정의해서 람다식을 다루는 것은 기존의 자바의 규칙들을 어기지 않으면서도 자연스럽다.

그렇기 때문에 인터페이스를 통해 람다식을 다루기로 결정되었으며,

람다식을 다루기 위한 인터페이스를 함수형 인터페이스(functional interface)라 부른다

@FunctionalInterface
public interface MyFunction{
    public abstract int max(int a, int b);
}
단, 함수형 인터페이스에서는 오직 하나의 추상 메서드만 정의되어 있어야 한다는 제약이 있다
그래야 람다식과 인터페이스의 메서드가 1:1로 연결될 수 있다

다만, static 메서드와 default 메서드의 개수에는 제약이 없다
함수형 인터페이스로 구현한 인터페이스라면 반드시 '@FunctionalInterface' 애노테이션을 정의하도록 하자.
컴파일러가 함수형 인터페이스를 올바르게 정의하였는지 확인해줌

3. 람다식의 문법은 어떻게 될까?

(parameter1, parameter2, ...) -> { body }

파라미터 : 람다식의 입력 매개변수로 파라미터가 없다면 빈 괄호로() 나타낼 수 있음, 하나의 파라미터면 괄호 생략 가능 () -> a + b

화살표 : 본문(body)을 구분하는 구분자

매서드 본문 : 하나의 표현식이나 여러 개의 문장으로 구성될 수 있음


출처

profile

ㄴㅏ랏말ㅆ.ㅁㅣ

@동여우

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!

검색 태그