코딩 개발/Spring

Spring - DBCP (DataBase Connection Pool)

호소세 2023. 7. 8. 10:33
728x90
반응형

이제 저희는 결국 Database에 연동하여 데이터를 CRUD 해야 하는 상황이 오게 됩니다.

그렇기 때문에 이전에 웹 프로그래밍을 진행할 때 사용했던 DBCP를 Spring에서는 어떻게 사용하는지 알아보겠습니다.

 

https://pabeba.tistory.com/170

 

Java - DBCP (Database Connection Pool)

DBCP란? Database Connection Pool 의 약어로 Java 언어로 개발된 어플리케이션에서 데이터베이스 연결 관리를 담당하는 라이브러리 또는 프레임 워크입니다. Java DBPC는 데이터베이스 연결을 관리하는 데

pabeba.tistory.com

이 글은 DBCP에 대해 조금 더 자세히 알아보는 글입니다. 참고해 주세요.

 

DBCP 생성

스프링에서 DBCP(Database Connection Pool)를 생성하려면 주로 DataSource 빈을 구성하는 코드를 작성하는 곳이 적절합니다. 이를 위해 일반적으로 스프링의 설정 파일인 AppConfig 클래스나 데이터 소스 관련 설정을 담당하는 클래스에 코드를 작성하는 것이 일반적입니다.

 

이전에 방법과 다른 것은 설정파일에 작성한다와 어노테이션을 이용하여 관리한다 정도입니다.

 

대신 Spring Container에서 관리되는 빈(Bean)으로 등록되면서 생성, 의존성 주입, 라이플 사이클 관리 등의 제어 역전이 됩니다.

 

생성 방법

코드를 작성하기 전에 Maven pom.xml 폴더에 추가해야할 것이 있습니다.

예상하셨듯이 library를 가져와야합니다.

https://mvnrepository.com/

Maven Repository에서 ojdbc8과 commons-dbcp를 가져와야합니다. 위의 사이트에서 검색해서 가져오시거나

제가 코드로 작성해 놓을게요

<pom.xml>

<dependency>
	<groupId>org.apache.commons</groupId>
	<artifactId>commons-dbcp2</artifactId>
	<version>2.8.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.oracle.database.jdbc/ojdbc8 -->
<dependency>
	<groupId>com.oracle.database.jdbc</groupId>
	<artifactId>ojdbc8</artifactId>
	<version>21.5.0.0</version>
</dependency>
@Configuration
@ComponentScan("myproject")
public class AppConfig {
	//메서드가 리턴하는 객체를 bean 으로 생성, 관리  bean name은 method 명이 된다 
	@Bean
	public DataSource dataSource() {
		BasicDataSource dataSource=new BasicDataSource();
		dataSource.setDriverClassName("oracle.jdbc.OracleDriver");
		dataSource.setUrl("jdbc:oracle:thin:@localhost:1521:xe");
		dataSource.setUsername("mango");
		dataSource.setPassword("apple");
		return dataSource;
	}
}

1. @Configuration 어노테이션이 적용된 AppConfig 클래스를 사용합니다.

2. @Bean으로 어노테이션을 적용하여 스프링 컨테이너에서 관리되는 Bean으로 만들어 줍니다.

3. DataSource 빈은 스프링의 빈 관리 기능에 따라 관리되고, 필요한 곳에서 주입될 수 있습니다.

4. 사용 후에는 여전히 Connection 객체를 반환하여 다시 재사용 가능하게 한다고 합니다.

 

DAO에서 DBCP 사용 예시

@Repository
public class MemberDAOImpl implements MemberDAO {
	private final DataSource dataSource;
	// 스프링 컨테이너(IOC Container)가 생성자 호출 시점에  datasource 구현체 dbcp => dependency injection
	@Autowired // DI 
	public MemberDAOImpl(DataSource dataSource) {
		super();
		this.dataSource = dataSource;
		System.out.println(getClass().getName()+" 생성자 실행, 객체 생성시 dbcp 주입받음 "+dataSource);
	}

	@Override
	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 MemberVO findMemberById(String id) throws SQLException {
		Connection con=null;
		PreparedStatement pstmt=null;
		ResultSet rs=null;
		MemberVO memberVO=null;
		try {
			con=dataSource.getConnection();//컨넥션을 dbcp로부터 빌려옴
			String sql="select id,password,name,address from spring_member where id=?";
			pstmt=con.prepareStatement(sql);
			pstmt.setString(1, id);
			rs=pstmt.executeQuery();
			if(rs.next()) {
				memberVO=new MemberVO(rs.getString(1),rs.getString(2),rs.getString(3),rs.getString(4));
			}
		}finally {
			closeAll(rs, pstmt, con);
		}
		return memberVO;
	}
}

DAO에서 DBCP에서 생성한 Connection들 중 하나를 주입받아서 사용하고 반납해야 합니다.

 

그래서 MemberDAOImpl 객체가 생성될 때 dataSource 객체를 주입받아 getConnection() 메서드를 이용해서 Connection을 생성합니다.

 

이전과 다른 점은 역시나 어노테이션 (@Autowired, @Repository)를 작성해 준 점? 밖에 없다고 생각합니다.

 

제가 직접 관리하는 것 대신 Spring Container에서 이러한 작업들을 대신해 준다는 점이 참 좋다고 생각합니다.

 

소감

비교하는 삶을 살면 안 되는 것은 앞서 많이 말씀드렸는데.... 비교를 하지 않고서 살지 못하는 사람이라면 어쩔 수 없다고 생각합니다. 하지만 그 비교가 부정적인 생각으로 번져 비교를 한 사람을 향해 비난의 화살이 날아가지 않게 해야 하는데, 요새는 인터넷의 발달로 너무나도 쉽게 공개적으로 누군가에 대한 악플과 안 좋은 글을 작성하게 됩니다.

 

모두가 행복한 삶을 살고 싶습니다. ㅎㅎ 

 

어떤 사람의 글 중에 남에게 관심이 없는 사람이 정말 성공한다고 합니다. 관심이 없다의 느낌이 자신의 주변 사람들에게 잘하지만 그들의 생활 깊숙이까지 관심을 가지지 않는다는 말입니다.

저도 주변인들에게 잘하되 너무 지대한 관심을 가지지 않도록 노력하겠습니다.

반응형