DataSource 를 이용해서 SQL을 처리하는 sql 태그는 다음과 같은 것들이 있다.
기능 |
태그 |
prefix |
DataSource 설정 |
SetDataSource |
sql |
SQL |
query (dateParam, param) , update (dateParam, param) , transaction |
sql 태그를 사용하기 위해서 페이지 상단에 다음과 같이 선언되어야 된다.
<%@ taglib uri="http://java.sun.com/jsp/jstl/sql" prefix="sql"%>
1. <sql:setDataSource/>
DataSource 를 지정하는 방식은 <sql:setDataSource/> 태그의 사용법은 다음과 같다.
Syntax <sql:setDataSource {dataSource="dataSource" | url="jdbcUrl" [driver="driverClassName"] [user="userName"] [password="password"]} [var="varName"] [scope="{page|request|session|application}"]/> |
오라클에서 사용을 한다면 다음과 같이 DataSource 를 설정할 수 있다.
<sql:setDataSource
url="jdbc:oracle:thin:@localhost:1521:ora81"
driver="oracle.jdbc.driver.OracleDriver"
user="scott"
password="tiger"
var="okjspDS"
scope="application" />
이미 컨텍스트에 JNDI 설정이 되어있다면 다음과 같이 바로 불러서 사용하거나 <sql:query/> 에서 바로 사용할 수 있다.
기존의 dataSource 를 불러와 사용하는 경우
<sql:setDataSource
dataSource="jdbc/sbjang"
var="okjspDS"
scope="application" />
<sql:query/> 에서 바로 사용하는 경우
<sql:query var="emp"
dataSource="jdbc/myora81">
2. <sql:query/>
java 와는 달리 sql 문장을 문자열로 연결하지 않아도 가독성을 높여서 작성할 수 있다. <sql:query/>태그의 형식은 다음과 같다.
Syntax 1: body 없는 경우 <sql:query sql="sqlQuery" var="varName" [scope="{page|request|session|application}"] [dataSource="dataSource"] [maxRows="maxRows"] [startRow="startRow"]/>
Syntax 2: body 에 쿼리의 파라메터가 있는 경우 <sql:query sql="sqlQuery" var="varName" [scope="{page|request|session|application}"] [dataSource="dataSource"] [maxRows="maxRows"] [startRow="startRow"]> <sql:param> 액션들 </sql:query>
Syntax 3: 쿼리와 파라메터들이 body 에 있는 경우 <sql:query var="varName" [scope="{page|request|session|application}"] [dataSource="dataSource"] [maxRows="maxRows"] [startRow="startRow"]> sqlQuery 선택적 <sql:param> 액션들 </sql:query>
|
3. <sql:dateParam/> , <sql:param/>
파라메터에는 두 가지가 있는데, 날짜 형식의 <sql:dateParam/> 와 일반적인 <sql:param/>태그가 있으며 형식은 다음과 같다.
Syntax <sql:dateParam value="value" type="[timestamp|time|date]"/>
Syntax 1: value 속성에 파라메터 값이 지정된 경우 <sql:param value="value"/>
Syntax 2: body 내용에 파라메터 값이 지정된 경우 <sql:param> parameter value </sql:param> |
<sql:dateParam/>은 java.sql.PreparedStatement.setTimestamp() 역할을 하고,
<sql:param/> 은 java.sql.PreparedStatement.setString() 의 역할을 한다. 바인드변수의 순서에 따라서 써주면 된다.
7장의 jdbc_resultset.jsp 파일을 JSTL로 바꾸어서 변경한 것이다.
예제 19. jstlsql01.jsp |
<%@ page pageEncoding="MS949" %> <%@ taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql" %> <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <fmt:setLocale value="ko" /> <sql:query var="emp" dataSource="jdbc/myora81"> SELECT EMPNO AS 사원번호, ENAME AS 이름, SAL AS 월급여, HIREDATE AS 입사일 FROM EMP
</sql:query>
<table border="1"> <tr> <%-- 필드의 정보를 출력한다. --%> <c:forEach var="columnName" items="${emp.columnNames}"> <th><c:out value="${columnName}"/></th> </c:forEach>
<%-- 데이터를 한 줄씩 출력한다. --%> <c:forEach var="row" items="${emp.rowsByIndex}"> <tr> <%-- 필드의 길이만큼 반복한다. --%> <c:forEach var="column" items="${row}" varStatus="i"> <c:choose> <c:when test="${i.index==3}"> <td><fmt:formatDate value="${column}" pattern="yyyy/MM/dd"/></td> </c:when> <c:otherwise> <td><c:out value="${column}"/></td> </c:otherwise> </c:choose> </c:forEach> </c:forEach> </table> <hr> <table border="1"> <c:forEach var="row" items="${emp.rows}"> <tr> <td>번호: <c:out value="${row['사원번호']}"/></td> <td>이름: <c:out value="${row['이름']}"/></td> </tr> </c:forEach> </table>
|
<s |
dataSource="jdbc/myora81" 의 JNDI는 7장에서 설명한 것처럼 컨텍스트에 설정된 DataSource 명이다.
SQL문은 보기 좋게 정렬을 해도 문자열로 덧붙일 필요가 없다. body 에 있는 sql문을 실행한 결과는 emp 라는 변수에 담겨서 이후에 사용이 된다. 이 변수는 ResultSet 과 같은데, JSTL에서 확장한 ResultSet 이고, javax.servlet.jsp.jstl.sql public interface Result 클래스로 내부적으로 정의된다. 지원하는 메소드는 다음과 같다.
javax.servlet.jsp.jstl.sql public interface Result public java.util.SortedMap[] getRows() public Object[][] getRowsByIndex() public String[] getColumnNames() public int getRowCount() public boolean isLimitedByMaxRows()
|
위와 같은 메소드들이 내부적으로 정의되어있기 때문에 각각의 getter 메소드들을 사용해서 변수 emp를 활용할 수 있다.
<c:forEach/> 의 items 에 있는 ${emp.columnNames}는 getColumnNames() 메소드를 불렀다는 것을 알 수 있다. 이전의 7장에서 ResultSetMetaData 를 활용해서 뽑아낸 정보와 같은 효과를 볼 수 있다.
테이블 내용을 반환하는 ${emp.rowsByIndex} 도 유념할 만하다. 한 행을 row라는 변수에 넣은 뒤에 다음의 <c:forEach/> 에서 이 row변수의 컬럼별로 내용을 출력한다.
column 이라는 변수에 넣은 뒤에 column의 index가 3일 경우 날짜형식을 출력하기 위해서 <fmt:formatDate/> 태그를 사용했고, 그 외의 경우는 바로 출력하게 했다.
다음 <c:forEach/> 에서는 결과를 SortedMap 배열에 넣은 뒤에 한 줄씩 빼서 컬럼이름으로 빼내는 방식이다.
4. <sql:update/>
java.sql.Statement.executeUpdate() 메소드에 해당하는 <sql:update/> 태그의 형식은 다음과 같다.
Syntax 1: body 없는 경우 <sql:update sql="sqlUpdate" [dataSource="dataSource"] [var="varName"] [scope="{page|request|session|application}"]/>
Syntax 2: update 파라메터가 body에 있는 경우 <sql:update sql="sqlUpdate" [dataSource="dataSource"] [var="varName"] [scope="{page|request|session|application}"]> <sql:param> 액션들 </sql:update>
Syntax 3: update 문과 선택적 update 파라메터가 body에 있는 경우 <sql:update [dataSource="dataSource"] [var="varName"] [scope="{page|request|session|application}"]> sqlUpdate 선택적 <sql:param> 액션들 </sql:update> |
형식과 동작은 <sql:query/> 태그와 동일하다. 다른 점은 executeUpdate() 메소드를 수행하기 때문에 DB에 변경을 가할 수 있다는 것이다.
5. <sql:transaction/>
트랜잭션을 구현하는 <sql:transaction/> 태그의 형식은 다음과 같다.
Syntax <sql:transaction [dataSource="dataSource"] [isolation=isolationLevel]> <sql:query> 과 <sql:update> 문들 </sql:transaction>
isolationLevel ::= "read_committed" | "read_uncommitted" | "repeatable_read" | "serializable" |
격리 수준(isolationLevel)은 java.sql.Connection 의 setTransactionIsolation() 메소드를 사용한다. 정리해 놓은 도표는 7장 JDBC의 Transaction 을 참고하기 바란다.
'강의노트 > 웹' 카테고리의 다른 글
CSS (0) | 2013.07.15 |
---|---|
JSTL XML 태그 (0) | 2013.07.11 |
JSTL 국제화 지역화 태그 (0) | 2013.07.10 |
JSTL core (0) | 2013.07.10 |
JSTL_EL (0) | 2013.07.09 |