본문 바로가기

Springboot

데이터베이스 연결(Driver)

드라이버의 역할 : 애플리케이션과 데이터베이스간의 통신을 중개하는 역할 ( 애플리케이션의 요청을 데이터베이스가 이해 할 수 있는 언어로 변환)

드라이버의 종류

ex) Oracle, MySQL, PostgreSQL

Java의 데이터베이스별 Driver

 

드라이버의 동작 방식

  1. 연결 초기화
    • 요청 수신: 애플리케이션은 데이터베이스 작업을 시작하기 위해 드라이버에 연결을 요청합니다. 이는 마치 항공편✈️ 이 이륙 허가를 받기 위해 관제탑에 요청하는 것과 유사합니다.
    • 연결 설정: 드라이버는 데이터베이스 서버에 로그인하고 필요한 설정을 수행하여 연결을 완료합니다. 이 과정은 네트워크 정보, 인증 자격 증명 등을 사용하여 이루어집니다.
  2. SQL 전송 및 실행
    • SQL 명령 변환: 애플리케이션에서 발송된 SQL 명령을 받은 드라이버는 해당 명령을 데이터베이스가 이해할 수 있는 형태로 변환합니다. 이는 외국어를 현지 언어로 번역하는 통역사의 역할과 같습니다.
    • 명령 처리: 변환된 명령은 데이터베이스 서버로 전송되어 실행됩니다. 데이터베이스는 쿼리를 처리하고, 요구된 데이터를 검색하거나 데이터에 변화를 줍니다.
  3. 결과 처리
    • 결과 수신: 데이터베이스에서 작업의 결과를 보내면, 드라이버는 이 결과를 받아 애플리케이션에서 해석할 수 있는 형태로 변환합니다.
    • 결과 전달: 최종적으로, 드라이버는 이 결과를 애플리케이션에 전달합니다. 이는 관제탑이 항공기✈️에 착륙 지시를 내리는 과정과 유사하며, 애플리케이션은 이 정보를 사용자에게 표시하거나 다음 작업을 진행합니다.
  4. 연결 종료
    • 연결 해제: 작업이 완료되면, 드라이버는 데이터베이스 서버와의 연결을 종료합니다. 이는 비행이 끝난 후 항공기✈️가 공항 게이트에 도킹하는 것과 비슷하며, 자원을 정리하고 다음 세션을 위해 시스템을 초기화합니다.

 

💡 JDBC Driver Manager 는 애플리케이션이 실행되고 있는 런타임 시점에

  • Connection(연결) 을 생성하여 쿼리를 요청할 수 있는 상태를 만들어주고
  • Statement(상태) 를 생성하여 쿼리를 요청하게 해주고
  • ResultSet(결과셋) 을 생성해 쿼리 결과를 받아올 수 있게 해줍니다. 

 

Spring Boot 의 JDBC 라이브러리

  • Spring Boot와 JDBC: Spring Boot는 데이터베이스 연결을 쉽게 구성할 수 있도록 다양한 JDBC 드라이버를 지원합니다. 이를 통해 개발자는 복잡한 설정 없이 데이터베이스와의 연결을 쉽게 구성할 수 있습니다.
  • spring-boot-starter-jdbc는 Spring Boot 프로젝트에서 JDBC를 통해 데이터베이스와 상호작용하기 위해 사용되는 스타터 패키지입니다.
    • 이 스타터 패키지는 데이터베이스 작업을 수행하는 데 필요한 주요 의존성과 자동 구성 기능을 제공합니다. 데이터베이스와의 연결을 쉽고 빠르게 구성할 수 있도록 도와주는 브릿지 역할을 합니다.
    • 주요 포함 내용
      1. JDBC API 지원: JDBC API를 통해 SQL 데이터베이스에 접근하고 작업을 수행할 수 있습니다.
      2. DataSource 구성: 데이터 소스 연결을 위한 기본적인 설정을 자동으로 구성합니다. 이는 데이터베이스 연결을 관리하는 데 필수적인 요소입니다.
      3. JdbcTemplate: **JdbcTemplate**은 Spring의 핵심 클래스 중 하나로, JDBC 작업의 많은 번거로움을 줄여 줍니다. SQL 쿼리 실행, 결과 세트 처리, 예외 처리 등을 단순화합니다.
    • 주요 장점 내용
      1. 간소화된 데이터베이스 연결: DataSource 설정과 JdbcTemplate 사용을 통해 복잡한 JDBC 코드를 간소화할 수 있습니다.
      2. 자동 구성: Spring Boot의 자동 구성 기능은 개발자가 데이터베이스 연결에 필요한 대부분의 구성을 자동으로 처리할 수 있도록 합니다.
      3. 효율적인 예외 처리: Spring의 **DataAccessException**을 통해 JDBC에서 발생하는 예외를 Spring의 일관된 예외 체계로 변환합니다.

 

JDBC Template (QueryMapper)

  • JDBC 로 직접 SQL을 작성했을때의 문제
    • SQL 쿼리 요청시 중복 코드 발생
    • DB별 예외에 대한 구분 없이 Checked Exception (SQL Exception) 처리
    • Connection, Statement 등.. 자원 관리를 따로 해줘야함
      • 자원 해제 안해주면 메모리 꽉차서 서버가 죽음
  • 이 문제 해결을 위해 처음으로 Persistence Framework 등장!
    • Persistence Framework 는 2가지가 있다.
      • SQL Mapper : JDBC Template, MyBatis 👈 요게 먼저나옴
      • ORM : JPA, Hibernate
  • SQL Mapper (QueryMapper)
    • SQL ↔ Object
    • SQL 문과 객체(Object)의 필드를 매핑하여 데이터를 객채화

JDBC Template (RowMapper)

  • SQL Mapper 첫번째 주자로 JDBCTemplate 에 RowMapper 탄생
    • 쿼리 수행 결과와 객채 필드 매핑
    • RowMapper 로 응답필드 매핑코드 재사용
    • Connection, Statement, ResultSet 반복적 처리 대신 해줌
    • 😵‍💫 But, 결과값을 객체 인스턴스에 매핑하는데 여전히 많은 코드가 필요함

JDBC Template는 JDBC Driver를 추상화하여 동작 (dbcp = db connection pool)

 

 

JDBC Template 실습

 

  1. insertUser: 새로운 사용자를 users 테이블에 추가합니다. 사용자의 이름과 이메일 주소를 매개변수로 받아 데이터베이스에 저장합니다.
  2. findUserNameById: 주어진 ID에 해당하는 사용자의 이름을 조회합니다. queryForObject 메서드를 사용하여 단일 결과를 반환합니다.
  3. updateUser: 주어진 ID의 사용자 이름을 새로운 이름으로 변경합니다. UPDATE SQL 명령을 사용하여 해당 ID의 사용자 정보를 업데이트합니다.
  4. deleteUser: 주어진 ID를 가진 사용자를 users 테이블에서 삭제합니다. DELETE SQL 명령을 사용하여 해당 ID의 사용자 정보를 삭제합니다.
// DataRepository.java
package com.thesun4sky.jdbc;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

@Repository
public class DataRepository {

	@Autowired
	private JdbcTemplate jdbcTemplate;

	// 테이블 생성
	public void createTable() {
		jdbcTemplate.execute("CREATE TABLE IF NOT EXISTS users (id SERIAL, name VARCHAR(255))");
	}

	// 사용자 추가 (Create)
	public void insertUser(String name) {
		jdbcTemplate.update("INSERT INTO users (name) VALUES (?)", name);
	}

	// 사용자 ID로 이름 조회 (Read)
	public String findUserNameById(Long id) {
		return jdbcTemplate.queryForObject(
			"SELECT name FROM users WHERE id = ?",
			new Object[]{id},
			String.class
		);
	}

	// 사용자 이름 변경 (Update)
	public void updateUser(Long id, String newName) {
		jdbcTemplate.update("UPDATE users SET name = ? WHERE id = ?", newName, id);
	}

	// 사용자 삭제 (Delete)
	public void deleteUser(Long id) {
		jdbcTemplate.update("DELETE FROM users WHERE id = ?", id);
	}
}
// JdbcApplication.java
package com.thesun4sky.jdbc;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class JdbcApplication {

	public static void main(String[] args) {
		// 어플리케이션 실행 컨텍스트 생성
		var context = SpringApplication.run(JdbcApplication.class, args);
		// 데이터 조회 클래스 빈 조회
		var repository = context.getBean(DataRepository.class);

		// 테이블 생성
		repository.createTable();
		// 유저정보 추가
		repository.insertUser("Teasun Kim");
		// 유저정보 조회
		System.out.println("User Name: " + repository.findUserNameById(1L));
	}
}

 

 

JDBC Template RowMapper 실습

  • RowMapper.mapRow : RowMapper 를 상속받아 mapRow() 메서드를 구현하면 JDBCTemplate 에서 row 응답을 mapRow() 메서드에 rs 파라미터로 넘겨주어 객체에 매핑하기 쉽도록 도와준다.
  • findUserById : jdbcTemplate.queryForObject() 메서드에서는 두번쨰 인자로 RowMapper 를 넣어줄 경우 해당 RowMappermapRow() 메서드를 사용하여 응답을 하도록 동작한다.
// UserRowMapper.java
import java.sql.ResultSet;
import java.sql.SQLException;

import org.springframework.jdbc.core.RowMapper;


public class UserRowMapper implements RowMapper<User> {

	// JDBCTemplate 에서 row 응답을 mapRow() 메서드에 rs 파라미터로 넘겨주어 객체에 매핑하기 쉽도록 도와준다.
  @Override
  public User mapRow(ResultSet rs, int rowNum) throws SQLException {
    var user = new User();
    user.setId(rs.getInt("ID"));
    user.setName(rs.getString("NAME"));
    return user;
  }
}

 

// 사용자 ID로 User 조회 (Read)
public User findUserById(Long id) {
	return jdbcTemplate.queryForObject(
		"SELECT * FROM users WHERE id = ?",
		new UserRowMapper(),  // 이자리에 매퍼를 생성자로 넣어주면 됨
		id
	);
}

'Springboot' 카테고리의 다른 글

AWS # Identity and Access Management  (0) 2024.07.05
QueryDSL, Auditing, Dynamic Insert/Update  (0) 2024.07.01
테이블 객체 만들기  (0) 2024.06.28
쿼리 파일 만들기 (QueryMapper)  (0) 2024.06.28
Filter, Intercepter  (0) 2024.06.26