인프런에서 주최하는 Warming-up 클럽 0기 백엔드 스터디에 참여하고 있다.
스터디에 참여하면서 배우게 된 내용을 전체적으로 정리하고, 참여하면서 느낀 부분을 회고해 보고자 한다.
(1) 3일 차 : 2024-02-21(Wed)
1. 데이터베이스 생성, 목록 확인, 삭제 (DDL : Database Definition Language)
(1) 여기서 DDL(Database Definition Language)은 테이블과 데이터의 구조와 형식, 타입 등을 지정하는 언어들은 DDL이라고 한다.
1-1. 데이터베이스 생성
create database [데이터베이스 이름];
1-2. 데이터베이스 목록 확인
show databases;
1-3. 데이터베이스 삭제
drop table [삭제할 데이터베이스];
1-4. 특정 데이터베이스 사용
use [사용할 데이터베이스 이름];
2. 테이블 생성, 목록 확인 (DDL)
2-1. 테이블 목록 확인
show tables;
2-2. 테이블 생성
create table
(
컬럼명1 데이터 타입1 부가정보1,
컬럼명1 데이터 타입1 부가정보1,
컬럼명1 데이터 타입1 부가정보1,
...
primary key (컬럼명)
);
2-3. 테이블 생성 예시
create table fruit
(
id bigint auto_increment,
name varchar(20),
price int,
stocked_date date,
primary key (id)
);
(1) auto_increment
- 데이터를 명시적으로 insert into하지 않더라도 1부터 자동으로 1씩 증가하며 카운트된다.
(2) primary key
- 중복되지 않으며 해당 컬럼은 null을 가질 수 없다는 의미를 갖는다 따라서 primary key는 테이블에서 로우의 행을 고유하게 식별할 때 사용된다.
3. MySQL의 데이터 타입
3-1. 숫자 타입 (정수 타입)
정수형 타입 | 특징 |
tinyint | 1 바이트 |
int | 4 바이트 |
bigint | 8 바이트 |
3-2. 실수 타입
실수형 타입 | 특징 |
double | 8 바이트 |
decimal(a, b) | 소수점을 b개 가지고 있는 전체 a 자릿수 실수 |
3-3. 문자열 타입
문자열 타입 | 특징 |
char(a) | a 글자가 들어갈 수 있는 문자열 형태 |
varchar(a) | 최대 a 글자가 들어갈 수 있는 문자열 형태 |
3-4. 날짜, 시간 타입
날짜, 시간 타입 | 특징 |
date | 날짜 형태, yyyy-MM-dd |
time | 시간 형태, HH:mm:ss |
datetime | 날짜 + 시간 형태의 타입, yyyy-MM-dd HH:mm:ss |
4. 데이터베이스 테이블 CRUD (DML : Database Manipulation Language)
(1) DML(Database Manipulation Language)은 데이터베이스 테이블 내부의 데이터들을 직접적으로 저장, 조회, 수정, 삭제할 수 있는 언어들을 말한다.
4-1. INSERT INTO ~ VALUES (Create)
insert into fruit (name, price, stocked_date)
values ('사과', 1000, '2024-02-01')
4-2. SELECT ~ FROM ~ WHERE ... (Read)
select * from fruit;
select name, price
from fruit
-- where
select name
from fruit
where name = '사과';
select *
from fruit
where name = '사과'
or price = 1000;
(1) *(asterisk)의 경우 테이블의 모든 컬럼을 조회한다
(2) * 없이 특정 필드만을 넣어서 조회 가능
(3) 조건절 where을 넣어서 조건에 부합하는 컬럼에 대한 로우만 가져올 수 있다.
(4) where문의 경우 and, or를 넣어서 조건을 이어서 명시해 줄 수 있다.
(5) where문의 경우 비교 연산자 =, >= 외에도 !=, <, >, >=, between, in, not in 등이 존재한다.
4-3. 조회 쿼리에서 사용되는 다양한 조건문
(1) between ~ and ~
-- 1000 <= price <= 2000원 가격인 과일 조회
select *
from fruit
where price between 1000 and 2000;
(2) in, not in
- in : where 절에서 사용되며 특정 열의 값이 주어진 값의 목록 중 하나와 일치하는지 여부를 확인한다. (or 연산과 동일)
- not in : 특정 열의 값이 주어진 목록들은 제외하고 조회된다.
-- 이름이 사과이거나 또는 수박인 과일을 조회한다.
select *
from fruit
where name in ('사과', '수박');
-- 사과가 아닌 과일을 조회힌다.
select *
from fruit
where name not in ('사과');
4-4. UPDATE ~ SET ~ WHERE (Update)
(1) 조건을 명시하지 않을 경우 모든 데이터가 업데이트되므로 조건을 명시하는 부분을 항상 신경쓰자.
update fruit
set price = 1500
where name = '사과';
4-5. DELETE FROM [TABLE NAME] WHERE ~ (Delete)
(1) update와 마찬가지로 조건을 명시하지 않을 경우 모든 데이터가 삭제되니 주의해야 한다.
delete from fruit
where name = '사과';
5. application.yml 파일을 사용해 데이터베이스에 접속하기 (스프링 부트)
5-1. application.yml
(1) 스프링 프로젝트에서 환경 설정을 위한 파일로 볼 수 있다. 크게 properties와 yml으로 구분되고 둘의 차이는 바로 표현 방식의 차이이다. application.yml은 설정 정보를 들여쓰기로 구분될 수 있는 계층 방식으로 기재하고 application.properties은 key=value 타입으로 구성한다.
(2) 위와 같이 jdbc를 통해 MySQL에 접속하며 본인 컴퓨터로 library 데이터베이스에 접속한다는 의미이다.
(3) 유저 이름, 패스워드, 데이터베이스에 접근할 때 사용할 데이터베이스 벤더사의 프로그램명을 입력해 준다.
(4) 따라서 스프링이 MySQL 데이터베이스에 접속할 수 있는 상태가 된다.
6. 회원 테이블 생성, UserController 코드 수정
6-1. 회원 테이블 생성
(1) 앞서 학습한 DDL 언어를 사용해서 user 테이블을 생성한다.
create table user
(
id bigint auto_increment,
name varchar(25),
age int,
primary key (id)
)
6-2. UserController.java
@RestController
@RequiredArgsConstructor
public class UserController {
private final JdbcTemplate jdbcTemplate;
@PostMapping("/user")
public void saveUser(@RequestBody UserCreateRequest request) {
String sql = "insert into user(name, age) values (?, ?)";
jdbcTemplate.update(sql, request.getName(), request.getAge());
}
@GetMapping("/user")
public List<UserListDto> getAllUsers() {
String sql = "select * from user";
return jdbcTemplate.query(sql, new RowMapper<UserListDto>() {
@Override
public UserListDto mapRow(ResultSet rs, int rowNum) throws SQLException {
long id = rs.getLong("id");
String name = rs.getString("name");
int age = rs.getInt("age");
return new UserListDto(id, name, age);
}
});
}
}
(1) jdbcTemplate.update()의 경우 쿼리를 통해 데이터베이스에 대한 갱신(update, delete, insert)이 일어날 때 사용할 수 있는 메서드로, 첫 번째 파라미터로 작성한 쿼리, 두 번째 세 번째 파라미터로는 요청 바디에서 넘어온 객체의 필드를 직접 넘기게 된다.
(1) jdbcTemplate.query(sql, new RowMapper<UserListDto>()
- 해당 메서드의 경우 사용자가 정의한 SQL을 직접 날려서, 받아온 결과들을 UserListDto에 매핑시키는 역할을 한다.
(2) RowMapper의 경우 쿼리의 결과를 받아서 원하는 결과 객체를 반환하는 역할을 수행한다.
(3) ResultSet에 getType("필드명") 메서드를 사용해 원하는 값을 가져올 수 있다.
(4) 이후 결과 반환을 위해 UserListDto가 필요하므로 생성자에 원하는 결과값을 파라미터로 넣어서 해당 객체를 생성 후 반환한다.
@RestController
@RequiredArgsConstructor
public class UserController {
private final JdbcTemplate jdbcTemplate;
@GetMapping("/user")
public List<UserListDto> getAllUsers() {
String sql = "select * from user";
return jdbcTemplate.query(sql, (rs, rowNum) -> {
long id = rs.getLong("id");
String name = rs.getString("name");
int age = rs.getInt("age");
return new UserListDto(id, name, age);
});
}
}
(5) 현재 해당 코드의 경우 자바 람다식을 사용해 코드를 줄일 수 있다.
7. 개인 회고
(1) 스프링에서 Repository를 다룰 때 거의 하이버네이트와 같은 ORM 기반 기술만 쓰다 보니 직접적으로 JdbcTemplate을 통해 데이터베이스에 접근하는 것은 코드가 손에 익숙하지 않았던 것 같다.
(2) 추가적으로 ORM 기술을 사용하다 보면 엔티티들을 직접 외부로 노출하지 않기 때문에 API를 위한 별도의 DTO를 만들어줘야 한다. 이 과정에서 람다식, 스트림이 자주 사용되는 데 이 부분에 대해 알고 있더라도 다시 한 번 정리하고 넘어가는 것이 좋을 것 같다고 생각했다.
※ 해당 포스팅에 대해 내용 추가가 필요하다고 생각되면 기존 포스팅 내용에 다른 내용이 추가될 수 있습니다.
개인적으로 공부하며 정리한 내용이기에 오타나 틀린 부분이 있을 수 있으며, 이에 대해 댓글로 알려주시면 감사하겠습니다.
'기록, 회고 > InFlearn Warming-up 0기 BE' 카테고리의 다른 글
[4일 차] - 내용 정리, 개인 회고 (0) | 2024.02.21 |
---|---|
[3일 차] - 과제 수행 : 익명 클래스, 함수형 프로그래밍(람다식), Stream API, 메서드 참조(Method Reference) (4) | 2024.02.20 |
[2일 차] - 과제 수행 : GET, POST API 설계 (4) | 2024.02.19 |
[2일 차] - 내용 정리, 개인 회고 (2) | 2024.02.19 |
[1일 차] - 과제 수행 : Spring(Java)에서 Annotation 사용하기 (1) | 2024.02.18 |
댓글