웹사이트 검색

Java DataSource, JDBC DataSource 예제


자바 데이터 소스

대부분의 경우 데이터베이스를 쉽게 전환할 수 있도록 연결을 위한 느슨한 결합, 트랜잭션 관리를 위한 연결 풀링 및 분산 시스템 지원을 찾고 있습니다. 애플리케이션에서 이러한 기능을 찾고 있는 경우 JDBC DataSource가 선호되는 접근 방식입니다. Java DataSource 인터페이스는 javax.sql 패키지에 있으며 두 개의 오버로드된 메서드 getConnection()getConnection(String str1,String str2)만 선언합니다. .

JDBC 데이터 소스

서로 다른 종류의 DataSource 인터페이스 구현을 제공하는 것은 서로 다른 데이터베이스 벤더의 책임입니다. 예를 들어 MySQL JDBC 드라이버는 com.mysql.jdbc.jdbc2.optional.MysqlDataSource 클래스를 사용하여 DataSource 인터페이스의 기본 구현을 제공하고 Oracle 데이터베이스 드라이버는 oracle.jdbc.pool.OracleDataSource를 사용하여 이를 구현합니다. 코드> 클래스. 이러한 구현 클래스는 사용자 자격 증명과 함께 데이터베이스 서버 세부 정보를 제공할 수 있는 방법을 제공합니다. 이러한 JDBC DataSource 구현 클래스에서 제공하는 다른 공통 기능 중 일부는 다음과 같습니다.

  • 빠른 처리를 위한 PreparedStatement 캐싱
  • 연결 시간 초과 설정
  • 로깅 기능
  • ResultSet 최대 크기 임계값

JDBC 데이터 소스 예

Java JDBC 데이터 소스 - 데이터베이스 설정

예제 프로그램을 시작하기 전에 테이블 및 샘플 데이터가 포함된 일부 데이터베이스 설정이 필요합니다. MySQL 또는 Oracle 데이터베이스 설치는 이 튜토리얼의 범위를 벗어나므로 샘플 데이터로 테이블을 설정하겠습니다.

--Create Employee table
CREATE TABLE `Employee` (
  `empId` int(10) unsigned NOT NULL,
  `name` varchar(10) DEFAULT NULL,
  PRIMARY KEY (`empId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- insert some sample data
INSERT INTO `Employee` (`empId`, `name`)
VALUES
	(1, 'Pankaj'),
	(2, 'David');

commit;
CREATE TABLE "EMPLOYEE"
  (
    "EMPID"   NUMBER NOT NULL ENABLE,
    "NAME"    VARCHAR2(10 BYTE) DEFAULT NULL,
    PRIMARY KEY ("EMPID")
  );

Insert into EMPLOYEE (EMPID,NAME) values (10,'Pankaj');
Insert into EMPLOYEE (EMPID,NAME) values (5,'Kumar');
Insert into EMPLOYEE (EMPID,NAME) values (1,'Pankaj');
commit;

이제 자바 프로그램으로 넘어갑시다. 데이터베이스 구성을 느슨하게 결합하기 위해 속성 파일에서 읽습니다. db.properties 파일:

#mysql DB properties
MYSQL_DB_DRIVER_CLASS=com.mysql.jdbc.Driver
MYSQL_DB_URL=jdbc:mysql://localhost:3306/UserDB
MYSQL_DB_USERNAME=pankaj
MYSQL_DB_PASSWORD=pankaj123

#Oracle DB Properties
ORACLE_DB_DRIVER_CLASS=oracle.jdbc.driver.OracleDriver
ORACLE_DB_URL=jdbc:oracle:thin:@localhost:1521:orcl
ORACLE_DB_USERNAME=hr
ORACLE_DB_PASSWORD=oracle

위의 구성이 로컬 설정과 일치하는지 확인하십시오. 또한 프로젝트의 빌드 경로에 MySQL 및 Oracle DB JDBC jar가 포함되어 있는지 확인하십시오.

Java JDBC 데이터 소스 - MySQL, Oracle 예제

MySQL 또는 Oracle DataSource를 가져오는 데 사용할 수 있는 팩터리 클래스를 작성해 보겠습니다.

package com.journaldev.jdbc.datasource;

import java.io.FileInputStream;
import java.io.IOException;
import java.sql.SQLException;
import java.util.Properties;

import javax.sql.DataSource;

import oracle.jdbc.pool.OracleDataSource;

import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;

public class MyDataSourceFactory {

	public static DataSource getMySQLDataSource() {
		Properties props = new Properties();
		FileInputStream fis = null;
		MysqlDataSource mysqlDS = null;
		try {
			fis = new FileInputStream("db.properties");
			props.load(fis);
			mysqlDS = new MysqlDataSource();
			mysqlDS.setURL(props.getProperty("MYSQL_DB_URL"));
			mysqlDS.setUser(props.getProperty("MYSQL_DB_USERNAME"));
			mysqlDS.setPassword(props.getProperty("MYSQL_DB_PASSWORD"));
		} catch (IOException e) {
			e.printStackTrace();
		}
		return mysqlDS;
	}
	
	public static DataSource getOracleDataSource(){
		Properties props = new Properties();
		FileInputStream fis = null;
		OracleDataSource oracleDS = null;
		try {
			fis = new FileInputStream("db.properties");
			props.load(fis);
			oracleDS = new OracleDataSource();
			oracleDS.setURL(props.getProperty("ORACLE_DB_URL"));
			oracleDS.setUser(props.getProperty("ORACLE_DB_USERNAME"));
			oracleDS.setPassword(props.getProperty("ORACLE_DB_PASSWORD"));
		} catch (IOException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return oracleDS;
	}
		
}

Oracle과 MySQL DataSource 구현 클래스는 매우 유사합니다. 이러한 방법을 사용하고 일부 테스트를 실행하는 간단한 테스트 프로그램을 작성해 보겠습니다.

package com.journaldev.jdbc.datasource;

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

import javax.sql.DataSource;

public class DataSourceTest {

	public static void main(String[] args) {
		
		testDataSource("mysql");
		System.out.println("**********");
		testDataSource("oracle");

	}

	private static void testDataSource(String dbType) {
		DataSource ds = null;
		if("mysql".equals(dbType)){
			ds = MyDataSourceFactory.getMySQLDataSource();
		}else if("oracle".equals(dbType)){
			ds = MyDataSourceFactory.getOracleDataSource();
		}else{
			System.out.println("invalid db type");
			return;
		}
		
		Connection con = null;
		Statement stmt = null;
		ResultSet rs = null;
		try {
			con = ds.getConnection();
			stmt = con.createStatement();
			rs = stmt.executeQuery("select empid, name from Employee");
			while(rs.next()){
				System.out.println("Employee ID="+rs.getInt("empid")+", Name="+rs.getString("name"));
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}finally{
				try {
					if(rs != null) rs.close();
					if(stmt != null) stmt.close();
					if(con != null) con.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
		}
	}

}

클라이언트 클래스는 데이터베이스 특정 클래스와 완전히 독립적입니다. 이는 클라이언트 프로그램에서 기본 구현 세부 정보를 숨기고 느슨한 결합 및 추상화 이점을 얻는 데 도움이 됩니다. 위의 테스트 프로그램을 실행하면 아래와 같은 결과를 얻을 수 있습니다.

Employee ID=1, Name=Pankaj
Employee ID=2, Name=David
**********
Employee ID=10, Name=Pankaj
Employee ID=5, Name=Kumar
Employee ID=1, Name=Pankaj

아파치 커먼즈 DBCP 예제

위의 Java DataSource 팩토리 클래스를 보면 두 가지 주요 문제가 있습니다.

  1. MySQL 및 Oracle DataSource를 생성하는 팩토리 클래스 메서드는 각각의 드라이버 API와 긴밀하게 연결되어 있습니다. 향후 Oracle 데이터베이스에 대한 지원을 제거하거나 다른 데이터베이스 지원을 추가하려면 코드 변경이 필요합니다.
  2. MySQL 및 Oracle DataSource를 가져오는 대부분의 코드는 비슷하며 유일한 차이점은 우리가 사용하는 구현 클래스입니다.

Apache Commons DBCP API는 프로그램과 다른 JDBC 드라이버 간의 추상화 계층으로 작동하는 Java DataSource 구현을 제공하여 이러한 문제를 제거하는 데 도움이 됩니다. Apache DBCP 라이브러리는 Commons Pool 라이브러리에 의존하므로 둘 다 이미지에 표시된 대로 빌드 경로에 있는지 확인하십시오. 다음은 DataSource의 간단한 구현인 BasicDataSource를 사용하는 DataSource 팩토리 클래스입니다.

package com.journaldev.jdbc.datasource;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;

import javax.sql.DataSource;

import org.apache.commons.dbcp.BasicDataSource;

public class DBCPDataSourceFactory {

	public static DataSource getDataSource(String dbType){
		Properties props = new Properties();
		FileInputStream fis = null;
		BasicDataSource ds = new BasicDataSource();
		
		try {
			fis = new FileInputStream("db.properties");
			props.load(fis);
		}catch(IOException e){
			e.printStackTrace();
			return null;
		}
		if("mysql".equals(dbType)){
			ds.setDriverClassName(props.getProperty("MYSQL_DB_DRIVER_CLASS"));
            ds.setUrl(props.getProperty("MYSQL_DB_URL"));
            ds.setUsername(props.getProperty("MYSQL_DB_USERNAME"));
            ds.setPassword(props.getProperty("MYSQL_DB_PASSWORD"));
		}else if("oracle".equals(dbType)){
			ds.setDriverClassName(props.getProperty("ORACLE_DB_DRIVER_CLASS"));
            ds.setUrl(props.getProperty("ORACLE_DB_URL"));
            ds.setUsername(props.getProperty("ORACLE_DB_USERNAME"));
            ds.setPassword(props.getProperty("ORACLE_DB_PASSWORD"));
		}else{
			return null;
		}
		
		return ds;
	}
}

보시다시피 사용자 입력에 따라 MySQL 또는 Oracle DataSource가 생성됩니다. 애플리케이션에서 하나의 데이터베이스만 지원하는 경우 이러한 논리가 필요하지 않습니다. 속성을 변경하기만 하면 한 데이터베이스 서버에서 다른 데이터베이스 서버로 전환할 수 있습니다. Apache DBCP가 추상화를 제공하는 핵심 포인트는 setDriverClassName() 메소드입니다. 다음은 다른 유형의 연결을 얻기 위해 위의 공장 방법을 사용하는 클라이언트 프로그램입니다.

package com.journaldev.jdbc.datasource;

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

import javax.sql.DataSource;

public class ApacheCommonsDBCPTest {

	public static void main(String[] args) {
		testDBCPDataSource("mysql");
		System.out.println("**********");
		testDBCPDataSource("oracle");
	}

	private static void testDBCPDataSource(String dbType) {
		DataSource ds = DBCPDataSourceFactory.getDataSource(dbType);
		
		Connection con = null;
		Statement stmt = null;
		ResultSet rs = null;
		try {
			con = ds.getConnection();
			stmt = con.createStatement();
			rs = stmt.executeQuery("select empid, name from Employee");
			while(rs.next()){
				System.out.println("Employee ID="+rs.getInt("empid")+", Name="+rs.getString("name"));
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}finally{
				try {
					if(rs != null) rs.close();
					if(stmt != null) stmt.close();
					if(con != null) con.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
		}
	}

}

위의 프로그램을 실행하면 출력은 이전 프로그램과 동일합니다. Java JDBC DataSource 이상 사용법을 보면 일반 DriverManager로도 가능합니다. Java DataSource의 주요 이점은 컨텍스트 내에서 JNDI와 함께 사용될 때입니다. 간단한 구성으로 컨테이너 자체에서 유지 관리하는 데이터베이스 연결 풀을 만들 수 있습니다. Tomcat 및 JBoss와 같은 대부분의 서블릿 컨테이너는 자체 Java DataSource 구현을 제공하며 간단한 XML 기반 구성을 통해 이를 구성한 다음 JNDI 컨텍스트 조회를 사용하여 Java DataSource를 가져오고 작업하기만 하면 됩니다. 이는 애플리케이션 측에서 서버 측으로의 연결 풀링 및 관리를 처리하여 애플리케이션에 대한 비즈니스 로직을 작성하는 데 더 많은 시간을 제공함으로써 우리에게 도움이 됩니다. 다음 튜토리얼에서는 Tomcat Container에서 DataSource를 구성하고 Web Application에서 사용하는 방법에 대해 알아봅니다.