Computer Science/Spring

[자바 웹 개발 워크북] 2장: 웹과 데이터베이스

무니화니 2024. 4. 17. 15:21

2-1 JDBC 프로그래밍 준비

데이터베이스는 데이터를 보관하고 관리를 하는 소프트웨어이다. 보통 우리가 사용하는 데이터베이스는 관계형 데이터베이스로, MySQL, MariaDB, PostegreSQL이다.

먼저 MariaDB 웹사이트에서 다운로드를 받았고, 사용자 계정을 추가하였다. 데이터베이스를 추가적으로 생성하였고, 방금 만든 사용자 계정에 권한을 추가하였다.
이후 MariaDB를 사용해보기 위하여 프로젝트를 생성하였다.
IntelliJ에서 MariaDB에 접근하기 위해서 SQL문을 이용하여 실행하였다.

JDBC란?

JDBC는 'Java Database Connectivity'의 약자로서, 자바 프로그램과 데이터베이스를 네트워크 상에서 연결하여, 데이터를 교환하는 프로그램이다.

JDBC 프로그램 작성 순서

  1. 네트워크를 통해서 데이터베이스와 연결
  2. 데이터베이스에 보낼 SQL 작성, 전송
  3. 데이터베이스가 보낸 결과를 받아서 처리
  4. 데이터베이스와 연결을 종료

테스트 프로그램을 이용하여 연결을 확인할 수 있었다.
@Test 어노테이션을 사용하면, 테스트 코드를 제작할 수 있는데,
@Test를 적용하는 메서드는 반드시 public으로 선언되어야 하고, 파라미터나 리턴 타입이 없다.

public class ConnectTests{
    @Test
    public void testConnection() throws Exception {
        Class.forName("org.mariadb.jdbc.Driver");
        Connection connection = DriverManager.getConnection(
        "jdbc:mariadb://localhost:3306/webdb",
        "webuser",
        "webuser");
    Assertions.assertNotNull(connection);
    connection.close();
    }
}

해당 코드를 작성해서 테스트를 진행했다.

  • Class.forName(): JDBC 드라이버 클래스를 메모리 상으로 로딩.
  • Connection connection: 데이터베이스와 네트워크의 연결을 의미
  • DriverManager.getConnection(): 연결 시도
  • jdbc:mariadb://localhost::306/webdb: jdbc == 프로토콜 + localhost:3306 == 네트워크 연결 정보 + webdb== 연결하려는 데이터베이스
  • Assertions.assertNotNull: Connection 타입의 객체는 null이 아님을 확신함 -> Test하는 대상
  • connection.close(): JDBC 프로그램은 데이터베이스와 연결을 맺고 종료하는 방식으로 처리됨
    • 작업이 완료되면 반드시 데이터베이스와의 연결을 종료해줘야함!!

SQL 중에서 DML (Data Manipulation Language)를 이용하여 데이터를 조작할 수 있다.

  • Insert : 값 추가
  • Update : 값 수정
  • Delete : 값 삭제
    DML은 데이터가 몇 개가 처리되었는지 숫자로 결과를 반환한다.
  • Select : 값 조회
    Select문은 DML이 아니고, 그저 데이터만 반환한다.

java.sql.Statement / java.sql. PreparedStatement

  • JDBC에서 SQL을 데이터베이스로 보내기 위해서는 Statement와 PreparedStatement를 이용함.
  • Statement: SQL 문 내부에 모든 데이터를 같이 전송하는 방식
  • PreparedStatement: SQL 문을 미리 전달하고 나중에 데이터를 보내는 방식
  • 현재 개발에서는 PreparedStatement 방식을 사용하는데, SQL Injection을 막기 위함
  • **setXXX: setInt(), setString() 처럼 다양한 타입에 맞게 데이터 세팅
  • **executeUpdate(): DML을 실행하고, 몇개의 행이 영향을 받았는지 반환
  • **executeQuery(): 쿼리를 실행할 때 사용, return 타입은 ResultSet

java.sql.ResultSet

  • getInt(), getString() 등의 메서드를 이용하여 필요한 타입으로 데이터를 읽어드리기 위해 사용.
  • **next(): 다음 행의 데이터를 읽음
  • **close()를 해주어야 데이터베이스도 자원을 회수 할 수 ㅣㅇㅆ음.

Connection Pool , DataSource

JDBC 프로그램은 데이터베이스와 네트워크로 연결하고, 데이터베이스와의 연결을 맺는 작업은 시간과 자원이 소요됨
- 성능 저하 가능.

커넥션 풀을 통해서 이 문제를 해결함.
Connection Pool: Connection을 미리 생성해서 보관, 필요할 때 마다 쓰는 방식.
- 실제 운영되는 웹 서비스들은 Connection Pool을 기본적으로 사용.
- 해당 예제에서는 HikariCP를 사용함.

DAO (Data Access Object)

DAO란 데이터를 전문적으로 처리하는 객체이다. / 데이터베이스의 접근과 처리를 전담하는 객체이다.
VO를 단위로 처리한다.
DAO를 호출하는 객체는 DAO가 내부에서 어떻게 데이터를 처리하는지 알 수 없게 구성한다.
즉, JDBC 프로그램을 작성한다 -> DAO를 작성한다. 라고 이해할 수 있다.

VO (Value Object) / Entity

객체지향에서는 데이터를 객체 로 처리함.
데이터베이스에서는 하나의 데이터를 엔티티라고 함.

-> Java에서 테이블과 유사한 구조의 클래스를 만들어서, 객체로 처리하는 방식을 이용.
-> 객체 = 값을 보관하는 용도 -> "VO" 라고 함.

VO는 DTO와 유사하지만, DTO는 각 계층을 오고 가는데 사용되는 택배 상자로 비유, VO는 데이터베이스의 엔티티를 자바 객체로 표현한 것!

- DTO: getter /setter를 이용하여 자유롭게 데이터를 가공.
- VO: 데이터 자체를 의미. getter만을 이용함.

**최종 정리:

DAO: DB에 접근하기 위한 객체. DB에 접근하여 데이터를 삽입, 삭제, 조회.
DTO: 로직을 가지지 않는 데이터 객체. 계층 간 데이터 교환을 위해 사용. Getter Setter 메서드만 가짐.
VO: Read-Only 속성을 가진 오브젝트. Getter 기능만 존재.**

2.2 프로젝트 내 JDBC 구현

Getter Setter 생성과 생성자 함수를 정의하기 위해 Lombok 라이브러리를 이용함.

  • getter / setter 구현 시 @ 어노테이션을 이용하여 자동생성
  • toString : @toString을 이용하여 메서드를 자동 생성

Hikari를 이용하여 Connection Pool 생성.

class를 enum으로 구성? 왜?

  • class를 enum으로 구성하면, 클래스를 상수처럼 구현할 수 있다.
  • 유일하게 한 개의 인스턴스가 생성되어 사용된다. (싱글톤)

Lombok의 @Cleanup:

  • @Cleanup이 있는 코드는 메서드가 끝날 때 close()가 호출되는 것을 보장함.
  • 이를 통해 try catch문 보다 가독성이 뛰어나게끔 코드를 제작할 수 있음.

2.3 웹 MVC와 JDBC의 결합

  • ModelMapper 라이브러리를 이용하여 객체의 정보를 다른 객체로 복사할 수 있다.
  • DTO -> VO, VO -> DTO 변환을 ModelMapper 라이브러리를 이용하여 구현한다.

Lombok의 log4j2를 이용하여 log를 작성한다.
(System.out.prinln()을 사용하는 것 보다 의미도 있고, 도움이 됨.)
@log4j2를 이용하여 로그 적용.

  • 어펜더 (Appender): 콘솔 창에 출력할 건지, 파일로 출력할 것인지 선택
  • 레벨: 로그의 중요도 개념 (Fatal - Error - Warn - Info - Debug - Trace)
    • 레벨이 Error이면 Fatal, Error 레벨의 로그가 출력
    • 레벨이 Info인 경우 Fatal, Error, Warn, Info 레벨이 출력
    • log4j2.xml 설정 파일을 이용해서 구현