[Spring][9]RDB, Object Relationship Mapping in Spring[관계형 데이터베이스, ORM]
BackEnd/Spring

[Spring][9]RDB, Object Relationship Mapping in Spring[관계형 데이터베이스, ORM]

목차

- 동기 , 비동기

- 관계형 데이터베이스

- 서브 쿼리

- Inner join

- ORM

- UX 개선


동기, 비동기 

 

예를 들면

파일 시스템에서 학생 시스템, 직원 시스템으로 분리되어있는데

한 직원이 서울로 이사하면 데이터를 변경을 해야 합니다. 

여기서 두 개의 데이터가 일치되지 않으면 동기화되지 않다는 뜻입니다.

 

다른 예시로는 

동기화는 일의 순서가 있는데 

우리가 라면을 끓이고 삼겹살을 구울 때처럼 동기화하는데 순서가 있습니다.

 

그러나 비동기화일의 순서가 없고 동기화되지 않는 상태입니다.

 

사람은 비동기화가 가능합니다.

라면을 끓이면서 같이 고기 굽는 것처럼 이요.

 

다만 컴퓨터는 동기적 프로그램입니다.

스레드가 없으면 전부다 동기적 프로그램으로 봐도 무방합니다.

 

 

비동기 프로그램 일의 순서가 없습니다.

 

 

또 다른 예시를 들면

 

만두를 4분 찌고 있을 때

같이 간장 만드는 프로그램을 만든다고 하면

 

프로그램을 만약 잘못 짜면 만두가 null -> nullpoint exception 이 됩니다.

 

 

비동기 프로그래밍에서는

일의 순서가 없기 때문에(언제 끝날지 몰라서) 타이밍을 잡기 힘듭니다.

 

 

동기화 프로그램 데이터베이스에서는 일치합니다.

(일의 순서가 있는 것)

 

비동기 프래그램 일의 순서가 없음, 짜는 게 힘들지만 개념은 쉽습니다.

(스레드를 돌리면 된다)

비동기 프로그램코드를 짜는 게 힘들다네요.

 

 

*

Tips

안드로이드에서는

IO(Input Output)- 데이터 요청

을 하면 응답을 해줘야 합니다

 

비동기 프로그램을 익숙하게 하려면 안드로이드를 하면 익숙해진다네요.

*

 


관계형 데이터베이스(RDB)

 

RDB 관계형 데이터베이스

 

데이터베이스를 나누면 괜찮아집니다.

 

무결성을 지키게 됩니다. (=일관성)

무결성이 깨지면 데이터의 일관성이 깨지며 원칙에 어긋나게 됩니다.

 

RDB에서의 저장 키 그리고 object

 

 

중복을 제거하기 위해서 나온 것이 데이터베이스입니다.

데이터베이스데이터를 공유하는 것이 목적입니다.

 

오브젝트(object)로 만들어지는 것은 전부 다 테이블(table)이라고 생각하면 됩니다.

 

그 이유는 DB에서는 오브젝트를 표현하기 힘들기 때문입니다.

(즉 칼럼 하나에 다 안 들어간다는 것)

 

오브젝트는 자바에서는 클래스입니다.

데이터베이스에는 테이블(table)로 이 클래스를 넣어야 합니다.!!

 

 

예를 들면

영화관의자각자 서로 여러 많은 속성을 들고 있습니다.

이러면 각자 테이블을 만들어야 합니다.

테이블로 만든다는 것은 하나의 데이터로 표현하지 못한다는 뜻입니다.

 

테이블끼리 연관관계가 있다면

R(relationship) 관계형 데이터베이스(database)가 됩니다. 

 (RDB)

 

 

오브젝트들끼리 연관관계를 가질 수 있는데

DB에서 테이블끼리 연관관계를 만들 수 있습니다.

 

DB에서 테이블을 만들 때의 특징으로는

 

  1. 테이블을 만들 때 하나의 데이터로 표현하지 못하면 모두 각각 테이블 형태로 만듭니다.
  2. 하나의 데이터로 표현 못해서 테이블을 만들면 길어질 수 있습니다.
  3. 데이터가 중복되면 쪼개면 됩니다.!

 

 

*

오브젝트 – 테이블 -> 문자열

고유명사는 하나의 칼럼으로 암 -> 하나 더 생기면 시스템을 바꿔야 함

*

 

 


서브 쿼리(Sub Query)

 

 

--1 1 유저 정보 필요해!

SELECT * FROM user WHERE id = 1;

 

 

 

1.     하드에 있는 걸 메모리에 퍼올립니다 (from user)

2.     Select칼럼을 결정합니다 

SELECT id, address, username FROM user WHERE id = 1;

프로젝션, where에서 먼저 찾으면(행을 줄임) -> 이러면 효율적임

 

 

쿼리문 기초

 

 

Select 안에 Select 이 들어간 것이 서브 쿼리라고 합니다.

 

하드에 퍼올리는 건 둘 다 두 번 접근(퍼올려야) 해야 합니다.

 

 

퍼올리고 어디서 찾을지 결정하고 필터링하고 이제 찾습니다.

 

 

서브쿼리의 모습

 

 

서브 쿼리의 방식은 비동기 방식동기화 방식으로 바꿔준 것입니다.

 

즉, 위의 방식은 하나의 절이 끝나야 다음절이 일을 하는 방식이지만

서브 쿼리는 한 번에 한 줄로 끝내서 바로 동작을 하는 방식입니다.

 

그렇지만 두 방식 모두 비효율적인 방식입니다. 

(하드에서 데이터를 두 방식 다 둘 다 퍼올려야 함)

 

다른 효율적인 방법으로는 Join을 써서 합치는 방법이 있습니다.

 

 

*

서브 쿼리는 ( ) 안에 있는 절은 하나의 값만 나오게 해야 한다.

(쿼리문 문법)

*


Inner join ( Equal join, join ) 

 

-> 쿼리문이 동일해도 Oracle, MariaDB... 다양한 DB 가 있어서 문법이 각각의 DB마다 따로 불립니다.

 표준( DB에서의 Query문 표준 )

 

 

INNER JOIN 으로 합쳐진다

 

 

 

아래에 user_id를 선택하지 않게 SELECT 뒤에 이 값을 빼고 넣어줍니다.

 

선택한 것들만 보이게 할 수 있다

 

 

user가 u로 설정되어있어서 u. 밑으로 여러 가지 columns 값들을 불러올 수 있습니다.

마찬가지로 post도 p로 설정되어있어서 user처럼 p. 밑의 값을 불러올 수 있습니다.

 

SELECT u.id, u.address, u.eamil, u.password, u.username, p.id, p.content, p.title를 써서 두 개의 테이블을 붙인 모습

 

 

각각의 id

 


Outer join

 

 

다음과 같이 작성을 하면 Inner join에서 한쪽 테이블이 연결이 안 되는 값도 보여주게 됩니다. (null값)

 

 

NULL값이 보인다

 

 

여기서 왼쪽이 driving table입니다,

즉 먼저 drive 되며,

 

그 후에 access 되는 tabledriven table이라고 합니다.

 

user u가 driving table이며, post p가 driven table입니다.

 

outer 명령어를 내렸기 때문에,

오른쪽은 null이지만

왼쪽은 보여주게 됩니다.

 

 

거울처럼 같지만 위치만 바뀐 경우

 

 

 


ORM 

 

ORM의 장점으로는

기존에 DB에 접근을 하는 것은 객체의 형태로는 접근이 불가능했었는데

JPA의 등장으로 Object의 형태로도 DB에 접근이 가능해져

ObjectMapping 하여 가져올 수 있다는 것입니다.

 

 

실습을 해봅시다.

 

yml로 가서 ddl-autocreate로 바꿔서 기존의 데이터를 없앱니다.

 

create

 

 

아래처럼 post클래스에서 user_id를 삭제합니다

 

 

user_id 삭제

 

getter, setter 삭제

 

getter, setter 삭제

 

*

여기서 post많은 위치(N)이며 : user는 1(하나)입니다.

바로 1:N 관계입니다

post가 N

 

그러므로 Post 포린 키로 

@ManyToOne을 붙여서

User 객체를 ORM(Object Relationship Mapping) 합니다.

*

 

ORM(@ManyToOne)

 

유저 오브젝트 안의 프라이머리 키가 자동적으로 Post의 포린 키로 만들어줍니다.

 

키가 설정된 모습

 

 

Usergetter, setter도 만들어줍니다.

 

 

 

아래 사진처럼 쿼리문을 작성하여 데이터를 넣어봅시다

 

데이터가 들어간 모습

 

데이터가 들어간 모습 그리고 포린 키랑 연결됩니다.

 

 

 

 


ORM 구현

 

Test를 위해

 

PostApiControllerTest 클래스와

PostRepository 인터페이스를 생성합니다

 

 

PostApiControllerTest

 

PostRepository(Interface)

 

둘 다 생성된 모습

 

PostApiControllerTest

 

PostRepository extends JpaRepository

 

PostRepositoryJpa extends 하기 때문에 기본적인 JPA가 담겨 있습니다.

 

RestController

 

데이터를 return 해야 하기하기 때문에 RestController로 설정합니다

 

PostApiControllerTest DI를 하고

 

 

GetMapping 하여 찾아서 리턴해줍니다.

/test/post을 입력하면

 

object 형태로 return

 

Object 형태로 저장되어있는 모습

 

 

Json.parser로 확인

 

콘솔 창에서 확인해보면

 

Hibernate 되어서 날아가는 모습

이렇게 하면 둘 다 퍼올립니다.

 

 

다른 방식으로 해봅시다

 

 

/test/post/{id}

 

 

반환하는 모습

 

json parser로 확인

 

outer join되는 모습

이렇게 하면 한 번만 퍼올려도 됩니다.

 

Driving table에 포린 키가 있는 것이 좋습니다.

90%의 대부분은 Driving table에 포린 키가 있는 것이 좋지만

10%는 그렇지 않을 때도 있을 수 있습니다.

 

JPAhireberate로 함수를 들고 있는데, 들고 있는 함수들 중에 ORM도 들고 있습니다.

 

그렇기 때문에

ORM의 좋은 점으로 자바에서 Oject로 설계할 수 있게 해 줍니다.

 

Driving 에는 포린 키가 있는 게 좋습니다

 

포린 키 

1.     N

2.     Driving 포린 키

 

 


UX 개선

 

Springboot에 여러 가지 유효성 검사를 할 수 있는 Tool(@)들이 있습니다.

 

 

 

 

 

 


 

 

 

 

 

 


 

포린 키 키 값 변경

 

@JoinColumn 추가

 

 

봐뀐 모습