본문으로 바로가기

아래 순서로 간단한 JAVA - MySQL 연동을 테스트 한다.

  1. 간단한 SELECT문 예제
  2. 위 예제를 별도 class(파일)로 분리 : 시행 착오
  3. 분리 완성한 코드(ArrayList 리턴)
  4. 분리 완성한 코드(ArrayList + HashMap 리턴)

1. 간단한 SELECT문 예제

package database;

import java.sql.*;

public class Database {
	public static void main(String argv[]) {
		try {
			Class.forName("com.mysql.jdbc.Driver");
			System.out.println("jdbc driver loaded");
		} catch (ClassNotFoundException e) {
			System.out.println(e.getMessage());
		}
		
		try {
			String url = "jdbc:mysql://localhost:3306/db";
			Connection con = DriverManager.getConnection(url, "user", "pass");
			System.out.println("mysql connected");
			Statement stmt = con.createStatement();
			ResultSet rs = stmt.executeQuery("SELECT no, name FROM member LIMIT 10");
			
			while (rs.next()) {
				String no = rs.getString(1);
				String name = rs.getString(2);
				System.out.println("no = " + no);
				System.out.println("name= "+ name);
			}
			
			stmt.close();
			con.close();
		}  catch (java.lang.Exception ex) {
			ex.printStackTrace();
		}
	}
}

2. DB 연결 및 공통 부분을 별도 파일(class)로 분리

매번 jdbc와 DB 연결-종료 관련 코딩을 삽입하는 것이 번거로우므로, 별도의 파일에 class 생성.

// DBFunction.java
package database;

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

public class DBFunction {
	
	public static Connection sqlConnection() {
		
		Connection conn = null;
		
		try {
			Class.forName("com.mysql.jdbc.Driver");
			System.out.println("jdbc driver loaded");
		} catch (ClassNotFoundException e) {
			System.out.println(e.getMessage());
		}
		
		try {
			String url = "jdbc:mysql://localhost:3306/db";
			conn = DriverManager.getConnection(url, "user", "pass");
		} catch(java.lang.Exception ex) {
			ex.printStackTrace();
		}
		
		return conn;
	}
	
    // 이 부분에서 오류가 발생(아래에 수정하는 내용이 있음)
	public static ResultSet sqlRead(String query) {
		
		Connection conn = sqlConnection();
		Statement stmt = null;
		ResultSet rs = null;
		
		try {
			stmt = conn.createStatement();
			rs = stmt.executeQuery(query);
			
			stmt.close();
			conn.close();
		} catch(SQLException e) {
			e.printStackTrace();
		}
		
		return rs;
		
	}
	
}
// Database.java
package database;

import java.sql.*;

public class Database {
	public static void main(String argv[]) {
		try {
			
			ResultSet list = DBFunction.sqlRead("SELECT no, name FROM member LIMIT 10");
			
			while (list.next()) {
				String no = list.getString(1);
				String name = list.getString(2);
				System.out.println("no = " + no);
				System.out.println("name= "+ name);
			}
			
		} catch (java.lang.Exception ex) {
			ex.printStackTrace();
		}
	}
}

생성한 class를 사용해서 DB 내용을 조회하려고 하면 오류가 발생한다.

 

Error Message

java.sql.SQLException: Operation not allowed after ResultSet closed

 

ResultSet 객체가 가진 Cursor의 next() 메소드를 사용하여 데이터를 조회하려고 하는데,

이미 Statement와 Connection이 close 되었기 때문에 데이터를 가리킬 수 없다. 실제로 ResultSet을 리턴하도록 코딩하는 경우는 없다.

 

3. 완성된 코드

ArrayList에 담아 리턴하는 방식으로 변경하여 완성.

// DBFunction.php
package database;

import java.util.ArrayList;
import java.sql.*;

public class DBFunction {
	
	public static Connection sqlConnection() {
		
		Connection conn = null;
		
		try {
			Class.forName("com.mysql.jdbc.Driver");
			System.out.println("jdbc driver loaded");
		} catch (ClassNotFoundException e) {
			System.out.println(e.getMessage());
		}
		
		try {
			String url = "jdbc:mysql://localhost:3306/db";
			String param = "?zeroDateTimeBehavior=convertToNull";
			conn = DriverManager.getConnection(url+param, "user", "pass");
		} catch (java.lang.Exception ex) {
			ex.printStackTrace();
		}
		
		return conn;
	}
	
	public static ArrayList<String[]> sqlRead(String query) {
		
		Connection conn = sqlConnection();
		ArrayList<String[]> result = new ArrayList<String[]>();
		
		try {
			Statement stmt = conn.createStatement();
			ResultSet rs = stmt.executeQuery(query);
			
			int columnCount = rs.getMetaData().getColumnCount();
			// System.out.println( "columnCount : " + columnCount );
			
			while (rs.next()) {
				
				String[] row = new String[columnCount];
				
				for (int i=0; i<columnCount; i++) {
					row[i] = rs.getString(i + 1);
					// System.out.println( "row " + i + " : " + row[i] );
				}
				result.add(row);
			}
			
			stmt.close();
			conn.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		
		return result;
		
	}
	
}
// Database.java
package database;

import java.util.ArrayList;

public class Database {
	public static void main(String argv[]) {
		try {
			
			ArrayList<String[]> list = DBFunction.sqlRead("SELECT * FROM lt_member LIMIT 3");
			
			for (int i=0; i<list.size(); i++) {
				
				System.out.println( "this is index " + i + "_____" );
				
				for (int j=0; j<list.get(i).length; j++) {
					System.out.println( "index " + i + "." + j + " is : " + list.get(i)[j] );
				}
				
			}
			
		} catch (java.lang.Exception ex) {
			ex.printStackTrace();
		}
	}
}

4. key-value 형태로 리턴(ArrayList + HashMap)

java의 ArrayList는 key-value 형태를 갖지 못하기 때문에 칼럼명을 지시하여 데이터를 다룰 수 없다.

필요한 경우 HashMap을 사용하면 된다.

// DBFunction.java
import java.util.HashMap; // 추가

...(생략)...

	// sqlRead 함수 수정
	public static ArrayList<HashMap<String, String>> sqlRead(String query) {
		
		Connection conn = sqlConnection();
		ArrayList<HashMap<String, String>> result = new ArrayList<>();
		HashMap<String, String> row = new HashMap<>();
		
		try {
			Statement stmt = conn.createStatement();
			ResultSet rs = stmt.executeQuery(query);
			
			int columnCount = rs.getMetaData().getColumnCount();
			// System.out.println( "columnCount : " + columnCount );
			
			while (rs.next()) {
				row = new HashMap<>();
				
				for (int i=0; i<columnCount; i++) {
					row.put(rs.getMetaData().getColumnName(i + 1), rs.getString(i + 1));
					System.out.println( "row " + i + " : " + row );
				}
				result.add( row );
			}
			
			stmt.close();
			conn.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		
		return result;
		
	}
// Database.java
package database;

import java.util.ArrayList;
import java.util.HashMap;

public class Database {

	public static void main(String argv[]) {
		
		try {
			
			ArrayList<HashMap<String, String>> list = DBFunction.sqlRead("SELECT no, name FROM member LIMIT 3");
		
			for (int i=0; i<list.size(); i++) {
				System.out.println( "index " + i + ".no is : " + list.get(i).get("no") );
				System.out.println( "index " + i + ".name is : " + list.get(i).get("name") );
			}
		
		} catch (java.lang.Exception ex) {
			ex.printStackTrace();
		}
		
	}

}