JSTL SQL 태그

강의노트/웹 2013. 7. 11. 14:09

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에 변경을 가할 수 있다는 것이다.

<sql:query var="books" 
        sql="select * from PUBLIC.books where id = ?" >
        <sql:param value="${bookId}" />
</sql:query>
 
<c:forEach var="bookRow" begin="0" items="${books.rows}">            
        <sql:update var="books" sql="update PUBLIC.books set
              inventory = inventory - ? where id = ?" >
              <sql:param value="${item.quantity}" />
              <sql:param value="${bookId}" />
        </sql:update>
      </c:forEach>
    </c:forEach>

 

<c:forEach var="bookRow" begin="0"
      items="${books.rowsByIndex}"> 
  <jsp:useBean id="bid"  type="java.lang.String" />
  <jsp:useBean id="bookRow" type="java.lang.Object[]" />
  <jsp:useBean id="addedBook" class="database.BookDetails"
    scope="page" >
    <jsp:setProperty name="addedBook" property="bookId"
      value="${bookRow[0]}" />
    <jsp:setProperty name="addedBook" property="surname"
      value="${bookRow[1]}" />
    <jsp:setProperty name="addedBook" property="firstName"
      value="${bookRow[2]}" />
    <jsp:setProperty name="addedBook" property="title"
      value="${bookRow[3]}" />
    <jsp:setProperty name="addedBook" property="price"
      value="${bookRow[4])}" />
    <jsp:setProperty name="addedBook" property="year"
      value="${bookRow[6]}" />
    <jsp:setProperty name="addedBook" 
      property="description" 
      value="${bookRow[7]}" />
    <jsp:setProperty name="addedBook" property="inventory"
      value="${bookRow[8]}" />
  </jsp:useBean>
  <% cart.add(bid, addedBook); %>
  ...
</c:forEach> 
 

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