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/> 태그의 사용법은 다음과 같다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
Syntax
<sql:setDataSource
{dataSource="dataSource" |
url="jdbcUrl"
[driver="driverClassName"]
[user="userName"]
[password="password"]}
[var="varName"]
[scope="{page|request|session|application}"]/>
|
cs |
오라클에서 사용을 한다면 다음과 같이 DataSource 를 설정할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
|
<sql:setDataSource
url="jdbc:oracle:thin:@localhost:1521:orcl"
driver="oracle.jdbc.driver.OracleDriver"
user="C##XERXES"
password="****"
var="okjspDS"
scope="application" />
|
cs |
이미 컨텍스트에 JNDI 설정이 되어있다면 다음과 같이 바로 불러서 사용하거나 <sql:query/> 에서 바로 사용할 수 있다.
기존의 dataSource 를 불러와 사용하는 경우
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
<sql:setDataSource
dataSource="jdbc/sbjang"
var="okjspDS"
scope="application" />
<sql:query/> 에서 바로 사용하는 경우
<sql:query var="emp"
dataSource="jdbc/myora81">
|
cs |
2. <sql:query/>
java 와는 달리 sql 문장을 문자열로 연결하지 않아도 가독성을 높여서 작성할 수 있다. <sql:query/>태그의 형식은 다음과 같다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
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>
|
cs |
파라메터에는 두 가지가 있는데, 날짜 형식의 <sql:dateParam/> 와 일반적인 <sql:param/>태그가 있으며 형식은 다음과 같다.
3. <sql:dateParam/> , <sql:param/>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
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>
|
cs |
<sql:param/> 은 java.sql.PreparedStatement.setString() 의 역할을 한다. 바인드변수의 순서에 따라서 써주면 된다.<sql:dateParam/>은 java.sql.PreparedStatement.setTimestamp() 역할을 하고,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
|
<%@ 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>
|
cs |
dataSource="jdbc/myora81" 의 JNDI는 7장에서 설명한 것처럼 컨텍스트에 설정된 DataSource 명이다.
SQL문은 보기 좋게 정렬을 해도 문자열로 덧붙일 필요가 없다. body 에 있는 sql문을 실행한 결과는 emp 라는 변수에 담겨서 이후에 사용이 된다. 이 변수는 ResultSet 과 같은데, JSTL에서 확장한 ResultSet 이고, javax.servlet.jsp.jstl.sql public interface Result 클래스로 내부적으로 정의된다. 지원하는 메소드는 다음과 같다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
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()
|
cs |
위와 같은 메소드들이 내부적으로 정의되어있기 때문에 각각의 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/> 태그의 형식은 다음과 같다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
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>
|
cs |
형식과 동작은 <sql:query/> 태그와 동일하다. 다른 점은 executeUpdate() 메소드를 수행하기 때문에 DB에 변경을 가할 수 있다는 것이다.
1
2
3
4
5
6
7
8
9
10
11
12
13
|
<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>
|
cs |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
<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>
|
cs |
5. <sql:transaction/>
트랜잭션을 구현하는 <sql:transaction/> 태그의 형식은 다음과 같다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
Syntax
<sql:transaction [dataSource="dataSource"]
[isolation=isolationLevel]>
<sql:query> 과 <sql:update> 문들
</sql:transaction>
isolationLevel ::= "read_committed"
| "read_uncommitted"
| "repeatable_read"
| "serializable"
|
cs |
격리 수준(isolationLevel)은 java.sql.Connection 의 setTransactionIsolation() 메소드를 사용한다.
'Programming > [JSP]' 카테고리의 다른 글
[WEB] 크롤링(HTTrack) (0) | 2018.05.08 |
---|---|
[JSTL] for tokens를 forEach로 바꾸기 (0) | 2018.05.05 |
[JSP] 톰캣으로 프로젝트 실행시 시작페이지 설정 (0) | 2018.05.03 |
[JSP] 썸네일 만들기 (0) | 2018.05.01 |
[JSP] 파일 업로드 기초 (0) | 2018.05.01 |