JSP에서 데이터베이스와 연동하는 방법에 대해 알아보기 전에, 선행학습이 필요하다
해당 링크를 통해 SQL문에 대한 선행학습부터! ▶ SQL기본 문법
◆ JDBC ( Java DataBase Connectivity )
자바에서 DB를 연동하여 SQL문을 실행할 수 있도록 해주는 자바API
JDBC를 사용하기 위해선 import java.sql.*; 이 필요하고,
try~catch문 안에서 이루어져야 한다. ( JSP는 try~catch가 필수는 아님 )
▶ 1. DB서버 연결
1-1. ojdbc8.jar 라이브러리 추가
Oracle을 사용하기 위해선 해당 DB사이트에서 라이브러리 다운이 필요하다.
ojdbc.jar파일 다운로드 후 프로젝트의 WEB-INF/lib 디렉터리에 추가해준다.
또는 SqlDeveloper나 Oracle자체에도 해당 라이브러리가 내장되어 있기 때문에 해당 파일을 복사해서 사용해도 무방하다.
- SqlDeveloper
- sqldeveloper-17.2.0.188.1159-no-jre\sqldeveloper\jdbc\lib
- Oracle
- C:\oraclexe\app\oracle\product\11.2.0\server\jdbc\lib
▶ Java프로젝트에서 라이브러리 추가
웹 프로젝트의 경우 lib디렉터리에 jar파일만 추가해 주어도 되지만, 자바 프로젝트의 경우에는 다른 방법으로 라이브러리를 추가해야한다.
프로젝트 우 클릭 -> BuildPath -> Configure BuildPath -> Libraries탭 -> Add External JARs로 해당 jar파일 추가
1-2. DriverManager가 사용해야 될 클래스를 탑재시키는 코드가 필요
java코드 또는 스크립트 렛( <% %> )안에 class.forName("oracle.jdbc.driver.OracleDriver");작성
- 해당 메서드의 인자 값은 데이터베이스 종류에 따라 달라진다.(정해져 있는 값임)
- 1-1의 ojdbc8.jar 라이브러리 추가가 되어있는 상태여야만 가능하다.
1-3. DriverManager객체로 Connection 객체 연결( 필수정보 3가지가 필요하다. )
DB와 연결된 Connection객체를 반환받아야 한다.
Connection conn = DriverManager.getConnection(url, "계정", "비밀번호");
- 인자1 : 해당 DB의 종류와 DB서버의 주소 ( 위치정보 )
- 인자2 : 사용할 DB접속 계정명
- 인자3 : 해당 DB에 설정한 비밀번호
- url 입력 :
String url = "jdbc:oracle:thin:@192.168.10.80:1521:xe";
=> 데이터베이스 종류에 따라 설정이 다를 수 있다.
<%
import java.sql.*;
class.forName(“oracle.jdbc.driver.OracleDriver”);
String url = "jdbc:oracle:thin:@localhost:1521:xe";
String user = "gunbin";
String pass = "1234";
Connection conn = DriverManager.getConnection(url, user, pass);
%>
▶ 2. 패킷 전송/수신
2-1. sql 문 작성
String형태로 sql문을 작성 한다.
( DDL 작업은 DB에서 하고, DML작업등의 경우만 JAVA에서 처리한다. )
ex) String sql = “insert into baby values(‘이순신’,’1’,’3.49’,’2018-01-04’,null)”;
2-2. 패킷화
Connection객체의 메서드를 이용하여 sql문을 패킷화 해주는 PreparedStatements객체를 반환 받는다.
ex ) PreparedStatement ps = conn.prepareStatement(sql); // 패킷화
- 또는 Statement state = conn.createStatement();를 이용하여 execute(sql)을 통하여 SQL문을 실행하는 방법 또한 가능하지만, 이는 동적 value값 할당이 불가능 하기 때문에 예전방법이다.
2-3. 패킷전송 및 실행 유도
PreparedStatements객체의 메서드로 패킷 전송을 시도한다.
ex ) int r = ps.executeUpdate(); // 실행된 행 반환
처리하고자 하는 명령문의 종류에 따라 메서드가 달라진다.
-
- executeUpdate()
- 데이터 변경이 일어나는 insert, update, delete문의 경우에 쓰는 메서드
( 처리된 행의 개수를 int형으로 반환한다. )
-
- executeQuery()
- 데이터를 가져오는 select문의 경우에 쓰는 메서드
( ResultSet객체 반환 )
...
Connection conn = DriverManager.getConnection(url, user, pass);
String sql = "insert into baby values('이순신','1','3.49','2018-01-04',null)";
PreparedStatement ps = conn.prepareStatement(sql); // 패킷화
int r = ps.executeUpdate();
System.out.println(r + "개의 행이 적용되었습니다.");
// 또는 옛날 방법
Statement state = conn.createStatement();
state.excecute(sql);
▶ 3. 서버 연결 해제
DB작업이 끝난후에 연결을 해제시켜 주어야 한다. conn.close();
- DB작업 예시
import java.sql.*;
class.forName(“oracle.jdbc.driver.OracleDriver”);
Connection conn =
DriverManager.getConnection(“jdbc:oracle:thin:@localhost:xe”,“root”,“1234”);
String sql = “insert into baby values(‘원빈’,‘1’,‘3.22’,‘2017/01/05’,null)”;
PreparedStatement ps = conn.prepareStatement(sql);
int r = ps.executeUpdate();
if(r>0) System.out.println(“성공”);
else System.out.println(“실패”);
conn.cleose();
◆ DB value값 입력
SQL문에 value값을 변수로 넣게 될 경우 String처리가 매우 번거롭기 때문에, PreparedStatement객체는 이를 동적으로 셋팅 할 수 있도록 지원해준다.
▶ SQL value값 동적처리 방법
1. 처리하고자 하는 SQL문의 value값을 ?(물음표)로 처리한다.
String sql = "insert into baby values(?,?,?,?,?)";
2. prepareStatement()메서드의 인자로 보낸다.
PreparedStatement ps = conn.prepareStatement(sql);
실행전 명령문을 패킷화 하는것이기 때문에 이전과 다르지 않다.
3. 물음표(?)로 처리해 두었던 value값을 할당
PrepareStatement객체의 setString() 메서드를 이용해 ? 안에 value값을 할당 할 수 있다.
ps.setString(1, name);
-
setString(번호, value값);
의 첫번째 인자는 물음표(?)의 순서를 의미하며.
첫번째는 0이 아닌 1부터 시작한다. -
ps.setObject, ps.setInt등등 값의 타입에 따라 메서드가 달라질 수 있다.
( 단, String은 모든 처리가 가능 ) -
물음표(?)로 동적 할당 처리를 할 수 있는 값들을 오직 value값들뿐이다.
- int r = ps.executeUpdate(); 하기 전에 모두 등록해야 사용이 가능하다.
...
String sql = "insert into baby values(?,?,?,?,?)";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1,"원빈");
ps.setInt(2, 1);
ps.setDouble(3, 3.22);
ps.setString(4, "2017/01/05");
ps.setString(5, null);
int r = ps.executeUpdate();
conn.cleose();
◆ select문 처리
데이터의 변경이 일어나는 insert, update, delete 문은 executeUpdate()메서드를 이용하여 처리된 행을 int형으로 반환하지만,
데이터를 불러오는 등의 작업인 select문은 executeQuery()메서드를 이용하여 ResultSet객체를 반환한다.
ResultSet rs = ps.executeQuery();
▶ ResultSet객체 순회
ResultSet객체는 Iterator객체와 비슷하게 사용한다.
-
- rs.next()
- 다음 행이 있는지 boolean반환( 최초 넥스트는 데이터가 있는지 없는지 확인 )
=> 다음 행으로 넘어가기 위해 데이터를 뽑아내기 전 꼭 필요한 작업
=> while문을 통해 계속해서 다음 데이터를 뽑아내기 위한 메서드
-
- rs.previous()
- 이전 레코드로이동
-
- rs.first()
- 처음으로 이동
-
- rs.last()
- 마지막으로 이동
-
- rs.getString(인덱스 또는 컬럼네임)
- 해당 행의 데이터를 뽑아내며, 데이터 타입에 따라 getInt()등 메서드가 달라질 수 있다.
▶ value값 가져오기
ResultSet객체의 getString()메서드의 인자는 인덱스 또는 컬럼네임이 될 수 있으며,
뽑아내는 데이터타입에 따라 getInt(), getDouble, getDate().. 등등으로 바뀔 수 있다.
- 객체형이 아닌 데이터를 뽑아 낼 때 데이터베이스의 데이터가 null일 경우 int는 0 등으로 뽑아진다.
...
ResultSet rs = ps.executeQuery();
while(rs.next){
System.out.println(rs.getString(1));
System.out.println(rs.getString(“name”));
System.out.println(rs.getString("gender"));
}