Opennet Technologies: JDBC

Download Report

Transcript Opennet Technologies: JDBC

Technologies for an Information Age: .opennet
JDBC Tutorial
Fall Semester 2001 MW 5:00 pm - 6:20 pm CENTRAL (not Indiana) Time
Bryan Carpenter and Geoffrey Fox
PTLIU Laboratory for Community Grids
Computer Science,
Informatics, Physics
Indiana University
Bloomington IN 47404
[email protected]
1
Introduction





JDBC—usually interpreted as an acronym for Java
Database Connectivity—was introduced in 1996, and
revamped in 1998 for Java 2.
It is an API definition intended for implementation as a Java
interface to an SQL database.
SQL (“sequel”) is the Structured Query Language, originally
defined by IBM in the 70’s, standardized by ANSI/ISO in
1992.
SQL is in turn based on the relational database model. It is
implemented (with much variation) by many vendors of
RDBMS (Relational Database Management System)
software.
First commercial implementation of SQL: Oracle, 1979.
2
These Lectures




Start with a naïve introduction to SQL.
Followed by an introduction to basics of JDBC.
Continue with an example invoking SQL commands
through a JSP-based Web application.
To run the examples exactly as presented here you will
need to have MySQL installed.
– An earlier version of these lectures was based on Oracle
instead, and that will show through—responses of the MySQL
interpreter may not always be formatted exactly as shown in
these slides.
3
Installing MySQL (circa 9/5/01)


Go to www.mysql.com (not mysql.org!)
Download the Zip file, MySQL 3.23.44 for Windows. File
is mysql-3.23.44-win.zip.
– If you don’t have Winzip archiving program or equivalent, you will
need to download that as well, e.g. from download.com, keyword
Winzip.





From Windows Explorer, double-click the zip-file to unpack
it.
Double-click the command
\mysql\bin\winmysqladmin.exe to start the MySQL
administration tool.
Click on the traffic-light icon to start the database server
itself (“Win NT” → “Start the server standalone”).
Execute the command \mysql\bin\mysql to start the SQL
interpreter.
Before issuing SQL commands, you will have to create4
SQL
5
Relations


Mathematically, a relation is a subset of a product space.
Equivalently, it is a set of “tuples” with entries from some
fixed domains.
In mathematics, the most important relations tend to be
binary relations between entities of the same type:
LessThan, on {0, 1, 2, 3}  {0, 1, 2, 3}:
{ (0, 1), (0, 2), (0, 3), (1, 2), (1, 3), (2, 3) }
Contains, on {sunder, sun, sundry, dry}  {sunder, sun, sundry,
dry}:
{ (sunder, sunder), (sunder, sun), (sun, sun),
(sundry, sundry), (sundry, sun), (sundry, dry), (dry, dry) }
SameColor, on {tomato, cherry, banana}  {tomato, cherry,
banana}:
{ (tomato, tomato), (tomato, cherry), (cherry, tomato),
(cherry, cherry), (banana, banana) }
Examples respectively of total order, partial order and
6
General Relations

For databases, we are nearly always interested in n-ary
relations between distinct domains, e.g. assume:
Login
= {wcao, Flora, Fulay, zyr98210, jin0328}
LastName = {Cao, Flora, Fulay, Zhang}
Dept
= {CSIT, EE, CS}
then we may define the relation:
Students, on Login  LastName  Dept :
{ (wcao,
Cao,
CSIT),
(Flora,
Flora, EE ),
(Fulay,
Fulay, CS ),
(zyr98210, Zhang, CS ),
(jin0328, Zhang, CS ) }
7
SQL Tables






SQL is inspired by this mathematical model.
Names are changed, and for pragmatic reasons the
SQL model does not try to be mathematically pure.
A relation is called a table.
The individual tuples in the relation are called rows.
The domain sets of the relation are called by columns or
attributes.
Typing is not as strict as the mathematical model
suggests. We define the allowed values of a column in
terms of a limited set of predefined types, rather than
actual sets.
8
Creating a Table

A possible SQL command to create a table for our
Students relation is:
CREATE TABLE students (
login VARCHAR(10),
lastname VARCHAR(20),
dept VARCHAR(5)
)

Things to note:
– Case is not significant here. By convention we use upper case
for SQL keywords.
– White-space, including line-breaks, is not significant.
– The CREATE TABLE statement is syntactically like a class
definition, defining columns (c.f. fields) and their types.
– In this analogy, rows of the table would be like class instances.
9
Column Types

There are a limited set of types for column data.

Unfortunately (although there is supposed to be a
standard) in practice the available types are completely
dependent on the vendor.

In JDBC the types are standardized and include:
INTEGER
FLOAT(N)
CHARACTER(N)
VARCHAR(N)
BLOB
Typically 32-bit integer.
Floating point with N bits of precision.
Fixed length string, N characters.
Variable length string, maximum N.
A large binary object.
10
MySQL

To create a table using the MySQL interpreter, type
then:
mysql> create table students (
2 login varchar(10),
3 lastname varchar(20),
4 dept varchar(5)
5 );
Table created

In this interpreter commands are terminated by a
semicolon.
11
Inserting a Row

The SQL command for adding a row to a table is, e.g.:
INSERT INTO students VALUES (‘wcao’, ‘Cao’, ‘CSIT’)

In mysql I enter:
mysql> insert into students values (
2 ‘wcao’,
3 ‘Cao’,
4 ‘CSIT’) ;
1 row created.

The following examples assume the other tuples from
the Student relation are entered in the same way.
12
The SELECT command

To view the Students table I can use the SELECT
command:
SELECT * FROM students

The asterisk is a wildcard that causes all columns to be
display.
In mysql:
mysql> select * from students ;
LOGIN
LASTNAME
DEPT
----------------- ----------------------------- -----------wcao
Cao
CSIT
Flora
Flora
EE
Fulay
Fulay
CS
zyr98210
Zhang
CS
jin0328
Zhang
CS
5 rows selected
13
Displaying Chosen Columns

To limit the set of columns printed, specify them in the
SELECT command, e.g.:
SELECT login, lastname FROM students

In mysql:
mysql> select login, lastname from students ;
LOGIN
LASTNAME
----------------- ----------------------------wcao
Cao
Flora
Flora
Fulay
Fulay
zyr98210
Zhang
jin0328
Zhang
5 rows selected
14
Displaying Chosen Rows

To limit the set of rows printed, I add a WHERE clause:
SELECT * FROM students WHERE dept=‘CS’

Other kinds of tests that can appear in the WHERE
clause will be described later.
In mysql:
mysql> select * from students where dept=‘CS’ ;
LOGIN
LASTNAME
DEPT
----------------- ----------------------------- -----------Fulay
Fulay
CS
zyr98210
Zhang
CS
jin0328
Zhang
CS
3 rows selected
15
A Second Table

The following examples assume I define a second table by:
CREATE TABLE departments (
abbrev VARCHAR(5),
name VARCHAR(50)
)
and add the rows:
{ (‘CSIT’, ‘Computational Science and Information Technology’),
(‘EE’,
‘Electrical Engineering’),
(‘CS’,
‘Computer Science’) }
16
Selecting from Multiple Tables

A SELECT command can display data from more than
one tables:
SELECT * FROM students, departments

By itself this just produces a mess. In mysql:
mysql> select * from students, departments ;
LOGIN
LASTNAME
DEPT
ABBRE
----------------- ----------------------------- ------------ ---------NAME
-------------------------------------------------------------------wcao
Cao
CSIT
CSIT
Computational Science and Information Technology
Flora
Flora
EE
CSIT
Computational Science and Information Technology
Fulay
Fulay
CS
CSIT
Computational Science and Information Technology
...
15 rows selected
17
Joins




The previous query returned 15 rows.
It simply yielded a “Cartesian product” of the two
relations, with every row of students being combined
with every row of departments.
In itself this is not a useful result. But is a basis from
which to add a WHERE clause to select out some
meaningful combinations of values from the two tables.
If two tables appearing in the same statement share
some identical column names, can disambiguate by
using qualified names, e.g.:
students.login, students.lastname, students.dept, etc.
18
References Between Tables

Here is a meaningful query involving the two tables:
SELECT login, name FROM students, departments
WHERE dept=abbrev

In mysql:
mysql> select login, name from students, departments
2 where dept=abbrev ;
LOGIN
NAME
----------------- -------------------------------------------------------------------------Fulay
Computer Science
zyr98210
Computer Science
jin0328
Computer Science
wcao
Computational Science and Information
Technology
Flora
Electrical Engineering
5 rows selected
19
Primary Keys and Foreign Keys

This kind of cross-reference is so important that SQL
provides syntax to allow automatic “integrity checks”
and allow optimizations.

We can change the abbrev column to be a primary key
of the departments table by the following SQL
command:
ALTER TABLE departments ADD PRIMARY KEY (abbrev)

We can also add a constraint that any allowed value in
the dept column of students must be a valid primary
key in the departments table by the SQL command:
ALTER TABLE students ADD FOREIGN KEY (dept)
REFERENCES departments (abbrev)
20
Integrity Checks

The system will now forbid addition of values to the dept
column of students that do not correspond to values in
the abbrev column of departments.

For example, I can try to change the dept column of the
row describing wcao by the SQL UPDATE command:
UPDATE students SET dept=‘IE’ WHERE login=‘wcao’

Because of the constraints, Oracle (for example) will
refuse to make this update. In sqlplus:
SQL> update students set dept=‘IE’ where login=‘wcao’ ;
ERROR at line 1 :
ORA-02291: integrity constraint violated - parent key not
found.

Incidentally this example illustrates the use of UPDATE
command, which changes attributes of existing rows.
21
MySQL Idiosynchrasies


Last two slides will work as described for Oracle.
MySQL seems to be more pernickety about adding a
primary key to an existing table. I first had to specify:
alter table departments modify abbrev varchar(5) not null ;
to redundantly assure the system that the primary key
would never go null.
– Note SQL also allows you to specify these column constraints in
the CREATE TABLE command.

Also note, MySQL does not currently implement the
integrity checks for foreign keys, described in the
preceding slide.
– The system accepts the FOREIGN KEY constraint, but ignores
it.
– The documentation says such checks will be implemented in the
version 4.1
22
Other Useful Commands

. . . in addition to CREATE, SELECT and UPDATE,
which were illustrated earlier:
DELETE FROM table_name WHERE condition
Deletes selected rows.
DROP TABLE table_name
Removes a table.
DESCRIBE table_name
Describes columns of a table.
COMMIT
Save changes made in this transaction.
ROLLBACK
Undo changes made in this transaction.
23
Conditions

Conditions in WHERE clauses are Boolean expressions
built from:
– Comparision operators =, <>, <, <=, >, >=
– Boolean operators AND, OR, NOT
– The LIKE operator.

The LIKE operator compares a column value to a
pattern.
– In the pattern the wildcard % represents zero or more
characters.
– The wildcard _ represents a single character.
24
MySQL Administrivia

To create a database called dbname:
mysql> create database dbname ;

To start using that database:
mysql> use dbname ;

To get a list of all current databases:
mysql> show databases ;

To get a list of all current tables:
mysql> show tables ;

To show the column characteristics of a table called
tablename:
mysql> describe tablename ;
25
JDBC
26
A Simple Example
import java.sql.* ;
public class ShowStudents {
public static void main(String args[]) throws Exception {
String url = “jdbc:mysql://localhost/opennet_fall01” ;
System.setProperty(“jdbc.drivers”,
“org.gjt.mm.mysql.Driver”) ;
Connection conn =
DriverManager.getConnection(url) ;
Statement stat = conn.createStatement() ;
ResultSet rs = stat.executeQuery(“SELECT * FROM students”) ;
while(rs.next())
System.out.println(rs.getString(1) + “ ” +
rs.getString(2) + “ ” + rs.getString(3))
;
conn.close() ;
}
}
27
Remarks




To compile and run this example you must have a JDBC
driver installed for the database, and it must be on your
class path.
For MySQL, go to http://mmmysql.sourceforge.net/
and download the file mm.mysql-2.0.7-you-must-unjarme.jar.
On Windows, save it in the folder C:\, for example.
In this folder, run the command
jar xvf mm.mysql-2.0.7-you-must-unjar-me.jar


You should find the class file for
org.gjt.mm.mysql.Driver inside the C:\mm.mysql2.0.7\ folder.
Create a CLASSPATH environment variable with value:
.;c:\mm.mysql-2.0.7
28
Running ShowStudents

If we run ShowStudents we may see something like:
C:\ptliuegs> java ShowStudents
wcao Cao CSIT
Flora Flora EE
Fulay Fulay CS
zyr98210 Zhang CS
jin0328 Zhang CS

Effect is essentially like typing the command
select * from students ;
directly into the MySQL interpreter.
29
Classes in the Example

The example introduces the following classes and
interfaces from java.sql:
DriverManager
Manages a set of JDBC drivers.
Connection
A connection or session with a specific database. Context in
which SQL statements are executed and results returned.
Statement
Object used for executing an SQL statement.
ResultSet
Provides access to a table of data generated by executing a
statement.
30
The Driver Manager




The driver manager sits between the JDBC application
and one or more JDBC drivers.
A JDBC driver contains vendor-specific code to interface
to a particular back-end database.
On initialization, the class DriverManager will try to load
driver classes referenced in the jdbc.drivers property.
One can also load JDBC drivers explicitly, e.g.:
Class.forName(“org.gjt.mm.mysql.Driver”) ;
31
Making a Connection

There are several getConnection() methods on
DriverManager with different argument lists. The one
we used is:
static Connection getConnection(String url)
If you are using a non-default DB account and
password, use instead:
static Connection getConnection(String url,
String username,
String password)
32
Database URLs

Generally speaking the syntax of the URL should follow
the normal conventions for Internet URLs:
protocol // host : port / name
– protocol will be a sub-protocol of jdbc:, e.g.
jdbc:mysql:
– host and port are self-explanatory.
– name is the name of the database on the host.

The precise format depends on the driver. Oracle JDBC
URLs follow the general pattern, but they use different
separators.
– @ and : in place of // and /.
33
The Connection Interface


The Connection interface includes many methods.
Our first example only uses two simple ones:
Statement createStatement()
Creates a Statement object for sending SQL statements to the
database.
void close()
Releases database connection and associated JDBC
resources.
34
The Statement Interface


Object used for executing an SQL statement.
The most important methods for us will be:
ResultSet executeQuery(String sql) throws SQLException
Executes an SQL statement that returns a single result set.
Typically sql will be a SELECT statement.
int executeUpdate(String sql) throws SQLException
Executes an SQL statement that returns nothing. Typically sql
will be an INSERT, UPDATE or DELETE statement. Result is
number rows modified.


Note only one ResultSet can exist per Statement. If
you need to interleave queries, use multiple Statement
objects.
Other useful methods:
– addBatch(), executeBatch() to batch several SQL commands.
35
The ResultSet Interface



A result set behaves something like an Enumeration or
Iterator. This allows to iterate over the set of rows
returned by a query.
The next() method is used to move to the first row, then
all subsequent rows.
There is a large number of methods of the form:
XXX getXXX(int columnIndex)



that extract the contents of a column in the current row.
The one we will use most is getString(), which
interprets the column as a String.
Note columnIndex starts at 1, not zero.
ResultSet has many other methods. Many were added
in JDBC 2.0.
36
A Web Front-end to SQL
37
Example: Web Front End to SQL



We will go through a fairly substantial example that
combines JDBC with JSP.
This Web application will allow a user to connect to a
MySQL database on the server host, and submit
arbitrary SQL commands and queries.
Besides introducing a couple of new JDBC features, it
will illustrate (in more depth than the vending machine
examples) the structure of a Web application involving
multiple JSP pages.
38
Preliminaries


Before making your database accessible through a Web
server, you should set up some password protection.
First, use the mysqladmin command in mysql\bin\ to
set the database administrator password, e.g.:
C:\mysql\bin> mysqladmin -u root password admin-password
– Can still connect to the database from the local host without
specifying a user name or password, but other computers can
no longer connect to your database with dangerous privileges.

Example on following slides assumes a special account
is created with free access to one specified database on
the server. The account is created by issuing the
command:
mysql> GRANT ALL ON opennet_fall01.* TO
tomcat@localhost
IDENTIFIED BY “password” ;
– The account name is tomcat, database is opennet_fall01.
– Issue this command from within the mysql interpreter.
39
A First Screen

The introductory screen to our application is a static HTML
form, sqllogin.html:
<html>
<head></head>
<body>
<h1>Connect to SQL database</h1>
<form method=“post” action=“sqlconnect.jsp”>
SQL password: <input type=“password”
name=“password”
size=“20”/>
<p/>
<input type=“submit” value=“Connect to database”/>
</form>
</body>
</html>
40
Browser displays:
41
Remarks

The form prompts for a password
– We will see that this is the password associated with a database
account for a user called tomcat.

This is sent using the POST method (for limited privacy)
to the JSP page sqlconnect.jsp.
42
The sqlconnect.jsp JSP page
<%@ page errorPage=“sqlerror.jsp” %>
<jsp:useBean id=“sql” class=“mybeans.SQLBean” scope=“session”/>
<jsp:setProperty name=“sql” property=“password”/>
<%
sql.connect() ;
%>
<html><head></head>
<body>
<jsp:include page="sqlcommand.jsp"/>
</body>
</html>


This page establishes a session bean, sql, class
mybeans.SQLBean.
We assume this bean has properties and methods:
– A write-only property password, set from the form parameter of the same
name.
– A void, no-argument method called connect(), which attempts to establish
the database connection.

Further properties and methods will be introduced as needed.
43
After connection, bulk of document is generated by
Aside: An Unfortunate Feature




If a form field is left empty, the parameter value sent to the server is
the empty string, “”.
Unfortunately the jsp:setProperty action does nothing in this case.
In our example this has the odd effect that if you return to the login
page and submit with an empty password while the old session is
still valid, the connection succeeds because the old password is
remembered by the bean (setPassword() is not called to change
it.)
It’s not clear how serious a security risk this is, but if you are
concerned, replace the use of the jsp:setProperty action with an
explicit scriptlet:
<%
sql.setPassword(request.getParameter("password")) ;
%>
44
The sqlerror.jsp JSP page


The page directive in sqlconnect.jsp established an
error page sqlerror.jsp.
If any bean method or accessor used in the page throws
an exception, control is transferred to the page
sqlerror.jsp:
<%@ page isErrorPage=“true” %>
<html><head></head>
<body>
SQL error: <%= exception.getMessage() %>
</body>
</html>

If a page is declared to be an error page through the
page directive, the scripting variable exception is
available for use.
45
The sqlcommand.jsp JSP page
<form action=“sqlquery.jsp”>
<h1>SQL <em>query</em></h1>
<textarea name=“query” cols=“60”
rows=“3”></textarea><p>
<input type=submit value=“Submit Query”/>
</form>
<form action=“sqlupdate.jsp”>
<h1>SQL <em>update</em></h1>
<textarea name=“update” cols=“60”
rows=“3”></textarea><p>
<input type=submit value=“Submit Update”>
</form>
<form action=“sqlclose.jsp”>
Close database connection:
<input type=submit value=“Close”/>
</form>
46
Submitting a Command
47
Remarks

This pages just prints three forms, for SQL queries, SQL
action commands, and disconnecting, respectively.

Clearly one could use a static HTML page to do this.
There is a subtle reason why one may prefer a JSP page.
– The JSP session tracking mechanism preferentially uses cookies.
If this fails, because the user has configured his/her browser to
reject cookies, the JSP engine can still use URL-rewriting for
session tracking.
– URLs in dynamically generated pages (in our example the
relative URLs sqlquery.jsp, sqlupdate.jsp and sqlclose.jsp)
are extended with a session ID, which is thereby returned to the
server when the forms are submitted (this happens automatically,
if necessary, for a JSP page).
– The server can thus determine session context, even without
cookies.
– This is only possible if the HTML is dynamically generated;
48
Handling Queries



The most complicated page in our application is
sqlquery.jsp.
This will execute an arbitrary SELECT command, and
print out the results as an HTML table.
We assume the SQLBean has:
– A write-only trigger property query. Setting this property runs
the query, and initializes:
– a read-only property numCols, representing the number of
columns in the result, and
– an indexed read-only property colNames, representing the labels
for the columns in the result.
Setting query also prepares the bean for a sequence of
calls to:
– a boolean, no-argument method called nextRow(), which
initializes:
– an indexed read-only property, colValues, representing the
49
The sqlquery.jsp JSP page
<%@ page errorPage=“sqlerror.jsp” %>
<jsp:useBean id=“sql” class=“mybeans.SQLBean” scope=“session”>
<jsp:forward page=“sessionerror.html”/>
</jsp:useBean>
<jsp:setProperty name=“sql” property=“query”/>
<html><head></head>
<body>
<table border cellspacing=0 cellpadding=5>
<%
int numCols = sql.getNumCols() ;
out.println(“<tr bgcolor=lightblue>”) ;
for(int i = 0 ; i < numCols ; i++) out.println(“<td>” + sql.getColNames(i) +
“</td>”) ;
out.println(“</tr>”) ;
while(sql.nextRow()) {
out.println(“<tr>”) ;
for(int i = 0 ; i < numCols ; i++) out.println(“<td>” + sql.getColValues(i) +
“</td>”) ;
out.println(“</tr>”) ;
}
%>
</table>
<jsp:include page=“sqlcommand.jsp”/>
</body>
50
The Response
51
Remarks

The body of the jsp:useBean element forwards control
to a page called sessionerror.html.
– If the bean is newly created here, it will not be correctly
initialized—the password is not set and the connect() call does
not get called on the new bean. Most likely this is a symptom of
the session having timed out.
– The HTML page should just print a message to this effect.


The jsp:setProperty action actually triggers the
database access.
The rather complicated scriptlet is only responsible for
generating the body of a suitable HTML table of results.
– We used Java out.println() calls in here to generate HTML.
This is to avoid a confusing number of switches between Java
inserts and HTML template text.
52
Handling Updates

The sqlupdate.jsp page is much simpler.

We assume the SQLBean has:
– A write-only trigger property update. Setting this property runs
the database update, and initializes:
– a read-only property numRows, representing the number of
rows modified by the operation.
53
The sqlupdate.jsp JSP page
<%@ page errorPage=“sqlerror.jsp” %>
<jsp:useBean id=“sql” class=“mybeans.SQLBean”
scope=“session”>
<jsp:forward page=“sessionerror.html”/>
</jsp:useBean>
<jsp:setProperty name=“sql” property=“update”/>
<html><head></head>
<body>
<jsp:getProperty name=“sql” property=“numRows”/> rows
of the database were successfully updated. <p/>
<jsp:include page=“sqlcommand.jsp”/>
</body>
</html>
54
The sqlclose.jsp JSP page
<% session.invalidate() ; %>
<html><head></head>
<body>
Session finished. <p/>
Thank you for using the SQL application.
</body>
</html>


The active part of this page is simply a scriptlet that
invalidates the current session.
The SQLBean class should be implemented to close
the database connection when the session to which it is
bound is terminated.
55
SQLBean Specification: Summary

For connection:
– A write-only property password.
– A void, no-argument method called connect(), which attempts to establish the
database connection.
– The database connection should be closed when the session terminates.

For queries:
– A write-only trigger property query. Setting this property runs the query, and
initializes:
– a read-only property numCols, representing the number of columns in the
result, and
– an indexed read-only property colNames, representing the labels for the
columns in the result.
Setting query also prepares the bean for a sequence of calls to:
– a boolean, no-argument method called nextRow(), which initializes:
– an indexed read-only property, colValues, representing the values of the
columns in the next row of the result.

For updates:
– A write-only trigger property update. Setting this property runs the database
update, and initializes:
– a read-only property numRows, representing the number of rows modified by
the operation.
56
SQLBean Implementation
package mybeans ;
import java.sql.*;
import javax.servlet.http.*;
public class SQLBean implements HttpSessionBindingListener {
private String password ;
private Connection conn ;
private Statement stat ;
private ResultSet rs ;
private ResultSetMetaData rsmd ;
private int numCols, numRows ;
static {
String driver = "org.gjt.mm.mysql.Driver" ;
System.setProperty("jdbc.drivers", driver) ;
}
... Method declarations ...
}
57
Remarks




The file imports the JDBC classes and also the Servlet
classes.
Latter only needed for HTTPSessionBindingListener,
which the bean class implements. This will be
discussed at the end.
A bunch of private instance variables are declared.
The optional static initializer block of a class is called
once, when the class is loaded. We define the
jdbc.drivers property in here.
58
Connecting to the Database
public void setPassword(String password) {
this.password = password ;
}
public void connect() throws SQLException {
String url = "jdbc:mysql://localhost/opennet_fall01" ;
String user = "tomcat" ;
conn = DriverManager.getConnection(url, user,
password);
stat = conn.createStatement();
}


“Set” method for the password property, and connect
method.
Now using the version of getConnection that takes
account details.
59
Handling Queries


This presents some special problems because we don’t
know in advance how many columns the result table will
need, or what is the meaning of the entries.
We can cope with this kind of situation using result set
metadata.
60
Result Set Metadata

The ResultSet class has a method:
ResultSetMetaData getMetaData()
that returns a metadata object describing the results.

The only methods on ResultSetMetaData we will use
here are:
int getColumnCount()
returns the number of columns in the result set.
String getColumnLabel(int columnIndex)
returns a suggested label for use in printouts.
61
Bean Methods for Queries
public void setQuery(String query) throws SQLException {
rs
= stat.executeQuery(query) ;
rsmd = rs.getMetaData() ;
numCols = rsmd.getColumnCount() ;
}
public int getNumCols() {
return numCols ;
}
public String getColNames(int i) throws SQLException {
return rsmd.getColumnLabel(i + 1) ;
}
public boolean nextRow() throws SQLException {
return rs.next() ;
}
public String getColValues(int i) throws SQLException {
return rs.getString(i + 1) ;
}
62
Remarks

We assume indexes in the column names and values
properties go from 0, whereas in JDBC they go from 1.
63
Bean Methods for Handling Updates
public void setUpdate(String update) throws SQLException {
numRows = stat.executeUpdate(update) ;
}
public int getNumRows() {
return numRows ;
}
64
Terminating the Session

A session may end for various reasons; e.g. it times out,
or the invalidate() method is called on the session (as it
is in sqlclose.jsp.)
– After this happens, the associated session bean objects will
eventually be garbage collected.

Our bean has a fairly costly resource associated with
it—an open database connection. We want to make
sure this connection is closed as early as possible after
the session ends.
– Preferably without waiting for the garbage collector.

One way to do this is to have the object implement the
HttpSessionBindingListener interface.
65
The HttpSessionBindingListener
Interface
package javax.servlet.http;
interface HttpSessionBindingListener {
public void valueBound(HttpSessionBindingEvent evt) ;
public void valueUnbound(HttpSessionBindingEvent evt) ;
}


If an object bound to a Servlet session implements this
interface, the event-handling method valueBound() is
invoked on the object whenever it is bound to a session
(by setAttribute().)
The method valueUnbound() is invoked whenever this
object is unbound from a session, either by
removeAttribute(), or when the session is invalidated
(e.g. when it times out).
66
Methods for Closing the connection
...
import javax.servlet.http.*;
public class SQLBean implements
HttpSessionBindingListener {
...
public void valueBound(HttpSessionBindingEvent evt) {}
public void valueUnbound(HttpSessionBindingEvent evt) {
System.out.println("Closing database connection...") ; //
debug
try {
conn.close() ;
} catch (SQLException e) {} // Not much to be done about
it.
}
}
67
Using JDBC From Tomcat



Unlike early versions, Tomcat 4 seems to ignore the
CLASSPATH environment variable.
It looks for classes in various places within its own
installation directory.
You should move the entire org\ folder from inside the
folder C:\mm.mysql-2.0.7\, which you may have
installed earlier, into the C:\jakarta-tomcat\classes\
folder (or the classes\ subfolder of your Tomcat
installation, wherever it is).
– So the class file for the driver is at, e.g.:
C:\jakarta-tomcat\classes\org\gjt\mm\mysql\Driver.class

Now the driver class will be found when the Bean
methods try to use it.
68
Conclusions


We developed a powerful Web application using JSP
and JDBC, glued together with JavaBeans.
The implementation is quite clean, with a good
separation between application logic (access to JDBC),
and presentation logic.
– As noted in earlier examples, session tracking and error
handling are particularly elegant.
– The Bean code presumably has some scope for reuse in other
applications.

We still had to use scripting inserts fairly freely,
especially for displaying tables.
69
Epilogue: The DBTags Tag Library

Described at:
http://jakarta.apache.org/taglibs/doc/dbtags-doc/index.html

This is a generic tag library for using SQL commands in
JSP pages.
The next slide shows example usage.
– Idea similar to Cold Fusion?


If you specifically want to embed SQL commands in
your JSP pages, a standardized tag library like this is
probably the way to go.
On the other hand, if you want application-specific logic
abstracted into tags (and methods), writing your own
Bean is much less work than implementing you own tag
library.
70
71