Sunteți pe pagina 1din 59

JDBC

globsyn technologies

Learning objectives
Connect to a database using JDBC and perform a simple query. Update relational data using JDBC to execute updates, inserts and deletes. Use prepared statements to produce reusable database queries and optimize execution time. Use callable statements to access database procedures. Use scrollable and updatable results sets for more robust solutions. Use commit and rollback to build transactional systems. Use batch processing for efficient handling of large datasets.

JDBC
JDBC (Java Database Connectivity) API allows Java programs to connect to databases. Database access is the same for all database vendors. The JVM uses a JDBC driver to translate generalized JDBC calls into vendor specific database calls.

JDBC Architecture
Application JDBC Driver

Java code calls JDBC library JDBC loads a driver Driver talks to a particular database Can have more than one driver -> more than one database Ideal: can change database engines without changing any application code

What do I need to use JDBC?


A JDBC compliant driver (either provided directly from the database vendor, or a third-party vendor). The java.sql.* package, which comes with the JDK (1.1.x and above).

JDBC Drivers
Type I: Bridge Type II: Native Type III: Middleware Type IV: Pure

JDBC Drivers
Type I Bridge

ODBC

ODBC Driver

DB

JDBC

Type II Native

CLI (.lib)

DB

Type III Middleware

Middleware Server

DB

Type IV Pure

DB

Type 1: JDBC-ODBC Bridge


Translates all JDBC calls into ODBC (Open DataBase Connectivity) calls and sends them to the ODBC driver. The ODBC driver, as well as, in many cases, the client database code, must be present on the client machine.

Type 1: JDBC-ODBC Bridge


Pros
The JDBC-ODBC Bridge allows access to almost any database, since the database's ODBC drivers are already available. Type 1 drivers may be useful for those companies that have an ODBC driver already installed on client machines.

Type 1: JDBC-ODBC Bridge


Cons
The performance is degraded since the JDBC call goes through the bridge to the ODBC driver, then to the native database connectivity interface. The result comes back through the reverse process. Considering the performance issue, type 1 drivers may not be suitable for large-scale applications. The ODBC driver and native connectivity interface must already be installed on the client machine.

Type 2: Native-API/partly Java driver


Converts JDBC calls into database-specific calls for databases such as SQL Server, Oracle, or Sybase. The type 2 driver communicates directly with the database server; therefore it requires that some binary code be present on the client machine.

Type 2: Native-API/partly Java driver


Pros
Type 2 drivers typically offer significantly better performance than the JDBC-ODBC Bridge.

Cons
The vendor database library needs to be loaded on each client machine. Consequently, type 2 drivers cannot be used for the Internet. Type 2 drivers show lower performance than type 3 and type 4 drivers.

Type 3: Net-protocol/all-Java driver


Follows a three-tiered approach whereby the JDBC database requests are passed through the network to the middle-tier server. The middle-tier server then translates the request to the database-specific nativeconnectivity interface to further the request to the database server.

Type 3: Net-protocol/all-Java driver


Pros
The net-protocol/all-Java driver is server-based, so there is no need for any vendor database library to be present on client machines. Further, there are many opportunities to optimize portability, performance, and scalability. Additionally, a type 3 driver typically provides support for features such as caching (connections, query results, and so on), load balancing, and advanced system administration such as logging and auditing.

Cons
Type 3 drivers require database-specific coding to be done in the middle tier. Additionally, traversing the recordset may take longer, since the data comes through the backend server.

Type 4: Native-protocol/all-Java driver


Converts JDBC calls into the vendor-specific database management system (DBMS) protocol so that client applications can communicate directly with the database server. Level 4 drivers are completely implemented in Java to achieve platform independence and eliminate deployment administration issues.

Type 4: Native-protocol/all-Java driver


Pros
Since type 4 JDBC drivers don't have to translate database requests to ODBC or a native connectivity interface or to pass the request on to another server, performance is typically quite good. Moreover, the native-protocol/all-Java driver boasts better performance than types 1 and 2. Also, there's no need to install special software on the client or server.

Cons
With type 4 drivers, the user needs a different driver for each database.

Type I Driver
Requires installation/configuration on client machines Not good for Web e.g. ODBC Bridge

Type II Driver
Native API drivers Requires installation/configuration on client machines Used to leverage existing CLI libraries Usually not thread-safe Mostly obsolete now e.g. Intersolv Oracle Driver, WebLogic drivers

Type III Driver


Calls middleware server, usually on database host Very flexible -- allows access to multiple databases using one driver But its another server application to install and maintain e.g. Symantec DBAnywhere

Type IV Driver
100% Pure Java Use Java networking libraries to talk directly to database engines Only disadvantage: need to download a new driver for each database engine e.g. Oracle, mSQL

java.sql
JDBC is implemented via classes in the java.sql package

Basic steps in using JDBC


Load the driver. Define the connection URL. Establish the connection. Create a statement object. Execute a query. Process the result. Close the connection.

Loading and Registering Driver


try{ Class.forName(Driver); }catch(ClassNotFoundException e) { System.out.println(Unable to load driver); }

JDBC API
DriverManager
Loads, chooses drivers

Connection
a series of SQL statements to and from the DB

Statement
a single SQL statement

ResultSet
the records returned from a Statement

DriverManager
Connection getConnection (String url, String user, String password) Connects to given JDBC URL with given user name and password. Throws java.sql.SQLException. Returns a Connection object.

Connection
A Connection represents a session with a specific database. Within the context of a Connection, SQL statements are executed and results are returned. Can have multiple connections to a database. Also provides metadata -- information about the database, tables, and fields. Also methods to deal with transactions.

Obtaining a Connection
try { Class.forName (Driver"); Connection con = DriverManager.getConnection(DBURL,username ,password); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); }

Connection Methods
Statement createStatement()

returns a new Statement object


PreparedStatement prepareStatement(String sql)

returns a new PreparedStatement object


CallableStatement prepareCall(String sql)

returns a new CallableStatement object

Why all these different kinds of statements? Optimization.

Statement
A Statement object is used for executing a static SQL statement and obtaining the results produced by it.

Statement Methods
ResultSet executeQuery(String)
Execute a SQL statement that returns a single ResultSet.

int executeUpdate(String)
Execute a SQL INSERT, UPDATE or DELETE statement. Returns the number of rows changed.

ResultSet
A ResultSet provides access to a table of data generated by executing a Statement. Only one ResultSet per Statement can be open at once. The table rows are retrieved in sequence. A ResultSet maintains a cursor pointing to its current row of data. The 'next' method moves the cursor to the next row.
you cant rewind in JDBC 1.0 In JDBC 2.0 it is supported

ResultSet Methods
boolean next()
activates the next row the first call to next() activates the first row returns false if there are no more rows

void close()
disposes of the ResultSet allows you to re-use the Statement that created it

ResultSet Methods
Type getType(int columnIndex)
returns the given field as the given type fields indexed starting at 1 (not 0)

Type getType(String columnName)


same, but uses name of field less efficient

int findColumn(String columnName)


looks up column index given column name

ResultSet Methods
String getString(int columnIndex) boolean getBoolean(int columnIndex) byte getByte(int columnIndex) short getShort(int columnIndex) int getInt(int columnIndex) long getLong(int columnIndex) float getFloat(int columnIndex) double getDouble(int columnIndex) Date getDate(int columnIndex) Time getTime(int columnIndex)

JDBC Class Usage


DriverManager Driver

Connection

Statement

ResultSet

Commonly used Type 4 Drivers


Oracle
oracle.jdbc.driver.OracleDriver

MySQL
com.mysql.jdbc.Driver

Configuring Driver
Download the driver jar file in a directory. Set the path of the directory in the CLASSPATH environment variable.

Connection URL
Oracle
jdbc:oracle:thin:@localhost:1521:orcl

MySQL
jdbc:mysql://localhost:3306/gps

A Simple JDBC application


loadDriver getConnection createStatement execute(SQL) Result handling yes More results ? no closeStatment closeConnection

import java.sql.*; public class jdbctest { public static void main(String args[]){ try{ Class.forName("oracle.jdbc.driver.OracleDriver"); Connection con = DriverManager.getConnection ("jdbc:oracle:thin:@localhost:1521:orcl", scott", tiger"); Statement stmt = con.createStatement(); ResultSet rs = stmt.executeQuery ("select name, number from emp where ecode> 2"); while(rs.next()) System.out.println(rs.getString(1) + " (" + rs.getInt(2) + ")"); stmt.close() con.close(); } catch(Exception e){ System.err.println(e); }}}

isNull
In SQL, NULL means the field is empty Not the same as 0 or In JDBC, you must explicitly ask if a field is null by calling ResultSet.isNull(column)

Transaction Management
The connection has a state called AutoCommit mode. If AutoCommit is true, then every statement is automatically committed. Default case: true

setAutoCommit
con.setAutoCommit(boolean) if AutoCommit is false, then every statement is added to an ongoing transaction you must explicitly commit or rollback the transaction using con.commit() and con.rollback()

Connecting to oracle by using type 4 driver


String driver = "oracle.jdbc.driver.OracleDriver"; String url = "jdbc:oracle:thin:@localhost:1521:caspian"; String username = "mp"; String password = "mp2"; Class.forName(driver); // load Oracle driver Connection conn = DriverManager.getConnection(url, username, password );

Connecting to MySql by using type 4 driver


String driver = com.mysql.jdbc.Driver"; String url = jdbc:mysql://localhost:3306/gps"; String username = root"; String password = root"; Database name Class.forName(driver); // load MySql driver Connection conn = DriverManager.getConnection(url, username, passwor d);

Batch update
statement = connection.createStatement(); String update1 = "UPDATE employees SET email = 'a@a.com' WHE RE email = 'a@b.com'"; statement.addBatch(update1); String update2 = "UPDATE employees SET email = 'b@b.com' WHE RE email = 'b@c.com'"; statement.addBatch(update2); String update3 = "UPDATE employees SET email = 'c@c.com' WHER E email = 'c@d.com'"; statement.addBatch(update3); statement.executeBatch();

Calling Stored Procedure in Oracle


String proc = "{ call proc3(?, ?, ?) }"; CallableStatement cs = conn.prepareCall(proc); cs.setString(1, "abcd");

cs.setInt(3, 10); cs.registerOutParameter(2, java.sql.Types.VARCHAR); cs.registerOutParameter(3, java.sql.Types.INTEGER);


cs.execute(); String param2 = cs.getString(2); int param3 = cs.getInt(3); System.out.println("param2=" + param2); System.out.println("param3=" + param3); conn.close();

ResultSetMetadata
ResultSet rs = stmt.executeQuery("select * from EMP"); ResultSetMetaData rsmd = rs.getMetaData();

int numberOfColumns = rsmd.getColumnCount(); for (int i = 1; i <= numberOfColumns; i++) { String colName = rsmd.getColumnName(i); String tableName = rsmd.getTableName(i); String name = rsmd.getColumnTypeName(i); boolean caseSen = rsmd.isCaseSensitive(i); boolean writable = rsmd.isWritable(i); System.out.println(colName+ +tableName+ +name+ +caseSen + + writable);
}

Result Set Enhancements In JDBC 2.0

Scrollability, positioning, and sensitivity are determined by the result set type.

Updatability is determined by the concurrency type.

Result Set Types for Scrollability and Sensitivity


forward-only: (JDBC 1.0 functionality--not scrollable, not positionable, and not sensitive) scroll-sensitive: (scrollable and positionable; also sensitive to underlying database changes) scroll-insensitive: (scrollable and positionable but not sensitive to underlying database changes)

Concurrency Types for Updatability


updatable: (updates, inserts, and deletes can be performed on the result set and copied to the database) read-only: (the result set cannot be modified in any way)

Summary of Result Set Categories


forward-only/read-only forward-only/updatable scroll-sensitive/read-only scroll-sensitive/updatable scroll-insensitive/read-only scroll-insensitive/updatable

Creating Scrollable or Updatable Result Sets


Statement createStatement (int resultSetType, int resultSetConcurrency) PreparedStatement prepareStatement (String sql, int resultSetType, int resultSetConcurrency) CallableStatement prepareCall (String sql, int resultSetType, int resultSetConcurrency)

Static constant values for result set type

ResultSet.TYPE_FORWARD_ONLY ResultSet.TYPE_SCROLL_INSENSITIVE ResultSet.TYPE_SCROLL_SENSITIVE

Static constant values for concurrency type

ResultSet.CONCUR_READ_ONLY ResultSet.CONCUR_UPDATABLE

Verify result set type and concurrency type


int getResultSetType() throws SQLException int getResultSetConcurrency() throws SQLException

Positioning in a Scrollable Result Set


void beforeFirst() throws SQLException void afterLast() throws SQLException boolean first() throws SQLException boolean last() throws SQLException boolean absolute(int row) throws SQLException boolean relative(int row) throws SQLException

Methods for Checking the Current Position


boolean isBeforeFirst() throws SQLException boolean isAfterLast() throws SQLException boolean isFirst() throws SQLException boolean isLast() throws SQLException int getRow() throws SQLException

Processing a Scrollable Result Set

boolean next() throws SQLException boolean previous() throws SQLException

Example
try { con = DriverManager.getConnection(url, user, pass); stmt = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE); rs = stmt.executeQuery("SELECT * FROM Users where nick=\"ian\""); // Get the resultset ready, update the passwd field, commit rs.first(); rs.updateString("password", "unguessable"); rs.updateRow(); rs.close(); stmt.close(); con.close(); } catch (SQLException ex) { System.err.println("SQLException: " + ex.getMessage()); }