📌 01. DB연동이란?
저번시간에는
- 메인 JSP클래스의 스크립트릿 영역에서 VO클래스에 담길 정보를 저장
- VO클래스에 저장된 정보를 스크립트릿 영역에서 리스트에 저장
- 스크립트릿 영역의 리스트를 BODY영역에 가져와서 UI로 나타내기
와 같은 과정이였다.
이제부터는 직접 VO클래스에 정보를 저장하는 것이 아닌 DB에 있는 TABLE에 저장된 데이터들을
VO클래스에 담아서 해당 데이터를 리스트로 저장하고 UI로 나타낼 것이다.
즉, 1번과정만 바뀌는 것 뿐이지만 실제로 DB에 연동하는 작업은 그리 간단하지 않다.
📌 02. JNDI
DB연동 작업을 하기 전에 먼저 JNDI가 뭔지 알아야 한다.
JNDI란 연결하고자 하는 DB의 정보를 NAMING해서
필요할때 가져다가 쓸 수 있도록 만들어둔 구조이다.
JNDI의 형태가 모두 동일하지 않지만 대표적인 형태는 아래와 같다.
<Context>
<Resource
auth="Container"
name="jdbc/oracle_test"
type="javax.sql.DataSource"
driverClassName="oracle.jdbc.driver.OracleDriver"
factory="org.apache.commons.dbcp.BasicDataSourceFactory"
url="jdbc:oracle:thin:@localhost:1521:xe"
username="" password=""
maxActive="10" maxIdle="10" maxWait="1"/>
</Context>
모든 행들을 이해할 필요는 없고 반드시 알아야 할 것은 name과 username, password 정도이다.
name은 말 그대로 해당 resource의 이름이다.
JNDI에는 여러 Resource가 담길 수 있다.
DB가 한개만 있어야 하는 것은 아니므로 상황에따라서
여러 DB에서 다른 정보들을 가져와야 하는 상황이 있을 수 있기 때문이다.
따라서 Resource의 이름을 정의해두면 메인JSP에서
내가 원하는 DB에 연동 작업을 상황에 따라서 할 수 있게 된다.
또한 username과 password는 DB에 접속하기 위해 사용되는 id와 password를 그대로 적어주는 부분이다.
📌 03. DB연결
JNDI를 통한 DB연결의 과정은 아래와 같다.
- JNDI 검색을 위한 준비한다.
- 검색한 JNDI의 모든 Resource를 가져온다.
- 가져오고자 하는 Resource를 해당 리소스의 이름을 통하여 가져온다.
- 가져온 리소스를 통하여 DB에 연동하기
코드는 아래와 같다.
// 1. JNDI 검색을 위한 준비한다.
InitialContext ic = new InitialContext();
// 2. 검색한 JNDI의 모든 Resource를 가져온다.
Context ctx = (Context)ic.lookup("java:comp/env");
// 3. 가져오고자 하는 Resource를 해당 리소스의 이름을 통하여 가져온다.
DataSource dataSource = (DataSource)ctx.lookup("jdbc/oracle_test");
// 4. 가져온 리소스를 통하여 DB에 연동하기
Connection conn = dataSource.getConnection();
📌 03. 쿼리문 작성
DB에 연동이 성공했다면 실제 Mysql에서와 같이 쿼리문을 작성해야지만
원하는 작업을 수행할 수 있다.
하지만 지금은 Mysql을 통해서가 아닌 JSP클래스를 통하여 쿼리문을 작성해야 하기 때문에
해당 작업 또한 여러 클래스의 기능을 사용해야한다.
과정은 아래와 같다.
- 쿼리문을 문자열 변수로 선언 후 DB에 쿼리문을 요청하는 객체를 생성.
- 쿼리문을 통하여 만들어진 결과로 접근할 수 있게 해주는 객체를 생성.
- 리스트를 선언 후 결과로 접근할 수 있는 객체를 통하여 반복문을 통해 모든 결과물을 리스트에 저장
코드는 아래와 같다.
dept라는 부서테이블에서
부서의 번호(컬럼명: deptno), 부서의 이름(컬럼명: dname), 부서의 위치(컬럼명: loc)를 검색하는 과정이다.
// 1. 쿼리문을 문자열 변수로 선언 후 DB에 쿼리문을 요청하는 객체를 생성.
String sql = "select * from deptno";
PreparedStatement pstmt = conn.prepareStatement(sql);
// 2. 쿼리문을 통하여 만들어진 결과로 접근할 수 있게 해주는 객체를 생성.
ResultSet rs = pstmt.executeQuery();
// 3. 리스트를 선언 후 결과로 접근할 수 있는 객체를 통하여 반복문을 통해 모든 결과물을 리스트에 저장
ArrayList<DeptVO> dept_list = new ArrayList<>();
while( rs.next() ) {
DeptVO vo = new DeptVO();
vo.setDeptno(rs.getInt("deptno"));
vo.setDname(rs.getString("dname"));
vo.setLOC(rs.getString("loc"));
dept_list.add(vo);
}
여기서 알아야 할 것은 반복문에서 테이블의 컬럼에 저장된 정보를 가져오는 부분이다.
첫번째 행의 vo.setDeptno(rs.getInt("deptno"));에서 vo.setDeptno까지는 이해하기가 쉽다.
하지만 괄호안의 rs.getInt("deptno")은 처음보는 형식일 것이다.
rs는 앞서 말했듯 쿼리문을 통한 결과물에 접근하기 위한 객체일뿐이다.
결과물은 테이블에 담긴
부서의 번호(컬럼명: deptno), 부서의 이름(컬럼명: dname), 부서의 위치(컬럼명: loc)가 있을것이다.
getInt("deptno")는 deptno라는 컬럼에 담긴 정보를 int형식으로 가져오는 작업을 수행한다.
즉, vo.setDeptno(rs.getInt("deptno")); 문장은
"deptno라는 컬럼에 담긴 정보를 int형식으로 가져서 vo객체에 있는 deptno변수에 저장해줘"
라는 뜻을 가진다.
📌 04. DB연결 종료
DB접근을 하고 사용한 객체들은 모두 닫아주어야 한다.
위에선 DB연결을 위해 사용했던 conn, 쿼리문을 작성하기 위해 사용했던 pstmt,
쿼리문의 결과에 접근하기 위해 사용했던 rs가 해당된다.
객체를 닫아줄때는 반드시 역순으로 닫아야 한다는 것에 주의해야 한다.
(객체의 선언은 conn -> pstmt -> rs이였지만
닫을떄는 rs -> pstmt -> conn이 된다.)
rs.close();
pstmt.close();
conn.close();
📌 05. DB연동의 이해
지금까지 보지못했던 클래스가 많이 등장하고 그 과정또한 간단하지 않아서
절대 외우기가 쉽지는 않다.
실제 업무에선 어떤 프로젝트를 진행하면서 하나의 DB에 한번만 연동하는 일을 거의 없다.
즉, DB에 연동을 할때마다 위와같은 코드를 매번 적어줘야 하는것은 비효율적이다.
따라서 보통은 해당 기능들을 모두 가지고있는 클래스를 생성해 DB연동이 필요할때 마다 클래스를 호출
하는 형식으로 작업을 수행한다.
다만 해당 클래스에서 내가 원하는데로 몇군데를 수정해야하는데
이러한 코드들을 이해하고 있지 못한다면 그 클래스의 기능조차 제대로 사용하지 못 할 것이다.
따라서 위의 과정들을 모두 외우지 못하더라도 과정에서 사용했던 클래스들이 어떤 기능을 가지고
어떤 과정을 통하여 DB에 연동되는지는 알고 있어야 한다.
'Java > JSP' 카테고리의 다른 글
Day06_Mybatis (1) | 2022.06.03 |
---|---|
Day05_AJAX (2) | 2022.05.31 |
Day04_EL표기법 (0) | 2022.05.31 |
Day02_VO클래스 (0) | 2021.12.30 |
Day01_JSP (1) | 2021.12.30 |