Copyright Oracle Corporation, All rights reserved. 6 Accessing a Database Using the JDBC API
Copyright Oracle Corporation, All rights reserved. 6-2 Objectives After completing this lesson, you should be able to do the following: Connect to a database using JDBC Perform queries using JDBC Invoke prepared statements and stored procedures Use transaction commit and rollback Use Oracle JDBC extensions After completing this lesson, you should be able to do the following: Connect to a database using JDBC Perform queries using JDBC Invoke prepared statements and stored procedures Use transaction commit and rollback Use Oracle JDBC extensions
Copyright Oracle Corporation, All rights reserved. 6-3 JDBC class library Overview Javasoft driver ODBC C library Oracle driver OCI C library Oracle driver Java sockets JBCL components Your Java code ODBC-basedOCI-basedPure Java
Copyright Oracle Corporation, All rights reserved. 6-4 JDBC is a standard Java class library, to query and modify relational data – Import java.sql.* in your Java code JDBC is modeled after ODBC – Supports SQL92 syntax and types – Allows for vendor-specific extensions – Many Oracle extensions JDBC is a standard Java class library, to query and modify relational data – Import java.sql.* in your Java code JDBC is modeled after ODBC – Supports SQL92 syntax and types – Allows for vendor-specific extensions – Many Oracle extensions What Is JDBC?
Copyright Oracle Corporation, All rights reserved. 6-5 Relationship Between JDBC Classes ResultSet ResultSetMetaData DatabaseMetaData Statement Connection DriverManager
Copyright Oracle Corporation, All rights reserved. 6-6 Registering a JDBC Driver JDBC drivers must register themselves with the DriverManager Drivers register themselves automatically when they are loaded JDBC drivers must register themselves with the DriverManager Drivers register themselves automatically when they are loaded try { Class c = Class.forName( "oracle.jdbc.driver.OracleDriver"); } catch (ClassNotFoundException e) { e.printStackTrace(); }
Copyright Oracle Corporation, All rights reserved. 6-7 DriverManager is used to open a connection to a database The database is specified using a URL, which identifies the JDBC driver jdbc: : Example: DriverManager is used to open a connection to a database The database is specified using a URL, which identifies the JDBC driver jdbc: : Example: Connecting to a Database : :
Copyright Oracle Corporation, All rights reserved. 6-8 Example: Connecting to Oracle The following code connects to an Oracle database Uses the Oracle JDBC Thin driver The following code connects to an Oracle database Uses the Oracle JDBC Thin driver Connection conn; try { conn = DriverManager.getConnection( "theUser", "thePassword"); } catch (SQLException e) {…}
Copyright Oracle Corporation, All rights reserved. 6-9 Obtaining Database Metadata Connection can be used to get a DatabaseMetaData object This provides many methods to obtain metadata for the database Connection can be used to get a DatabaseMetaData object This provides many methods to obtain metadata for the database Connection conn; … try { DatabaseMetaData dm = conn.getMetaData(); String s1 = dm.getURL(); String s2 = dm.getSQLKeywords(); boolean b1 = dm.supportsTransactions(); boolean b2 = dm.supportsSelectForUpdate(); } catch (SQLException e) {…}
Copyright Oracle Corporation, All rights reserved Three interfaces are defined, providing the following capabilities: Execute queries and other DML/DDL operations Execute precompiled statements Call stored procedures Three interfaces are defined, providing the following capabilities: Execute queries and other DML/DDL operations Execute precompiled statements Call stored procedures Statements Statement PreparedStatement CallableStatement
Copyright Oracle Corporation, All rights reserved Statements and Queries The Statement class can be used as follows, to execute a query executeQuery() executes a SQL query, and returns a ResultSet The Statement class can be used as follows, to execute a query executeQuery() executes a SQL query, and returns a ResultSet try { Statement stmt = conn.createStatement(); ResultSet rset = stmt.executeQuery ("select ENAME, SAL from EMP"); } catch (SQLException e) {…}
Copyright Oracle Corporation, All rights reserved Processing Query Results ResultSet holds a table of result data returned by a SQL query Support for cursors – Cursor starts at beginning of data set – Use next() to move to next record Retrieve data using getXXX() methods, mapping results to equivalent Java types ResultSet holds a table of result data returned by a SQL query Support for cursors – Cursor starts at beginning of data set – Use next() to move to next record Retrieve data using getXXX() methods, mapping results to equivalent Java types
Copyright Oracle Corporation, All rights reserved Processing Results: Example try { ResultSet rset = stmt.executeQuery( "select ENAME, SAL from EMP"); while (rset.next()) { String ename = rset.getString(1); BigDecimal sal = rset.getBigDecimal(2, 2); // Can also access columns by name: // String ename = rset.getString("ENAME"); // BigDecimal sal = rset.getBigDecimal("SAL"); } catch (SQLException e) {…}
Copyright Oracle Corporation, All rights reserved Obtaining ResultSet Metadata ResultSet can be used to get a ResultSetMetaData object Provides result set metadata ResultSet can be used to get a ResultSetMetaData object Provides result set metadata try { ResultSet rset = … ; ResultSetMetaData md = rset.getMetaData(); while (rset.next()) { for (int i = 0; i < md.getColumnCount(); i++) { String lbl = md.getColumnLabel(); String typ = md.getColumnTypeName(); … } } catch (SQLException e) {…}
Copyright Oracle Corporation, All rights reserved Mapping Database Types to Java Types ResultSet maps database types to Java types ResultSet rset = stmt.executeQuery ("select EMPNO, ENAME, HIREDATE from EMP"); BigDecimal empno = rset.getBigDecimal(1, 2); String ename = rset.getString(2); Date hiredate = rset.getDate(3); Col Name EMPNO ENAME HIREDATE Type NUMBER VARCHAR2 DATE
Copyright Oracle Corporation, All rights reserved Prepared Statements If you need to execute a statement several times, with different bind variables: Use a PreparedStatement object Identify bind variables with a ? sign If you need to execute a statement several times, with different bind variables: Use a PreparedStatement object Identify bind variables with a ? sign try { Connection conn = DriverManager.getConnection(…); PreparedStatement pstmt = conn.prepareStatement("update EMP set SAL = ?"); … } catch (SQLException e) {…}
Copyright Oracle Corporation, All rights reserved Binding Variables and Executing a PreparedStatement Specify bind variables using the methods setXXX() in PreparedStatement try { PreparedStatement pstmt = conn.prepareStatement("update EMP set SAL = ?"); … pstmt.setBigDecimal(1, new BigDecimal(55000)); pstmt.executeUpdate(); pstmt.setBigDecimal(1, new BigDecimal(65000)); pstmt.executeUpdate(); … } catch (SQLException e) {…}
Copyright Oracle Corporation, All rights reserved Stored Procedures To call a stored procedure, you need a CallableStatement object IN parameters are set using setXXX(), as for a PreparedStatement Return values and OUT parameters must be registered, to specify their types To call a stored procedure, you need a CallableStatement object IN parameters are set using setXXX(), as for a PreparedStatement Return values and OUT parameters must be registered, to specify their types
Copyright Oracle Corporation, All rights reserved Calling Stored Procedures getSal(v_ename in varchar2, v_job out varchar2) return numeric … CallableStatement cs = conn.prepareCall( "{? = call getSal(?,?)}" ); cs.registerOutParameter(1, Types.NUMERIC); cs.setString(2, "smith"); cs.registerOutParameter(3, Types.VARCHAR); cs.executeUpdate(); System.out.println("Smith makes " + cs.getFloat(1) + " as a " + cs.getString(3));
Copyright Oracle Corporation, All rights reserved Transactions Transactions are governed by the autoCommit property in Connection – true initially, causing a separate transaction per SQL statement If you want to take control: Transactions are governed by the autoCommit property in Connection – true initially, causing a separate transaction per SQL statement If you want to take control: Connection conn = DriverManager.getConnection(…); conn.setAutoCommit(false); // No autocommits now … // Issue SQL statements conn.commit(); … or … // Commit transaction conn.rollback(); // Rollback transaction
Copyright Oracle Corporation, All rights reserved PreparedStatement CallableStatement Oracle Extensions Oracle provides many extensions to standard JDBC, for example: Connection Statement ResultSet OraclePreparedStatement OracleCallableStatement OracleStatement OracleResultSet OracleConnection
Copyright Oracle Corporation, All rights reserved Prefetching Rows in a Query Oracle JDBC drivers enable you to set the number of rows to prefetch to the client – Can be defined for the Connection – Alternatively, define for individual Statements Reduces the number of round trips to the server Oracle JDBC drivers enable you to set the number of rows to prefetch to the client – Can be defined for the Connection – Alternatively, define for individual Statements Reduces the number of round trips to the server
Copyright Oracle Corporation, All rights reserved Prefetching Rows: Example Connection conn = DriverManager.getConnection(…); ((OracleConnection)conn).setDefaultRowPrefetch(7); Statement st = conn.createStatement(); ResultSet rs = st.executeQuery("select * from EMP"); while (rs.next()) System.out.println(rs.getString(1)); ((OracleStatement)st).setRowPrefetch(2); rs = st.executeQuery("select * from EMP"); while (rs.next()) System.out.println(rs.getString(1)); Connection conn = DriverManager.getConnection(…); ((OracleConnection)conn).setDefaultRowPrefetch(7); Statement st = conn.createStatement(); ResultSet rs = st.executeQuery("select * from EMP"); while (rs.next()) System.out.println(rs.getString(1)); ((OracleStatement)st).setRowPrefetch(2); rs = st.executeQuery("select * from EMP"); while (rs.next()) System.out.println(rs.getString(1));
Copyright Oracle Corporation, All rights reserved Prespecifying Column Types When a query is performed, JDBC uses a network round trip to identify result types Oracle JDBC enables column types to be predefined – Eliminates one network round trip When a query is performed, JDBC uses a network round trip to identify result types Oracle JDBC enables column types to be predefined – Eliminates one network round trip ((OracleStatement)st).clearDefines(); ((OracleStatement)st).defineColumnType(col, type);
Copyright Oracle Corporation, All rights reserved Prespecifying Types: Example Statement st = conn.createStatement(); // Ask for the EMPNO column as a String. // This avoids a round trip to get the column type. // EMPNO is converted to a string on the server. ((OracleStatement)st).defineColumnType (1, Types.VARCHAR); ResultSet rs = st.executeQuery ("select EMPNO from EMP"); while (rs.next()) System.out.println (rs.getString(1));
Copyright Oracle Corporation, All rights reserved Batched Updates of Prepared Statements By default, prepared statements are executed as soon as executeUpdate() is called Oracle JDBC enables prepared statements to be batched: By default, prepared statements are executed as soon as executeUpdate() is called Oracle JDBC enables prepared statements to be batched: ((OraclePreparedStatement)ps).setExecuteBatch(3); ((OraclePreparedStatement)ps).executeBatch(); ((OraclePreparedStatement)ps).getExecuteBatch();
Copyright Oracle Corporation, All rights reserved Guided Practice: When Are the Statements Executed? OraclePreparedStatement methods setExecuteBatch() and sendBatch() OraclePreparedStatement methods setExecuteBatch() and sendBatch() PreparedStatement ps = conn.prepareStatement ("update EMP set SAL = SAL + 100"); ((OraclePreparedStatement)ps).setExecuteBatch(3); ps.executeUpdate(); ((OraclePreparedStatement)ps).sendBatch()
Copyright Oracle Corporation, All rights reserved The ROWID Pseudo Column Oracle JDBC drivers do not support getCursorName() for cursor usage Oracle provides a ROWID type instead – ROWID is a pseudo column in a query – Retrieve its value from a ResultSet, using getString() ROWID can also be bound to a parameter in a PreparedStatement Oracle JDBC drivers do not support getCursorName() for cursor usage Oracle provides a ROWID type instead – ROWID is a pseudo column in a query – Retrieve its value from a ResultSet, using getString() ROWID can also be bound to a parameter in a PreparedStatement
Copyright Oracle Corporation, All rights reserved Example: Using ROWID for In-Place Updates ResultSet rset = stmt.executeQuery ("select ENAME, ROWID from EMP for update"); PreparedStatement pstmt = conn.prepareStatement ("update EMP set ENAME = ? where ROWID = ?"); while (rset.next()) { String ename = rset.getString(1); String rowid = rset.getString(2); pstmt.setString(1, ename.toLowerCase()); pstmt.setString(2, rowid); pstmt.executeUpdate(); }
Copyright Oracle Corporation, All rights reserved Oracle Extensions for Stored Subprograms Stored subprograms in standard JDBC: Oracle JDBC supports Oracle escape syntax, and PL/SQL anonymous blocks: Stored subprograms in standard JDBC: Oracle JDBC supports Oracle escape syntax, and PL/SQL anonymous blocks: CallableStatement cs = conn.prepareCall ( "{? = call func(?,?)}" ); CallableStatement cs2 = conn.prepareCall ("begin :1 = func(:2,:3); end;");
Copyright Oracle Corporation, All rights reserved Oracle CURSOR Type Oracle provides a CURSOR type, to iterate a result set returned by a stored procedure CallableStatement cs = conn.prepareCall ("begin open ? for select ENAME from EMP; end;"); cs.registerOutParameter(1, OracleTypes.CURSOR); cs.executeUpdate(); ResultSet cursor = ((OracleCallableStatement)cs).getCursor(1); while (cursor.next()) System.out.println(cursor.getString(1));
Copyright Oracle Corporation, All rights reserved Suppressing Table Remarks DatabaseMetaData TABLE_REMARKS should be avoided Require slow outer joins To enable or disable table remarks: DatabaseMetaData TABLE_REMARKS should be avoided Require slow outer joins To enable or disable table remarks: ((OracleConnection)conn).setRemarksReporting(bool);
Copyright Oracle Corporation, All rights reserved Summary JDBC provides classes and interfaces for database connectivity – Connect to a database – Perform DML and DDL operations – Prepared statements and stored procedures Oracle JDBC provides many extensions – Performance and flexibility JDBC provides classes and interfaces for database connectivity – Connect to a database – Perform DML and DDL operations – Prepared statements and stored procedures Oracle JDBC provides many extensions – Performance and flexibility
Copyright Oracle Corporation, All rights reserved Practice 6-1 Overview Connect to a database, using JDBC Create and execute a query, using JDBC Iterate a result set Perform an update operation Perform an update operation with parameters Connect to a database, using JDBC Create and execute a query, using JDBC Iterate a result set Perform an update operation Perform an update operation with parameters
Copyright Oracle Corporation, All rights reserved Full Notes Page for Practices
Copyright Oracle Corporation, All rights reserved Full Notes Page for Practices
Copyright Oracle Corporation, All rights reserved Full Notes Page for Practices
Copyright Oracle Corporation, All rights reserved Full Notes Page for Practices