JDBC를 이용한 DB 처리
순서
1. JDBC드라이버 로딩
- JDBC 드라이버는 DB를 만든 회사에서 제공한다.
Class.forName("oracle.jdbc.driver.OracleDriver");
2. 해당 DB에 접속
- 접속이 성공하면 Connection객체가 생성된다.
DriverManager.getConnection()
메서드를 이용한다. (static메서드)
3. 질의 (SQL명령 수행)
- Statement객체 또는 PreparedStatement객체를 이용하여 SQL문장을 실행한다.
- Connection객체로부터 Statement객체를 제공받을 수 있다 (순서를 잘 지켜야함)
4. 질의 결과를 받아서 처리
- 1) SQL문이 SELECT 일 경우
- executeQuery()
- ResultSet객체가 만들어지고, 거기에 SELECT한 결과가 저장된다.
- 2) SQL문이 INSERT, UPDATE, DELETE 일 경우
- executeUpdate()
- 정수값을 반환한다. (보통 실행에 성공한 레코드 수를 의미)
5. 종료 (자원반납)
- 사용했던 자원을 모두 반납한다 -> 자원 반납을 하지 않으면 메모리 누수 발생!
if(rs != null) try {rs.close();} catch (SQLException e) {}
if(stmt != null) try {stmt.close();} catch (SQLException e) {}
if(conn != null) try {conn.close();} catch (SQLException e) {}
예시: T01_JdbcTest.java
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
String url ="jdbc:oracle:thin:@localhost:1521/xe";
String user = "LKR94";
String password = "java";
conn = DriverManager.getConnection(url, user, password);
stmt = conn.createStatement();
String sql = "SELECT * FROM LPROD";
rs = stmt.executeQuery(sql);
System.out.println("실행한 쿼리문 : " + sql);
System.out.println("=== 쿼리문 실행 결과 ===");
while(rs.next()) {
System.out.println("LPROD_ID : " + rs.getInt("LPROD_ID"));
System.out.println("LPROD_GU : " + rs.getString("LPROD_GU"));
System.out.println("LPROD_NM : " + rs.getString("LPROD_NM"));
System.out.println("------------------");
}
System.out.println("출력 끝...");
} catch (SQLException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} finally {
if(rs != null) try {rs.close();} catch (SQLException e) {}
if(stmt != null) try {stmt.close();} catch (SQLException e) {}
if(conn != null) try {conn.close();} catch (SQLException e) {}
}
PreparedStatement + '?' 와일드카드
- parsing 안하니 속도빨라짐
- SQL Injection 일어날 걱정 x
- SQL Injection: 사용자의 입력값에 의해 SQL문이 삽입되어 데이터베이스 서버를 조작할 수 있는 공격기법
- ?의 위치는 1부터 시작 (인덱스처럼 0부터 아님)
- setStirng 하면 '' 알아서 넣어줌, setInt는 안해줌
T02_MemberInfoTest.java
String sql = "INSERT INTO MYMEMBER "
+ " (MEM_ID, MEM_NAME, MEM_TEL, MEM_ADDR) "
+ " VALUES (?, ?, ?, ?) ";
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, memId);
pstmt.setString(2, memName);
pstmt.setString(3, memTel);
pstmt.setString(4, memAddr);
Properties
예제
준비: 새 소스폴더에 res 만들어주기
- 소스폴더: 컴파일대상이됨
- project: build automatically 체크가 되어있기때문에 소스들이 자동으로 컴파일되고 있던 것
- java build path: source에 이제 res도 추가됨
- default output folder: res, src의 컴파일된 파일들을 bin에 담아주겠다
1단계: db.properties 생성
- 대입연산자 기준 왼쪽: key & 오른쪽: value
2단계: 외부 properties 파일 읽어와 properties 객체로 처리하기
- T03_PropertiesTest.java
- main에서 실행
Properties prop = new Properties();
File file = new FIle("res/db.properties");
try{
FileInputStream fis = new FileInputStream(file);
prop.load(fis);
Enumeration<String> keys = (Enumeration<String>) prop.propertyNames();
while(keys.hasMoreElements()) {
String key = keys.nextElement();
String value = prop.getProperty(key);
System.out.println(key + " => " + value);
}
System.out.println("출력 끝...");
} catch (IOException e) {
e.printStackTrace;
}
결과
ResourceBundle
- ResourceBundle객체란?
- 확장자가 properties인 파일 정보를 읽어와 key값과 value값을 분리한 정보를 갖는 객체
- 읽어올 파일은 'key값=value값' 형태로 되어 있어야 한다
- 객체 생성 후 파일을 지정할 때는 '파일명'만 지정하고 확장자는 지정하지 않는다
Locale?
- The java.util.Locale class object represents a specific geographical, political, or cultural region.
- 지역의 언어, 나라 등의 정보를 가지고 있는 클래스
예제 T04
준비: 언어별 db.properties파일 생성
기본 db.properties
한국어 db_ko.properties
영어 db_en.properties
1단계: ResourceBundle 객체 생성
System.out.println(Locale.getDefault());
ResourceBundle bundle = ResourceBundle.getBundle("db");
ResourceBundle bundle = ResourceBundle.getBundle("db", Locale.US);
2단계: ResourceBundle 객체 안의 내용 출력
Enumeration<String> keys = bundle.getKeys();
while (keys.hasMoreElements()) {
String key = keys.nextElement();
String value = bundle.getString(key);
System.out.println(key + " => " + value);
}
System.out.println("출력 끝...");
결과
Locale이 default일 때 (매개변수 없을 때)
Locale 미국
그냥 db.properties는 이제 아무도 안읽어주네..^_ㅠ
properties 파일 이용한 DB 정보 설정
- DB설정파일을 외부파일(.propeties)로 둠으로써 유지보수를 간편히
- IT IS ALL ABOUT 유지보수!!!
방법1. Properties 객체 이용
- P07_JDBCTest - JDBCUtil2.java 참고
핵심
- 드라이버 로딩 이전에 properties객체를 생성 후 파일을 읽어들여 사용자가 직접 드라이버 주소, url, id, pw를 입력하는 것이 아닌 파일에 담겨있는 정보를 불러와서 쓴다는 것
비교
db.properties 이용하지않을 때
db.properties 파일을 이용할 때
방법2. ResourceBundle 객체 이용
- P07_JDBCTest - JDBCUtil3.java, T04_ResourceBundleTest 참고
핵심
- FileInputStream 이용해서 파일 읽을 필요 없이, 객체 생성시 db.properties의 key와 value값이 나누어 저장이 되기때문에 훨씬 간결하다.