[Java] JDBC에서 Class.forName과 클래스 로딩에 대해 알아보기
지난 포스팅에서 Java Reflection에 대해 다뤘습니다. JDBC를 사용할 때 쓰이는 Class.forName 역시 Java Reflection에서 제공하는 기능 중에 하나입니다. JDBC 를 사용하여 DB에 접근하기 위해서는 제일 먼저 드
limdevbasic.tistory.com
Java - DB 연동을 위한 설정
1. 수 많은 db와 개발툴 중 오라클, 이클립스 기준이라는걸 알아두자
2. ojdbc8.jar 파일 다운로드
3. lib 폴더 만들기
- 라이브러리 폴더 만들기: 프로젝트-우클릭-New-Folder
4. lib 폴더에 ojdbc8.jar 파일 붙여넣기
work - java 폴더에서 파일 복사 후, 이클립스의 lib 폴더에 붙여넣기
5. 라이브러리 생성
project 우클릭 - properties - java Build Path - Libraries - Classpath - Add jars - 사용중인 프로젝트의 ojdbc8.jar 선택 후 OK - apply - apply and close 하면 아래처럼 라이브러리 생성됨
6. 언어 설정 - 한글 설정 확인 및 설정
방법1
project 우클릭 - properties - java Editor - java facets - ‘java 11fh’로 변경
방법2
상단 window - properties - enco 검색 - Workspace - ‘Others: UTF-8’인지 확인할 것 ▶ 한글 설정 되어있는지 확인
7. 이클립스 방식
(1). 필요한 클래스의 정보를 DB에 저장 및 로드하기 위한 매개 클래스 생성
1. 이 방식은 db에 저장된 데이터를 자바의 VO라는 클래스로 저장받아 활용하는 방법으로 Getter Setter방식을 이용한다
원하는 자바프로젝트 - src - dto 패키지 - ‘클래스Vo’ 이름의 클래스 생성
2. 메소드 자동 생성 기능 활용( 이클립스 상단 Source - Generate toString() - 만들고 싶은 것 체크(거의 대부분 select All))
3. 이클립스 상단 Source - Generate Getters and Setters - 만들고 싶은 것 체크(사실 테이블에 있는 컬럼 전부를 select All)
8. JDBC 연동(스프링부트와 달라요!)
JDBC 개요
DriverManager
JDBC Driver를 관리하며 DB와 연결해서 Connection 구현 객체를 생성
Connection - DB 연결
Connection 인터페이스는 Statement, PreparedStatement, CallableStatement 구현 객체를 생성하며, 트랜잭션 처리 및 DB 연결을 끊을 때 사용한다.
Statement
SQL의 DDL과 DML을 실행할 때 사용한다. 주로 변경되지 않는 정적
DB 관리하는 클래스(DBManager) 생성
원하는 자바프로젝트 - src - util 패키지 - ‘DBManager’ 클래스 생성
1. JDBC DB 연동
아래 코드를 작성하여 Connection conn = null; 위에서 import할 것
⇒ Ctrl + Shift + o ⇒ DB 연결 ⇒ import됨
public static Connection getConnection() {
Connection conn = null;
}
아래 내용만 하게 되면 예외 처리 필요한 코드이기 때문에 빨간 줄이 뜨게 된다.
Class.forName("oracle.jdbc.OracleDriver");
그래서 빨간줄 위에 마우스를 올려 예외처리를 해줄 것⇒ Surround with try/catch
// 1. JDBC 드라이버 로드
// OracleDriver 클래스를 가져와 사용하겠다.
// 예외 처리 필요한 코드
// try {} : 예외가 발생할 거 같은 블록을 시도할 때
try {
Class.forName("oracle.jdbc.OracleDriver");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
2. 데이터 베이스 연결 객체 생성
오라클 세부정보 확인 ⇒ 오라클 - Oracle 접속 - 필요한 유저 우클릭 - 속성 눌러서 확인
오라클 유저 세부 정보를 url로 작성
⇒ SQL Developer에서 유저 접속 시 나오는 세부 정보(jdbc:oracle:thin:@localhost:1521:orcl --> 쓰는 오라클 확인)를
url 로 작성한다.
String url = "jdbc:oracle:thin:@localhost:1521:orcl";
연결하려는 유저와 비밀번호까지 작성하여 객체를 생성
// 연결하려는 유저
String userid = "user_exchanges";
// 연결하려는 유저의 비밀번호
String password = "1234";
3. DB 쿼리문 사용 - PreparedStatement 객체 생성
4. DB 쿼리문 수행 결과 - SQL문 실행 결과 처리
DBManager1.java의 코드--> vo활용 X(db와 연결한 것)
package util;
import java.sql.Connection; // 1. DB 연결
import java.sql.DriverManager; // 2. DB 관리
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
// DB 관리(연결, 닫기)
public class DBManager1 {
// DB 연결
public static Connection getConnection() {
Connection conn = null;
// try{}: 예외가 발생할 것 같은 블록을 시도할 때
try {
// (1단계) JDBC 드라이버(클래스) 로드
Class.forName("oracle.jdbc.OracleDriver"); //오라클 드라이버 클래스를 가져와서 쓰겠다는 의미 => 예외처리 필요
// (2단계) 데이터 베이스 연결 객체 생성
// 오라클 - Oracle 접속 - 필요한 유저 우클릭 - 속성에서 확인
// 데이터베이스 연결 정보
String url = "jdbc:oracle:thin:@localhost:1521:orcl";
// 연결하려는 유저
String uid = "user_exchanges";
// 연결하려는 유저의 비밀번호
String pass = "1234";
conn = DriverManager.getConnection(url, uid, pass);
// catch(){}: 예외가 발생했을 때 처리 과정
} catch (Exception e) {
e.printStackTrace();
}
return conn;
}
// DB 닫기
public static void close(Connection conn, PreparedStatement pstmt, ResultSet rs) {
try {
if(rs != null) {
rs.close();
}
if(pstmt != null) {
pstmt.close();
}
if(conn != null) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
OperatingSystem1.java의 코드(vo활용 X, db내용 별도의 경로 없이 끌고온 것)
package main;
import java.sql.Connection;
import java.sql.PreparedStatement; // 3. DB 쿼리문 사용
import java.sql.ResultSet; // 4. DB 쿼리문 수행 결과
import java.sql.SQLException;
import util.DBManager1;
public class OperatingSystem1 {
public static void main(String[] args) {
getExchanges();
/* 교수님 예시(if문 안에는 할당하고, 변수 선언은 밖에서 할것.
HistoryVo history = getHistory();
System.out.println(history);
*/
}
// DB의 환율 정보 조회: select
public static void getExchanges() {
String sql = "SELECT * FROM exchanges"; // 프로젝트 활용시, select 쿼리문 수정
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
conn = DBManager1.getConnection();
// (3단계) PreparedStatement 객체 생성
pstmt = conn.prepareStatement(sql);
// (4단계) SQL문 실행 결과 처리
rs = pstmt.executeQuery(); // 조회(select)
// System.out.println(rs.next()); // false로 나옴. 이게 있으면 뒤의 if문이 실행X이므로 주석처리.
// if(rs.next()) { // 다음 내용은 한번만 조회
while(rs.next()) { // 전체 내용을 반복하여 조회
/*
rs.getInt("num");
// System.out.println(rs.getInt("num"));
//
history = new HistoryVo(); // 프로젝트 활용시, 이런식으로 변수에 저장
hisotry.setNum(rs.getInt("num")); // historyVo에 있는 private int num;를 말함(교수님 예시)
history.setYear(rs.getInt("year"));
history.setDecsription(rs.getString("description"));
history.setCharacter_num(rs.getInt("character_num"));
*/
}
} catch (SQLException e) {
e.printStackTrace();
}
DBManager1.close(conn, pstmt, rs); // DB 닫기
// return history; // 교수님 예시
}
}
OperatingSystem.java의 코드
package main;
import java.sql.Connection;
import java.sql.PreparedStatement; // 3. DB 쿼리문 사용
import java.sql.ResultSet; // 4. DB 쿼리문 수행 결과
import util.DBManager;
public class OperatingSystem {
public static void main(String[] args) {
areaInfo(3); // code가 3번인 area
System.out.println("==============");
insertArea(10, "청도", "1", 3);
insertArea(11, "하얼빈", "3", 4);
}
// ============================================================
// DB 삽입(insert) 함수
// Insert 함수는 rs 사용하지 않음.
static void insertArea(int code, String name, String is_around, int country_code) {
String sql = "INSERT INTO area VALUES(?, ?, ?, ?)";
PreparedStatement pstmt = null;
Connection conn = null;
try {
conn = DBManager.getConnection(); // DB 연결
// (3단계) PreparedStatement 객체 생성
pstmt = conn.prepareStatement(sql); // 쿼리문 실행
pstmt.setInt(1, code);
pstmt.setString(2, name);
pstmt.setString(3, is_around);
pstmt.setInt(4, country_code);
// (4단계) SQL문 실행 결과 처리
// pstmt.executeQuery(); // 쿼리문 결과 처리
pstmt.executeUpdate(); // insert/update/delete 쿼리문 결과 처리
} catch(Exception e) {
System.out.println("예외 발생시 처리할 코드: 쿼리문 삽입");
}
DBManager.close(conn, pstmt); // DB 닫기
}
// ============================================================
// DB 조회(select) 함수
static void areaInfo(int code) {
String sql = "SELECT * FROM exchanges where code=?";
PreparedStatement pstmt = null;
ResultSet rs = null;
Connection conn = null;
try {
conn = DBManager.getConnection(); // DB 연결
// (3단계) PreparedStatement 객체 생성
pstmt = conn.prepareStatement(sql); // 쿼리문 실행
pstmt.setInt(1, code); // 1: 물음표 순서, code: 물음표 값
// (4단계) SQL문 실행 결과 처리
rs = pstmt.executeQuery(); // 쿼리문 결과 처리
// rs.next(): 다음 행(row)을 확인(반환값타입: boolean)
// if(rs.next()) { // if는 한번만 실행하므로 반복실행은 while
while(rs.next()) {
// 컬럼을 일일이 가져오기엔 번거로우므로, 배열 or 리스트 라이브러리 사용하여 가져옴
// rs.getInt(0);
// rs.getBoolean(0);
int code1 = rs.getInt("code");
// String ex_date = rs.getString("ex_date");
// String currency_name = rs.getString("currency_name");
// double base_rate = rs.getDouble("base_rate");
// double purchase_krw = rs.getDouble("purchase_krw");
}
} catch(Exception e) {
System.out.println("예외 발생시 처리할 코드: 쿼리문 조회");
}
DBManager.close(conn, pstmt, rs); // DB 닫기
}
}