Database(๋ฐ์ดํฐ๋ฒ ์ด์ค)
๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ๋ฐ์ดํฐ์ ์งํฉ์ผ๋ก, ์ ๋ณด๋ฅผ ์ ์ฅํ๊ณ ๊ด๋ฆฌํด์ฃผ๋ ์ญํ ์ํ
DBMS(Database Management System): Database๋ฅผ ๊ด๋ฆฌํ๊ณ ์ด์ํ๋ ์ํํธ์จ์ด
RDBMS(Relational DBMS)
๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค
- ํ ์ด๋ธ(table)์ด๋ผ๋ ์ต์ ๋จ์๋ก ๊ตฌ์ฑ๋๋ฉฐ, ์ด ํ ์ด๋ธ์ ์ด(column)๊ณผ ํ(row)์ผ๋ก ์ด๋ฃจ์ด์ ธ ์์
- ํ ์ด๋ธ๊ฐ FK(Foreign Key)๋ฅผ ํตํด ๋ค๋ฅธ ๋ฐ์ดํฐ๋ฅผ ์กฐํฉํด์ ํจ๊ป ๋ณผ ์ ์๋ค๋ ์ฅ์ ์ด ์์
- RDBMS ์ข ๋ฅ๋ก๋ Oracle, MySQL, PostgreSQL ๋ฑ ์กด์ฌ
SQL(Structured Query Language)
SQL์ RDBMS์์ ์ฌ์ฉ๋๋ ์ธ์ด๋ก, ์ ๋ง์ ์ ๋ณด๋ฅผ Database์์ ์กฐ์ํ๊ณ ๊ด๋ฆฌํ๊ธฐ ์ํด์๋ SQL ์ธ์ด๋ฅผ ์ฌ์ฉํด์ผ ํจ
- ๊ตญ์ ํ์คํ๊ธฐ๊ตฌ์์ SQL์ ๋ํ ํ์ค์ ์ ํด์ ๋ฐํํ๊ณ ์์
- ๊ทธ๋ฌ๋ DBMS๋ฅผ ๋ง๋๋ ํ์ฌ๊ฐ ์ฌ๋ฌ ๊ณณ์ด๊ธฐ ๋๋ฌธ์ DBMS ๋ง๋ค ํ์ค SQL์ ์ค์ํ๋, ๊ฐ ์ ํ์ ํน์ฑ์ ๋ฐ์ํ๊ธฐ ์ํ ์ฝ๊ฐ์ ์ฐจ์ด๊ฐ ์กด์ฌํจ
DDL(Data Definition Language)
ํ ์ด๋ธ์ด๋ ๊ด๊ณ์ ๊ตฌ์กฐ๋ฅผ ์์ฑํ๋๋ฐ ์ฌ์ฉ
CREATE
์๋ก์ด ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ฐ ํ ์ด๋ธ ์์ฑ
CREATE DATABASE ๋ฐ์ดํฐ๋ฒ ์ด์ค์ด๋ฆ;
CREATE TABLE ํ
์ด๋ธ์ด๋ฆ(
ํ๋์ด๋ฆ1 ํ๋ํ์
1,
ํ๋์ด๋ฆ2 ํ๋ํ์
2,
...
);
[์ ์ฝ ์กฐ๊ฑด]
- AUTO_INCREMENT: ์ปฌ๋ผ์ ๊ฐ์ด ์ค๋ณต๋์ง ์๊ฒ 1์ฉ ์๋์ผ๋ก ์ฆ๊ฐํ๊ฒ ํด์ค(๊ณ ์ ๋ฒํธ ์์ฑ)
CREATE TABLE ํ
์ด๋ธ์ด๋ฆ(
ํ๋์ด๋ฆ ํ๋ํ์
AUTO_INCREMENT;
// id bigint AUTO_INCREMENT;
);
- NOT NULL: ํด๋น ํ๋๋ NULL ๊ฐ์ ์ ์ฅํ ์ ์์
CREATE TABLE ํ
์ด๋ธ์ด๋ฆ(
ํ๋์ด๋ฆ ํ๋ํ์
NOT NULL,
...
);
- UNIQUE: ํด๋น ํ๋๋ ์๋ก ๋ค๋ฅธ ๊ฐ์ ๊ฐ์ ธ์ผ๋ง ํจ
CREATE TABLE ํ
์ด๋ธ์ด๋ฆ(
ํ๋์ด๋ฆ ํ๋ํ์
UNIQUE,
...
);
- PRIMARY KEY: ํด๋น ํ๋๊ฐ NOT NULL๊ณผ UNIQUE ์ ์ฝ ์กฐ๊ฑด์ ํน์ง์ ๋ชจ๋ ๊ฐ์ง
CREATE TABLE ํ
์ด๋ธ์ด๋ฆ(
ํ๋์ด๋ฆ ํ๋ํ์
PRIMARY KEY,
...
);
PRIMARY KEY(๊ธฐ๋ณธ ํค)๋ ํ ์ด๋ธ ๋ด์์ '์ ์ผํ๊ฒ ์กด์ฌํ๋ ๊ฐ์ ์กฐํฉ'์ ์ค์ ํด์ ์ค๋ณต๋ ๋ฐ์ดํฐ๊ฐ ํ ์ด๋ธ์ ์ฝ์ ๋๋ ๊ฒ์ ๋ฐฉ์งํ๋ ์ ์ฝ์กฐ๊ฑด์
1. ๋ฐ์ดํฐ์ ์ค๋ณต ๋ฐฉ์ง
- ๋ง์ฝ ๊ธฐ๋ณธํค๋ฅผ ์ค์ ํ์ง ์๊ณ ์ ํ์์ ๊ด๋ฆฌํ๋ ํ ์ด๋ธ์ด ์์ ๋ ๊ธฐ์กด์ ์๋ ํ์์ด ์์ ์ ๊ฐ์ ํ ๊ฒ์ ์๊ณ ๋ค์ ํ์๊ฐ์ ์ ํ๋ ๊ฒฝ์ฐ ํน์ ์ต๊ทผ์ ๋ฒํธ ๋ฐ ์ฃผ์๊ฐ ๋ณ๊ฒฝ๋ ๊ฒฝ์ฐ์
๋ ์ค์ ์ด๋ ์ ๋ณด๊ฐ ์ ํํ ์ ๋ณด์ธ์ง ํ๋จํ๊ธฐ ์ด๋ ค์ โบ ๋ฐ์ดํฐ ๋ฌด๊ฒฐ์ฑ์ด ๊นจ์ง
2. ๋ฐ์ดํฐ๋ฅผ ๋น ๋ฅด๊ฒ ํ์ ๊ฐ๋ฅ
- ๊ธฐ๋ณธ ํค๋ฅผ ์ค์ ํ๋ฉด DBMS๋ ์ธ๋ฑ์ค๋ฅผ ๋ง๋ฆ
- ์ธ๋ฑ์ค๋ ํด๋น ๋ฐ์ดํฐ๋ฅผ ๋นจ๋ฆฌ ์ฐพ์ ์ ์๊ฒ ๋์์ฃผ๋ ์ผ์ข ์ ๋ชฉ์ฐจ์
- ๋ง์ฝ ์ฃผ๋ฏผ๋ฒํธ ์ปฌ๋ผ์ ๊ธฐ๋ณธ ํค๊ฐ ์ค์ ๋์ด ์์ง ์๋๋ค๋ฉด, ์ฃผ๋ฏผ๋ฒํธ๊ฐ ์ค๋ณต๋ ์ ์๋ค๋ ๊ฒ์ ์ฐ๋ฆฌ๋ ์์ง๋ง DBMS๋ ๋ชจ๋ฅด๊ธฐ ๋๋ฌธ์ ์ฃผ๋ฏผ๋ฒํธ๊ฐ ์ค๋ณต๋ ์ ์๋ ๊ฒ์ ๊ฐ์ ํด 5000๋ง row๋ฅผ ์ ๋ถ ํ์ธํ๊ฒ๋จ
์ด๋, ์ฃผ๋ฏผ๋ฒํธ์ ๊ธฐ๋ณธ ํค ์ค์ ์ด ๋์ด์์ผ๋ฉด row๋ฅผ ์ ๋ถ ํ์ธํ์ง ์๊ณ 1๊ฐ๋ง ์ฐพ์ผ๋ฉด ๋ฐ๋ก ํด๋น ๋ฐ์ดํฐ ๋ฐํ ๊ฐ๋ฅ
- FOREIGN KEY: ํ๋์ ํ
์ด๋ธ์ ๋ค๋ฅธ ํ
์ด๋ธ์ ์์กดํ๊ฒ ๋ง๋ค๋ฉฐ ๋ฐ์ดํฐ์ ๋ฌด๊ฒฐ์ฑ์ ๋ณด์ฅํด์ค
๏นก FK๋ฅผ ๊ฐ์ง๋ ํ ์ด๋ธ์ด ์ฐธ์กฐํ๋ ๊ธฐ์ค ํ ์ด๋ธ์ ์ด์ ๋ฐ๋์ PK, UNIQUE ์ ์ฝ์กฐ๊ฑด์ด ์ค์ ๋์ด ์์ด์ผํจ
CREATE TABLE ํ
์ด๋ธ์ด๋ฆ(
ํ๋์ด๋ฆ, ํ๋ํ์
,
...
FOREIGN KEY(ํ๋์ด๋ฆ)
REFERENCES ํ
์ด๋ธ์ด๋ฆ(ํ๋์ด๋ฆ)
);
FOREIGN KEY(์ธ๋ ํค)๋ ๋ ๊ฐ์ ํ ์ด๋ธ์ ์ฐ๊ฒฐํ๋ ๋ค๋ฆฌ ์ญํ ์ ํด์ฃผ๋ ํค
- ์ธ๋ ํค๋ฅผ ์ฌ์ฉํ๋ฉด ์ค๋ณต๋๋ ๋ฐ์ดํฐ๋ฅผ ์์ ๊ณ , ์ธ๋ํค๋ฅผ ์ฌ์ฉํด์ ์ฐธ์กฐํ๋ ํ ์ด๋ธ์ ์ ๊ทผํด ์ ๋ณด๋ฅผ ๊ฐ์ ธ์ฌ ์ ์์
- ๊ธฐ๋ณธ ํค๊ฐ ํ๋์ ํ ์ด๋ธ์์ ์ค๋ณต๋ ๋ฐ์ดํฐ๊ฐ ์ฝ์ ๋๋ ๊ฒ์ ๋ฐฉ์งํ๋ ์ญํ ์ ํด์ฃผ๋๋ฐ ์ธ๋ ํค ์ญ์ ๋น์ทํ ๋ฌธ์ ๋ฅผ ๋ฐฉ์งํ๋ ์ญํ ์ํํจ! ์ธ๋ ํค๋ ๋ฐ์ดํฐ๊ฐ ์๋กญ๊ฒ ์ถ๊ฐ๋ ๋ ์ธ๋ ํค์ ํด๋นํ๋ ๊ฐ์ด ์ธ๋ ํค๊ฐ ์ฐธ์กฐํ๋ ํ ์ด๋ธ์ ์กด์ฌํ๋์ง๋ฅผ ํ์ธํจ
- CASCADE: FOREIGN KEY๋ก ์ฐ๊ด๋ ๋ฐ์ดํฐ๋ฅผ ์ญ์ , ๋ณ๊ฒฝํ ์ ์์
CREATE TABLE ํ
์ด๋ธ์ด๋ฆ(
ํ๋์ด๋ฆ ํ๋ํ์
,
...
FOREIGN KEY(ํ๋์ด๋ฆ)
REFERENCES ํ
์ด๋ธ์ด๋ฆ(ํ๋์ด๋ฆ) ON DELETE CASCADE
// ON UPDATE CASCADE
);
ALTER
๋ฐ์ดํฐ๋ฒ ์ด์ค์ ํ ์ด๋ธ์ ๋ด์ฉ ์์
ALTER TABLE ํ
์ด๋ธ์ด๋ฆ ADD ํ๋์ด๋ฆ ํ๋ํ์
;
ALTER TABLE ํ
์ด๋ธ์ด๋ฆ DROP ํ๋์ด๋ฆ;
ALTER TABLE ํ
์ด๋ธ์ด๋ฆ MODIFY COLUMN ํ๋์ด๋ฆ ํ๋ํ์
;
DROP
๋ฐ์ดํฐ๋ฒ ์ด์ค์ ํ ์ด๋ธ ์ญ์ ํ ์ ์์. ๋ฐ์ดํฐ ๋ฐ ํ ์ด๋ธ ์ ์ฒด ์ญ์
DROP DATABASE ๋ฐ์ดํฐ๋ฒ ์ด์ค์ด๋ฆ;
DROP TABLE ํ
์ด๋ธ์ด๋ฆ;
TRUNCATE
๋ฐ์ดํฐ๋ฒ ์ด์ค์ ํ ์ด๋ธ์ ์ญ์ ํ ์ ์์. ์ต์ด ํ ์ด๋ธ์ด ๋ง๋ค์ด์ก๋ ์ํ์ธ ์ปฌ๋ผ๊ฐ๋ง ๋จ๊น
TRUNCATE DATABASE ๋ฐ์ดํฐ๋ฒ ์ด์ค์ด๋ฆ;
TRUNCATE TABLE ํ
์ด๋ธ์ด๋ฆ;
DCL(Data Control Language)
๋ฐ์ดํฐ์ ์ฌ์ฉ ๊ถํ์ ๊ด๋ฆฌํ๋๋ฐ ์ฌ์ฉํจ
GRANT
์ฌ์ฉ์ ๋๋ ROLE์ ๋ํด ๊ถํ์ ๋ถ์ฌํ ์ ์์
GRANT [๊ฐ์ฒด๊ถํ๋ช
] (์ปฌ๋ผ)
ON [๊ฐ์ฒด๋ช
]
TO { ์ ์ ๋ช
| ๋กค๋ช
| PUBLIC } [WITH GRANT OPTION];
// ex
GRANT SELECT, INSERT
ON mp
TO scott WITH GRANT OPTION;
REVOKE
์ฌ์ฉ์ ๋๋ ROLE์ ๋ํด ๊ถํ์ ํ์ํ ์ ์์
REVOKE { ๊ถํ๋ช
[, ๊ถํ๋ช
...] ALL }
ON ๊ฐ์ฒด๋ช
FROM { ์ ์ ๋ช
[, ์ ์ ๋ช
...] | ๋กค๋ช
(ROLE) | PUBLIC }
[CASCADE CONSTRAINTS];
// ex
REVOKE SELECT, INSERT
ON emp
FROM scott
[CASCASE CONSTRAINTS];
DML(Data Manipulation Language)
ํ ์ด๋ธ์ ๋ฐ์ดํฐ๋ฅผ ๊ฒ์, ์ฝ์ , ์์ , ์ญ์ ํ๋๋ฐ ์ฌ์ฉํจ
INSERT
ํ ์ด๋ธ์ ์๋ก์ด row ์ถ๊ฐ
INSERT INTO ํ
์ด๋ธ์ด๋ฆ(ํ๋์ด๋ฆ1, ํ๋์ด๋ฆ2, ํ๋์ด๋ฆ3, ...) VALUES(๋ฐ์ดํฐ๊ฐ1, ๋ฐ์ดํฐ๊ฐ2, ๋ฐ์ดํฐ๊ฐ3, ...);
INSERT INTO ํ
์ด๋ธ์ด๋ฆ VALUES(๋ฐ์ดํฐ๊ฐ1, ๋ฐ์ดํฐ๊ฐ2, ๋ฐ์ดํฐ๊ฐ3, ...);
SELECT
ํ ์ด๋ธ์ row ์ ํ
SELECT ํ๋์ด๋ฆ FROM ํ
์ด๋ธ์ด๋ฆ [WHERE ์กฐ๊ฑด];
UPDATE
ํ ์ด๋ธ์ row์ ๋ด์ฉ ์์
UPDATE ํ
์ด๋ธ์ด๋ฆ SET ํ๋์ด๋ฆ1=๋ฐ์ดํฐ๊ฐ1, ํ๋์ด๋ฆ2=๋ฐ์ดํฐ๊ฐ2, ... WHERE ํ๋์ด๋ฆ=๋ฐ์ดํฐ๊ฐ;
DELETE
ํ ์ด๋ธ์ row ์ญ์
DELETE FROM ํ
์ด๋ธ์ด๋ฆ WHERE ํ๋์ด๋ฆ=๋ฐ์ดํฐ๊ฐ;
SQL ์ฐ์ตํ๊ธฐ
Intellij Database ์ฐ๋ํ๊ธฐ
1. ์ค๋ฅธ์ชฝ ํญ์ Database ํญ ํด๋ฆญํ๊ณ + ๋ฒํผ ๋๋ฅธ ํ, ๋ฐ์ดํฐ ์์ค > MySQL ํด๋ฆญ


2. ์ฌ์ฉ์, ๋น๋ฐ๋ฒํธ, ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ ๋ณด ์ถ๊ฐ ํ OK ํด๋ฆญ

3. ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ ์ฑ๊ณต

ํ ์ด๋ธ ์์ฑํ๊ธฐ
CREATE TABLE IF NOT EXISTS MAJOR
(
major_code varchar(100) primary key comment '์ฃผํน๊ธฐ์ฝ๋',
major_name varchar(100) not null comment '์ฃผํน๊ธฐ๋ช
',
tutor_name varchar(100) not null comment 'ํํฐ'
);
CREATE TABLE IF NOT EXISTS STUDENT
(
student_code varchar(100) primary key comment '์๊ฐ์์ฝ๋',
name varchar(100) not null comment '์ด๋ฆ',
birth varchar(8) null comment '์๋
์์ผ',
gender varchar(1) not null comment '์ฑ๋ณ',
phone varchar(11) null comment '์ ํ๋ฒํธ',
major_code varchar(100) not null comment '์ฃผํน๊ธฐ์ฝ๋',
foreign key(major_code) references major(major_code)
);
CREATE TABLE IF NOT EXISTS EXAM
(
student_code varchar(100) not null comment '์๊ฐ์์ฝ๋',
exam_seq int not null comment '์ํ์ฃผ์ฐจ',
score decimal(10,2) not null comment '์ํ์ ์',
result varchar(1) not null comment 'ํฉ๋ถ'
);

ํ ์ด๋ธ ์์ ํ๊ธฐ
ALTER TABLE EXAM ADD PRIMARY KEY(student_code, exam_seq);
ALTER TABLE EXAM ADD CONSTRAINT exam_fk_student_code FOREIGN KEY(student_code) REFERENCES STUDENT(student_code);
ํ ์ด๋ธ์ ๋ฐ์ดํฐ ์ฝ์ ํ๊ธฐ
INSERT INTO MAJOR VALUES('m1', '์คํ๋ง', '๋จ๋ณ๊ด');
INSERT INTO MAJOR VALUES('m2', '๋
ธ๋', '๊ฐ์นํ');
INSERT INTO MAJOR VALUES('m3', 'ํ๋ผ์คํฌ', '์ด๋ฒ๊ท');
INSERT INTO MAJOR VALUES('m4', '๋ฃจ๋น์จ๋ ์ผ์ฆ', '์ฐจ์์');
...
INSERT INTO STUDENT VALUES('s1', '์ต์๋น', '20220331', 'M', '01000000001', 'm1');
INSERT INTO STUDENT VALUES('s2', '๊ฐ์ค๊ท', '20220501', 'M', '01000000002', 'm1');
INSERT INTO STUDENT VALUES('s3', '๊น์์ฒ ', '20220711', 'M', '01000000003', 'm1');
...
INSERT INTO EXAM VALUES('s1', 1, 8.5, 'P');
INSERT INTO EXAM VALUES('s1', 2, 9.5, 'P');
INSERT INTO EXAM VALUES('s1', 3, 3.5, 'F');
INSERT INTO EXAM VALUES('s2', 1, 8.2, 'P');
...
ํ ์ด๋ธ ๋ด ๋ฐ์ดํฐ ์์ ํ๊ธฐ
INSERT INTO STUDENT VALUES('s0', '์๊ฐ์', '20220331', 'M', '01000000005', 'm1');
UPDATE STUDENT SET major_code= 'm2' where student_code= 's0';
ํ ์ด๋ธ ๋ด ๋ฐ์ดํฐ ์ญ์ ํ๊ธฐ
DELETE FROM STUDENT WHERE student_code = 's0';
ํ ์ด๋ธ ๋ด ํน์ ๋ฐ์ดํฐ ์กฐํํ๊ธฐ
SELECT * FROM STUDENT;
SELECT * FROM STUDENT WHERE STUDENT_CODE = 's1';
SELECT name, major_code FROM STUDENT WHERE student_code = 's1';

SELECT s.name, s.major_code, m.major_name FROM STUDENT s JOIN MAJOR m ON s.major_code = m.major_code;
SELECT s.name, s.major_code, m.major_name FROM STUDENT s, MAJOR m WHERE s.major_code = m.major_code;

JOIN์ ๋๋์ด์ง ํ ์ด๋ธ์ ํ๋๋ก ํฉ์น๊ธฐ ์ํด ๋ฐ์ดํฐ๋ฒ ์ด์ค๊ฐ ์ ๊ณตํ๋ ๊ธฐ๋ฅ์ด๋ค.
- JOIN์ ON์ด๋ผ๋ ํค์๋๋ฅผ ํตํด ๊ธฐ์ค์ด ๋๋ ์ปฌ๋ผ์ ์ ํํด 2๊ฐ์ ํ ์ด๋ธ์ ํฉ์ณ์ค
- JOIN์ ํ ๋์๋ ์ ์ด๋ ํ๋์ ์ปฌ๋ผ์ ์๋ก ๊ณต์ ํ๊ณ ์์ด์ผํ๊ธฐ ๋๋ฌธ์ ํ ์ด๋ธ์ ์ธ๋ ํค๊ฐ ์ค์ ๋์ด ์๋ค๋ฉด ํด๋น ์ปฌ๋ผ์ ํตํด JOIN์ ํ๋ฉด ์กฐ๊ฑด์ ์ถฉ์กฑํ ์ ์์
โผ๏ธ JOIN์ ํ๊ธฐ ์ํด ์ธ๋ ํค๋ฅผ ์ค์ ํ๋ ๊ฒ์ด ํญ์ ์ข์ ์ ํ์ด ์๋ ์ ์์!
- ์ธ๋ ํค๋ฅผ ์ค์ ํ๋ฉด ๋ฐ์ดํฐ ๋ฌด๊ฒฐ์ฑ์ ํ์ธํ๋ ์ถ๊ฐ ์ฐ์ฐ ๋ฐ์
- ๋ํ ๋ฌด๊ฒฐ์ฑ์ ์ง์ผ์ผํ๊ธฐ ๋๋ฌธ์ ์ํฉ์ ๋ฐ๋ผ ๊ฐ๋ฐํ๋๋ฐ ๋ถํธํ ์ ์์
ํญ์ ํ ์ด๋ธ์ ๋ชจ๋ ์ ์ฝ์กฐ๊ฑด์ ๊ฑธ์ด์ผ ํ๋ ๊ฒ์ ์๋๊ณ , ํ๋ก์ ํธ์ ์ํฉ์ ๋ฐ๋ผ ๊ฐ์ฅ ํจ์จ์ ์ธ ์ ์ฝ์กฐ๊ฑด์ ํ ์ด๋ธ์ ์ ์ฉํด์ผ ํจ
JDBC๋?
์ ํ๋ฆฌ์ผ์ด์ ์๋ฒ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ์์ฒญ์ ์ฒ๋ฆฌํ๊ธฐ ์ํด ์ํต์ ํด์ผํจ. ์ด๋, Java ์ ํ๋ฆฌ์ผ์ด์ ๊ณผ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์ฐ๊ฒฐํด์ฃผ๋ ์ญํ ์ ํ๋ ๊ฒ์ด JDBC์!
์ ํ๋ฆฌ์ผ์ด์ ์๋ฒ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ฐ์ ์ํต

1. ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ์ ์ํด ์ปค๋ฅ์ ์ฐ๊ฒฐํด์ผ ํจ
2. SQL ์์ฑ ํ ์ปค๋ฅ์ ์ ํตํด SQL ์์ฒญ
3. ์์ฒญํ SQL์ ๋ํ ์๋ต์ ๋ฐ์์ผํจ
์ด๋ MySQL ์๋ฒ๊ฐ ์๋๋ผ PostgreSQL ์๋ฒ๋ก ๋ณ๊ฒฝํด์ผ ํ๋ ๊ฒฝ์ฐ, MySQL๊ณผ PostgreSQL์ ์ปค๋ฅ์ ์ ์ฐ๊ฒฐํ๋ ๋ฐฉ๋ฒ, SQL ์ ๋ฌ ๋ฐฉ๋ฒ, ๊ฒฐ๊ณผ ์๋ต ์ ๋ฌํ๋ ๋ฐฉ๋ฒ ๋ชจ๋ ๋ค๋ฅผ ์ ์์
์ฆ, ์ ํ๋ฆฌ์ผ์ด์ ์๋ฒ ์ชฝ์ ์์ฑํ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ ์ฝ๋์ธ ๋ก์ง์ ์ ๋ถ ์์ ํด์ผ ํจ
์ด๋ฐ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด JDBC ํ์ค ์ธํฐํ์ด์ค ๋ฑ์ฅํจ!
JDBC(Java Database Connectivity)
๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ๊ทผํ ์ ์๋๋ก Java์์ ์ ๊ณตํ๋ API
- JDBC์ ์ฐ๊ฒฐ์ ํด์ผํ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ JDBC ๋๋ผ์ด๋ฒ๋ฅผ ์ ๊ณตํ๋ฉด, ์ด ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ฐ๊ฒฐ ๋ก์ง์ ๋ณ๊ฒฝํ ํ์ ์์ด ์์ฝ๊ฒ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ณ๊ฒฝ ๊ฐ๋ฅ
- JDBC ๋๋ผ์ด๋ฒ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค ํ์ฌ๋ค์ด ์์ ๋ค์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋ง๋๋ก JDBC ์ธํฐํ์ด์ค๋ฅผ ์ค์ ๋ก ๊ตฌํํ ํ ์ ๊ณตํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
→ MySQL ๋๋ผ์ด๋ฒ๋ฅผ ์ฌ์ฉํด์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ์ ์ฌ์ฉํ๊ณ ์๋ค๊ฐ PostgreSQL ์๋ฒ๋ก ๋ณ๊ฒฝ์ด ํ์ํ ๋, ๋๋ผ์ด๋ฒ๋ง ๊ต์ฒดํด์ฃผ๋ฉด ๋จ

JdbcTemplate

JDBC๋ก ์์ฝ๊ฒ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ต์ฒด๊ฐ ๊ฐ๋ฅํด์ก์ง๋ง, ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ์ ํ๊ธฐ ์ํด ์์ ๊ฐ์ด ์๋ง์ ์์ ํ์ํจ
์ด๋ฐ ์์ ๋ค์ ๋์ ์ฒ๋ฆฌํด์ฃผ๋ Spring JDBC ๋ฑ์ฅํจ! ๊ทธ ์ค ํ๋๊ฐ JdbcTemplate์
JdbcTemplate๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด application.properties์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ๊ทผํ๊ธฐ ์ํ ์ ๋ณด ์์ฑํด์ผํจ!
๏นก์ค์ ๋ก ๊ฐ๋ฐํ ๋์๋ JdbcTemplate์ ์ฌ์ฉํ ํ๋ฅ ์ด ๋ฎ์
// build.gradle ๋ด dependencies์ ์ถ๊ฐ
// MySQL
implementation 'mysql:mysql-connector-java:8.0.28'
implementation 'org.springframework.boot:spring-boot-starter-data-jdbc'
# memo ๋ฐ์ดํฐ๋ฒ ์ด์ค ์์ฑํ๊ธฐ
create database memo;
// application.properties์ ์ถ๊ฐ
spring.datasource.url=jdbc:mysql://localhost:3306/memo
spring.datasource.username=root
spring.datasource.password={๋น๋ฐ๋ฒํธ}
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
Memo ํ ์ด๋ธ ์์ฑ
create table memo
(
id bigint not null auto_increment,
contents varchar(500) not null,
username varchar(255) not null,
primary key (id)
);
MemoController์ JdbcTemplate ์ ์ฉ
package com.sparta.memo.controller;
import com.sparta.memo.dto.MemoRequestDto;
import com.sparta.memo.dto.MemoResponseDto;
import com.sparta.memo.entity.Memo;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;
import org.springframework.web.bind.annotation.*;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;
@RestController
@RequestMapping("/api")
public class MemoController {
private final JdbcTemplate jdbcTemplate; // jdbcTemplate ๋ณ์ ์ ์ธ
// ์ด๊ธฐํ๋ฅผ ์ํ ์์ฑ์
// ์ธ๋ถ์์ ๋ง๋ค์ด์ ธ ์๋ JdbcTemplate์ ์ฌ๊ธฐ์ ๋ฃ์ด์ค
// JdbcTemplate ๊ฐ์ฒด๋ Spring์์ ๋ฐ๋ก ๊ด๋ฆฌํด์ฃผ๊ณ ์์
public MemoController(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
@PostMapping("/memos")
public MemoResponseDto createMemo(@RequestBody MemoRequestDto requestDto) {
// RequestDto -> Entity
Memo memo = new Memo(requestDto);
// DB ์ ์ฅ
KeyHolder keyHolder = new GeneratedKeyHolder(); // ๊ธฐ๋ณธ ํค๋ฅผ ๋ฐํ๋ฐ๊ธฐ ์ํ ๊ฐ์ฒด
String sql = "INSERT INTO memo (username, contents) VALUES (?, ?)"; // INSERT๋ฌธ
// INSERT, UPDATE, DELETE ์ธ ๊ฐ์ง ๋ชจ๋ update ๋ฉ์๋ ์ด์ฉ
jdbcTemplate.update( con -> {
PreparedStatement preparedStatement = con.prepareStatement(sql,
Statement.RETURN_GENERATED_KEYS);
preparedStatement.setString(1, memo.getUsername());
preparedStatement.setString(2, memo.getContents());
return preparedStatement;
},
keyHolder);
// DB Insert ํ ๋ฐ์์จ ๊ธฐ๋ณธํค ํ์ธ
Long id = keyHolder.getKey().longValue();
memo.setId(id);
// Entity -> ResponseDto
MemoResponseDto memoResponseDto = new MemoResponseDto(memo);
return memoResponseDto;
}
@GetMapping("/memos")
public List<MemoResponseDto> getMemos() {
// DB ์กฐํ
String sql = "SELECT * FROM memo";
return jdbcTemplate.query(sql, new RowMapper<MemoResponseDto>() {
@Override
public MemoResponseDto mapRow(ResultSet rs, int rowNum) throws SQLException {
// SQL ์ ๊ฒฐ๊ณผ๋ก ๋ฐ์์จ Memo ๋ฐ์ดํฐ๋ค์ MemoResponseDto ํ์
์ผ๋ก ๋ณํํด์ค ๋ฉ์๋
Long id = rs.getLong("id");
String username = rs.getString("username");
String contents = rs.getString("contents");
return new MemoResponseDto(id, username, contents);
}
});
}
@PutMapping("/memos/{id}")
public Long updateMemo(@PathVariable Long id, @RequestBody MemoRequestDto requestDto) {
// ํด๋น ๋ฉ๋ชจ๊ฐ DB์ ์กด์ฌํ๋์ง ํ์ธ
Memo memo = findById(id);
if(memo != null) {
// memo ๋ด์ฉ ์์
String sql = "UPDATE memo SET username = ?, contents = ? WHERE id = ?";
jdbcTemplate.update(sql, requestDto.getUsername(), requestDto.getContents(), id);
return id;
} else {
throw new IllegalArgumentException("์ ํํ ๋ฉ๋ชจ๋ ์กด์ฌํ์ง ์์ต๋๋ค.");
}
}
@DeleteMapping("/memos/{id}")
public Long deleteMemo(@PathVariable Long id) {
// ํด๋น ๋ฉ๋ชจ๊ฐ DB์ ์กด์ฌํ๋์ง ํ์ธ
Memo memo = findById(id);
if(memo != null) {
// memo ์ญ์
String sql = "DELETE FROM memo WHERE id = ?";
jdbcTemplate.update(sql, id);
return id;
} else {
throw new IllegalArgumentException("์ ํํ ๋ฉ๋ชจ๋ ์กด์ฌํ์ง ์์ต๋๋ค.");
}
}
private Memo findById(Long id) {
// DB ์กฐํ
String sql = "SELECT * FROM memo WHERE id = ?";
return jdbcTemplate.query(sql, resultSet -> {
if(resultSet.next()) {
Memo memo = new Memo();
memo.setUsername(resultSet.getString("username"));
memo.setContents(resultSet.getString("contents"));
return memo;
} else {
return null;
}
}, id);
}
}
JdbcTemplate์ ์ฌ์ฉํด๋ ์์ฑํ๊ธฐ ์ด๋ ต๊ณ ๊น๋ค๋ก์ด ๋ฌธ์ ์กด์ฌํจ. ์๋ฐ ๊ฐ๋ฐ์๋ค์ ์ํด ๋ฐ์ดํฐ๋ฒ ์ด์ค์ Java ๊ฐ์ฒด๋ฅผ mappingํด์ ์ํตํ ์ ์๋ ORM์ด๋ผ๋ ๊ธฐ์ ๋ฑ์ฅํจ!