[Spring] CH16 스프링부트 레파지토리(저장소) - JDBC (책)

jaegeunsong97·2023년 3월 21일
0

[Fast Campus] Spring

목록 보기
26/44
post-thumbnail

https://github.com/codingspecialist/Springboot-JDBC.git

📕 JDBC


JDBC(Java Database Connectivity)는 자바 언어에서 데이터베이스에 접속하고 SQL 쿼리를 실행하기 위한 API입니다.

JDBC API는 데이터베이스에 대한 일반적인 인터페이스를 제공하여, 다양한 데이터베이스와 연결할 수 있도록 합니다. 이를 통해 개발자는 데이터베이스 연결과 관련된 작업을 프로그래밍으로 처리할 수 있습니다.

JDBC API의 주요 구성 요소는 다음과 같습니다.
1. Driver Manager

JDBC 드라이버를 로드하고 데이터베이스 연결을 관리하는 클래스입니다.
1. Connection

데이터베이스와의 연결을 나타내는 객체입니다.
1. Statement

SQL 쿼리를 실행하는 데 사용되는 객체입니다.
1. PreparedStatement

미리 컴파일된 SQL 쿼리를 실행하는 데 사용되는 객체입니다.
1. ResultSet

SQL 쿼리 실행 결과로 반환된 데이터를 처리하는 데 사용되는 객체입니다.
JDBC API를 사용하여 데이터베이스와 상호 작용하는 일반적인 절차는 다음과 같습니다.

  1. JDBC 드라이버 로드
  2. 데이터베이스 연결
  3. SQL 쿼리 실행
  4. 쿼리 실행 결과 처리
  5. 데이터베이스 연결 해제

JDBC API는 다양한 데이터베이스와 호환되며, 데이터베이스의 종류나 버전에 따라 조금씩 다른 구현 방법이 필요할 수 있습니다. 따라서, JDBC API를 사용할 때는 데이터베이스와의 호환성을 고려하여 구현해야 합니다.

📕 DataSource


Java에서 DataSource는 데이터베이스와의 연결을 관리하는 인터페이스입니다. JDBC를 사용하여 데이터베이스에 연결할 때는 DriverManager를 사용하여 연결을 관리하지만, DataSource를 사용하면 더욱 안정적인 데이터베이스 연결을 구현할 수 있습니다.

DataSource는 일반적으로 커넥션 풀링(connection pooling)을 구현하며, 데이터베이스와의 연결을 미리 만들어두고 필요할 때마다 커넥션을 재사용하여 성능을 향상시킵니다. 또한, DataSource는 데이터베이스와의 연결을 설정하는 데 필요한 정보를 포함하며, 데이터베이스 종류, 호스트, 포트, 사용자 이름, 비밀번호 등의 정보를 설정할 수 있습니다.

Java에서는 javax.sql.DataSource 인터페이스를 제공하며, 이 인터페이스를 구현하는 다양한 데이터베이스연결 풀 라이브러리가 존재합니다.

예를 들어, Apache Commons DBCP, HikariCP, Tomcat JDBC 등이 있습니다. 이러한 라이브러리를 사용하여 DataSource를 쉽게 구현할 수 있으며, 데이터베이스 연결 관리를 편리하게 할 수 있습니다.

dependencies {
  implementation 'org.springframework.boot:spring-boot-starter-jdbc'
  implementation 'org.springframework.boot:spring-boot-starter-web'
  compileOnly 'org.projectlombok:lombok'
  developmentOnly 'org.springframework.boot:spring-boot-devtools'
  runtimeOnly 'com.h2database:h2'
  annotationProcessor 'org.projectlombok:lombok'
  testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
package shop.mtcoding.jdbcstudy.model;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Repository;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

@Slf4j
@Repository
public class CustomerRepository {
    private DataSource dataSource;

    public CustomerRepository(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    public void save(Customer customer) {
        Connection connection = null;
        PreparedStatement statement = null;
        try {
            String sql = "INSERT INTO customer (name, tel) VALUES (?, ?)";
            connection = dataSource.getConnection();
            statement = connection.prepareStatement(sql);
            statement.setString(1, customer.getName());
            statement.setString(2, customer.getTel());
            statement.executeUpdate();
        } catch (SQLException e) {
            log.error(e.getMessage());
            throw new RuntimeException(e.getSQLState());
        } finally {
            try {
                statement.close();
                connection.close();
            } catch (SQLException e) {
                log.error(e.getMessage());
            }
        }
    }

    public void update(Customer customer) {
        Connection connection = null;
        PreparedStatement statement = null;
        try {
            String sql = "UPDATE customer SET name = ?, tel = ? WHERE id = ?";
            connection = dataSource.getConnection();
            statement = connection.prepareStatement(sql);
            statement.setString(1, customer.getName());
            statement.setString(2, customer.getTel());
            statement.setLong(3, customer.getId());
            statement.executeUpdate();
        } catch (SQLException e) {
            log.error(e.getMessage());
            throw new RuntimeException(e.getSQLState());
        } finally {
            try {
                statement.close();
                connection.close();
            } catch (SQLException e) {
                log.error(e.getMessage());
            }
        }
    }

    public void delete(Long id) {
        Connection connection = null;
        PreparedStatement statement = null;
        try {
            String sql = "DELETE FROM customer WHERE id = ?";
            connection = dataSource.getConnection();
            statement = connection.prepareStatement(sql);
            statement.setLong(1, id);
            statement.executeUpdate();
        } catch (SQLException e) {
            log.error(e.getMessage());
            throw new RuntimeException(e.getSQLState());
        } finally {
            try {
                statement.close();
                connection.close();
            } catch (SQLException e) {
                log.error(e.getMessage());
            }
        }
    }

    public Customer findById(Long id) {
        Connection connection = null;
        PreparedStatement statement = null;
        ResultSet rs = null;
        try {
            String sql = "SELECT * FROM customer WHERE id = ?";
            connection = dataSource.getConnection();
            statement = connection.prepareStatement(sql);
            statement.setLong(1, id);
            rs = statement.executeQuery();
            if (rs.next()) {
                return mapper(rs);
            } else {
                throw new RuntimeException("DB warning : 해당 id의 고객이 없습니다");
            }
        } catch (SQLException e) {
            log.error(e.getMessage());
            throw new RuntimeException(e.getSQLState());
        } finally {
            try {
                rs.close();
                statement.close();
                connection.close();
            }catch (SQLException e){
                log.error(e.getMessage());
            }
        }
    }

    public List<Customer> findAll(int page) {
        Connection connection = null;
        PreparedStatement statement = null;
        ResultSet rs = null;
        try {
            final int row = 2;
            String sql = "SELECT * FROM customer limit ?, ?";
            connection = dataSource.getConnection();
            statement = connection.prepareStatement(sql);
            statement.setInt(1, page * row);
            statement.setInt(2, row);
            rs = statement.executeQuery();
            List<Customer> customers = new ArrayList<>();
            while (rs.next()) {
                Customer c = mapper(rs);
                customers.add(c);
            }
            return customers;
        } catch (SQLException e) {
            log.error(e.getMessage());
            throw new RuntimeException(e.getSQLState());
        } finally {
            try {
                rs.close();
                statement.close();
                connection.close();
            }catch (SQLException e){
                log.error(e.getMessage());
            }
        }
    }

    // Object Relational Mapping
    public Customer mapper(ResultSet rs) throws SQLException {
        System.out.println("mapper 실행");
        return new Customer(rs.getLong("id"), rs.getString("name"), rs.getString("tel"));
    }
}
profile
블로그 이전 : https://medium.com/@jaegeunsong97

0개의 댓글