서비스가 커지고 문제가 복잡해질수록, 이를 처리하기 위한 소프트웨어의 아키텍쳐적인 부분이 중요해진다.

 

내가 진행했던 토이프로젝트의 서버는 크게 세 가지 일을 했다.

 

-새로운 데이터를 처리

-서비스로직을 처리(시간표그려주기 등)

-기존의 데이터를 이용 (db 활용)

 

Spring 에서는 해당 부분들이 각각의 레이어로 나누어져있다.

 

-Presentation layer : 사용자와 상호작용하는 처리 계층. CLI, HTTP요청, HTML처리 등을 담당 (Model, View, Controller..)

   ==> 특정 url에 요청을 보내면 해당 url에 묶인 메서드가 호출되었던 부분과 비슷.

 Spring에서 @Controller로 표현

 

-Domain(business / service) layer : 서비스나 시스템의 핵심 로직. 유효성 검사, 계산 등 어플리케이션의 도메인과 관련된 작업들을 담당함. 프로그램이 복잡해지면, 비지니스 로직을 수행하기 위한 별도의 계층이 필요하다. 그게 Domain layer

 Spring에서 @Service로 표현

 

-Data Access(persistence) Layer (DAO 계층) : Database / Message Queue / 외부 API와의 통신 등을 처리한다.

DB 혹은 데이터 소스가 서버 외부에 별개로 존재하는 경우가 매우 많기 때문에, 데이터 소스와의 소통계층이 필요함.

Spring에서 @Repository로 표현

 

레스토랑에 비유하면

@Controller : 웨이터

@Service : 쉐프

@Repository : 주방보조 (재료가져다줌)

 

<Database>

DBMS : Database Management System

RDBMS : Relational Database Magagement System

==RDBMS==============

-테이블이라는 최소  단위로 구성되고, 테이블은 열과 행으로 이루어져있다.

-MySQL, PostgreSQL, Oracle 등

======================

 

H2 : In-memory DB의 대표주자. 인메모리DB란 서버가 작동하는 동안에만 내용을 저장하고, 서버를 닫으면 데이터가 모두 삭제  ==> 연습용으로 좋다.

 

<SQL> : Structured Query Language  :  RDBMS에서 사용하는 언어

 

=====DDL=====  : Data Definition Language   : 테이블이나 관계의 구조를 생성하는데 사용

CREATE DATABASE 데이터베이스이름;

CREATE TABLE 테이블이름

(

필드이름1 필드타입1,

필드이름2 필드타입2,

...

)

ALTER TABLE 테이블이름 ADD 필드이름 필드타입;

ALTER TABLE 테이블이름 DROP 필드이름;

ALTER TABLE 테이블이름 MODIFY COLUMN 필드이름 필드타입;

 

DROP DATABASE 데이터베이스이름;

DROP TABLE 테이블이름;

TRUNCATE DATABASE 데이터베이스이름;

TRUNCATE TABLE 테이블이름;

 

=====DCL=====  : Data Control Language   :  데이터의 사용 권한을 관리하는데 사용

GRANT SELECT , INSERT          : 권한 부여

ON mp

TO scott WITH GRANT OPTION;

 

REVOKE SELECT, INSERT         :  권한 회수

ON emp

FROM scott

[CASCASE CONSTRAINTS];

 

=====DML=====  : Data Manipulation Language   :  테이블에서 데이터를 검색 / 삽입 / 수정 / 삭제

INSERT INTO 테이블이름 (필드이름1,필드이름2,필드이름3...) VALUES(데이터값1, 데이터2, 데이터3....)

INSERT INTO 테이블이름 VALUES (데이터1,데이터2,데이터3....)

 

SELECT 필드이름 FROM 테이블이름 WHERE[조건];

 

UPDATE 테이블이름 SET 필드이름1 = 데이터값1, 필드이름2 = 데이터값2...... , WHERE 필드이름 = 데이터값;

 

DELETE FROM 테이블이름 WHERE 필드이름 = 데이터값;

 

 

<SQL Cheatsheet>

=====CREATE 제약조건들=====

AUTO_INCREMENT  :  컬럼의 값이 중복되지 않게 1씩 자동으로 증가하게 해줘 고유번호를 생성

NOT NULL : 해당필드는 NULL값을 저장할 수 없게됨

UNIQUE : 해당필드는 서로 다른값을 가져야만 함

PRIMARY KEY : 해당필드가 NOT NULL과 UNIQUE 특징을 모두 가지게 됨

     ==> 테이블에 유일하게 존재하는 값의 조합을 설정해서 중복된 데이터가 테이블에 삽입되는 것을 방지하는 제약조건

     ==> 데이터의 무결성을 위해서 사용, 데이터를 빠르게 검색할 수 있게 됨

FOREIGN KEY : 두개의 테이블을 연결하는 다리 역할을 하는 KEY 

     ==> FOREIGN KEY (필드이름) REFERENCES 테이블이름(필드이름)

     ==> FOREIGN KEY 역시 데이터의 무결성을 보장. FK를 적용하려는 컬럼이 참조하는 테이블의 컬럼은 PK, UNIQUE

 

 

어플리케이션이 데이터베이스를 직접 다룰 때의 문제점

- 훨씬 번거롭다 : 테이블 만들고, 쿼리 작성하고, 쿼리를 jdbc api통해 실행, 결과 객체도 직접 만들어줘야함

- SQL의존적이다: SQL에 컬럼을 추가하면, 관련된 객체, 쿼리문 등등 모든 부분을 수정해야함 => 비지니스로직보다 SQL↑

- 패러다임 불일치

https://knoc-story.tistory.com/m/90

==> ORM, JPA 기술의 등장

ORM : object relation Mapping

 

<JPA>  : Java Persistence API

=>자바 ORM 기술에 대한 표준 명세

1. 쿼리를 자동으로 만들어줌

2. 어플리케이션 계층에서 sql 의존성을 줄임 (번거로운 반복작업 ↓)

3. 패러다임의 불일치 해결

4. 방언을 지원하기 때문에, h2 DB, mySQL, oracle 등 SQL표준을 준수한 DB무엇을 붙여도 같은 코드로 쓸 수 있다.

 

@Entity     annotation을 통해 해당 클래스가 DB의 테이블 역할을 한다는 것을 알려준다.

@OneToMany  // @ManyToOne // @OneToOne // @ManyToMany   : Entity들의 연관관계 형성

 

eg) Food 엔티티의 food // Orders 엔티티의 food_id가 매핑되어야 한다고 할 때,

Food 클래스 안에서:

@OneToMany(mappedBy = "food", fetch = FetchType.EAGER)

private List<Orders> orders = new ArrayList<>();

 

Orders 클래스 안에서:

@ManyToOne

@JoinColumn(name = "food")

private Food food;                      ==> 생성자까지 추가해줘야함

 

repository 패키지에 각 entity별로 FoodRepository와 같이 생성

public interface FoodRepository extends JpaRepository<Food, Long>{}

foodRepository.saveAll(List<Food>)와 같이 사용 가능

메서드들 : save, saveAll, findAll, findById 등등

웬만한 기능들은 JpaRepository에 구현 되어있기 때문에, Repository 구현체에서 override 해주면 된다.

만들 수 있는 것들이 추천됨

https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods  에서 query method 들을 확인가능

 

<추가 공부>

-영속성 컨텍스트, 1차 캐시

 

 

 

+ Recent posts