자바프로그램이 여러 데이터베이스에 접속하려면 데이터베이스 구조 구현에 따라야 한다. 직접적으로 데이터베이스에 붙어서 하려면 코드를 달리 작성해줘야 하는 문제가 생긴다. 유지보수와 재활용성에 문제점이 생김.
이 문제를 해결하기위해 공통의 인터페이스를 제공하는것이 JDBC이다
해당 인터페이스를 사용할 수 있도록 구현해놓은 것
이것을 만든게 jdbc bender
각각의 회사에서 만든 jdbc Driver드라이버 클래스를 제공한다
실제 데이터베이스를 사용할 수 있도록!
jdbc vender(판매자들)이 jdbc Driver 클래스를 작성해서 배포함
- 사용하는 데이터베이스에 맞는 driver class를 등록
1-1. Class라는 class를 사용
1-2. DriverManager Class 사용
Class.*forName*("com.mysql.cj.jdbc.Driver"); //forName: drive 부터 로딩한다
- DBMS와 연결 (실제 데이터베이스연결하는 부분) - Connection 객체 생성
- 접속에 성공하면 JDBC에 있는 인터페이스 중 하나인 connection이라는 인스턴스(객체)가 생성된다
- 하지만 부하가 많이 걸린다
- 데이터베이스는 세션이 한정적이다 사용후 닫아줘야 한다
- 데이터베이스와 연결후 → 성공후 인스턴스를 만들 수 있다. 데이터베이스는 한번에 열수있는세션이 한정적이기 때문에 다 쓰고난 후 close로 닫아줘야 한다. 그래야 데이터베이스 쪽에서 세션을 닫을 수 있다
- JDBC URL
- 형식이 정해져있다
- JDBC URL + ID+ PW 입력후 connection을 생성
- statement 객체 생성
- 일반 Statement 객체
- Prepared Statement (일반 statement의 개량형)
- Callable statement → stored procedure를 호출할때 사용
우리는 Prepared Statment를 사용Prepared Statment
- 쿼리에 대한 변환 작업을 미리 statement에 넣어 두는 것
마치 캐시와 같은 역할을 해주기 때문에 많은 양의 쿼리를 실행해야 할때 속도면에서 이점을 얻을 수 있다- 데이터베이스 인젝션을 예방할 수 있다
Prepared Statment는 쿼리가 한번들어오면 고정되어서 외부의 입력으로 변경이 불가능해짐- Prepared Statment는 인파라미터를 사용할 수 있다
DELETE FROM buytbl WHERE userID = ?
? 여러개 사용 가능
- 쿼리 실행
- execute() : 4개 상태 전부 가능하지만 나온결과를 판단해서 개발자가 처리해야한다
- 내가쓰는게 뭔지 모르고 동적으로 변경이 될경우 사용
- 정해지지 않은경우 아래의 방법들을 사용함 (보편적으로 사용한다)
- executeQuery() : select 계열의 결과 레코드 집합을 호출하는 쿼리 수행
- executeUpdate() : Insert, update, delete 계열의 쿼리를 수행할때
- 결과 쿼리
ResultSet rs = psrat.executeQuery();
- rs.
next()
할때마다 행(row)을 가리키는 커서(cursor)가 다음행으로 하나씩 실행
- 다음행이 존재하면 true
- 다음행이 존재하지 않으면 false
- rs.
getString()
가져온 값을 자바String 형태로 변경
- rs.getString(”name”)
- rs.getString(2) index는 1부터 시작이다 0부터 넣으면 안됨!
public class Main {
public static void main(String[] args) {
Connection con = null;
PreparedStatement pstmt = null;
ResultSet rs2 = null;
//1. JDBC driver loading - 내가사용하는 데이터베이스의 드라이버 클래스명을 입력
// MySQL8.0부터는 아래의 class 를 사용한다
try {
Class.forName("com.mysql.cj.jdbc.Driver");
System.out.println("드라이버 로딩 성공");
//2. 실제 데이터베이스에 연결 프로토콜 DBMS 스키마명 //타임존
String jdbcURL = "jdbc:mysql://localhost:3306/sqldb?characterEncoding=UTF-8&serverTimezone=UTC&useSSL=false";
// 접속에 성공하면 Connection 이라는 객체가 생긴다
con = DriverManager.getConnection(jdbcURL,"root","kim8480848");
System.out.println("데이터베이스 연결 성공");
String sql = "SELECT userID, name, addr FROM usertbl";
//3. Statement 생성
//3-2 PreparedStatement
pstmt = con.prepareStatement(sql);
//4. 쿼리 실행
//Statement 를 사용해서 sql 쿼리를 DBMS 에 실제로 전달한다
//전처리된 sql 문장 실행
rs2 = pstmt.executeQuery();
//5. 결과 처리
//가져온값 전체를 돌아라 .next() 끝에 도달하면 false가 나옴
while (rs2.next()){
String id = rs2.getString(1);
String name = rs2.getString(2);
String addr = rs2.getString(3);
System.out.println(id + ", " + name + ", " + addr);
}
} catch (ClassNotFoundException e) { //Class.forName
throw new RuntimeException(e);
} catch (SQLException e2) { //DriverManager.getConnection
throw new RuntimeException(e2);
}finally {
//finally exception이 뜨거나 말거나 무조건 실행
try {
//자원들을 각각하나씩 해제 해야한다
if (rs2 != null) rs2.close();
if (pstmt != null) pstmt.close();
if (con != null)
con.close(); //자원을 아끼기 위해 닫아주기
}catch (Exception e){
}
}
}
}
- 속도를 향상 시켜준다
- 자원의 효율성
- connection 부분 제어가 가능하다
참고자료
[Java] JDBC를 사용한 데이터베이스 연동(Mysql)
SQL injection 대응 : Prepared Statement