[Spring] Spring JDBC: DataSource로 MySQL 연동하기

민지·2023년 4월 19일
0

Spring

목록 보기
1/3

기존 진행방법 (Plain JDBC)

SQL String 자바 객체 -> JDBC interface -> JDBC DRIVER -> DBMS

JDBC?

DB에 접근할 수 있도록,
즉 DB Connection을 지원하는 Java에서 제공되는 API.

우리는 Java에서 쿼리문을 작성해 DB에서 실행시켜 데이터를 CRUD하는 목적으로 이를 사용한다.

하지만 기존 JDBC를 사용할 때에는 쿼리문을 작성하기 이전, 이후로 전처리와 후처리 코드들이 필요했다.

또한 이러한 처리 방식은 DB가 필요할 때마다 Connection을 맺는 작업을 진행.

결과적으로 작업 속도가 느리며 자원을 많이 소모.

Connection Pool ?

공간을 미리 생성하여 DB Connection을 미리 만들고,
이를 빌려오고 반납하는 등의 Connection 관리 Pool Instance 이다.

일반적으로 CP 인스턴스 생성자에 Connection을 생성하는 코드가 포함되어 있기에 생성과 동시에 DB Connection을 만든다.

이용의 효율성 증대!

구조

(미리 얘기하지만 해당 게시물에서 사용할 DataSource인 SimpleDriverDataSource는 CP를 사용하지는 않는다. 모든 DataSource가 CP를 사용하는 것은 아님.)

DBCP

시스템 성능 향상을 위해서,
DB connection을 실제 서비스 운영할 때마다 매번 커넥션을 생성, 소멸시키지 않고 미리 생성한 Connection 을 빌려주고 반납하게 하도록 하는 역할

커넥션 풀 제공 모듈은 Tomcat JDBC, HikariCP, DBCP, c3p0 등이 있다.

결과적으로 우리는 sql문 작성과 결과 처리만 해주면 된다!

DataSource

Spring JDBC 접근 방법 중 하나로써, 커넥션을 관리하는 인터페이스.

여러 종류가 있는데 가장 심플한 SimpleDriverDataSource를 사용했다.

종류

  • SimpleDriverDataSource : CP 사용 안함
  • SingleConnectionDataSource : 커넥션 1개 생성 후 재활용
  • Apache Common DBCP : 스프링부트 2.0 이전에 Default DataSource.
  • HikariCp : 스프링부트 2.0 이후에 표준 DataSource.

사용법

Bean을 생성하는 방법은
1. xml에서 생성 후 property 값을 지정
2. Config.java에서 Annotation(@Bean)을 통해 생성 후 Setter로 값을 지정
두가지가 있다.

공통작업

  1. pom.xml 에 dependency 의존 모듈 추가
<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>5.3.26</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-jdbc</artifactId>
			<version>5.3.26</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>8.0.31</version>
		</dependency>

방법 1. applicationContext.xml

  1. dataSource와 등등 필요한 Bean객체를 생성한다.

<applicationContext.xml>

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

	<bean id="dataSource" class="org.springframework.jdbc.datasource.SimpleDriverDataSource">
		<property name="driverClass" value="com.mysql.cj.jdbc.Driver"/>
		<property name="url" value="jdbc:mysql://127.0.0.1:3306/사용할DB명?serverTimezone=UTC&amp;useUniCode=yes&amp;characterEncoding=UTF-8"/>
		<property name="username" value="유저네임등록"/>
		<property name="password" value="유저비번등록"/>
	</bean>
	
	<bean id="dbUtil" class="com.ssafy.util.DBUtil">
		
	</bean>
	
	<bean id="boardDao" class="com.ssafy.board.model.dao.BoardDaoImpl">
		<constructor-arg ref="dbUtil"></constructor-arg>
		<constructor-arg ref="dataSource"></constructor-arg>
	</bean>

</beans>
  1. 사용하는 파일에 가서 @Autowired로 Annotation을 달아줘도 되고, 생성자를 만든 후 사용할 수도 있다.

Annotation을 다는 방법은 아래와 동일하니 참고.

생성자 추가해주기

public class BoardDaoImpl implements BoardDao {

	private DataSource dataSource;
	private DBUtil dbUtil;
	
	
	public BoardDaoImpl() {
		super();
	}

	//Bean에서 id값으로 준 dataSource와 이름 맞춰주면 됨
	public BoardDaoImpl(DataSource dataSource, DBUtil dbUtil) {
		super();
		this.dataSource = dataSource;
		this.dbUtil = dbUtil;
	}
  	//...
}

방법 2. Config.java -> Annotation(@Bean)

  1. Annotation 을 통한 Bean 생성

<Config.java>

import javax.sql.DataSource;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.SimpleDriverDataSource;

@Configuration
@ComponentScan(basePackages = {"/"})
public class Config {
	@Bean
	public DataSource dataSource() {
		SimpleDriverDataSource sdds = new SimpleDriverDataSource();
		sdds.setDriverClass(com.mysql.cj.jdbc.Driver.class);
		sdds.setUrl("jdbc:mysql://127.0.0.1:3306/사용할DB명?serverTimezone=UTC&useUniCode=yes&characterEncoding=UTF-8");
		sdds.setUsername("유저네임등록");
		sdds.setPassword("유저비번등록");
		
		return sdds;
	}

}

이를 사용할 DaoImpl 파일로 이동. (<BoardDaoImpl.java>)

  1. @AutoWired 를 통한 의존성 주입을 한다.

참고) @Autowired는 생성자/필드/Setter 중 원하는 곳에 어노테이션을 달아 사용할 수 있다. 각각의 특징있지만 따로 다루든지 하겠다. 보통 생성자 의존성 주입을 많이 사용함.

@Repository("BoardDao")
public class BoardDaoImpl implements BoardDao {

	private DataSource dataSource;
	private DBUtil dbUtil;
	
  //생성자 주입
	@Autowired
	public BoardDaoImpl(DataSource dataSource, DBUtil dbUtil) {
		super();
		this.dataSource = dataSource;
		this.dbUtil = dbUtil;
	}
  	//필요한 메서드 구현
  	//예시 글작성 메서드
  	@Override
	public int writeArticle(BoardDto boardDto) throws SQLException {
		System.out.println("쓰는중...");
		int cnt = 0;
		Connection conn = null;
		PreparedStatement pstmt = null;
		try {
			conn = dataSource.getConnection();
			StringBuilder sql = new StringBuilder();
			sql.append("insert into board (user_id, subject, content, hit, register_time) \n");
			sql.append("values (?, ?, ?, 0, now())");
			pstmt = conn.prepareStatement(sql.toString());
			pstmt.setString(1, boardDto.getUserId());
			pstmt.setString(2, boardDto.getSubject());
			pstmt.setString(3, boardDto.getContent());
			cnt = pstmt.executeUpdate();	
		} finally {
			dbUtil.close(pstmt, conn);
			
		}
		return cnt;
	}
}

마치며

Annotation이 확실히 편하다.
현재 사용한 드라이버는 CP를 이용하지 않아 기존과 크게 성능의 차이는 없겠다. 그치만 Spring JDBC를 사용하면서 외부에서 클래스를 가져다 쓰는 것만으로 코드가 간결해짐. 굳.

profile
개발의, 개발에 의한, 개발을 위한 기록장

0개의 댓글