본문 바로가기
Java Web Programming/6. Spring | MyBatis

[Spring] DBCP를 Spring config로 설정해보기! (+IOC/DI+DL)

by 파프리카_ 2020. 10. 27.
728x90
반응형

DBCP를 사용하는 이유?!

- data driver loading & connection 시 매번 하다보면 비용이 발생한다. 

이를 해결하기 위해, DBCP(DataBaseConnectionPool)을 이용해, 미리 한번 만들어 둔 Connection을 빌려오고 반납하는 형식을 이용한다.  


DBCP 사용 환경  설정

> pom.xml <dependency> 추가

  <dependencies>
  	<!-- DBCP를 위해 -->
	<!-- https://mvnrepository.com/artifact/commons-dbcp/commons-dbcp -->
	<dependency>
	    <groupId>commons-dbcp</groupId>
	    <artifactId>commons-dbcp</artifactId>
	    <version>1.4</version>
	</dependency>
	
   	 <!-- 스프링 라이브러리를 이용하기 위해 -->
  	<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
	<dependency>
	    <groupId>org.springframework</groupId>
	    <artifactId>spring-context</artifactId>
	    <version>4.3.14.RELEASE</version>
	</dependency>
  </dependencies>

 

/ioc.xml 에 추가

<!--  DBCP -->
<bean id="dbcp" class="org.apache.commons.dbcp.BasicDataSource">
  <property name="driverClassName" value="oracle.jdbc.OracleDriver"/>	
  <property name="url" value="jdbc:oracle:thin:@127.0.0.1:1521:xe"/>	
  <property name="username" value="scott"/>	
  <property name="password" value="tiger"/>	
</bean>

[ Spring Framework 동작 프로세싱 ] 


SQL

table 생성

CREATE TABLE account(
    id      VARCHAR2(100) PRIMARY KEY,
    name    VARCHAR2(100) NOT NULL,
    balance NUMBER        NOT NULL
)

/model

/AccountVO.java

package model;

public class AccountVO{
	private String id;
	private String name;
	private int balance;
	
	public AccountVO() {
		super();
	}

	public AccountVO(String id, String name, int balance) {
		super();
		this.id = id;
		this.name = name;
		this.balance = balance;
	}

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getBalance() {
		return balance;
	}

	public void setBalance(int balance) {
		this.balance = balance;
	}
	
}

 

영속성 계층

 

★ 메서드 오버라이딩 규칙 ★

 1. 메서드 명과 매개별수가 동일해야 하고,
 2. 접근제어자는 하위로 갈수록 범위가 좁아지면 않되고,
 3. 상위 메서드에 선언한 Exception 또는 하위 Exception만 throws 가능하다.

 

/AccountDAO.java <<interface>>

package model;

import java.sql.SQLException;

public interface AccountDAO {
	public AccountVO findAccountById(String id) throws SQLException;
}

 

/AccountDAOImpl.java

package model;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import javax.sql.DataSource;

public class AccountDAOImpl implements AccountDAO {

	private DataSource dataSource;
	
	//Spring IOC Container로부터 DBCP를 주입받는다 (DI 방식)
	public AccountDAOImpl(DataSource dataSource) {
		super();
		this.dataSource = dataSource;
	}

	//closeAll() method
	public void closeAll(ResultSet rs, PreparedStatement pstmt, 
			Connection con) throws SQLException {
		if (rs != null)
			rs.close();
		if (pstmt != null)
			pstmt.close();
		if (con != null)
			con.close();
	}
	
	@Override
	public AccountVO findAccountById(String id) throws SQLException {
		Connection con = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		AccountVO vo = null;
		
		try {
			con = dataSource.getConnection(); //dbcp로부터 connection 빌려옴
			String sql = "SELECT name, balance FROM account WHERE id=?";
			pstmt = con.prepareStatement(sql);
			pstmt.setString(1, id);
			rs = pstmt.executeQuery();
			if (rs.next())
				vo = new AccountVO(id, rs.getString(1), rs.getInt(2));
		} finally {
			closeAll(rs, pstmt, con);
		}
		
		return vo;
	}
}

/controller

프레젠테이션 계층

/AccountController.java 

package controller;

import java.sql.SQLException;

import model.AccountDAO;
import model.AccountVO;

public class AccountController {
	//private AccountDAOImpl accountDAO; //결합도가 낮다
	
	//인터페이스타입으로 선언해야 결합도가 높아진다!
	private AccountDAO accounDAO;

	//생성자 (accountDAO)
	public AccountController(AccountDAO accounDAO) {
		super();
		this.accounDAO = accounDAO;
	} 
	
	//method
	public AccountVO findAccountById(String id) throws SQLException {
		return accounDAO.findAccountById(id);
	}
}

/test

/TestIOC.java

package test;

import java.sql.SQLException;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import controller.AccountController;
import model.AccountDAO;

public class TestIOC {
	public static void main(String[] args) {
		ClassPathXmlApplicationContext factory
			= new ClassPathXmlApplicationContext("ioc.xml");
		//System.out.println(factory.getBean("dbcp"));
		
		
		/*
		 * AccountDAO dao = (AccountDAO) factory.getBean("accountDAO");
		 * 
		 * try { System.out.println(dao.findAccountById("milk")); } catch (SQLException
		 * e) { e.printStackTrace(); }
		 * 
		 * 
		 */
		
		AccountController controller 
			= (AccountController) factory.getBean("accountController");
		
		try {
			controller.findAccountById("milk");
		} catch (SQLException e) {
			e.printStackTrace();
		}
		
		factory.close();
	}
}

/ioc.xml

 

Beans Graph

1) DBCP  2) accountDAO 3)accountController 주입

<?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">

	<!--  DBCP -->
	<bean id="dbcp" class="org.apache.commons.dbcp.BasicDataSource">
		<property name="driverClassName" value="oracle.jdbc.OracleDriver"/>	
		<property name="url" value="jdbc:oracle:thin:@127.0.0.1:1521:xe"/>	
		<property name="username" value="scott"/>	
		<property name="password" value="tiger"/>	
	</bean>
	
	<!-- accountDAO의 생성자에 dbcp 주입 -->
	<bean id="accountDAO" class="model.AccountDAOImpl">
		<constructor-arg ref="dbcp"/>
	</bean>
	
	<!-- AccountController의 생성자에 accoundDAO 주입 -->
	<bean id="accountController" class="controller.AccountController">
		<constructor-arg ref="accountDAO"/>
	</bean>
	
</beans>

[ 결과 ]

728x90
반응형