Download presentation
Presentation is loading. Please wait.
1
Using JDBC to Access the Database
Schedule: Timing Topic 50 minutes Lecture 30 minutes Practice 80 minutes Total
2
Objectives After completing this lesson, you should be able to do the following: Describe how Java applications connect to the database Describe how Java database functionality is supported by the Oracle database Load and register a JDBC driver Connect to an Oracle database Follow the steps to execute a simple SELECT statement Map simple Oracle database types to Java types Lesson Aim This lesson introduces you to using Java to access an Oracle database. This lesson introduces you to the basic use of JDBC to query a database from a Java class. It presents the different steps required to perform SQL statements.
3
Oracle Application Server 10g J2EE Certified Environment
Java, J2EE, and Oracle 10g Web server Application server Client Data Presentation Business logic Oracle database Oracle Application Server 10g J2EE Certified Environment Java and Oracle 10g Oracle provides a complete and integrated platform called Oracle 10g, which supports all of the server-side requirements for Java applications. Oracle 10g consists of the following: Oracle Database In addition to its database management features, the Oracle database (currently Oracle 10g) provides support for a variety of Java-based structures, including Java components and Java stored procedures. These Java structures are executed in the database by its built-in Java Virtual Machine, called the Oracle Java Virtual Machine (Oracle JVM). Oracle Application Server 10g Oracle Application Server 10g maintains and executes all your application logic, including Enterprise JavaBeans, through its own built-in JVM, the Enterprise Java Engine. Oracle Application Server 10g uses Apache Web server to access the OC4J where servlets and JSPs are executed. Using J2EE with Oracle 10g J2EE is a standard technology which provides a set of APIs and a run-time infrastructure for hosting and managing applications. It specifies roles and interfaces for applications and the run time onto which applications can be deployed. And, hence, the application developers need to focus only on the application logic and related services, while leveraging the run time for all infrastructure-related services. JDBC
4
Connecting to a Database with Java
Client applications, JSPs, and servlets use JDBC. Client application or applet JDBC Relational DB How Java Connects to a Database To query an Oracle database, any Java application must have a way to connect to the database. This is performed by using JDBC. Java Database Connectivity (JDBC) is a standard application programming interface (API) that is used for connecting a Java application to relational databases. The networking protocol that is used depends on which JDBC driver you are using. For example, the OCI driver uses Oracle Net, or thin driver uses TCP/IP Running SQL from a Server-Side Application Java procedures inside the database use JDBC to execute their SQL queries. This includes Java stored procedures. Instructor Note If you are connecting within the server, you can use the default connection. A Java stored procedure accesses the database by using the default connection. To connect within the server, you must first connect to the server from outside, so you already have a database session. The default connection takes the same user and privileges as your existing database session. Therefore, you do not need to specify a URL, user ID, or password for the default connection. You can also use the URL, jdbc:oracle:kprb, as an alternative way to get the default connection.
5
What Is JDBC? JDBC is a standard interface for connecting to relational databases from Java. The JDBC API includes Core API Package in java.sql. JDBC 2.0 API includes Optional Package API in javax.sql. JDBC 3.0 API includes the Core API and Optional Package API Include the Oracle JDBC driver archive file in the CLASSPATH. The JDBC class library is part of the Java 2, Standard Edition (J2SE). Java Database Connectivity (JDBC) The java.sql package contains a set of interfaces that specify the JDBC API. This package is part of Java 2, Standard Edition. Database vendors implement these interfaces in different ways, but the JDBC API itself is standard. Using JDBC, you can write code that: Connects to one or more data servers Executes any SQL statement Obtains a result set so that you can navigate through query results Obtains metadata from the data server Each database vendor provides one or more JDBC drivers. A JDBC driver implements the interfaces in the java.sql package, providing the code to connect to and query a specific database. Instructor Note JDBC 1.22 is part of JDK 1.1; JDBC 2.0 is part of Java 2.
6
Preparing the Environment
Set the CLASSPATH: Import JDBC packages: [Oracle Home]\jdbc\lib\classes12.jar // Standard packages import java.sql.*; import java.math.*; // optional // Oracle extension to JDBC packages import oracle.jdbc.*; import oracle.sql.*; Requirements for Using Oracle JDBC This section describes the environment variables that must be set for the JDBC OCI driver and the JDBC thin driver, focusing on the Sun Microsystems Solaris and Microsoft Windows NT platforms. You must set the CLASSPATH for your installed JDBC OCI or thin driver. Depending on whether you are using the SDK 1.2.x versions or JDK 1.1.x versions, you must set one of these values for the CLASSPATH: [Oracle Home]/jdbc/lib/classes12.jar (and optionally [Oracle Home]/jdbc/lib/nls_charset12.jar) for full NLS character support) or: [Oracle Home]/jdbc/lib/classes111.jar (and optionally [Oracle Home]/jdbc/lib/nls_charset11.jar) for full NLS character support) Ensure that there is only one classes*.zip file version and one nls_charset*.zip file version in your CLASSPATH.
7
Requirements for Using Oracle JDBC (continued)
JDBC OCI Driver If you are installing the JDBC OCI driver, you must also set the following value for the library path environment variable: [Oracle Home]/lib The JDBC Package Your Java class must import java.sql.* to be able to use the JDBC classes and include the JDBC driver classes from your database vendor in the CLASSPATH. For more information about required path and classpath settings for Oracle JDBC, refer to the Oracle 10g JDBC Developer’s Guide and Reference.
8
Steps for Using JDBC to Execute SQL Statements
1. Register JDBC driver. 2. Obtain a connection. 3. Create statement object. 4. Execute SQL statement. 4a. Process SELECT statement. 4b. Process DML or DDL statement. Steps to Execute an SQL Statement with JDBC The following are the key steps: 1. Load and register the driver. (Use the java.sql.DriverManager class.) 2. Obtain a connection object. (Use java.sql.DriverManager to do this.) 3. Create a statement object. (Use the Connection object.) 4. Execute a query, DML, or DDL. (Use the Statement object.) 5. If you obtain a ResultSet object while executing a query, then iterate through the ResultSet to process the data for each row that satisfies the query. 6. Close the ResultSet, Statement, and Connection objects, when finished. Dealing with Exceptions When using JDBC, all the methods that access the database throw SQLException if anything goes wrong. You must always deal with this exception in your JDBC code. SQLException has a number of methods that you can call to get information about the exception, including: getMessage(): Returns a string that describes the error getErrorCode(): Retrieves the vendor-specific exception code getSQLState(): Retrieves the SQL state value Class.forName(): Throws a ClassNotFoundException if the specified class cannot be found 6. Close connections. 5. Process query results.
9
Step 1: Registering the Driver
Register the driver in the code: DriverManager.registerDriver (new oracle.jdbc.OracleDriver()); Class.forName ("oracle.jdbc.OracleDriver"); Register the driver when launching the class: java –D jdbc.drivers = oracle.jdbc.OracleDriver <ClassName>; Loading the Driver JDBC drivers must register themselves with the driver manager. There are two ways to perform this: Use the registerDriver() method of DriverManager. Use the forName() method of the java.lang.Class class to load the JDBC drivers directly, as follows: try { Class.forName("oracle.jdbc.driver.OracleDriver"); } catch (ClassNotFoundException e) {} Using the Class.forName() method calls the static initializer of the driver class. The driver class does not need to be present at compile time. However, this method is valid only for JDK-compliant Java Virtual Machines. You can register the driver at execution time. In this case, the registering statements that may exist in your Java class are ignored. Example of using the –Djdbc option in the command line: C:>java -Djdbc.drivers=oracle.jdbc.OracleDriver MyClass Instructor Note oracle.jdbc.OracleDriver class provides new interfaces and classes that can be used in place of the previous oracle.jdbc.driver.OracleDriver classes.
10
Connecting to the Database
Using the package oracle.jdbc.driver, Oracle provides different drivers to establish a connection to the database. OracleDriver Thin client OCI Server-based … Database commands JDBC calls Database About JDBC Drivers A JDBC driver implements the interfaces in the java.sql package, providing the code to connect to and query a specific database. A JDBC driver can also provide a vendor’s own extensions to the standard; Oracle drivers provide extensions to support special Oracle data types. Oracle provides three drivers: Thin client driver OCI-based driver Server-based driver The Oracle JDBC driver is located in the file classes111.zip for JDBC 1.0 or in the file classes12.zip for JDBC 2.0. These archive files contain supporting classes for both the thin and OCI JDBC drivers. Supported JDK and JDBC versions Oracle has two versions of the thin driver and the OCI driver—one that is compatible with SDK 1.2 and one that is compatible with JDK 1.1.x. The J2SE versions support standard JDBC 2.0. The JDK 1.1.x versions support most JDBC 2.0 features, but must do so through Oracle extensions because JDBC 2.0 features are not available in JDK 1.1.x versions.
11
Oracle JDBC Drivers: Thin Client Driver
Is written entirely in Java Must be used by applets Applet JDBC Oracle Thin driver Client Server Thin Client Driver This driver can connect to an Oracle 10g database but also to either an Oracle8i database or an Oracle9i database. You must use this driver if you are developing a client application that can connect to different versions of an Oracle database, to provide maximum portability. To communicate with the database, the thin client driver uses a lightweight version of Oracle*Net over TCP/IP that can be downloaded at run time to the client. The Oracle JDBC Thin driver is a 100% pure Java, Type IV driver. It is targeted to Oracle JDBC applets but can be used for applications as well. Because it is written entirely in Java, this driver is platform-independent. It does not require any additional Oracle software on the client side. The thin driver communicates with the server by using Two Task Common (TTC), a protocol developed by Oracle to access the Oracle Relational Database Management System (RDBMS). The JDBC Thin driver allows a direct connection to the database by providing an implementation of TCP/IP that emulates Oracle Net and TTC (the wire protocol used by OCI) on top of Java sockets. Both of these protocols are lightweight implementation versions of their counterparts on the server. The Oracle Net protocol runs over TCP/IP only. Note: When the JDBC Thin driver is used with an applet, the client browser must have the capability to support Java sockets.
12
Oracle JDBC Drivers: OCI Client Drivers
Is written in C and Java Must be installed on the client Application JDBC OCI driver Oracle ocixxx.dll OCI Client Drivers You must choose an OCI driver if you are developing an application and need maximum performance. The JDBC OCI driver is a Type II driver for use with client-server Java applications. This driver requires an Oracle client installation, and therefore is Oracle platform-specific and not suitable for applets. The JDBC OCI driver provides OCI connection pooling functionality, which can either be part of the JDBC client or a JDBC stored procedure. The OCI driver supports Oracle7, Oracle8/8i, Oracle9i and Oracle 10g with the highest compatibility. It also supports all installed Oracle Net adapters, including IPC, named pipes, TCP/IP, and IPX/SPX. The OCI driver, written in a combination of Java and C, converts JDBC invocations to calls to the Oracle Call Interface (OCI), using native methods to call C-entry points. These calls are then sent over Oracle Net to the Oracle database server. The OCI driver communicates with the server by using the Oracle-developed TTC protocol. The OCI driver uses the OCI libraries, C-entry points, Oracle Net, CORE libraries, and other necessary files on the client machine on which it is installed. Instructor Note In Oracle, the OCI driver is a single OCI driver for use with all database versions. It replaces the distinct OCI8 and OCI7 drivers of previous releases. While the OCI8 and OCI7 drivers are deprecated for Oracle, they are still supported for backward compatibility. Client Server
13
Choosing the Right Driver
Type of Program Driver Applet Thin Client application Thin OCI EJB, servlet (on the middle tier) Thin OCI Stored procedure Server side Choosing the Appropriate Driver Consider the following when choosing a JDBC driver to use for your application or applet: If you are writing an applet, you must use the JDBC Thin driver. JDBC OCI-based driver classes will not work inside a Web browser, because they call native (C language) methods. If you want maximum portability and performance under Oracle 10g and earlier, then use the JDBC Thin driver. You can connect to an Oracle server from either an application or an applet by using the JDBC Thin driver. If you are writing a client application for an Oracle client environment and need maximum performance, then choose the JDBC OCI driver. If performance is critical to your application, you want maximum scalability of the Oracle server, or you need the enhanced availability features such as Transparent Application Failover (TAF) or the enhanced proxy features such as middle-tier authentication, then choose the OCI driver.
14
Step 2: Getting a Database Connection
In JDBC 1.0, use the DriverManager class, which provides overloaded getConnection() methods. All connection methods require a JDBC URL to specify the connection details. Example: Vendors can provide different types of JDBC drivers. Connection conn = DriverManager.getConnection( "scott","tiger"); Getting a Connection to the Database Use the DriverManager class to create a connection by calling the getConnection() method. The getConnection() method is overloaded, for example: getConnection(String url) getConnection(String url, Properties props), where properties must include at least a value for the following key names: user and password. getConnection(String url, String user, String password) In each case, you must supply a URL-like string that identifies the registered JDBC driver to use, and the database connection string and security credentials, if required. Instructor Note JDBC 2.0 and later versions provide other ways of obtaining a connection object such as using JNDI instead of a database URL.
15
Database identification
About JDBC URLs JDBC uses a URL-like string. The URL identifies The JDBC driver to use for the connection Database connection details, which vary depending on the driver used Example using Oracle Thin JDBC driver: jdbc:<subprotocol>:<subname> Protocol Database identification JDBC URLs JDBC uses a URL to identify the database connection. A JDBC URL looks different from an HTTP or FTP URL. But, like any URL, it is a locator for a particular resource; in this case, a database. The structure of a JDBC URL is flexible, allowing the driver writer to specify what to include in the URL. End users need to learn what structure their vendor uses. The slide shows the general syntax for a JDBC URL and the syntax that Oracle uses for connecting with an Oracle driver. The general syntax of a JDBC URL is as follows: jdbc:<subprotocol>:<subname> jdbc is the protocol. All URLs start with their protocol. <subprotocol> is the name of a driver or database connectivity mechanism. Driver developers register their subprotocols with JavaSoft to make sure that no one else uses the same subprotocol name. For all Oracle JDBC drivers, the subprotocol is oracle. <subname> identifies the database. The structure and contents of this string are determined by the driver developer. For Oracle JDBC drivers, the subname is where: <driver> is the driver <database> provides database connectivity information The following slides describe the syntax of an Oracle JDBC URL for the different JDBC drivers for client-side Java application code.
16
JDBC URLs with Oracle Drivers
Oracle Thin driver Oracle OCI driver Syntax: Example: Syntax: entry> Example: JDBC URLs with Oracle Drivers The basic structure of the JDBC URL for connecting to a database using one of the Oracle JDBC drivers is jdbc:<subprotocol>:<driver>:<database>. Oracle Thin driver <driver> is thin. <database> is a string of the form <host>:<port>:<sid>. That is, it is the host name, TCP/IP port, and Oracle SID of the database to which you want to connect. For example: Oracle OCI driver <driver> is oci, oci8 or oci7, depending on which OCI driver you are using. <database> is a TNSNAMES entry from the tnsnames.ora file. For example:
17
Step 3: Creating a Statement
JDBC statement objects are created from the Connection instance: Use the createStatement() method, which provides a context for executing an SQL statement. Example: Connection conn = DriverManager.getConnection( "scott","tiger"); Statement stmt = conn.createStatement(); Statement Objects in JDBC The execute() method is useful for dynamically executing an unknown SQL string. JDBC provides two other statement objects: PreparedStatement, for precompiled SQL statements CallableStatement, for statements that execute stored procedures Objects and Interfaces java.sql.Statement is an interface, not an object. When you declare a Statement object and initialize it using the createStatement() method, you are creating the implementation of the Statement interface supplied by the Oracle driver that you are using.
18
Using the Statement Interface
The Statement interface provides three methods to execute SQL statements: Use executeQuery(String sql)for SELECT statements. Returns a ResultSet object for processing rows Use executeUpdate(String sql) for DML or DDL. Returns an int Use execute(String) for any SQL statement. Returns a boolean value Statement Objects in JDBC (continued) Use executeQuery(String sql) for SELECT statements. Returns a ResultSet object for processing rows Use executeUpdate(String sql) for DML or DDL. Returns an int value indicating number of rows affected by the DML; otherwise, it is 0 for DDL Use execute(String) for any SQL statement. Returns a boolean value of true if the statement returns a ResultSet (such as a query); otherwise, it returns a value of false
19
Step 4a: Executing a Query
Provide a SQL query string, without semicolon, as an argument to the executeQuery() method. Returns a ResultSet object: Statement stmt = null; ResultSet rset = null; stmt = conn.createStatement(); rset = stmt.executeQuery ("SELECT ename FROM emp"); Execute a Query and Return a ResultSet Object To query the database, use the executeQuery() method of your Statement object. This method takes a SQL statement as input and returns a JDBC ResultSet object. This statement follows standard SQL syntax.
20
The ResultSet Object The JDBC driver returns the results of a query in a ResultSet object. ResultSet: Maintains a cursor pointing to its current row of data Provides methods to retrieve column values The ResultSet Object The ResultSet object is a table of data representing a database result set, which is generated by executing a statement that queries the database. A ResultSet object maintains a cursor pointing to its current row of data. Initially, the cursor is positioned before the first row. A default ResultSet object is not updatable and has a cursor that moves forward only. Thus, it is possible to iterate through it only once, and only from the first row to the last row. New methods in the JDBC 2.0 API make it possible to produce ResultSet objects that are scrollable and updatable.
21
Step 4b: Submitting DML Statements
1. Create an empty statement object: 2. Use executeUpdate to execute the statement: Example: Statement stmt = conn.createStatement(); int count = stmt.executeUpdate(SQLDMLstatement); Statement stmt = conn.createStatement(); int rowcount = stmt.executeUpdate ("DELETE FROM order_items WHERE order_id = 2354"); How to Update a Table in the Database The slide shows the syntax for the methods that execute a database update using a DML statement. Whereas executeQuery returns a ResultSet object containing the results of the query sent to the DBMS, the return value for executeUpdate is an int that indicates how many rows of a table were updated. When the method executeUpdate is used to execute a DDL statement, such as in creating a table, it returns the int 0. When the return value for executeUpdate is 0, it can mean: (1) the statement executed was an update statement that affected zero rows, or (2) the statement executed was a DDL statement. Example: Using the executeUpdate() method, the PICTURES table is populated with the region_id from the regions table. System.out.println("Table Insert"); stmt.executeUpdate ("INSERT INTO pictures (id) SELECT region_id FROM regions");
22
Step 4b: Submitting DDL Statements
1. Create an empty statement object: 2. Use executeUpdate to execute the statement: Example: Statement stmt = conn.createStatement(); int count = stmt.executeUpdate(SQLDDLstatement); Statement stmt = conn.createStatement(); int rowcount = stmt.executeUpdate ("CREATE TABLE temp (col1 NUMBER(5,2), col2 VARCHAR2(30)"); How to Create DDL Statements The slide shows the syntax for the methods that execute a DDL statement. executeUpdate() returns an int containing 0, for a statement with no return value, such as a SQL DDL statement.
23
Step 5: Processing the Query Results
The executeQuery() method returns a ResultSet. Use the next() method in loop to iterate through rows. Use getXXX() methods to obtain column values by column position in query, or column name. stmt = conn.createStatement(); rset = stmt.executeQuery( "SELECT ename FROM emp"); while (rset.next()) { System.out.println (rset.getString("ename")); } The getXXX() Methods The ResultSet class has several methods that retrieve column values for the current row. Each of these getXXX() methods attempts to convert the column value to the specified Java type and return a suitable Java value. For example, getInt() gets the column value as an integer, getString() gets the column value as a string, and getDate() returns the column value as a date. The next() method returns true if a row was found; otherwise, it returns false. Use it to check whether a row is available, and to step through subsequent rows. There are many getXXX() methods to get the column values, where XXX is a Java data type. For example, getString(pos) returns column in pos as a String, getInt(idx) returns column in pos as an int, and so on. There is a potential problem of database null values and trying to use getInt, and so on, because Java primitives do not support null values. Usually, it is recommended that you use getBigDecimal if numeric values have nulls.
24
Step 6: Closing Connections
Explicitly close a Connection, Statement, and ResultSet object to release resources that are no longer needed. Call their respective close() methods: Connection conn = ...; Statement stmt = ...; ResultSet rset = stmt.executeQuery( "SELECT ename FROM emp"); ... // clean up rset.close(); stmt.close(); conn.close(); Closing the ResultSet, Statement, and Connection Objects You must explicitly close all ResultSet and Statement objects after you finish using them. The close() methods clean up memory and release database cursors, so if you do not explicitly close your ResultSet and Statement objects, serious memory leaks may occur, and you may run out of cursors in the database. You then need to close the connection. The server-side driver runs within a default session. You are already connected, and you cannot close the default connection made by the driver. Calling close() on the connection does nothing.
25
Querying in JDBC import java.sql.*; Connect
DriverManager.registerDriver(…) Connection conn = DriverManager.getConnection( "jdbc:oracle:thin … Statement stmt = conn.createStatement (); ResultSet rset = stmt.executeQuery ( "select * from EMPLOYEES"); while (rset.next ()) System.out.println( rset.getString (2)); rset.close(); stmt.close(); conn.close(); Connect Query Process results Querying a Database with JDBC The slide shows the four main steps in querying a database with JDBC. 1. JDBC drivers must register themselves with the driver manager. Use the registerDriver() method of the DriverManager class. A Connection object is obtained by using the getConnection() method as shown. You must pass the username and the password to authenticate yourself, and you must also pass the JDBC URL that dictates the type of JDBC driver that you are using. 2. A Statement object is obtained only after you have a Connection object, after which you can invoke the executeQuery() method for SELECT statements or the executeUpdate() method for INSERT, UPDATE, DELETE, and DDL statements. JDBC also provides the PreparedStatement object for precompiled SQL statements. When you declare a Statement object and initialize it by using the createStatement() method, you implement the Statement interface that is supplied by the driver you are using. 3. The slide shows an executeQuery() method on the Statement object, which returns a ResultSet containing the results of your query. A ResultSet maintains a cursor pointing to its current row of data. Use next() to step through the ResultSet row by row, and use getString(), getInt(), and other methods, to assign each value to a Java variable. 4. The Result Set, Statement, and Connection should then be closed. Close
26
A Basic Query Example import java.sql.*; class TestJdbc {
public static void main (String args [ ]) throws SQLException { DriverManager.registerDriver (new oracle.jdbc.OracleDriver()); Connection conn = DriverManager.getConnection "tiger"); Statement stmt = conn.createStatement (); ResultSet rset = stmt.executeQuery ("SELECT ename FROM emp"); while (rset.next ()) System.out.println (rset.getString ("ename")); rset.close(); stmt.close(); conn.close(); } }
27
Mapping Database Types to Java Types
ResultSet maps database types to Java types: ResultSet rset = stmt.executeQuery ("SELECT empno, hiredate, job FROM emp"); while (rset.next()){ int id = rset.getInt(1); Date hiredate = rset.getDate(2); String job = rset.getString(3); Column Name empno hiredate job Type NUMBER DATE VARCHAR2 Method getInt() getDate() getString() Mapping Database Types to Java Types In many cases, you can get all of the columns in your result set by using the getObject() or getString() methods of ResultSet. For performance reasons, or because you want to perform complex calculations, it is sometimes important to have your data in a type that exactly matches the database column. The JDBC section of the Java tutorial contains a matrix that maps ResultSet.getXXX methods to ANSI SQL types. For each SQL type, the matrix shows: Which getXXX methods can be used to retrieve the SQL type Which getXXX method is recommended to retrieve the SQL type
28
Mapping Database Types to Java Types (continued)
Table of ANSI SQL Types and Java Types The following table lists the ANSI SQL types, the corresponding data type to use in Java, and the name of the method to call in ResultSet to obtain that type of column value: Table of Oracle SQL Types
29
Handling an Unknown SQL Statement
1. Create an empty statement object: 2. Use execute to execute the statement: 3. Process the statement accordingly: Statement stmt = conn.createStatement(); boolean isQuery = stmt.execute(SQLstatement); if (isQuery) { // was a query - process results ResultSet r = stmt.getResultSet(); ... } else { // was an update or DDL - process result int count = stmt.getUpdateCount(); ... } Dynamically Executing an Unknown SQL Statement An application may not know whether a given statement returns a result set until the statement has been executed. In addition, some stored procedures may return several different result sets and update counts. JDBC provides a mechanism so that an application can execute a statement and then process an arbitrary collection of result sets and update counts. The mechanism is based on the use of a general execute() method and then calls to three other methods: getResultSet, getUpdateCount, and getMoreResults. These methods enable an application to explore the statement results one at a time and determine whether a given result is a result set or an update count. execute() returns true if the result of the statement is a result set; it returns false if the result of the statement is an update count. You can then call either getResultSet() or getUpdateCount() on the statement. The following example uses execute() to dynamically execute an unknown statement: public void executeStmt (String statement) throws SQLException { Statement stmt = conn.createStatement(); // Execute the statement boolean isQuery = stmt.execute(statement); if (isQuery ) { <statement was a query; process the results> } else { <statement was an update or DDL> int updateCount = stmt.getUpdateCount(); // Process the results }
30
Handling Exceptions SQL statements can throw a java.sql.SQLException.
Use standard Java error handling methods. try { rset = stmt.executeQuery("SELECT empno, ename FROM emp"); } catch (java.sql.SQLException e) { ... /* handle SQL errors */ } ... finally { // clean up try { if (rset != null) rset.close(); } catch (Exception e) { ... /* handle closing errors */ } Handling Exceptions You can use the try-catch-finally block structure for closing resources. Code Example Connection conn = null; Statement stmt = null; ResultSet rset = null; // initialize stmt = conn.createStatement(); try { rset = stmt.executeQuery("SELECT empno, ename FROM emp"); } catch (java.sql.SQLException e) { ... /* handle errors */ } ... // Clean up resources finally { try { if (rset != null) rset.close(); } catch (Exception e) {} try { if (stmt != null) stmt.close(); } catch (Exception e) {} try { if (conn != null) conn.close(); } catch (Exception e) {}
31
Managing Transactions
By default, connections are in autocommit mode. Use conn.setAutoCommit(false)to turn autocommit off. To control transactions when you are not in autocommit mode, use: conn.commit(): Commit a transaction conn.rollback(): Roll back a transaction Closing a connection commits the transaction even with the autocommit off option. Transactions with JDBC After you perform an UPDATE or INSERT operation in a result set, you propagate the changes to the database in a separate step that you can skip if you want to cancel the changes. With JDBC, database transactions are managed by the Connection object. When you create a Connection object, it is in autocommit mode (which means that each statement is committed after it is executed). You can change the connection’s autocommit mode at any time by calling setAutoCommit(). The following is a full description of autocommit mode: If a connection is in autocommit mode, all its SQL statements are executed and committed as individual transactions. If a statement returns a result set, the statement finishes when the last row of the result set has been retrieved or the result set has been closed. If autocommit mode has been disabled, its SQL statements are grouped into transactions, which must be terminated by calling either commit() or rollback(). The commit() method makes permanent all changes because the previous commit or rollback releases any database locks held by the connection. rollback() drops all changes because the previous commit or rollback releases any database locks. commit() and rollback() must be called only when you are not in autocommit mode. Note: The server-side driver does not support autocommit mode. You must control transactions explicitly.
32
The PreparedStatement Object
A PreparedStatement prevents reparsing of SQL statements. Use this object for statements that you want to execute more than once. A PreparedStatement can contain variables that you supply each time you execute the statement. PreparedStatement PreparedStatement is inherited from Statement; the difference is that PreparedStatement holds precompiled SQL statements. If you execute a Statement object many times, its SQL statement is compiled each time. PreparedStatement is more efficient because its SQL statement is compiled only once, when you first prepare PreparedStatement. After that, each time you execute the SQL statement in PreparedStatement, the SQL statement does not have to be recompiled. Therefore, if you need to execute the same SQL statement several times in an application, it is more efficient to use PreparedStatement than Statement. PreparedStatement Parameters PreparedStatement does not have to execute exactly the same query each time. You can specify parameters in the PreparedStatement SQL string and supply the actual values for these parameters when the statement is executed. The next slide shows how to supply parameters and execute a prepared statement.
33
How to Create a PreparedStatement
1. Register the driver and create the database connection. 2. Create the PreparedStatement, identifying variables with a question mark (?): PreparedStatement pstmt = conn.prepareStatement ("UPDATE emp SET ename = ? WHERE empno = ?"); PreparedStatement pstmt = conn.prepareStatement ("SELECT ename FROM emp WHERE empno = ?"); Creating a PreparedStatement To write changes to the database, such as for INSERT or UPDATE operations, you typically create a PreparedStatement object. You can use the PreparedStatement object to execute a statement with varying sets of input parameters. The prepareStatement() method of your JDBC Connection object allows you to define a statement that takes bind variable parameters, and returns a JDBC PreparedStatement object with your statement definition.
34
How to Execute a PreparedStatement
1. Supply values for the variables: 2. Execute the statement: pstmt.setXXX(index, value); pstmt.executeQuery(); pstmt.executeUpdate(); int empNo = 3521; PreparedStatement pstmt = conn.prepareStatement("UPDATE emp SET ename = ? WHERE empno = ? "); pstmt.setString(1, "DURAND"); pstmt.setInt(2, empNo); pstmt.executeUpdate(); Specifying Values for the Bind Variables You use the PreparedStatement.setXXX() methods to supply values for the variables in a prepared statement. There is one setXXX() method for each Java type: setString(), setInt(), and so on. You must use the setXXX() method that is compatible with the SQL type of the variable. In the example in the slide, the first variable is updating a VARCHAR column, and so you must use setString() to supply a value for the variable. You can use setObject() with any variable type. Each variable has an index. The index of the first variable in the prepared statement is 1, the index of the second variable is 2, and so on. If there is only one variable, its index is 1. The index of a variable is passed to the setXXX() method. Closing a PreparedStatement A PreparedStatement is not cached. If you close it, you will have to start again.
35
The CallableStatement Object
A CallableStatement object holds parameters for calling stored procedures. A callable statement can contain variables that you supply each time you execute the call. When the stored procedure returns, computed values (if any) are retrieved through the CallabableStatement object. The CallableStatement Object The way to access stored procedures using JDBC is through the CallableStatement class which is inherited from the PreparedStatement class. CallableStatement is like PreparedStatement in that you can specify parameters using the question mark (?) notation, but it contains no SQL statements. Both functions and procedures take parameters represented by identifiers. A function executes some procedural logic and it returns a value that can be any data type supported by the database. The parameters supplied to the function do not change after the function is executed. A procedure executes some procedural logic but does not return any value. However, some of the parameters supplied to the procedure may have their values changed after the procedure is executed. Note: Calling a stored procedure is the same whether the stored procedure was written originally in Java or in any other language supported by the database, such as PL/SQL. Indeed, a stored procedure written in Java appears to the programmer as a PL/SQL stored procedure.
36
How to Create a Callable Statement
Register the driver and create the database connection. Create the callable statement, identifying variables with a question mark (?). CallableStatement cstmt = conn.prepareCall("{call " + ADDITEM + "(?,?,?)}"); cstmt.registerOutParameter(2,Types.INTEGER); cStmt.registerOutParameter(3,Types.DOUBLE); Creating a Callable Statement First you need an active connection to the database in order to obtain a CallableStatement object. Next, you create a CallableStatement object using the prepareCall() method of the Connection class. This method typically takes a string as an argument. The syntax for the string has two forms. The first form includes a result parameter and the second form does not: {? = call proc (…) } // A result is returned into a variable {call proc (…) } // Does not return a result In the example in the slide, the second form is used, where the stored procedure in question is ADDITEM. Note that the parameters to the stored procedures are specified using the question mark notation used earlier in PreparedStatement. You must register the data type of the parameters using the registerOutParameter() method of CallableStatement if you expect a return value, or if the procedure is going to modify a variable (also known as an OUT variable). In the example in the slide, the second and third parameters are going to be computed by the stored procedure, whereas the first parameter is an input (the input is specified in the next slide). Parameters are referred to sequentially, by number. The first parameter is 1. To specify the data type of each OUT variable, you use parameter types from the Types class. When the stored procedure successfully returns, the values can be retrieved from the CallableStatement object.
37
How to Execute a Callable Statement
1. Set the input parameters. 2. Execute the statement. 3. Get the output parameters. cstmt.setXXX(index, value); cstmt.execute(statement); How to Execute a Callable Statement There are three steps in executing the stored procedure after you have registered the types of the OUT variables: 1. Set the IN parameters. Use the setXXX() methods to supply values for the IN parameters. There is one setXXX() method for each Java type: setString(), setInt(), and so on. You must use the setXXX() method that is compatible with the SQL type of the variable. You can use setObject() with any variable type. Each variable has an index. The index of the first variable in the prepared statement is 1, the index of the second is 2, and so on. If there is only one variable, its index is 1. 2. Execute the call to the stored procedure. Execute the procedure using the execute() method. 3. Get the OUT parameters. Once the procedure is completed, you retrieve OUT variables, if any, using the getXXX() methods. Note that these methods must match the types you registered in the previous slide. Instructor Note The stored procedures lesson contains an example of executing a callable statement. var = cstmt.getXXX(index);
38
Oracle JDBC Extensions
Oracle provides many extensions to standard JDBC; for example: Connection OracleConnection Statement OracleStatement PreparedStatement OraclePreparedStatement CallableStatement OracleCallableStatement Oracle JDBC Extensions The rest of this lesson is devoted to the extensions provided by the Oracle JDBC drivers, to provide greater efficiency, reliability, and flexibility. These extensions are located in Oracle-specific subclasses of the standard JDBC classes and interfaces. Some of the Oracle subclasses are shown in the slide. Here is a list of the performance features discussed in the following pages: Row prefetches Batch updates Prespecifying types Oracle ROWIDs Suppressing metadata table remarks ResultSet OracleResultSet
39
Maximize Database Access
Use connection pooling to minimize the operation costs of creating and closing sessions. Use explicit data source declaration for physical reference to the database. Use the getConnection() method to obtain a logical connection instance. Connection Pooling Presentation A connection pool is a cache of database connections. It is maintained in memory, which enables the connections to be reused. This technique is important for increasing performance, especially when the JDBC API is used in a middle-tier environment. Connection pooling does not affect application code. The application simply accesses a JDBC data source and uses it in the standard way. The data source implements connection pooling transparently to the application by using the PooledConnection and ConnectionPoolDataSource facilities provided by the JDBC 2.0 driver.
40
Middle-tier server code ConnectionPoolDataSource
Connection Pooling Middle tier Java servlet Data source Middle-tier server code ConnectionPoolDataSource JDBC driver Database Connection Pooling Presentation (continued) When using pooled connections, you must perform the following two steps: Use a DataSource object rather than the DriverManager class to get a connection. The DataSource object is implemented and deployed so that it will create pooled connections. Use a finally statement to close a pooled connection. The following finally statement appears after the try and catch blocks that apply to the code in which the pooled connection is used: try { Connection con = ds.getConnection("Login","Password"); // ... code to use the pooled connection con } catch (Exception ex { // code to handle exceptions } finally { if(con != null) con.close(); } Note: Connection pooling is supported in both JDK1.1 and JDK 1.2 OCI and thin drivers. Connection pooling is not supported for the server driver because the server driver can have only one connection, which is to the logged-in session in which it is running. Database commands
41
Full Notes Page for Practice 1
Connection Pooling Presentation (continued) A Simple Pooled Connection Sample import java.sql.*; import javax.sql.*; import oracle.jdbc.*; import oracle.jdbc.pool.*; class PooledConnection1 { public static void main (String args []) throws SQLException // Create a OracleConnectionPoolDataSource instance OracleConnectionPoolDataSource ocpds = new OracleConnectionPoolDataSource(); String url = try { String url1 = System.getProperty("JDBC_URL"); if (url1 != null) url = url1; } catch (Exception e) { // If there is any security exception, // ignore it and use the default } Full Notes Page for Practice 1
42
Connection Pooling Presentation (continued)
A Simple Pooled Connection Sample (continued) // Set connection parameters ocpds.setURL(url); ocpds.setUser("scott"); ocpds.setPassword("tiger"); // Create a pooled connection PooledConnection pc = ocpds.getPooledConnection(); // Get a Logical connection Connection conn = pc.getConnection(); // Create a Statement Statement stmt = conn.createStatement (); // Select the ENAME column from the EMP table ResultSet rset = stmt.executeQuery ("select ENAME from EMP"); // Iterate through the result and print the employee names while (rset.next ()) System.out.println (rset.getString (1)); // Close the ResultSet rset.close(); rset = null; // Close the Statement, logical connection, and pooled connection stmt.close(); stmt = null; conn.close(); conn = null; pc.close(); pc = null; }
43
Summary In this lesson, you should have learned the following:
JDBC provides database connectivity for various Java constructs, including servlets and client applications. JDBC is a standard Java interface and part of the J2SE. The steps for using SQL statements in Java are Register, Connect, Submit, and Close. SQL statements can throw exceptions. You can control default transactions behavior.
44
Practice 16: Overview This practice covers:
Setting up the Java environment for JDBC Adding JDBC components to query the database Populating the OrderEntryFrame with Customers from the database Practice 16: Overview Note: If you have successfully completed the previous practice, then continue using the same directory and files. If the compilation from the previous practice was unsuccessful and you want to move on to this practice, then change to the les15 directory, load the OrderEntryWorkspaceLes15 workspace, and continue with this practice. Viewing the model: To view the course application model up to this practice, load the OrderEntryWorkspaceLes15 workspace. In the Applications – Navigator node, expand the OrderEntryWorkspaceLes15 – OrderEntryProjectLes15 - Application Sources – oe, and double-click the UML Class Diagram1 entry. This diagram displays all the classes created to this point in the course. Instructor Note In the previous practices, the phone number was defined as a String. However, in the database it is stored as a complex object type. A utility, named JPublisher, can be used to convert an object type to a string, so that it can be used in your application. This process is much more detailed than can be covered in this course. So in the JDBC practice, the phone number item will not be populated with any values. For more information about converting object types, please attend the Oracle9i: Access the Database with JDBC and Stored Procedures course.
45
Full Notes Page Practice 16: Using JDBC to Access the Database Goal
The goal of this practice is to use the course application to interact with the Oracle database. During this practice, you perform query statements to access a database and integrate them into the application. Note: If you have successfully completed the previous practice, then continue using the same directory and files. If the compilation from the previous practice was unsuccessful and you want to move on to this practice, then change to the les15 directory, load the OrderEntryWorkspaceLes15 workspace, and continue with this practice. Your Assignment In the DataMan class, you specify the code to connect to the database, to query a single column from a table. Then you modify the OrderEntryFrame class and integrate the rows returned from the database into the GUI interface. Set the Environment to Use JDBC 1. Update the project to include necessary JDBC classes. a. Double-click the OrderEntryProjectLes16, and select the Libraries node. b. In the Available Libraries pane, find and move the Oracle JDBC library to the Selected Libraries pane. Click OK. Add JDBC Components to Query the Database 2. Modify the DataMan class and provide the connection information. Note: Place the database related code in the try block. a. Specify the packages to import. import java.sql.*; b. Find the code section where the ProductMap class variables are being declared. Add a static variable to hold the connection information. private static Connection conn = null; c. Add the try { in the code block shown here because the exception portion is shown. Also, finish the syntax for the exception section and add the missing start brace. So, the corrected code block would look like: “try{ // Register the Oracle JDBC driver DriverManager.registerDriver(new oracle.jdbc.OracleDriver()); // Define the connection url (include db conn) String url = // Provide db connection information conn = DriverManager.getConnection (url, “ora<n>”,”oracle”); //Include an Exception in the catch block }catch (Exception e){ } d. Save and compile the DataMan.java file. Correct any errors. Full Notes Page
46
Practice 16: Using JDBC to Access the Database (continued)
3. Create a method to execute the select statement based on a customer number, and return the result to a customer object. Remember the method name for later. In this practice, you populate only three of the items from the database. In the previous practices, the phone number was defined as a String. However, in the database, it is stored as a complex object type. A utility, named JPublisher, can be used to convert an object type to a string, so that it can be used in your application. This process is much more detailed than can be covered in this course. So in your JDBC practice, the phone number item will not be populated with any values. For more information about converting object types, please attend the Oracle9i: Access the Database with JDBC and Stored Procedures course. a. Following the code to connect to the database, create the method to issue the query based on a customer ID. public static Customer selectCustomerById(int id) throws Exception { Customer customer = null; Statement stmt = conn.createStatement (); System.out.println("Table Customers query for customer with id: " + id); ResultSet rset = stmt.executeQuery ("SELECT cust_last_name, nls_territory" + "FROM customers WHERE customer_id = " + id); b. If a record is returned, populate the customer object. if (rset.next ()) customer = new Customer(); customer.setId(id); customer.setName(rset.getString(1)); //holds first column customer.setAddress(rset.getString(2)); //holds second column System.out.println("Customer found: " + customer); // prints all three columns to the command window } Full Notes Page
47
Practice 16: Using JDBC to Access the Database (continued)
c. Otherwise, throw an exception that the customer is not found, close the statement, and return the customer. else { throw new NotFoundException("Customer with id " + id + " not found"); } rset.close(); stmt.close(); return customer; d. Save and compile the DataMan.java file. Correct any errors." Populate the OrderEntryFrame with Database Customers 4. Modify the OrderEntryFrame to populate the customer with those coming from the database. a. Open the OrderEntryFrame.java class in the Code Editor, and search for the findBtn_actionPerformed() method. In this method, locate the line of code where the customer object is being set: customer=DataMan.findCustomerById(custId); Remove this comment line from this line and add a line to populate the customer object from the database method you created in DataMan.java (that is, selectCustomerById()): customer=DataMan.selectCustomerById(custId); b. In the following catch block, remove the Notfound part of the exception. You want to catch the exception from DataMan if no customer is found. catch (NotFoundException err) changes to catch (Exception err) c. Compile and test the application. Try retrieving records from customer 101, 103, 308, 203, 341, and 999. Did they all return a customer? If not, did you see the exception raised? Full Notes Page
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.