10 JDBC
10 JDBC
Murach’s Java Servlets/JSP (2nd Ed.), C14 © 2008, Mike Murach & Associates, Inc. Slide 1
Objectives
Applied
Develop data classes that provide OR mapping and all of the
database methods that your servlets need.
Develop servlets that use connection pooling and the methods of
your data classes.
Knowledge
In terms of the DriverManager, Connection, Statement, ResultSet,
and PreparedStatement classes, describe what a web application
has to do to get data from a database.
Explain how prepared statements can improve the performance of
database operations.
Describe the use of a ResultSetMetaData object.
Murach’s Java Servlets/JSP (2nd Ed.), C14 © 2008, Mike Murach & Associates, Inc. Slide 2
Objectives (cont.)
Explain how connection pooling can improve the performance of
a web application.
Describe OR (object to relational) mapping.
Murach’s Java Servlets/JSP (2nd Ed.), C14 © 2008, Mike Murach & Associates, Inc. Slide 3
The four types of JDBC database drivers
Type 1 A JDBC-ODBC bridge driver converts JDBC calls into
ODBC calls that access the DBMS protocol. The ODBC
driver must be installed on the client machine.
Type 2 A native protocol partly Java driver converts JDBC calls
into calls in the native DBMS protocol. This conversion
takes place on the client.
Type 3 A net protocol all Java driver converts JDBC calls into a net
protocol that’s independent of any native DBMS protocol.
Then, middleware software running on a server converts the
net protocol to the native DBMS protocol. This conversion
takes place on the server side.
Type 4 A native protocol all Java driver converts JDBC calls into a
native DBMS protocol. This conversion takes place on the
server side.
Murach’s Java Servlets/JSP (2nd Ed.), C14 © 2008, Mike Murach & Associates, Inc. Slide 4
How to download a database driver
For MySQL databases, you can download a JDBC driver named
Connector/J from the MySQL web site. This driver is an open-
source, type-4 driver that’s available for free.
For other databases, you can usually download a type-4 JDBC
driver from the database’s web site.
Murach’s Java Servlets/JSP (2nd Ed.), C14 © 2008, Mike Murach & Associates, Inc. Slide 5
Database URL syntax
jdbc:subprotocolName:databaseURL
Murach’s Java Servlets/JSP (2nd Ed.), C14 © 2008, Mike Murach & Associates, Inc. Slide 6
How to connect to an Oracle database with
automatic driver loading
Connection connection = DriverManager.getConnection(
"jdbc:oracle:thin@localhost/murach", "scott",
"tiger");
Murach’s Java Servlets/JSP (2nd Ed.), C14 © 2008, Mike Murach & Associates, Inc. Slide 7
How to connect to a database
You use the getConnection method of the DriverManager class to
return a Connection object.
When you use the getConnection method, you must supply a URL
for the database, a username, and a password. This method throws
a SQLException.
With JDBC 4.0, the SQLException class implements the Iterable
interface.
With JDBC 4.0, the database driver is loaded automatically. This
new feature is known as automatic driver loading. Prior to JDBC
4.0, you needed to use the forName method of the Class class to
load the driver. This method throws a ClassNotFoundException.
The connection string for each driver is different, so see the
documentation for details.
It’s possible (though not typical) to load multiple database drivers
and establish connections to multiple types of databases.
Murach’s Java Servlets/JSP (2nd Ed.), C14 © 2008, Mike Murach & Associates, Inc. Slide 8
How to create a result set that contains 1 row and
1 column
Statement statement = connection.createStatement();
ResultSet userIDResult = statement.executeQuery(
"SELECT UserID FROM User " +
"WHERE EmailAddress = '[email protected]'");
Murach’s Java Servlets/JSP (2nd Ed.), C14 © 2008, Mike Murach & Associates, Inc. Slide 9
How to move the cursor to the first record in the
result set
boolean userIDExists = userIDResult.next();
Murach’s Java Servlets/JSP (2nd Ed.), C14 © 2008, Mike Murach & Associates, Inc. Slide 10
ResultSet methods for forward-only, read-only
result sets
Method Description
next() Moves the cursor to the next row in the result set.
last() Moves the cursor to the last row in the result set.
close() Releases the result set’s resources.
getRow() Returns an int value that identifies the current row of
the result set.
Murach’s Java Servlets/JSP (2nd Ed.), C14 © 2008, Mike Murach & Associates, Inc. Slide 11
How to return a result set and move the cursor
through it
To return a result set, you use the createStatement method of a
Connection object to create a Statement object. Then, you use the
executeQuery method of the Statement object to execute a
SELECT statement that returns a ResultSet object.
By default, the createStatement method creates a forward-only,
read-only result set. This means that you can only move the
cursor through it from the first record to the last and that you
can’t update it.
When a result set is created, the cursor is positioned before the
first row. Then, you can use the methods of the ResultSet object
to move the cursor.
The createStatement, executeQuery, and next methods throw an
SQLException. As a result, any code that uses these methods
needs to catch or throw this exception.
Murach’s Java Servlets/JSP (2nd Ed.), C14 © 2008, Mike Murach & Associates, Inc. Slide 12
Methods of a ResultSet object that return data
from a result set
Method Description
getXXX(int columnIndex) Returns data from the specified
column number.
getXXX(String columnName) Returns data from the specified
column name.
Murach’s Java Servlets/JSP (2nd Ed.), C14 © 2008, Mike Murach & Associates, Inc. Slide 13
Code that uses column indexes to return fields from
the products result set
String code = products.getString(1);
String description = products.getString(2);
double price = products.getDouble(3);
Murach’s Java Servlets/JSP (2nd Ed.), C14 © 2008, Mike Murach & Associates, Inc. Slide 14
How to retrieve data from a result set
The getXXX methods can be used to return all eight primitive types.
Examples:
getInt
getLong
The getXXX methods can also be used to return strings, dates, and
times. Examples:
getString
getDate
getTime
getTimestamp
Murach’s Java Servlets/JSP (2nd Ed.), C14 © 2008, Mike Murach & Associates, Inc. Slide 15
How to use the executeUpdate method to modify
data
How to add a record
String query =
"INSERT INTO Product (ProductCode,
ProductDescription, ProductPrice) " +
"VALUES ('" + product.getCode() + "', " +
"'" + product.getDescription() + "', " +
"'" + product.getPrice() + "')";
Statement statement = connection.createStatement();
int rowCount = statement.executeUpdate(query);
How to update a record
String query = "UPDATE Product SET " +
"ProductCode = '" + product.getCode() + "', " +
"ProductDescription = '" + product.getDescription() +
"', " +
"ProductPrice = '" + product.getPrice() + "' " +
"WHERE ProductCode = '" + product.getCode() + "'";
Statement statement = connection.createStatement();
int rowCount = statement.executeUpdate(query);
Murach’s Java Servlets/JSP (2nd Ed.), C14 © 2008, Mike Murach & Associates, Inc. Slide 16
How to use the executeUpdate method to modify
data (cont.)
How to delete a record
String query = "DELETE FROM Product " +
"WHERE ProductCode = '" + productCode +
"'";
Statement statement = connection.createStatement();
int rowCount = statement.executeUpdate(query);
Returns an int value that identifies the number of records that were
affected by the SQL statement.
Murach’s Java Servlets/JSP (2nd Ed.), C14 © 2008, Mike Murach & Associates, Inc. Slide 17
How to use a prepared statement
To return a result set
String preparedSQL = "SELECT ProductCode,
ProductDescription, ProductPrice "
+ "FROM Product WHERE ProductCode = ?";
PreparedStatement ps =
connection.prepareStatement(preparedSQL);
ps.setString(1, productCode);
ResultSet product = ps.executeQuery();
Murach’s Java Servlets/JSP (2nd Ed.), C14 © 2008, Mike Murach & Associates, Inc. Slide 18
How to use a prepared statement (cont.)
To modify data
String preparedSQL = "UPDATE Product SET "
+ " ProductCode = ?, "
+ " ProductDescription = ?, "
+ " ProductPrice = ?"
+ "WHERE ProductCode = ?";
PreparedStatement ps =
connection.prepareStatement(preparedSQL);
ps.setString(1, product.getCode());
ps.setString(2, product.getDescription());
ps.setDouble(3, product.getPrice());
ps.setString(4, product.getCode());
ps.executeUpdate();
Murach’s Java Servlets/JSP (2nd Ed.), C14 © 2008, Mike Murach & Associates, Inc. Slide 19
How to use a prepared statement (cont.)
To insert a record
String preparedQuery =
"INSERT INTO Product (ProductCode,
ProductDescription, ProductPrice) "
+ "VALUES (?, ?, ?)";
PreparedStatement ps =
connection.prepareStatement(preparedQuery);
ps.setString(1, product.getCode());
ps.setString(2, product.getDescription());
ps.setDouble(3, product.getPrice());
ps.executeUpdate();
Murach’s Java Servlets/JSP (2nd Ed.), C14 © 2008, Mike Murach & Associates, Inc. Slide 20
How to use a prepared statement (cont.)
To delete a record
String preparedQuery = "DELETE FROM Product "
+ "WHERE ProductCode = ?";
PreparedStatement ps =
connection.prepareStatement(preparedQuery);
ps.setString(1, productCode);
ps.executeUpdate();
Murach’s Java Servlets/JSP (2nd Ed.), C14 © 2008, Mike Murach & Associates, Inc. Slide 21
How to work with prepared statements
When you use prepared statements in your Java programs, the
database server only has to check the syntax and prepare an
execution plan once for each SQL statement. This improves the
efficiency of the database operations.
To specify a parameter for a prepared statement, type a question
mark (?) in the SQL statement.
To supply values for the parameters in a prepared statement, use
the set methods of the PreparedStatement interface.
To execute a SELECT statement, use the executeQuery method.
To execute an INSERT , UPDATE, or DELETE statement, use
the executeUpdate method.
Murach’s Java Servlets/JSP (2nd Ed.), C14 © 2008, Mike Murach & Associates, Inc. Slide 22
The SQL Gateway application after executing an
INSERT statement
Murach’s Java Servlets/JSP (2nd Ed.), C14 © 2008, Mike Murach & Associates, Inc. Slide 23
The SQL Gateway application after executing a
SELECT statement
Murach’s Java Servlets/JSP (2nd Ed.), C14 © 2008, Mike Murach & Associates, Inc. Slide 24
The code for the JSP (sqlGateway.jsp)
<!doctype html public
"-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>Murach's Java Servlets and JSP</title>
</head>
<body>
Murach’s Java Servlets/JSP (2nd Ed.), C14 © 2008, Mike Murach & Associates, Inc. Slide 25
The code for the JSP (cont.)
<p>
<b>SQL statement:</b><br>
<form action="sqlGateway" method="post">
<textarea name="sqlStatement" cols="60"
rows="8">${sqlStatement}
</textarea><br><br>
<input type="submit" value="Execute">
</form>
</p>
<p>
<b>SQL result:</b><br>
${sqlResult}
</p>
</body>
</html>
Murach’s Java Servlets/JSP (2nd Ed.), C14 © 2008, Mike Murach & Associates, Inc. Slide 26
The SQLGatewayServlet class
package sql;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.sql.*;
try
{
Murach’s Java Servlets/JSP (2nd Ed.), C14 © 2008, Mike Murach & Associates, Inc. Slide 27
The SQLGatewayServlet class (cont.)
// get a connection
String dbURL =
"jdbc:mysql://localhost:3306/murach";
String username = "root";
String password = "sesame";
Connection connection =
DriverManager.getConnection(
dbURL, username, password);
// create a statement
Statement statement =
connection.createStatement();
Murach’s Java Servlets/JSP (2nd Ed.), C14 © 2008, Mike Murach & Associates, Inc. Slide 28
The SQLGatewayServlet class (cont.)
// create the HTML for the result set
ResultSet resultSet =
statement.executeQuery(sqlStatement);
sqlResult =
SQLUtil.getHtmlTable(resultSet);
resultSet.close();
}
else
{
int i =
statement.executeUpdate(sqlStatement);
if (i == 0) // a DDL statement
sqlResult = "The statement executed "
+ "successfully.";
else
// an INSERT, UPDATE, or DELETE statement
sqlResult = "The statement executed "
+ "successfully.<br>"
+ i + " row(s) affected.";
}
}
Murach’s Java Servlets/JSP (2nd Ed.), C14 © 2008, Mike Murach & Associates, Inc. Slide 29
The SQLGatewayServlet class (cont.)
statement.close();
connection.close();
}
catch(SQLException e)
{
sqlResult =
"Error executing the SQL statement: <br>"
+ e.getMessage();
}
Murach’s Java Servlets/JSP (2nd Ed.), C14 © 2008, Mike Murach & Associates, Inc. Slide 30
The SQLUtil class
package sql;
import java.util.*;
import java.sql.*;
htmlRows.append(
"<table cellpadding=\"5\" border=\"1\">");
htmlRows.append("<tr>");
for (int i = 1; i <= columnCount; i++)
htmlRows.append("<td><b>"
+ metaData.getColumnName(i) + "</b></td>");
htmlRows.append("</tr>");
Murach’s Java Servlets/JSP (2nd Ed.), C14 © 2008, Mike Murach & Associates, Inc. Slide 31
The SQLUtil class (cont.)
while (results.next())
{
htmlRows.append("<tr>");
for (int i = 1; i <= columnCount; i++)
htmlRows.append("<td>"
+ results.getString(i) + "</td>");
}
htmlRows.append("</tr>");
htmlRows.append("</table>");
return htmlRows.toString();
}
}
Murach’s Java Servlets/JSP (2nd Ed.), C14 © 2008, Mike Murach & Associates, Inc. Slide 32
Connection pooling
HttpServlet
HttpServlet-thread1 HttpServlet-thread2
ConnectionPool object
Database
Murach’s Java Servlets/JSP (2nd Ed.), C14 © 2008, Mike Murach & Associates, Inc. Slide 33
How connection pooling works
When database connection pooling (DBCP) is used, a limited
number of connections are opened for a database and these
connections are shared by the users who connect to the database.
This improves the performance of the database operations.
When one of the threads of a servlet needs to perform a database
operation, the thread gets a Connection object from the
ConnectionPool object to do the operation. When it is finished, it
returns the Connection object to the pool.
Tomcat 6 includes the database connection pool that’s available
from the Jakarta-Commons project. The files for this database
connection pool are stored in the JAR file named tomcat-dbcp.jar.
To make this connection pool available to your system, you can
copy it from Tomcat’s lib directory to the JDK’s jre\lib\ext
directory.
Murach’s Java Servlets/JSP (2nd Ed.), C14 © 2008, Mike Murach & Associates, Inc. Slide 34
A glassfish-resources.xml file that configures a
connection pool on Glassfish
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE resources PUBLIC "-//GlassFish.org//DTD GlassFish Applicati
Server 3.1 Resource Definitions//EN"
"http://glassfish.org/dtds/glassfish-resources_1_5.dtd">
<resources>
<jdbc-connection-pool name="java:app/emailListConnectionPool" res-
type="javax.sql.ConnectionPoolDataSource"
datasource-classname="com.mysql.jdbc.jdbc2.optional.MysqlDataSourc
<property name="ServerName" value="localhost"/>
<property name="Port" value="3306" />
<property name="DatabaseName" value="email_list" />
<property name="User" value="root" />
<property name="Password" value="1234"/>
<property name="Url"
value="jdbc:mysql://localhost:3306/email_list?autoReconnect=true"/>
<!--property name="driverClass" value="com.mysql.jdbc.Driver"/ no
required -->
</jdbc-connection-pool>
<jdbc-resource enabled="true" jndi-
name="java:app/jdbc/emailListDataSource" object-type="user"
pool-name="java:app/emailListConnectionPool"/>
</resources> nd © 2008, Mike Murach & Associates, Inc. Slide 35
Murach’s Java Servlets/JSP (2 Ed.), C14
A context.xml file that configures a connection pool
on Tomcat
<?xml version="1.0" encoding="UTF-8"?>
<Context path="/ch14email">
</Context>
Murach’s Java Servlets/JSP (2nd Ed.), C14 © 2008, Mike Murach & Associates, Inc. Slide 36
A class that defines a connection pool
package data;
import java.sql.*;
import javax.sql.DataSource;
import javax.naming.InitialContext;
private ConnectionPool()
{
try
{
InitialContext ic = new InitialContext();
dataSource = (DataSource)
ic.lookup("java:/comp/env/jdbc/murach");
}
Murach’s Java Servlets/JSP (2nd Ed.), C14 © 2008, Mike Murach & Associates, Inc. Slide 37
A class that defines a connection pool (cont.)
catch(Exception e)
{
e.printStackTrace();
}
}
Murach’s Java Servlets/JSP (2nd Ed.), C14 © 2008, Mike Murach & Associates, Inc. Slide 38
A class that defines a connection pool (cont.)
public Connection getConnection()
{
try
{
return dataSource.getConnection();
}
catch (SQLException sqle)
{
sqle.printStackTrace();
return null;
}
}
Murach’s Java Servlets/JSP (2nd Ed.), C14 © 2008, Mike Murach & Associates, Inc. Slide 39
A class that defines a connection pool (cont.)
public void freeConnection(Connection c)
{
try
{
c.close();
}
catch (SQLException sqle)
{
sqle.printStackTrace();
}
}
}
Murach’s Java Servlets/JSP (2nd Ed.), C14 © 2008, Mike Murach & Associates, Inc. Slide 40
Code that uses the connection pool
ConnectionPool pool = ConnectionPool.getInstance();
Connection connection = pool.getConnection();
pool.freeConnection(connection);
Murach’s Java Servlets/JSP (2nd Ed.), C14 © 2008, Mike Murach & Associates, Inc. Slide 41
The Email List application as it displays an error
message
Murach’s Java Servlets/JSP (2nd Ed.), C14 © 2008, Mike Murach & Associates, Inc. Slide 42
Murach’s Java Servlets/JSP (2nd Ed.), C14 © 2008, Mike Murach & Associates, Inc. Slide 43
The beginning of the JSP for the email interface
<!DOCTYPE HTML PUBLIC
"-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Murach's Java Servlets and JSP</title>
</head>
<body>
<h1>Join our email list</h1>
<p>To join our email list, enter your name and
email address below. <br>
Then, click on the Submit button.</p>
<p><i>${message}</i></p>
Murach’s Java Servlets/JSP (2nd Ed.), C14 © 2008, Mike Murach & Associates, Inc. Slide 44
The beginning of the JSP for the email interface
(cont.)
<form action="addToEmailList" method="get">
<table cellspacing="5" border="0">
<tr>
<td align="right">First name:</td>
<td><input type="text" name="firstName"
value="${user.firstName}">
</td>
</tr>
Murach’s Java Servlets/JSP (2nd Ed.), C14 © 2008, Mike Murach & Associates, Inc. Slide 45
The servlet for the Email List application
package email;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import business.User;
import data.UserDB;
Murach’s Java Servlets/JSP (2nd Ed.), C14 © 2008, Mike Murach & Associates, Inc. Slide 46
The servlet for the Email List application (cont.)
// get parameters from the request
String firstName
= request.getParameter("firstName");
String lastName = request.getParameter("lastName");
String emailAddress
= request.getParameter("emailAddress");
Murach’s Java Servlets/JSP (2nd Ed.), C14 © 2008, Mike Murach & Associates, Inc. Slide 47
The servlet for the Email List application (cont.)
if (UserDB.emailExists(user.getEmailAddress()))
{
message
= "This email address already exists<br>" +
"Please enter another email address.";
url = "/join_email_list.jsp";
}
else
{
UserDB.insert(user);
url = "/display_email_entry.jsp";
}
Murach’s Java Servlets/JSP (2nd Ed.), C14 © 2008, Mike Murach & Associates, Inc. Slide 48
The servlet for the Email List application (cont.)
// forward the request and response to the view
RequestDispatcher dispatcher =
getServletContext().getRequestDispatcher(url);
dispatcher.forward(request, response);
}
}
Murach’s Java Servlets/JSP (2nd Ed.), C14 © 2008, Mike Murach & Associates, Inc. Slide 49
The UserDB class
package data;
import java.sql.*;
import business.User;
String query =
"INSERT INTO User (FirstName, LastName, " +
"EmailAddress) " +
"VALUES (?, ?, ?)";
Murach’s Java Servlets/JSP (2nd Ed.), C14 © 2008, Mike Murach & Associates, Inc. Slide 50
The UserDB class (cont.)
try
{
ps = connection.prepareStatement(query);
ps.setString(1, user.getFirstName());
ps.setString(2, user.getLastName());
ps.setString(3, user.getEmailAddress());
return ps.executeUpdate();
}
catch(SQLException e)
{
e.printStackTrace();
return 0;
}
finally
{
DBUtil.closePreparedStatement(ps);
pool.freeConnection(connection);
}
}
Murach’s Java Servlets/JSP (2nd Ed.), C14 © 2008, Mike Murach & Associates, Inc. Slide 51
The UserDB class (cont.)
public static int update(User user)
{
ConnectionPool pool = ConnectionPool.getInstance();
Connection connection = pool.getConnection();
PreparedStatement ps = null;
return ps.executeUpdate();
}
Murach’s Java Servlets/JSP (2nd Ed.), C14 © 2008, Mike Murach & Associates, Inc. Slide 52
The UserDB class (cont.)
catch(SQLException e)
{
e.printStackTrace();
return 0;
}
finally
{
DBUtil.closePreparedStatement(ps);
pool.freeConnection(connection);
}
}
Murach’s Java Servlets/JSP (2nd Ed.), C14 © 2008, Mike Murach & Associates, Inc. Slide 53
The UserDB class (cont.)
try
{
ps = connection.prepareStatement(query);
ps.setString(1, user.getEmailAddress());
return ps.executeUpdate();
}
catch(SQLException e)
{
e.printStackTrace();
return 0;
}
finally
{
DBUtil.closePreparedStatement(ps);
pool.freeConnection(connection);
}
}
Murach’s Java Servlets/JSP (2nd Ed.), C14 © 2008, Mike Murach & Associates, Inc. Slide 54
The UserDB class (cont.)
public static boolean emailExists(String emailAddress)
{
ConnectionPool pool = ConnectionPool.getInstance();
Connection connection = pool.getConnection();
PreparedStatement ps = null;
ResultSet rs = null;
Murach’s Java Servlets/JSP (2nd Ed.), C14 © 2008, Mike Murach & Associates, Inc. Slide 55
The UserDB class (cont.)
finally
{
DBUtil.closeResultSet(rs);
DBUtil.closePreparedStatement(ps);
pool.freeConnection(connection);
}
}
Murach’s Java Servlets/JSP (2nd Ed.), C14 © 2008, Mike Murach & Associates, Inc. Slide 56
The UserDB class (cont.)
try
{
ps = connection.prepareStatement(query);
ps.setString(1, emailAddress);
rs = ps.executeQuery();
User user = null;
if (rs.next())
{
user = new User();
user.setFirstName(
rs.getString("FirstName"));
user.setLastName(rs.getString("LastName"));
user.setEmailAddress(
rs.getString("EmailAddress"));
}
return user;
}
catch (SQLException e){
e.printStackTrace();
return null;
}
Murach’s Java Servlets/JSP (2nd Ed.), C14 © 2008, Mike Murach & Associates, Inc. Slide 57
The UserDB class (cont.)
finally
{
DBUtil.closeResultSet(rs);
DBUtil.closePreparedStatement(ps);
pool.freeConnection(connection);
}
}
}
Murach’s Java Servlets/JSP (2nd Ed.), C14 © 2008, Mike Murach & Associates, Inc. Slide 58
The DBUtil class
package data;
import java.sql.*;
Murach’s Java Servlets/JSP (2nd Ed.), C14 © 2008, Mike Murach & Associates, Inc. Slide 59
The DBUtil class (cont.)
public static void closePreparedStatement(Statement ps)
{
try
{
if (ps != null)
ps.close();
}
catch(SQLException e)
{
e.printStackTrace();
}
}
Murach’s Java Servlets/JSP (2nd Ed.), C14 © 2008, Mike Murach & Associates, Inc. Slide 60
The DBUtil class (cont.)
public static void closeResultSet(ResultSet rs)
{
try
{
if (rs != null)
rs.close();
}
catch(SQLException e)
{
e.printStackTrace();
}
}
}
Murach’s Java Servlets/JSP (2nd Ed.), C14 © 2008, Mike Murach & Associates, Inc. Slide 61