JiwonDev

#19 JDBC

by JiwonDev

# JDBC? (Java Database Connectivity)

Java ์ฝ”๋“œ์—์„œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ์ œ๊ณตํ•ด์ฃผ๋Š” API. ์ฐธ๊ณ ๋กœ JDBC๊ฐ€ ๋‚˜์˜ค๊ธฐ ์ด์ „์—๋Š” MS์ง„ํ˜• ( C์–ธ์–ด)์—์„œ ๋งŒ๋“  ODBC API (Open DB Connectivity)๋ฅผ ์ œ๊ณตํ–ˆ์—ˆ๋‹ค.

JDBC API๋ฅผ ์ด์šฉํ•ด ๋น„์Šทํ•œ ์ฝ”๋“œ๋กœ ๋‹ค์–‘ํ•œ ์ข…๋ฅ˜์˜ DB์™€ ์—ฐ๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค.

 


# JDBC์˜ ๊ธฐ๋Šฅ

์ฐธ๊ณ ๋กœ JDBC๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์—๋Š” ์—ฌ๋Ÿฌ๊ฐ€์ง€ ์œ ํ˜•์ด ์žˆ๊ธดํ•˜๋‚˜ [์œ ํ˜• 4] ์ด์™ธ ์ง์ ‘ ์‚ฌ์šฉํ•  ์ผ์€ ๊ฑฐ์˜ ์—†๋‹ค๊ณ  ๋ณด๋ฉด ๋œ๋‹ค.

  1. ์œ ํ˜• I : JDBC- ODBC ๋ธŒ๋ฆฌ์ง€ ( Java <-> JDBC <-> ODBC <-> DB)
  2. ์œ ํ˜• II : ๋„ค์ดํ‹ฐ๋ธŒ APT-๋ถ€๋ถ„์ ์œผ๋กœ Java ๋“œ๋ผ์ด๋ฒ„ ( ์œ ํ˜• 1์—์„œ ODBC๋ถ€๋ถ„์„ ๊ฐœ๋ฐœ์ž๊ฐ€ ์ฝ”๋“œ๋กœ ์ง์ ‘ ๊ตฌํ˜„)
  3. ์œ ํ˜• III : ๋„คํŠธ์›Œํฌ ํ”„๋กœํ† ์ฝœ-์™„์ „ Java ๋“œ๋ผ์ด๋ฒ„ ( ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ๋‹จ์—์„œ ์ž๋ฐ”๋กœ ๋„คํŠธ์›Œํฌ ์ง์ ‘ ๊ตฌํ˜„, ์ถ”์ฒœ X)
  4. ์œ ํ˜• IV : Thin Driver- Fully Java Driver ( DB ์—…์ฒด๋ณ„๋กœ JDBC ๋“œ๋ผ์ด๋ฒ„ ์ œ๊ณต )
    ํด๋ผ์ด์–ธํŠธ JVM์— ์ง์ ‘ ์„ค์น˜๋˜์–ด ๋ณ„๋„์˜ ์†Œํ”„ํŠธ์›จ์–ด๊ฐ€ ํ•„์š”์—†๊ณ , DB๊ณต๊ธ‰ ์—…์ฒด์—์„œ ์ง์ ‘ JDBC ๋“œ๋ผ์ด๋ฒ„ ๊ฐœ๋ฐœ.

์œ ํ˜•4. ์ž๋ฐ” ์•ฑ์˜ JDBC ์‚ฌ์šฉ๋ฐฉ๋ฒ•

 


# JDBC ์—ฐ๊ฒฐํ•˜๊ธฐ

# 1. Import ํŒจํ‚ค์ง€

JDBC API 4.0(2017๋…„) ๊ธฐ์ค€, java.sql ํŒจํ‚ค์ง€์™€ javax.sql(ํ™•์žฅ API, ์„œ๋ฒ„์ธก ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ๊ธฐ๋Šฅ ์ œ๊ณต) ํŒจํ‚ค์ง€๋ฅผ ์ œ๊ณตํ•œ๋‹ค. 


# 2. JDBC Driver ์—ฐ๊ฒฐ

Importํ•œ API๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์‚ฌ์šฉํ•˜๊ณ ์žํ•˜๋Š” JDBC ๋“œ๋ผ์ด๋ฒ„๋ฅผ ์ž๋ฐ” ์•ฑ์œผ๋กœ ๊ฐ€์ ธ์™€ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

  •  Class.forName()

Class.forName("JDBC ๋“œ๋ผ์ด๋ฒ„ ์ด๋ฆ„")

Class.forName(“sun.jdbc.odbc.JdbcOdbcDriver”); // MS-SQL ๋“œ๋ผ์ด๋ฒ„ ๋“ฑ๋ก
Class.forName(“postgresql.Driver”); // PostgreSQL ๋“œ๋ผ์ด๋ฒ„ ๋“ฑ๋ก
Class.forName(“oracle.jdbc.driver.OracleDriver”); // Oracle ๋“œ๋ผ์ด๋ฒ„ ๋“ฑ๋ก
๋”๋ณด๊ธฐ

* Java 1.6, JDBC 4.0 ์ดํ›„์˜ JDBC์—์„œ๋Š” ์„œ๋น„์Šค ๋กœ๋”(java.util.ServiceLoader) ๊ธฐ๋ฐ˜์œผ๋กœ JDBC Driver๊ฐ€ ์ž๋™์œผ๋กœ ๋“ฑ๋ก๋ฉ๋‹ˆ๋‹ค. ์ฆ‰ Class.forName("com.mysql.jdbc.Driver") ๋ฅ˜์˜ ์ฝ”๋“œ๋ฅผ ์ˆ˜๋™์œผ๋กœ ํ˜ธ์ถœํ•˜์ง€ ์•Š์•„๋„ ๋“ฑ๋ก๋ฉ๋‹ˆ๋‹ค.

// JDBC๋ฅผ ์—ฐ๊ฒฐํ•˜๋Š” ์ฝ”๋“œ ์˜ˆ์ œ
Class.forName("oracle.jdbc.driver.OracleDriver"); //java 1.6 ์ดํ›„์—์„œ๋Š” ์ƒ๋žตํ•ด๋„ ๋“ฑ๋ก๋จ.
conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:orcl", "scott", "tiger");
stmt = conn.createStatement();
String sql = "select * from tablename";
rs = stmt.executeQuery(sql);

 

  • Class.forName์˜ ๋™์ž‘

์šฐ์„ , 'Class' ๊ฐ์ฒด๋Š” JVM์—์„œ ๋™์ž‘ํ•  ํด๋ž˜์Šค์˜ ์ •๋ณด๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” Java์˜ Meta-Class๋ผ๊ณ  ์ƒ๊ฐํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. Class.forName("package.ClassName") ์€ ํ•ด๋‹น ๋ฌธ์ž์—ด์— ํ•ด๋‹นํ•˜๋Š” ํด๋ž˜์Šค ์ƒ์„ฑ ํ›„ ๋ฐ˜ํ™˜ํ•ด์ค๋‹ˆ๋‹ค. ์ฐธ๊ณ ๋กœ ๋ชจ๋“  JDBC ํŒจํ‚ค์ง€์˜ ๋‚ด๋ถ€๋Š” ์•„๋ž˜์™€ ๋น„์Šทํ•œ ๊ฐ™์€ ๊ตฌ์กฐ๋ฅผ ๊ฐ€์ง‘๋‹ˆ๋‹ค.

public class Driver extends NonRegisteringDriver implements java.sql.Driver {
    static { // static!!
        try {
        	// ์ƒˆ๋กœ์šด ๋“œ๋ผ์ด๋ฒ„๋ฅผ ๋“ฑ๋กํ•˜๋Š” ์ฝ”๋“œ
           java.sql.DriverManager.registerDriver(new Driver());
        } catch (SQLException E) {
            throw new RuntimeException("Can't register driver!");
        }
    }
    ...
}

์ฆ‰, ๋‚ด๋ถ€์ ์œผ๋กœ DriverManager.registerDriver(new Driver()); ๋ฅผ ์ด์šฉํ•˜์—ฌ ๋“œ๋ผ์ด๋ฒ„ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ์ƒ์„ฑํ•œ ๋“œ๋ผ์ด๋ฒ„ ๊ฐ์ฒด๋Š”, DriverManager.getConnection(~)์„ ์ด์šฉํ•˜์—ฌ ์ปค๋„ฅ์…˜์ด ์ƒ์„ฑ๋˜๋Š” ์‹œ์ ์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

pakage.SomeClass obj = new pakage.SomeClass(); ์œผ๋กœ ์‚ฌ์šฉํ•˜์ง€์•Š๊ณ  ๊ตณ์ด Class.forName()์„ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ ๋Š” static ๊ฐ์ฒด๋กœ ๊ด€๋ฆฌ๋˜์–ด์ง€๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๋งŒ์•ฝ new๋กœ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ด๋ฒ„๋ฆฌ๋ฉด JDBC ๋“œ๋ผ์ด๋ฒ„ ๊ฐ์ฒด๋Š” ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐ›๋Š” ์ฐธ์กฐ๋ณ€์ˆ˜๋„, ๋Œ€์ž…๋„ ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ์ฒด ์ฐธ์กฐ ์นด์šดํŠธ๊ฐ€ 0์ด ๋˜์–ด JVM์˜ GC์˜ ๋Œ€์ƒ์ด ๋ฉ๋‹ˆ๋‹ค.

// Class.forName() ๋ฉ”์„œ๋“œ ์ •์˜. static ๋ฉ”์„œ๋“œ์ด๋‹ค.
// ์ฆ‰, JDBC ๋“œ๋ผ์ด๋ฒ„ ์ƒ์„ฑ ๋ฉ”์„œ๋“œ๊ฐ€ ๋‹ค๋ฅธ ๊ฐ์ฒด๋ณด๋‹ค ๋จผ์ € ์ƒ์„ฑ๋œ๋‹ค. 
// java.sql.DriverManager.registerDriver(new Driver());

public static Class<?> forName(String className)
                        throws ClassNotFoundException

์ •์  ๋ฉ”์„œ๋“œ์ธ Class.forName(~)์„ ์‚ฌ์šฉํ•˜๋ฉด ํ•ด๋‹น ํด๋ž˜์Šค์˜ ์ •๋ณด๊ฐ€ static ๋ธ”๋Ÿญ์— ๊ด€๋ฆฌ๋˜์–ด GC์˜ ๋Œ€์ƒ์ด ๋˜์ง€์•Š๊ณ , ๋‹ค๋ฅธ ํด๋ž˜์Šค๋ณด๋‹ค ๋จผ์ € JVM ๋ฉ”๋ชจ๋ฆฌ์— ์ธ์Šคํ„ด์Šค์˜ ์ƒ์„ฑ๊ณผ ์ดˆ๊ธฐํ™”๊ฐ€ ์ด๋ฃจ์–ด์ง€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.


JDBC ๋“œ๋ผ์ด๋ฒ„์™€ ๊ด€๋ จ๋œ ๋ฐ”์ดํŠธ์ฝ”๋“œ(.class) ํŒŒ์ผ์„ ๋Ÿฐํƒ€์ž„์— ๊ฐ์ฒด๋กœ ์ƒ์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.  ์ฐธ๊ณ ๋กœ Class.forName() ๋‚ด๋ถ€์—์„œ DriverManager.registerDriver()๋ฅผ ํ˜ธ์ถœํ•จ์œผ๋กœ์จ JDBC ๋“œ๋ผ์ด๋ฒ„๋ฅผ ๋“ฑ๋กํ•˜๊ณ  ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.

DBMS ์ด๋ฆ„ JDBC ๋“œ๋ผ์ด๋ฒ„ ํŒจํ‚ค์ง€ ๊ฒฝ๋กœ(=์ด๋ฆ„)
MySQL com.mysql.jdbc.Driver
Oracle oracle.jdbc.driver.OracleDriver
MS SQL Server com.microsoft.sqlserver.jdbc.SQLServerDriver
MS Access net.ucanaccess.jdbc.UcanaccessDriver
PostgreSQL org.postgresql.Driver
IBM DB2 com.ibm.db2.jdbc.net.DB2Driver

  • DriverManager.registerDriver()

ํŠน์ • DB์˜ JDBC ๋“œ๋ผ์ด๋ฒ„๋ฅผ ๊ฐœ๋ฐœ์ž๊ฐ€ ์ง์ ‘ ๊ตฌํ˜„ํ•  ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค. Class.forName( " JDBC ํŒจํ‚ค์ง€ ์ด๋ฆ„ ") ์—์„œ, JDBC ํŒจํ‚ค์ง€ ๋‚ด๋ถ€์—์„œ ํ•ด๋‹น ๋ฉ”์„œ๋“œ๋ฅผ ์ด์šฉํ•ด ๋“œ๋ผ์ด๋ฒ„ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.

DriverManager.registerDrivers(new oracle.jdbc.driver.OracleDriver()); // Oracle ๋“œ๋ผ์ด๋ฒ„ ๋“ฑ๋ก

// DB ๋“œ๋ผ์ด๋ฒ„ ํŒจํ‚ค์ง€ ๋‚ด๋ถ€์—์„œ ์‚ฌ์šฉ๋œ๋‹ค.
// Class.forName("java.sql.Driver");
public class Driver extends NonRegisteringDriver implements java.sql.Driver {
    static {
        try {
           java.sql.DriverManager.registerDriver(new Driver());
        } catch (SQLException E) {
            throw new RuntimeException("Can't register driver!");
        }
    }
    ...
}

 


# 2. DB Connection ๋งŒ๋“ค๊ธฐ

๋งŒ๋“ค์–ด์ง„ ๋“œ๋ผ์ด๋ฒ„ ๊ฐ์ฒด๋ฅผ ์ด์šฉํ•ด ํ•ด๋‹น DB์™€ ์—ฐ๊ฒฐํ•œ๋‹ค. 

  • getConnection (URL, ์‚ฌ์šฉ์ž ์ด๋ฆ„, ์•”ํ˜ธ); – URL(*jdbDriver ๊ฒฝ๋กœ), ์‚ฌ์šฉ์ž ์ด๋ฆ„, ๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€ ์žˆ๋‹ค.
  • getConnection (URL); – URL(*jdbDriver ๊ฒฝ๋กœ)์—๋Š” ์‚ฌ์šฉ์ž ์ด๋ฆ„๊ณผ ๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€ ํฌํ•จ๋˜์–ด์•ผํ•œ๋‹ค.
DBMS Connection URL
MySQL jdbc : mysql : // HOST_NAME : PORT / DATABASE_NAME
Oracle jdbc : oracle : thin : @HOST_NAME : PORT : SERVICE_NAME
Ms SQL Server jdbc : sqlserver : // HOST_NAME : PORT; DatabaseName =
PostgreSQL jdbc : postgresql : // HOST_NAME : PORT / DATABASE_NAME
Class.forName("oracle.jdbc.driver.OracleDriver");

try { 
    // DriverManager.getConnection( jdbcDriver, dbUser, dbPassword)
    conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:orcl", "scott", "tiger");
	
    // ์—ฐ๊ฒฐ์— ์„ฑ๊ณตํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ์‚ฌ์šฉ๊ฐ€๋Šฅ.
    stmt = conn.createStatement();
    String sql = "select * from tablename";
    rs = stmt.executeQuery(sql);	

} catch ( SQLException ex ) {
    //  ์˜ˆ์™ธ์ฒ˜๋ฆฌ...
} finally {
    if (conn != null )
        try { conn.close()
        } catch ( SQLException ex ){}
}

 


# 3. (SQL) Statement ์ž‘์„ฑ & ์ฟผ๋ฆฌ ์‹คํ–‰

// ์ •์ ์ธ(๊ณ ์ •๋œ) ์ฟผ๋ฆฌ๋ฌธ์„ ์‹คํ–‰ ํ•  ๊ฒฝ์šฐ
Statement stmt = null; // Statement ๊ฐ์ฒด ์ƒ์„ฑ
String sql = "select * from test";
stmt = conn.createStatement(sql);


// ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์ž…๋ ฅ ๋ฐ›์•„ ๋™์ ์ธ ์ฟผ๋ฆฌ๋ฌธ์„ ์‹คํ–‰ํ•  ๊ฒฝ์šฐ
PreparedStatement pstmt = null; // PreparedStatement ๊ฐ์ฒด ์ƒ์„ฑ
String sql = "INSERT INTO test VALUES (?,?)";
pstmt = conn.prepareStatement(sql);

// ํŒŒ๋ผ๋ฉ”ํƒ€ ์ž…๋ ฅ (3,"LEE")
pstmt.setInt(1,3);
pstmt.setString(2, "LEE");
//insert, update, delete๋“ฑ ๋ฆฌํ„ด ๊ฐ’์ด ํ•„์š” ์—†๋Š” ์ฟผ๋ฆฌ๋ฌธ์ผ ๋•Œ ์‚ฌ์šฉ
pstmt.executeUpdate(SQL);
stmt.executeUpdate(SQL);
  
  
// select๋“ฑ ๋ฆฌํ„ด ๊ฐ’์ด ํ•„์š”ํ•œ ์ฟผ๋ฆฌ๋ฌธ์ผ ๋•Œ ์‚ฌ์šฉ
ResultSEt rs = null;
rs = pstmt.executeQuery(SQL);
rs = stmt.executeQuery(SQL);

// ๋ฐ›์•„์˜จ ResultSet์€ iter์ฒ˜๋Ÿผ ์‚ฌ์šฉ๊ฐ€๋Šฅ.
while(rs.next()){
    String name = rs.getString("name");
}

rs.next()


# 4. Close Connection

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ปค๋„ฅ์…˜์„ ์ƒ์„ฑํ•œ ์—ญ์ˆœ์œผ๋กœ ๋ฐ˜๋‚ฉ. ๋ณดํ†ต finally ๋ธ”๋Ÿญ object.close() ํ˜•์‹์œผ๋กœ ์‚ฌ์šฉ๋œ๋‹ค.

์ฐธ๊ณ ๋กœ Java7(1.7)๋ถ€ํ„ฐ ์ œ๊ณต๋˜๋Š” Try-with-Resource ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•˜๋ฉด close๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ ๋„ ์‰ฝ๊ฒŒ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค. ์ฐธ๊ณ ๋กœ Java9 ๋ถ€ํ„ฐ๋Š” Try-with-Resource๋ฌธ์—์„œ ๋ฐ–์—์„œ ์„ ์–ธ๋œ ๊ฐ์ฒด๋ฅผ ๊ฐ€์ ธ์™€๋„ ๋™์ผํ•˜๊ฒŒ ๊ด€๋ฆฌํ•ด์ค€๋‹ค.

Try-with-Resource ์— ๋Œ€ํ•˜์—ฌ 

 

#7 Exception (์˜ˆ์™ธ์ฒ˜๋ฆฌ)

์ž๋ฐ”์—์„œ์˜ ์˜ค๋ฅ˜, ์˜ˆ์™ธ ์ž๋ฐ”์—์„œ ์˜ˆ์™ธ, ์˜ค๋ฅ˜๋Š” java.lang.Throwable ํด๋ž˜์Šค๋ฅผ ์ƒ์†๋ฐ›์œผ๋ฉฐ ๊ตฌํ˜„ํ•˜๋ฉฐ 3๊ฐ€์ง€ ์ข…๋ฅ˜๋กœ ๋‚˜๋‰œ๋‹ค. Error ์ž๋ฐ” ํ”„๋กœ๊ทธ๋žจ ๋ฐ–์—์„œ ๋ฐœ์ƒํ•œ ์˜ˆ์™ธ. ํ”„๋กœ์„ธ์Šค์— ์˜ํ–ฅ, ๋” ์ด์ƒ ์‹คํ–‰ ๋ถˆ๊ฐ€

jiwondev.tistory.com

conn.close() // dbDriver ์ปค๋„ฅ์…˜
pstmt.close() // ์ฟผ๋ฆฌ๋ฌธ
stmt.close();
public class Class1 {
    public method1() throws Exception {
      Connection conn = DriverManager.getConnection("...");
      Statement stat = conn.createStatement();
      ResultSet rs = stat.executeQuery("SELECT 1 from dual")
		
      // Java9 ๋ถ€ํ„ฐ๋Š” ์ด๋Ÿฐ ์‹์œผ๋กœ ๋ฐ–์—์„œ ์„ ์–ธ๋œ ๊ฐ์ฒด๋ฅผ ๊ฐ€์ ธ์™€ ์‚ฌ์šฉํ•  ์ˆ˜๋„์žˆ๋‹ค.
      try (conn; stat; rs) {
          // ...
      } catch (Exception e) {
          // ...
      } 
    }
}
Connection connection=dataSource.getConnection();
        // Java7 ๋ถ€ํ„ฐ ์ง€์›๋˜๋Š” try(์ž์›) ๊ด€๋ฆฌ ๊ธฐ๋Šฅ.
        // finally๋กœ ๋”ฐ๋กœ close ํ•ด์ค„ ํ•„์š”๊ฐ€ ์—†๋‹ค.
        try(connection){
            connection.setAutoCommit(false);
            //execute some SQL statements...
            connection.commit(); 
        }catch(SQLException e){
            connection.rollback();
}

* ํ•ด๋‹น ์˜ˆ์ œ์—์„œ ๋‚˜์˜ค๋Š” ํŠธ๋žœ์žญ์…˜ ์ฒ˜๋ฆฌ๋Š” ๋‹ค์Œ ๊ธ€( JDBC ํŠธ๋žœ์žญ์…˜ )์—์„œ ๋”ฐ๋กœ ๋‹ค๋ฃฐ ์˜ˆ์ •์ด๋‹ค.

 


# ์‹ค์ œ ์‚ฌ์šฉ ์˜ˆ์ œ

  • ๋ฐ์ดํ„ฐ ์ฝ์–ด์˜ค๊ธฐ (๊ณ ์ „์ ์ธ ๋ฐฉ๋ฒ•)
package test;

// JDBC API import
import java.sql.*;
import org.apache.log4j.Logger;

public class dbconn {
    // ์‹ค์ œ DB ์ ‘๊ทผ ์ฝ”๋“œ์—์„œ user์™€ pw์€ ์•”ํ˜ธํ™”ํ•ด์„œ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•œ๋‹ค.
    // ํ•ด๋‹น ์ฝ”๋“œ๊ฐ€ ํผ์ง€๊ฑฐ๋‚˜ ํ•ดํ‚น๋‹นํ•˜๋”๋ผ๋„ ์ถ”๊ฐ€์ ์ธ ํ”ผํ•ด๋ฅผ ๋ง‰์„ ์ˆ˜ ์žˆ๋‹ค.
    static Logger logger = Logger.getLogger(dbconn.class); // logging
    static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
    static final String DB_URL = "jdbc:mysql://192.168.0.143:3306/test";
    static final String USERNAME = "root";
    static final String PASSWORD = "1234";

    public static void main(String[] args) throws SQLException {
        Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;

        try {
            Class.forName(JDBC_DRIVER);
            conn = DriverManager.getConnection(DB_URL, USERNAME, PASSWORD);
            stmt = conn.createStatement();

            String sql1 = "select * from test";
            rs = stmt.executeQuery(sql1);

            while (rs.next()) {
                String no = rs.getString("no");
                String name = rs.getString("name");
                System.out.println("no = " + no + " , " + "name = " + name);
            }

        } catch (SQLException se1) {
            // SQL ๊ด€๋ จ ์˜ˆ์™ธ์ฒ˜๋ฆฌ

        } catch (Exception ex) {
            // ๊ทธ ์™ธ์˜ ์˜ˆ์™ธ์ฒ˜๋ฆฌ

        } finally {
            // ์‚ฌ์šฉ์„ ์™„๋ฃŒํ•œ ๊ฐ์ฒด๋“ค์€ .close()๋กœ ๋ฐ˜ํ™˜.
            rs.close();
            stmt.close();
            conn.close();
        }
    }
}

 

  • ๋ฐ์ดํ„ฐ ์ž…๋ ฅํ•˜๊ธฐ (Try-with-resource)
package test;

import java.sql.*;

public class dbpstmt {
    static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
    static final String DB_URL = "jdbc:mysql://192.168.0.143:3306/test";
    static final String USERNAME = "root";
    static final String PASSWORD = "1234";

    public static void main(String[] args) throws SQLException {
        Connection conn = null;
        PreparedStatement pstmt = null;
		
        // Try-with-Resource
        try(
            Class.forName(JDBC_DRIVER);
            conn = DriverManager.getConnection(DB_URL, USERNAME, PASSWORD);
            pstmt = conn.prepareStatement("INSERT INTO test VALUES (?,?)");
        ){
            String sql = "INSERT INTO test VALUES (?,?)";
            Class.forName(JDBC_DRIVER);

            conn = DriverManager.getConnection(DB_URL, USERNAME, PASSWORD);
            pstmt = conn.prepareStatement(sql);
            pstmt.setInt(1, 3);
            pstmt.setString(2, "LEE");

            pstmt.executeUpdate();

        } catch (SQLException e) {
            // ์˜ˆ์™ธ์ฒ˜๋ฆฌ
        } catch (Exception e) {
            // ์˜ˆ์™ธ์ฒ˜๋ฆฌ
        }
    }
}

# ์ปค๋„ฅ์…˜ ํ’€ (DataBase Connection Pool)

๋ฉ€ํ‹ฐ ์“ฐ๋ ˆ๋“œ์˜ ์“ฐ๋ ˆ๋“œ ํ’€์ฒ˜๋Ÿผ, DB์™€ ์—ฐ๊ฒฐํ•˜๋Š” ์ปค๋„ฅ์…˜์„ ๋ฏธ๋ฆฌ ์ƒ์„ฑํ•ด๋‘๊ณ  ํ•„์š”ํ•  ๋•Œ ๊บผ๋‚ด ์“ฐ๋Š” ๊ธฐ๋ฒ•์„ ๋งํ•œ๋‹ค. ์ปค๋„ฅ์…˜ ํ’€์˜ ์˜คํ”ˆ์†Œ์Šค์—๋Š” ๋Œ€ํ‘œ์ ์œผ๋กœ DBCP ์™€ C3P0๊ฐ€ ์žˆ๋Š”๋ฐ, ์—ฌ๊ธฐ์—์„œ๋Š” DBCP์— ๋Œ€ํ•ด์„œ ๋‹ค๋ฃจ๊ณ ์ž ํ•œ๋‹ค.

JDBC๋ฅผ ์ด์šฉํ•ด DB์— ์ ‘๊ทผํ•˜๋Š” ๊ณผ์ •์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์š”์•ฝ ๊ฐ€๋Šฅํ•˜๋‹ค.

  1. DB ์ ‘์†์„ ์œ„ํ•œ JDBC ๋“œ๋ผ์ด๋ฒ„ ๋กœ๋“œ
  2. getConnection Method๋กœ ๋ถ€ํ„ฐ DB ์ปค๋„ฅ์…˜ ๊ฐ์ฒด๋ฅผ ์–ป์Œ
  3. ์ฟผ๋ฆฌ ์ˆ˜ํ–‰์„ ์œ„ํ•œ PreparedStatement, Statement ๊ฐ์ฒด ์ƒ์„ฑ
  4. excuteQuery๋ฅผ ์‹คํ–‰ํ•ด์„œ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ›์•„์˜ด.
  5. ์ฒ˜๋ฆฌ๊ฐ€ ์™„๋ฃŒ๋˜๋ฉด ๋ฆฌ์†Œ์Šค๋“ค์„ closeํ•˜์—ฌ ๋ฐ˜ํ™˜ (๋˜๋Š” try-with-resoucre๋ฌธ ์‚ฌ์šฉ์œผ๋กœ ํ•ด๋‹น ๊ณผ์ • ์ƒ๋žต)

Java์—์„œ DB์— ์ ‘๊ทผํ•  ๋•Œ๋งˆ๋‹ค Driver๋ฅผ ๋กœ๋“œํ•˜๊ณ , ์ปค๋„ฅ์…˜ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์€ ์ƒ๋‹นํžˆ ๋น„ํšจ์œจ์ ์ธ ์ž‘์—…์ด๋‹ค. ๊ทธ๋ž˜์„œ WAS๋“ฑ์„ ์‚ฌ์šฉํ•  ๋•Œ ๋ฏธ๋ฆฌ ์ผ์ •๋Ÿ‰์˜ DB Connection ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์ด๋ฅผ ํ• ๋‹น๋ฐ›๋Š” ๋ฐฉ๋ฒ•(Connection Pool)์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋งŒ๋“ค์–ด์ค€๋‹ค.

 

์ปค๋„ฅ์…˜ ํ’€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ๋Š” ๋ฌด๋ฃŒ์ธ DBCP๊ฐ€ ๋งŽ์ด ์‚ฌ์šฉ๋˜์—ˆ๊ณ , ์ตœ๊ทผ(2021)์— ์‚ฌ์šฉ๋˜๋Š” ์Šคํ”„๋ง ๋ถ€ํŠธ 2.0๋ถ€ํ„ฐ๋Š” HikariCP ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๊ณ  ํ•œ๋‹ค.

๋”๋ณด๊ธฐ

HikariCP

HikariCP๋Š” ์Šคํ”„๋ง ๋ถ€ํŠธ 2.0๋ถ€ํ„ฐ ์„ค์ •๋œ default JDBC Connection Pool์ž…๋‹ˆ๋‹ค.๊ธฐ์กด์˜ DBCP๋“ค ๋ณด๋‹ค ๋น ๋ฅด๊ฒŒ ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•˜๊ณ  ๊ฐ€๋ณ์Šต๋‹ˆ๋‹ค.๋งŽ์€ Connection pool ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค์€ PreparedStatement caching์„ ์ง€์›ํ•˜์ง€๋งŒ HikariCP๋Š” ์ง€์›ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ฆ‰ HikariCP ๋Š” Statement Cache ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

 

 

  • ๋Œ€๋ถ€๋ถ„์˜ JDBC ๋“œ๋ผ์ด๋ฒ„๋“ค์€ Statement cache ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. (ex. Oracle, MySQL, DB2)
  • ์ด๋Ÿฐ ๋“œ๋ผ์ด๋ฒ„๋“ค์˜ ํŠน์ง• ์ค‘ ํ•˜๋‚˜๋Š” ์‹คํ–‰ ๊ณ„ํš์„ ์ปค๋„ฅ์…˜ ๊ฐ„ ๊ณต์œ ํ•˜๋Š” ๊ธฐ๋Šฅ์ด ์žˆ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

 

  • Connection Pool Layer์—์„œ PreparedStatement Caching ์€ connection ํ•˜๋‚˜๋‹น ์บ์‹œ๊ฐ€ ์ด๋ฃจ์–ด์ง‘๋‹ˆ๋‹ค.
  • ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์ด 100๊ฐœ์˜ ์‹คํ–‰๋œ ์ฟผ๋ฆฌ์™€ 10๊ฐœ์˜ connection pool ์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค๋ฉด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋Š” 1000๊ฐœ์˜ ์‹คํ–‰ ๊ณ„ํš์„ holding ํ•˜๊ณ  ์žˆ๋Š” ์…ˆ์ด์ฃ .
  • ์ด ์ปค๋„ฅ์…˜ํ’€์€ ์‹คํ–‰๊ณ„ํš๊ณผ ํ•จ๊ป˜ preparedStatement๋„ ๋งŽ์ด caching ๋˜์–ด ์žˆ๋Š” ์ƒํƒœ์ž…๋‹ˆ๋‹ค.
  • ์œ„์—์„œ ์• ๊ธฐํ•œ 1000๊ฐœ์˜ ์‹คํ–‰ ๊ณ„ํš์„ ์ปค๋„ฅ์…˜ํ’€์—์„œ hoding ํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋‚ด์— 100๊ฐœ์˜ ์ฟผ๋ฆฌ๋ฅผ ์บ์‹ฑํ•˜๋Š” ๊ฒƒ์ด ๋‚ซ๋‹ค๋Š” ๊ฒƒ์ด Statement Cache๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ์ด์œ ์ž…๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒํ•˜๋ฉด ์„ฑ๋Šฅ์„ ํ–ฅ์ƒ ์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 

HikariCP๋Š” ์ด์ฒ˜๋Ÿผ Statement ์บ์‹ฑ์„ Connection Pool์— ์„ค์ •ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹Œ Driver์— ์„ค์ •ํ•œ๋‹ค๋Š” ํŠน์ง•์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์‹ค์ œ ์ด ๋ฐฉ์‹์„ ์ด์šฉํ•˜์—ฌ ๋‹ค๋ฅธ DBCP๋ณด๋‹ค ๋ฒค์น˜๋งˆํ‚น์ƒ ๋” ๋‚˜์€ ์„ฑ๋Šฅ์„ ๋ณด์—ฌ์ฃผ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

 

์ถœ์ฒ˜: github.com/brettwooldridge/HikariCP (HikariCP ๊ฐœ๋ฐœ์ž์˜ ๊นƒํ—ˆ๋ธŒ)

 

์ฐธ๊ณ ๋กœ HikariCP๋ง๊ณ  ์‚ฌ์šฉ๋˜๋˜ DBCP๋“ค์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.
- C3P0 (๊ณผ๊ฑฐ ํ•˜์ด๋ฒ„๋„ค์ดํŠธ์—์„œ ์ถ”์ฒœ, ์„ฑ๋Šฅ์ด ํƒ€ CP์— ๋น„ํ•ด์„œ ๋ณ„๋กœ)
- DBCP (์•„ํŒŒ์น˜์—์„œ ๊ด€๋ฆฌ, C3P0๋ณด๋‹ค ์„ฑ๋Šฅ์ด ์ข‹์Œ)
- proxool (์ •๋ง ์ข‹์•˜์ง€๋งŒ 2008๋…„์ดํ›„ ์—…๋ฐ์ดํŠธ๊ฐ€ ์—†์Œ)
- Bone CP (JDBC, C3P0์˜ ๋Š๋ฆผ์ด ์‹ซ์–ด์„œ ๋น ๋ฆ„์„ ์ปจ์…‰์œผ๋กœ ๊ฐœ๋ฐœ, JDBC CP๊ธฐ๋ฐ˜)
- HikariCP (Bone CP๋ณด๋‹ค ๋น ๋ฆ„. ํ˜„์žฌ Spring์—์„œ ๋ฐ€๊ณ ์žˆ๋Š” CP)


# Commons DBCP (= Apache DBCP)

๋Œ€ํ‘œ์ ์ธ ์ปค๋„ฅ์…˜ ํ’€ ์˜คํ”ˆ์†Œ์Šค ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๋‹ค. ํ˜„์žฌ DBCP๋Š” ์•„ํŒŒ์น˜ ์‚ฌ์ดํŠธ์—์„œ JAR ํŒŒ์ผ์„ ๋‹ค์šด ๋ฐ›์„ ์ˆ˜ ์žˆ๋Š”๋ฐ, DBCP ๋‚ด๋ถ€์—์„œ ์‚ฌ์šฉํ•œ Pool์ธ  Commons Pool ๊ณผ ๋กœ๊ทธ๊ธฐ๋ก์— ์‚ฌ์šฉ๋˜๋Š” Commons Logging์„ ํ•จ๊ป˜ ๋ฐ›์•„์•ผ ์‚ฌ์šฉ ํ•  ์ˆ˜ ์žˆ๋‹ค.

Commons DBCP2 : http://commons.apache.org/proper/commons-dbcp/

Commons Pool2 : http://commons.apache.org/proper/commons-pool/

Commons Logging : http://commons.apache.org/proper/commons-logging/

JSP์—์„œ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ์‚ฌ์ดํŠธ์—์„œ ํ•„์š”ํ•œ JARํŒŒ์ผ๋“ค์„ ๋‹ค์šด๋ฐ›์•„ WEB-INF/lib ๋””๋ ‰ํ† ๋ฆฌ์— ๋ณต์‚ฌํ•˜๋ฉด ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๋‹ค. ๋‹ค์šด๋กœ๋“œํ•œ DBCP๋Š” ์„œ๋ธ”๋ฆฟ์œผ๋กœ ์ดˆ๊ธฐํ™”ํ•˜๊ณ  ๋‚œ ๋’ค, ์ปค๋„ฅ์…˜ ๊ฐ์ฒด๋ฅผ [DBCP ์ปค๋„ฅ์…˜ ํ’€]์—์„œ ๋ฐ›์•„์™€ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

 

# web.xml์—์„œ DBCP ์ดˆ๊ธฐํ™” ์„œ๋ธ”๋ฆฟ ๋“ฑ๋ก.

<load-on-stratup> ํƒœ๊ทธ๋ฅผ ์ด์šฉํ•ด ์•ฑ์ด ์‹คํ–‰๋  ๋•Œ ํ•ด๋‹น ์„œ๋ธ”๋ฆฟ์ด ๋™์ž‘ํ•˜๋„๋ก ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

    <servlet>
        <servlet-name>DBCPInit</servlet-name>
        <servlet-class>jdbc.DBCPInit</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

 

# ์ปค๋„ฅ์…˜ ํ’€์—์„œ ์ปค๋„ฅ์…˜์„ ๊ฐ€์ ธ์˜ค๋Š” ๋ฐฉ๋ฒ•

web.xml์— DBCP ์ดˆ๊ธฐํ™” ์„œ๋ธ”๋ฆฟ์„ ๋“ฑ๋กํ–ˆ๋‹ค๋ฉด, ๋‹ค์Œ๊ณผ ์ปค๋„ฅ์…˜์„ ๊ฐ€์ ธ์™€ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

String jdbcDriver = "jdbc:apache:commons:dbcp:cp";
...
conn = DriverManager.getConnection(jdbcDriver);

 

# DBCP ์ดˆ๊ธฐํ™” ์„œ๋ธ”๋ฆฟ (DBCPInit.java)

์ฐธ๊ณ ๋กœ ํ•ด๋‹น ์„œ๋ธ”๋ฆฟ์—์„œ DBCP์˜ ์„ค์ •๊ฐ’์„ ์ง€์ •ํ•ด์ค„ ์ˆ˜ ์žˆ๋‹ค.

package jdbc;

import java.sql.DriverManager;
import java.util.Properties;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;

import org.apache.commons.dbcp2.ConnectionFactory;
import org.apache.commons.dbcp2.DriverManagerConnectionFactory;
import org.apache.commons.dbcp2.PoolableConnection;
import org.apache.commons.dbcp2.PoolableConnectionFactory;
import org.apache.commons.dbcp2.PoolingDriver;
import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;

public class DBCPInit extends HttpServlet {

    @Override
    public void init() throws ServletException {
            loadJDBCDriver();
            initConnectionPool();
    }
    private void loadJDBCDriver() {
        try {
            //์ปค๋„ฅ์…˜ ํ’€์—์„œ ์‚ฌ์šฉํ•  jdbc ๋“œ๋ผ์ด๋ฒ„๋ฅผ ๋กœ๋”ฉ
            Class.forName("com.mysql.jdbc.Driver");
        } catch (ClassNotFoundException ex) {
            throw new RuntimeException("fail to load JDBC Driver", ex);
        }
    }
    private void initConnectionPool() {
        try {
            String jdbcUrl = "jdbc:mysql://localhost:3306/chap14?" + "useUnicode=true&characterEncoding=utf8";
            String username = "phs1116";
            String pw = "1234";
            
            //์ปค๋„ฅ์…˜ํŒฉํ† ๋ฆฌ ์ƒ์„ฑ. ์ปค๋„ฅ์…˜ ํŒฉํ† ๋ฆฌ๋Š” ์ƒˆ๋กœ์šด ์ปค๋„ฅ์…˜์„ ์ƒ์„ฑํ• ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.
            ConnectionFactory connFactory = new DriverManagerConnectionFactory(jdbcUrl, username, pw);
            
            //DBCP๊ฐ€ ์ปค๋„ฅ์…˜ ํ’€์— ์ปค๋„ฅ์…˜์„ ๋ณด๊ด€ํ• ๋•Œ ์‚ฌ์šฉํ•˜๋Š” PoolableConnectionFactory ์ƒ์„ฑ
            //์‹ค์ œ๋กœ ๋‚ด๋ถ€์ ์œผ๋กœ ์ปค๋„ฅ์…˜์„ ๋‹ด๊ณ ์žˆ๊ณ  ์ปค๋„ฅ์…˜์„ ๊ด€๋ฆฌํ•˜๋Š”๋ฐ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•œ๋‹ค. ex)์ปค๋„ฅ์…˜์„ closeํ•˜๋ฉด ์ข…๋ฃŒํ•˜์ง€ ์•Š๊ณ  ์ปค๋„ฅ์…˜ ํ’€์— ๋ฐ˜ํ™˜
            PoolableConnectionFactory poolableConnFactory = new PoolableConnectionFactory(connFactory, null);
            //์ปค๋„ฅ์…˜์ด ์œ ํšจํ•œ์ง€ ํ™•์ธํ• ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ์ฟผ๋ฆฌ๋ฅผ ์„ค์ •ํ•œ๋‹ค.
            poolableConnFactory.setValidationQuery("select 1");
            
            
            //์ปค๋„ฅ์…˜ ํ’€์˜ ์„ค์ • ์ •๋ณด๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.
            GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
            //์œ ํœด ์ปค๋„ฅ์…˜ ๊ฒ€์‚ฌ ์ฃผ๊ธฐ
            poolConfig.setTimeBetweenEvictionRunsMillis(1000L * 60L * 1L);
            //ํ’€์— ์žˆ๋Š” ์ปค๋„ฅ์…˜์ด ์œ ํšจํ•œ์ง€ ๊ฒ€์‚ฌ ์œ ๋ฌด ์„ค์ •
            poolConfig.setTestWhileIdle(true);
            //์ปค๋„ฅ์…˜ ์ตœ์†Œ๊ฐฏ์ˆ˜ ์„ค์ •
            poolConfig.setMinIdle(4);
            //์ปค๋„ฅ์…˜ ์ตœ๋Œ€ ๊ฐฏ์ˆ˜ ์„ค์ •
            poolConfig.setMaxTotal(50);

            //์ปค๋„ฅ์…˜ ํ’€ ์ƒ์„ฑ. ์ธ์ž๋กœ๋Š” ์œ„์—์„œ ์ƒ์„ฑํ•œ  PoolabeConnectionFactory์™€ GenericObjectPoolConfig๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.
            GenericObjectPool<PoolableConnection> connectionPool = new GenericObjectPool<>(poolableConnFactory,
                    poolConfig);
            
            //PoolabeConnectionFactory์—๋„ ์ปค๋„ฅ์…˜ ํ’€์„ ์—ฐ๊ฒฐ
            poolableConnFactory.setPool(connectionPool);
            
            //์ปค๋„ฅ์…˜ ํ’€์„ ์ œ๊ณตํ•˜๋Š” jdbc ๋“œ๋ผ์ด๋ฒ„๋ฅผ ๋“ฑ๋ก.
            Class.forName("org.apache.commons.dbcp2.PoolingDriver");
            
 
            PoolingDriver driver = (PoolingDriver) DriverManager.getDriver("jdbc:apache:commons:dbcp:");
            //์œ„์—์„œ ์ปค๋„ฅ์…˜ ํ’€ ๋“œ๋ผ์ด๋ฒ„์— ์ƒ์„ฑํ•œ ์ปค๋„ฅ์…˜ ํ’€์„ ๋“ฑ๋ฃํ•œ๋‹ค. ์ด๋ฆ„์€ cp์ด๋‹ค.
            driver.registerPool("cp", connectionPool);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

 


# Tomcat DBCP ์ด์šฉํ•˜๊ธฐ

๋”ฐ๋กœ ๋‹ค์šด๋กœ๋“œ ๋ฐ›์ง€์•Š๊ณ  Tomcat WAS์— ๋‚ด์žฅ๋œ Tomcat DBCP๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค. 

ํ†ฐ์บฃ์„ ์„ค์น˜ํ–ˆ๋‹ค๋ฉด $CATALINA_HOME/lib/tomcat-dbcp.jar ๊ฒฝ๋กœ์— ํ•ด๋‹น DBCP๊ฐ€ ํ•จ๊ป˜ ์„ค์น˜๋˜์žˆ๋‹ค.

 

1. Tomcat/conf/server.xml ์— ์žˆ๋Š” GlobalNamingResources ํƒœ๊ทธ ์‚ฌ์ด์— DBCP ์ •๋ณด๋ฅผ ์ ๋Š”๋‹ค.

ํ•ด๋‹น ์˜ˆ์ œ๋Š” ์˜ค๋ผํด์„ ์‚ฌ์šฉํ•ด์„œ driverClassName = "oracle.jdbc.driver.OracleDriver" ๋ผ๊ณ  ์„ค์ •ํ•ด์ฃผ์—ˆ๋‹ค. ๋‚˜๋จธ์ง€๋Š” DBCP ์„ค์ • ๊ฐ’์ด๋‹ค. maxIdle์€ ํ‰์ƒ์‹œ์— ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ์ปค๋„ฅ์…˜ ๊ฐ์ฒด ์ˆ˜, maxTotal ์€ ์ตœ๋Œ€ ์ˆ˜๋ฅผ ์˜๋ฏธํ•œ๋‹ค.

Tomcat/conf/server.xml

<GlobalNamingResources>
	<!-- Editable user database that can also be used by UserDatabaseRealm 
			to authenticate users -->
           
        <!-- My DBCP Setting ========================= -->
	<Resource auth="Container"
		driverClassName="oracle.jdbc.driver.OracleDriver" maxIdle="10"
		maxTotal="20" maxWaitMillis="-1" name="jdbc/myshop" password="tiger"
		type="javax.sql.DataSource" url="jdbc:oracle:thin:@127.0.0.1:1521:XE"
		username="myshop" />
	<!-- ========================================= -->
</GlobalNamingResources>

2. ๊ทธ๋ฆฌ๊ณ  context.xml์— ์œ„์—์„œ ์ง€์ •ํ•œ DBCP์˜ ์ด๋ฆ„์„ ๋“ฑ๋กํ•ด์ค€๋‹ค.

Tomcat/conf/context.xml

<!-- MyDBCP Setting =================================== -->
	<ResourceLink global="jdbc/myshop" name="jdbc/myshop" type="org.apache.tomcat.dbcp.dbcp2.BasicDataSource"/>
<!-- ================================================== -->

3. ์ดํ›„ WEB-INF/web.xml์— DBCP ์„ธํŒ…์„ ํ•ด์ฃผ๋ฉด ํ†ฐ์บฃ์— ๋‚ด์žฅ๋œ DBCP๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

<web-app>
	<!-- My DBCP Setting ================================== -->
  	<resource-ref>
 		<description>Oracle Datasource example</description>
 		<res-ref-name>jdbc/myshop</res-ref-name>
 		<res-type>javax.sql.DataSource</res-type>
 		<res-auth>Container</res-auth>
  	</resource-ref>
 	<!-- ================================================== -->
</web-app>

 

4. ์ดํ›„ ์•„๋ž˜์™€ ๊ฐ™์ด ์ž๋ฐ”์ฝ”๋“œ์—์„œ DBCP ์ปค๋„ฅ์…˜์„ ๋ฐ›์•„์˜ฌ ์ˆ˜ ์žˆ๋‹ค.

Context initContext = new InitialContext(); 
// Initialcontext ์ƒ์„ฑ -> ์ด๋ฆ„์œผ๋กœ ๊ฐ์ฒด ์ฐพ์„ ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ค€๋‹ค.

Context envContext  = (Context)initContext.lookup("java:/comp/env"); 
// ํ†ฐ์บฃ(์„œ๋ฒ„)์„ ๋จผ์ € ์ฐพ๋Š”๋‹ค.
// ํ†ฐ์บฃ์„ ์ฐพ์„ ๋•Œ๋Š” java:comp/env ๋กœ ์ฐพ๋Š”๋‹ค.

DataSource ds = (DataSource)envContext.lookup("jdbc/myshop"); 
// server.xml์— ๋“ฑ๋กํ–ˆ๋˜ ์ด๋ฆ„ myshop์„ ์ฐพ๋Š”๋‹ค.(ํƒ€์ž…์€ DataSource ํƒ€์ž…)
// ์ฐธ๊ณ ๋กœ ์ด๋ ‡๊ฒŒ ์ด๋ฆ„์œผ๋กœ ๊ฐ์ฒด๋ฅผ ์ฐพ๋Š” ๋ฐฉ์‹์„ JNDI(Java Naming Directory Interface)๋ผ ํ•œ๋‹ค.

Connection conn = ds.getConnection();

System.out.println("<h1>๋ฐ์ดํ„ฐ ์†Œ์Šค ๋ฃฉ์—… ์„ฑ๊ณต: "+ds +"</h1>");
System.out.println("<h2> con="+ conn + "</h2>");
	
if(conn!=null) conn.close();
// ์ปค๋„ฅ์…˜ ์—ฐ๊ฒฐ์„ ๋Š๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์ปค๋„ฅ์…˜ํ’€์— ์ž๋™์œผ๋กœ ๋ฐ˜๋‚ฉ์„ ํ•œ๋‹ค.

 

'๐ŸŒฑBackend > Java' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

#21 Servlet Context Listener  (0) 2021.07.21
#20 JDBC ํŠธ๋žœ์žญ์…˜ (Spring -@Transaction)  (0) 2021.07.21
#18 JSP Model1, Model2 (MVC)  (0) 2021.07.18
#17 Servlet Filter  (0) 2021.07.18
#16 Servlet ์ดํ•ด  (1) 2021.07.18

๋ธ”๋กœ๊ทธ์˜ ์ •๋ณด

JiwonDev

JiwonDev

ํ™œ๋™ํ•˜๊ธฐ