JDBC (Java Database Connectivity)
- 데이터베이스에 SQL문을 사용하려면 별도의 툴을 사용해야 함.
- JDBC는 자바 애플리케이션에서 DB에 연결해서 쿼리를 요청하고, 결과를 DB로부터 받아오는 것이 목적.
즉, 자바 애플리케이션과 데이터베이스의 다리 역할을 해주는 것.
- 데이터베이스에 연결하고 작업을 할 수 있으며, 표준으로 제공되는 인터페이스이다.
종류에 관계 없이 SQL문을 쓸 수 있다.
- 영속성 레이어를 위해 존재한 최초의 컴포넌트.
87년에 처음 출시되었다.
JDBC Architecture Model
- JDBC 인터페이스는 두 개의 레이어로 구분된다.
JDBC API와 JDBC Driver가 그것.
JDBC 드라이버
- JDBC 드라이버는 DB벤더에서 개발하고 배포해준다.
- 백엔드 엔지니어는 JDBC API를 이용해 JDBC 드라이버와 커넥션을 맺고 드라이버에서 쿼리에 대한 요청을 하게 됨.
- JDBC 드라이버는 4가지 형태의 타입이 있는데, 주로 사용되는 것은 TYPE 4이다.
- JDBC Driver Model
1 Type I : JDBC- ODBC Bridge
2 Type II: Native APT- Partly Java Driver
3 Type III: Network Protocol- Fully Java Driver
4 Type IV: Thin Driver- Fully Java Driver
(우리가 사용할 MySQL에서도 type4용JDBC Driver를 제공)
JDBC Flow
- 드라이버 manager를 통해 Connection 객체를 받는다.
- 커넥션으로 Statement를 만들고, statement를 실행시킴.
- 문제가 있다면 처리, result set을 받아옴. update를 실행할 수도 있음.
엔터티 구성, 서비스 로직 실행, 화면 전달.
- 끝났다면 스테이트먼트와 커넥션을 닫아야 함.
문제가 생겼다면 커넥션은 무조건 닫아줘야 하며, 커넥션을 닫지 않으면 큰 문제가 생길 수 있음.
MySQL 설치 및 테이블 준비
MySQL 만들기
- docker을 사용해서 MySQL을 하나 만들어준다.
강의에서는
docker run --name kdt-mysql -e MYSQL_PORT_HOST=% -e MYSQL_ROOT_PASSWORD=root! -p3306:3306 -d mysql:8
으로 만들어줬다.
docker ps
나 docker logs (번호)
로 잘 만들어졌는지 확인하자.
IntelliJ에서 열기
- IntelliJ의 우측에 있는 데이터 베이스를 누르고, 다음
+
버튼을 눌러준다.
- 사용자와 비밀번호에 맞는 값을 넣어준다.
이 경우에는 root
와 root1234!
이며 제대로 작업이 됐다면,
이렇게 될것이다.
- 다음은 데이터 쿼리를 조작해주자.
- 이 버튼으로 쿼리 콘솔 창을 띄울수 있다. 다음, 적당한 내용을 넣어서 MySQL 테이블을 만들어준다.
- 이렇게.
여기까지 완료되었으면 JDBC 실습을 위한 MySQL연결과 테이블 생성이 끝났다. 이제 JDBC를 사용해 SQL을 사용해서 테이블 수정 등을 실습해 보자.
드라이버 설치하기
- JDBC를 사용하기 위해서는 pom.xml에 드라이버를 붙여서 설정해주어야 한다.
구글에 mysql jdbc driver maven repository 검색하면 드라이버 설치 페이지가 바로 나온다. 문답무용으로 설치해주자.
가장 높은 버전을 설치한다.
- pom.xml의 dependency에 자리를 만들고 붙여넣어주면 된다.
작업 후 새로고침을 눌러주면 maven이 알아서 깔아준다. 좀만 기다리자.
Connection을 닫아야 하는 이유
- 데이터베이스 커넥션은 많은 리소스를 차지하고, 이것은 데이터베이스 애플리케이션에 많은 부담을 준다.
- 커넥션을 열어놓고 아무것도 하지 않으면 사용하지 않는 커넥션 때문에 불필요한 리소스를 할애하게 된다.
- 꼭 쿼리 실행 후 닫아주도록 하자.
try with resources
- 자바 10부터 도입된 기능으로 try 블록에서 커넥션을 사용할 수 있고, 사용 후 알아서 커넥션이 닫히게 할 수 있다.
- 이랬던 코드가
- 이렇게 바뀐다. 코드의 복잡성도 줄일 수 있고, 귀찮음도 덜어주는 아주 좋은 기능이다.
- AutoCloseable을 구현한다.
- Timestamp는 LocalDateTime으로 하는 것이 유용하다.
- Null이 발생할 수 있는 부분은 Nullable체크를 하고 바꿔주어야 한다. 그렇지 않으면 NullPointException이 발생할 수도 있다.
PreparedStatement
- SQL문을 문자열 조합으로 했을 때, SQL injection에 굉장히 취약해질 수 있으며 원치 않은 쿼리가 실행될 수도 있다.
SQL 문자열 조합은 인젝션을 고려하여 신중하게 사용해야 하고, 잘 컨트롤되어야 한다.
- 일반적인 Statement을 사용하면 쿼리를 사용할 때마다 쿼리 문장을 분석하고, 컴파일되고, 실행되는 3단계를 거치게 된다.
- 반면 PreparedStatement는 처음 한 번만 이 세 단계를 거치고 cache에 담아 재사용하게 된다. compile되기 때문에 처음 만들어진 쿼리문이 고정이 되고, 추후 OR절을 추가하거나 하는 조작이 불가능하다.
- 즉, PreparedStatement을 이용하면 미리 Statement를 만들어 놓기 때문에 쿼리를 중간에 바꾸 수 없고(다이나믹 쿼리 불가), 일반적인 Statement가 거치는 3단계를 생략하기 때문에 성능 상의 장점도 갖는다.
- 따라서 웬만하면 PreparedStatement을 이용하는 것이 좋다.
- 일반적인 Statement를 사용한 코드. 출력에 OR절을 추가해서 SQL injection을 일으켰다.
- PreparedStatement를 사용한 코드. 미리 만들어진(prepared)된 Statement를 사용하기 때문에 OR절을 사용해도 값의 조작이 불가능하다
- prefare은 index를 세팅해야하며, 인덱스는 1부터 시작한다.
- insert 문을 작성해서 추가할 수 있다.
- update 문을 작성해서 수정할 수 있다.
- delete 문을 작성해서 삭제할 수 있다.