JDBC 프로그래밍

Hyunsu·2023년 11월 19일
0

Today I Learned

목록 보기
37/37
post-thumbnail

📝 목차

  1. JDBC
  2. DAO 와 DTO
  3. Connection Pool

1. JDBC

Java 가 DB 와 통신할 수 있도록 해주는 API 이다.
이클립스에서 오라클 DB 를 사용하기 위해서는 오라클 JDBC LIB 를 이클립스에 복사해야한다.

C:\app\사용자명\product\11.2.0\dbhome_1\jdbc\lib 에서ojdbc6_g.jar 를 복사하고
라이브러리 폴더 C:\Program Files\Java\jre1.8.0_151\lib\ext 에 붙여넣는다.

JDBC 실행 순서

데이터를 삽입 삭제 갱신 할 때에는 executeUpdate 를 사용한다.

String driver = "oracle.jdbc.driver.OracleDriver"; // 오라클 드라이버 이름
String url = "jdbc:oracle:thin:@localhost:1521:xe"; // DB 설치된 서버의 IP:포트:오라클명
String id = "scott"; // 계정 아이디
String pw = "tiger"; // 계정 비밀번호

Connection con = null; // 연결 객체
Statement stmt = null; // 통신 객체

try {
	Class.forName(driver); // OracleDriver 로딩
    
    con = DriverManager.getConnection(url, id, pw); // Java 와 Oracle 연결
    stmt = con.createStatement(); // query 전송 객체
    String sql = "INSERT INTO book(book_id, book_name, book_loc)";
    	   sql += " VALUES (BOOK_SEQ.NEXTVAL, '" + bookName + "', '" + bookLoc + "')";
    int result = stmt.executeUpdate(sql); // query 전송 (result 는 행의 개수 반환)
    
    if (result == 1) {
    	out.print("INSERT success");
    } else {
    	out.print("INSERT fail");
    }
    
} catch (Exception e) {
	e.printStackTrace();
} finally {
	try {
   		// 자원 해제
    	if (stmt != null) stmt.close();
        if (con != null) con.close();
    } catch (Exception e2) {
    	e2.printStackTrace();
    }
}

데이터를 검색 할 때에는 executeQuery 를 사용한다.

String driver = "oracle.jdbc.driver.OracleDriver"; 
String url = "jdbc:oracle:thin:@localhost:1521:xe";
String id = "scott";
String pw = "tiger";

Connection con = null;
Statement stmt = null;
ResultSet res = null; // select 결과 저장 객체

try {
	Class.forName(driver);
    
    con = DriverManager.getConnection(url, id, pw);
    stmt = con.createStatement();
    String sql = "SELECT * FROM book";
	res = stmt.executeQuery(sql); // select 문으로 데이터 가져옴
    
    while (res.next()) { // 다음 행이 존재한다면
        int bookId = res.getInt("book_id");
        String bookName = res.getString("book_name");
        String bookLoc = res.getString("book_loc");    

        out.print("bookId : " + bookId + ", ");
        out.print("bookName : " + bookName + ", ");
        out.print("bookLoc : " + bookLoc + "<br>");
    }
    
} catch (Exception e) {
	e.printStackTrace();
} finally {
	try {
    	if (res != null) res.close();
    	if (stmt != null) stmt.close();
        if (con != null) con.close();
    } catch (Exception e2) {
    	e2.printStackTrace();
    }
}
  • OracleDriver 로딩 : Driver loading

    OracleDriver 을 메모리에 로딩한다. Class.forName(driver);

  • Java 와 Oracle 연결 : Connection

    연결을 해주는 con 객체를 구한다. url 에는 해당하는 데이터 베이스를 넣고 id 와 pw 에는 계정 정보를 입력한다. con = DriverManager.getConnection(url, id, pw);

  • query 전송 객체 : Statement

    쿼리문을 이용해 통신하기 위한 객체이다. stmt = con.createStatement();

  • query 작성 : query

    쿼리문을 작성한다. String sql = "SELECT * FROM book";

  • query 전송 : run

    query 전송 객체를 이용해서 쿼리를 전송한다.
    데이터를 삽입 삭제 갱신 할 때에는 res = stmt.executeUpdate(sql); 문을 실행하고 검색 할 때에만 res = stmt.executeQuery(sql); 문을 사용한다.

PreparedStatement

PreparedStatement 를 통해 query 작성을 더 간편하게 할 수 있다.
일반 JDBC 실행 순서에서 Statement 와 query 의 순서를 바꿔 실행한다.

// Driver loading
Class.forName(driver);

// Connection
con = DriverManager.getConnection(url, id, pw);

// query
String sql = "UPDATE book SET book_loc=? WHERE book_name=?";

// PreparedStatement
pstmt = con.prepareStatement(sql);
pstmt.setString(1, "001-00007123");
pstmt.setString(2, "book7");

// run
int res = pstmt.executeUpdate();

2. DAO 와 DTO

브라우저가 웹 서버에 요청을 하면 웹 서버는 필요에 따라 DB 에 접근해 작업을 한 뒤 다시 결과값을 응답한다. 이때 DB 와 통신하기 위한 기능을 모듈화 한 것을 의미한다.

  • DAO (Data Access Object) : 데이터에 접근하는 객체로 DB 와 관련된 기능을 모듈화

    웹 서버인 웹 컨테이너는 DB 에 접속하는 기능 이외에도 다양한 기능을 하는데 그 중 DB 에 접근하는 기능을 Object 형태로 따로 모듈화 해놓은 것이다.
  • DTO (Data Transfer Object) : DB 에 있는 데이터를 자바 형태로 변환해주는 객체

    DB 의 데이터 형태와 자바에서의 데이터 형태는 서로 다르기 때문에 이를 변환해준다.

DAO 와 DTO 구현

위에서 작성한 JDBC 코드를 DAO 와 DTO 를 이용해서 모듈화 할 수 있다.

public class BookDTO {
	int bookId;
	String bookName;
	String bookLoc;
	
	public BookDTO(int bookId, String bookName, String bookLoc) {
		this.bookId = bookId;
		this.bookName = bookName;
		this.bookLoc = bookLoc;
	}
	
	public int getBookId() {
		return bookId;
	}
	
	public String getBookName() {
		return bookName;
	}
	
	public String getBookLoc() {
		return bookLoc;
	}
}

public class BookDAO {
	String driver = "oracle.jdbc.driver.OracleDriver";
	String url = "jdbc:oracle:thin:@localhost:1521:xe";
	String id = "scott";
	String pw = "tiger";
	
	public BookDAO() {
		try {
			Class.forName(driver);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public ArrayList<BookDTO> select() {
		ArrayList<BookDTO> list = new ArrayList<BookDTO>();
		
		Connection con = null;
		PreparedStatement pstmt = null;
		ResultSet res = null;
		
		try {
			con = DriverManager.getConnection(url, id, pw);
			String sql = "SELECT * FROM book";
			pstmt = con.prepareStatement(sql);
			res = pstmt.executeQuery();
			
			while (res.next()) {
				int bookId = res.getInt("book_id");
				String bookName = res.getString("book_name");
				String bookLoc = res.getString("book_loc");
				
				BookDTO bookDTO = new BookDTO(bookId, bookName, bookLoc);
				list.add(bookDTO);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if (res != null) res.close();
				if (pstmt != null) pstmt.close();
				if (con != null) con.close();
			} catch (Exception e2) {
				e2.printStackTrace();
			}
		}
		
		return list;
	}
}

@WebServlet("/bs")
public class BookServlet extends HttpServlet {
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setContentType("text/html; charset=UTF-8");
		PrintWriter out = response.getWriter();
		
		BookDAO bookDAO = new BookDAO();
		ArrayList<BookDTO> list = bookDAO.select();
		
		for(BookDTO dto : list) {
			out.print("bookId : " + dto.getBookId() + ", ");
			out.print("bookName : " + dto.getBookName() + ", ");
			out.print("bookLoc : " + dto.getBookLoc() + "<br>");
		}
	}
    
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}
}

3. Connection Pool

DB 와 통신하는 자원을 효율적으로 관리하기 위한 방법이다. 웹 서버가 DB 에 접근할 때 웹 컨테이너에 미리 생성해놓은 커넥션풀을 rent 하면 DB Connection - Data Handling - DB Connection Close 작업에서 좀 더 간편히 접근 가능하다. 작업이 끝나면 커넥션풀을 return 한다.

커넥션 풀 설정

Servers 의 context.xml 파일에 다음 코드를 넣어준다.

<Resource
	auth = "Container" // 현재 사용하고 있는 tomcat 컨테이너를 커넥션풀로 사용
    driverClassName = "oracle.jdbc.driver.OracleDriver"
    url = "jdbc:oracle:thin:@localhost:1521:xe"
    username = "scott"
    password = "tiger"
    name = "jdbc/Oracle11g" // 커넥션풀 이름
    type = "javax.sql.DataSource" // 커넥션 생성 객체 API
    maxActive = "4" // 생성 개수 4 + 자동 생성 1 = 5
    maxWait = "10000" // 자동 생성할 때 기다리는 시간 10s
/>

커넥션 풀 구현

컨테이너에 생성되어있는 커넥션풀을 rent 해서 사용할 수 있다.

public BookDAO() {
	DataSource dataSource;

	try {
    	Context context = new InitialContext();
        dataSource = (DataSource)context.lookup("java:comp/env/jdbc/Oracle11g"); // 컨테이너로부터 커넥션풀 찾기
    } catch (Exception e) {
   		e.printStackTrace();
    }
}

public ArrayList<BookDTO> select() {
	ArrayList<BookDTO> list = new ArrayList<BookDTO>();
		
	Connection con = null;
	PreparedStatement pstmt = null;
	ResultSet res = null;
		
	try {
		con = dataSource.getConnection(); // 커넥션풀 rent
        ...
    } catch (Exception e) { ... } finally { ... }
}
profile
현수의 개발 저장소

0개의 댓글