무선접속과 물리적 네트워크가 나날이 발전해감에도 불구하고, 전체 시간에서 데이터베이스의 연결성에 문제가 발생하는 것에 대해서는 보장해주지 못하고 있고, 이러한 일은 사실상 불가능 하다. 비록 데이터베이스 연결에 대한 신뢰성있는 접근이 가능하다고 하더라도 자원의 한계를 고려하여 매우 신중하고 현명하게 이러한 일을 결정해야 한다. 캐싱은 이러한 문제점을 해결해 줄 수 있는 하나의 방법이며, 이러한 해결책은 설계에 과정에서 개발자들의 요구에 의해서 이루어 지고, 캐싱 레이어를 둠으로 해서 이를 구현할 수 있도록 하고 있다.
이번 아티클에서는 JDBC 2.0과 관련된 클래스를 소개하며, 이를 이용하여 단순하게 데이터베이스에 엑세스 할 수 있는 코드를 작성할 수 있고, JDBC 커넥션의 이용을 줄여줄거나, JDBC 1.0의 result set에서는 스크롤 할 수 없었던 것을 스크롤 할 수 있는 기능에 대해서 이야기 한다. 이 클래스는 sun으로 부터 획득할 수 있고, JDBC RowSet 인터페이스의 3가지 구현형태를 이용함으로 해서 쉽게 작성할 수이 있다. 이중 하나가 이번 아티클에서 소개하고자 하는 것이다. CachedRowSet 클래스는 단순한 JSP 애플리케이션을 위한 데이터모델로 주로 이용된다. EJB가 과잉으로 이용되어 있는 단순한 웹 환경에서 data-caching을 지원할 수 있는 좋은 케이스이다.
"disconnected" ResultSet과 같이 CachedRowSet을 고려할때, 이것은 javax.sql.RowSet에 이미 구현되어 있으며, javax.sql.RowSet는 java.sql.ResultSet로 상속받았기 때문에 이러한 구현이 되어 있는 것이다. 여기에는 알려진 많은 메소드 들이 있는것을 확인 할 수 있다. RowSet 인터페이스는 JDBC API 를 지원하며 JavaBeans 컴포넌트 모델 관점으로 지원된다. 이것은 표준 JDBC 2.0의 ResultSet의 기능과 메소드를 제공한다. 그러나 데이터베이스 커넥션을 유지 하지는 않아도 된다. 단지 JavaBean과 차이점은 javax.sql.RowSet의 구현으로 시리얼라이즈 되어 있다는 것이다. 이것은 ResultSet이 시리얼라이즈 되는것을 허용한다는 말이며, 원격지 클라이언트로 전송이 가능하고, 수정된 값을 서버로 전송이 가능하다는 말이 된다.CachedRowSet의 릴리즈를 하기에 좋은 시기는, Microsoft의 ActiveX Data Object(ADO)와 같이 결과 셋을 변환 가능하도록 하는 웹 개발에 가능할 것이다. 많은 엔트리/업데이트 형식은 레코드 내에서 전방향, 후방향으로 쉽게 스크롤이 가능하다. 이상적으로 사용자는 그들의 캐시된 상태의 레코드를 업데이트 할 수 있고, 모든 변화를 Save 커멘드를 이용하여 변경할 수 있도록 하고 있다. JDBC 2.0 ResultSet 인터페이스를 통해서 스크롤링 타입을 지원하고 있으며, 이것은 레코드를 통해서 데이터베이스에 오픈된 커넥션을 관리하기 위해 각각 세션이 필요하기 때문이다. 최대 데이터베이스 리소스는 정말 필요한 경우에 한해서 커넥션을 이용할 수 있도록 하고 있다. 커넥션이 필요없게 되면 커넥션풀을 가능한한 빠른 시점에 릴리즈를 할 수 있다. CachedRowSet은 이러한 유용성을 제공하고 있으며, 이것은 쿼리나 업데이트를 수행하는 동안에만 필요하다.
javax.sql.RowSet의 완전한 서드파티가 필요할 경우 아주 조금 필요할 것이며, 이것도 필요할 경우에만 이다. CachedRowSet는 새로운 Java 2 플랫폼에서 Enterprise Edition 의 javax.sql.RowSet 인터페이스와 함께 잘 알려진 기능을 수행할 것이다.
현재 CachedRowSet 구현부는 Java Developer Connection에서 다운로드 받을수 있다. 다운로드를 수행한 후에 rowset.jar 파일을 클래스 패스에 걸어주면 된다. CachedRowSEt 객체는 sun.jdbc.rowset 패키지 위치에 존재한다.
Create a CachedRowSet
CachedRowSet는 사실 JavaBean이다. 이것은 데이터베이스에 연결을 수행하도록 하고, 그것이 포함된 데이터를 탐색할 수 있도록 해준다. 테이블은 아래에 설명된것처럼 CachedRowSet에 필요한 초기화 프로퍼티 값을 지정해줌으로 해서 이전 데이터베이스 접속과 관계없이 생성할 수 있다.
Property | Description |
---|---|
Username | Database username |
Password | Database user password |
URL | Database JDBC URL such as jdbc:odbc:mydsn |
Command | SQL query statement |
이것이 JavaBean이기 때문에 CachedRowSet의 인스턴스를 생성할때 단순하게 기본 생성자를 이용함으로 해서 가능하다.
CachedRowSet crs = new CachedRowSet();
인스턴스를 한번 생성하면, 이것은 초기화 파라미터를 설정해줌으로 해서 초기화를 수행할 수 있다. 사실 CachedRowSet은 JSP에서 사용되는 단순한 빈으로 이용할 수 있다. JSP에서 CachedRowSet의 인스턴스를 생성하면 JSP의 표준 태그인 useBean을 이용하여 생성할 수 있다. JSP에서 가장 공통적이고 일반적인 방법을 이용하여 생성할 수 있는 것이다. useBean 태그는 새로운 인스턴스를 생성한다. 이것은 session 값으로 저장될 수 있으며, 스크립트 밸류에서 노출되게 할 수 있다. 만약 CachedRowSet을 초기화 할 수 있도록 useBean 태그에서도 처리할 수 있다. 이러한 접근은 애플리케이션의 서버가 커넥션 풀을 지원하는지 여부에 따라 결정되며, JDBC 1.0드라이버만 필요하다. Listing 1은 가장 명확한 방법으로 CachedRowSet을 JSP페이지에서 생성하는 예를 보여준다.
Listing 1: Explicit CachedRowSet initialization
class="sun.jdbc.rowset.CachedRowSet"
scope="session">
<%
// load database driver
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
// initialize our CachedRowSet bean
Contacts.setUsername("dbuser"); // example userid
Contacts.setPassword("dbpassword"); // example password
Contacts.setUrl("jdbc:odbc:ContactDB"); // example DSN
Contacts.setCommand("SELECT name, telephone from Contacts");
Contacts.execute();
%>
</jsp:useBean>
이러한 방식으로 CachedRowSet을 생성하면 필요한 데이터베이스와 연결을 획득하게 된다. Java 코드에서는 useBean과 end 태그 사이에 스크립트를 통해서 이러한 값을 설정할 수 있다. useBean은 session 스코프 안에 놓이게 된다. 그러므로 연속적인 페이지에서는 useBean 태그를 이용하지 않아도 이 객체를 이용할 수 있다.
JSP 컨테이너가 J2EE 커넥션 풀링을 지원하기 위해서, dataSourceName프로퍼티를 이용할 수 있을 것이다. 이러한 경우에는 생성하는 대신에 JNDI로 부터 연결을 획득하는 방법을 취할 수 있다. 이 스타일은 이미 생성된 커넥션 풀을 이용하여 커넥션을 생성하는 코드를 줄여갈 수 있다.
Listing 2: Initialization from a J2EE connection pool
// initialize our CachedRowSet bean using dataSourceName
// property
Contacts.setDataSourceName("Databases/ContactsDB/Datasource");
Contacts.setCommand("SELECT name, telephone from Contacts");
Contacts.execute();
%>
J2EE 커넥션 풀로 부터 CachedRowSet을 생성하여 소유된 커넥션을 통해서 생성하 것이 오히려 더욱 바람직하다. dataSourceName 프로퍼티는 CachedRowSet이, JNDI 네임스페이스를 통해 커넥션을 찾아야 한다는 것을 말한다. execute() 메소드를 호출하면 CahcedRowSet은 JNDI로 부터 javax.sql.DataSource의 인스턴스를 탐색한다는 말이된다. DataSource객체는 JDBC 커넥션을 RowSet에 제공한다.
CachedRowSet에 의존해서 커넥션을 획득하는것 대신에, execute 메소드에 전달할 아규먼트로 존재하는 커넥션을 제공할 수 있다. Listing 3은 J2EE로부터 커넥션풀을 획득하지만 JNDI 룩업을 명시적으로 수행하고 있다.Listing 3: Initialization by passing an existing connection
// get connection from pool
InitialContext ctx = new InitialContext();
javax.sql.DataSource ds =
(javax.sql.DataSource)ctx.lookup
("Databases/ContactsDB/DataSource");
java.sql.Connection con = ds.getConnection();
Contacts.setCommand("SELECT name, telephone from Contacts");
// supply the connection to the RowSet
Contacts.execute(con);
%>
커넥션 풀의 JNDI 룩업 이름은 애플리케이션의 서버에 다양하게 존재할 수 있다. 커넥션 풀에 대해서는 JNDI 룩업 패턴을 이용하여 서버에게 문의하는 방식을 이용한다.
Display CachedRowSet Properties in a JSP
초기화된 CachedRowSet을 획득한 이후에는 java.sql.ResultSet 객체를 이용할 수 있다. 이전에 이야기한것과 같이 CachedRowSet은 java.sql.ResultSet 인터페이스를 구현한 다른 버젼일 뿐이다. CahcedRowSet에 대상 로의 커서의 위치를 통해서 접근할 수 있으며 getString()메소드를 이용할 수 있다. 만약 데이터 타입을 모르겠다면 getObject()메소드를 이용할 수 있다. 원래 결과 셋의 이름 대신에 인덱스를 이용하여 칼럼에 접근 할 수도 있다.
Contacts.getString(1);
만약 Listing 1에서 봤던것 처럼 useBean 태그를 포함하고 있다면, CachedRowSet에 대해서 페이지 어디에서든지 접근할 수 있으며 스크립팅 ID를 이용하여 이러한 접근이 가능하다. 아래와 같이, CachedRowSet 칼럼을 HTML form 필드에 이용할 수 있다.
name="ContactName"
value="<%=Contacts.getString(1)%>"/>
추가적으로 프로퍼티를 획득할 수 있는데, CachedRowSet에 대한 정보를 다양하게 획득 할 수 있다. 현재 row 넘버를 확인하는 예는 다음과 같다.
Navigation은 CachedRowSet 프로퍼티를 디스플레이하기 위해 매우 중요한 정보이다. CachedRowSet은 ResultSet 인터페이스에 선언된 커맨드를 이용하게 된다. JDBC 2.0 메소드에 새로 추가된 것은 previous()와 first(), last()가 그것이다.
표준 JDBC 버젼을 현재 JDBC1.0에서 이용하고 있따. 아직 2.0레벨의 ODBC드라이버는 업데이트 되지 않았따. 클라이언트 캐시 데이터 때문에 CachedRowSet은 스크롤 기능을 제공한다. forward와 backword로 커서 이동은 JDBC 1.0드라이버의 기능이다.
This nice feature relieves developers from having towrite their own ResultSet
cache objects forrecord-browsing applications. JSP로 부터 네비게이션을 수행하고자 한다면, 단순하게 request에 커맨드 파라미터를 이용하면 된다.
if ( req.getParameter("next") != null ) {
if (! Contacts.next() )
Contacts.last();
} else if ( req.getParameter("prev") != null) {
if (! Contacts.previous())
Contacts.first();
}
각 네비게이션 메소드는 true혹은 false를 반환한다. 이것은 그것들의 연속된 값에 의존하고 있으며, 만약 실패하는 경우 커서는 반드시 유효한 위치를 반환해야한다. 단순하게 submit 버튼의 예이며, 여기에서는 next라는 이름으로 하고자 하는 일을 반영하고 있으며, 파라미터로 네비게이션 정보를 보낸다.
Perform Updates to a CachedRowSet
CachedRowSet의 기능중에서 가장 좋아하는 기능은 데이터베이스에 업데이트를 수행하는 작업이다. ASP와 같은 개발 프로그램에서 Micorsoft ADO를 이용한 부분은 상당히 좋은 평가를 받는 방식이다. CahcedRowSet은 하나의 처리를 통해서 업데이트에 대한 SQL의 수를 잠재적으로 줄여준다. Combining 업데이터는 제한된 데이터베이스를 가지게 하며, 보틀넥을 생기게 만든는, 웹 어플리케이션에서 주요 이점중에 하나이다. 대부분의 CachedRowSet을 이용한 애플리케이션에서, 오직 초기 SQL 구문을 이용하여 쿼리를 제공하기만 하면 된다. 그리고 단지 3개의 메소드를 지정된 순서대로 호출해주기만 하면 업데이트가 진행된다. 데이터베이스 예에서 다음과 같이 컬럼타입에 의존된 형태는 다음 과 같이 처리할 수 있다.
필요하다면 위와같은 메소드를 어러번 반복적으로 호출해주면된다.
다음으로, 커서퍼지션을 이동할 수 있다. RowSet은 현재 로의 변환에 대해서 커밋을 수행하고자 하는지 알려주어야 한다.
Contacts.updateRow();
상단의 코드는 데이터베이스의 변화를 수행하지는 않는다. 이것은 RowSet의 캐시된 포지션 정보를 변경에 대해서 커밋을 수행하는 것이다. CahcedRowSet의 중요한 기능이다. 만약 레코드가 변경된다면, 이것은 데이터베이스와 연결되어 변환되는 것이 아니다. 사용자는 RowSet에 변화가 된 내용을 데이터베이스에 커밋을 수행할 준비가 되면 커넥션이 필요하게 된다.
세번째와 마지막 단계는 acceptCanges()를 호출하는 것이다. 이것은 데이터베이스에 배치로 변화를 적용하는 것이다. 다시 CachedRowSet을 Listing 1과 같이 생성했다면 다음 코드는 변화된 내용을 데이터베이스에 반영할 것이다.
만약 초기화와 CahcedRowSet을 Listing 3과 같이 수행한경우라면 다음과 같이 커넥션 객체를 전달하면 된다.
JSP에서 요청 파라미터와 연관되게 한다면 커밋과 업데이트를 수행하기 위해서 다음과 같이 처리할 수 있다.
Contacts.acceptChanges();
}
CachedRowSet은 입력과 딜리트 역시 수행하도록 되어 있따. CachedRowSet에 입력을 하는 방법도 매우 단순하다. 이것은 또한 직관적이지 않을 수 있다. 입력하기 전에 "insert row"라고 불리는 특정 포지션으로 커서의 위치를 이동해야한다.
다음 코드는 CachedRowSet에 새로운 로를 업데이트 하는 과정이다.
|
- 현재커서 이후에 새로운 로를 입력한다.
- 모든 필드를 비어있는 상태로 초기화 한다.
- 폼으로 부터 새로운 입력 로를 표현한다.
추가적으로 레코드 입력 기능은 JSP에서 새로운 파라미터인 "insert"를 필요로 할 것이다.
Contacts.moveToInsertRow();
Contacts.updateString(1, "");
Contacts.updateString(2, "");
Contacts.insertRow();
Contacts.moveToCurrentRow();
Contacts.next();
}
Other Uses of the CachedRowSet
cached ResultSet을 JSP 이면에서 필요로 하는 경우가 있다. CahcedRowSet은 대부분 시리얼라이즈된 테이블 데이터를 클라이언트로 보내야할 요청이 있을때 유용하다. 무선 컴퓨터 장치가 있다고 했을때, 네트워크 데이터 소스로 부터 주시적으로 연결이 끊어지게 된다. 하지만 데이터를 추가하고 유지해야한다. 이러한 경우 CachedRowSet을 EJB 세션 빈으로 부터 테이블 형식의 데이터를 읽을 수 있게 한다.
CachedRowSet는 돈을 저장하는것과 같다고 생각하라. 만약 아주큰 데이터 셋을 적용하고자 한다면, CachedRowSet은 적절한 선택이 아니다.
Listing 4에서 보여주는 JSP entry/edit 페이지는 CachedRowSet을 이용하여 데이터 모델을 처리하는 완벽한 예제이다. 명백하개 JSP 페이지에서 초기화 코드를 포함하고 있다는 것을 확인하라. 코드는 useBean 태그를 이용하였다. 큰 프로젝트에서는 이것은 컨트롤러 서블릿 단에서 처리될 것이다.
Listing 4: JSP example update/entry form
|
아래 그림은 브라우저로 상위 코드를 실행한 것이다.
JSP from Listing 4 viewed in a browser |
Conclusion
JSP 애플리케이션은 data-cache의 미들레이어를 이용하여 개량된 자원의 공유를 원한다. EJB는 대부분 작은 크기의 애플리케이션에서 쓸데없는 짓을 많이 했다. CachedRowSet은 데이터베이스 연결 없이 JDBC 데이터 소스에 지정된 형식으로 접근할 수 있는 방법을 제공한다. CachedRowSet은 또한 단순하게 data-access 코드를 entry/edit JSP 애플리케이션에서 이용하도록 해준다. 기억할 것은 예제 페이지에서는 한번의 SQL 스테이트먼트를 이용하여 update, insert, delete 작업을 수행할 수 잇다는것을 보여준다. 추가적으로 CachedRowSet은 disconnect와 reconnect을 데이터소스를 이용하여 처리할 수 있는 기능을 제공한다.
RESOURCES:
- Download this article's source code and resource files:
source code archive - Download
CachedRowSet
from the Java Developer Connection (registration required):
cachedrowset download - "The JDBC 2.0 API Tutorial and Reference," Maydene Fisher and Seth White. Chapter 5 focuses on
RowSet
implementations:
Rowset tutorial - J2EE API documentation. See Javadoc for the
javax.sql
package:
J2EE API - Read more about JDBC in JavaWorld's Topical Index:
Java Database Connectivity (JDBC) on JavaWorld - To read more about JSPs, browse the Server-Side Java section of JavaWorld's Topical Index:
Server-Side Java on JavaWorld - Talk about JSPs in ITworld.com's Server-Side Java discussion, moderated by Govind Seshadri:
ITworld.com Forums: Server-Side Java - Sign up for the JavaWorld This Week free weekly email newsletter and keep up with what's new at JavaWorld:
ITworld.com Newsletters
Reprinted with permission from the February 2001 edition of JavaWorld magazine. Copyright Web Publishing Inc., an IDG Communications company. Register for editorial e-mail alerts
About the Author
Taylor Cowan, a systemarchitect with Bondi Software, is currently developing JSP custom taglibraries and frameworks for J2EE application servers. He has amaster's degree in computer science from the University of North Texas.
'WEB_Programming > Pure Java' 카테고리의 다른 글
Regular Expression > Test Harness (0) | 2008.11.06 |
---|---|
Regular Expression > Introduction (0) | 2008.11.06 |
The SortedMap Interface (1) | 2008.11.03 |
The SortedSet Interface (0) | 2008.11.03 |
Object Ordering (0) | 2008.10.29 |