The JDBC API is a Java API that can access any kind of tabular data, especially data stored in a Relational Database.
- Connect to a data source, like a database
- Send queries and update statements to the database
- Retrieve and process the results received from the database in answer to your query
The following simple code fragment gives a simple example of these three steps:
public void connectToAndQueryDatabase(String username, String password) { Connection con = DriverManager.getConnection( "jdbc:myDriver:myDatabase", username, password); Statement stmt = con.createStatement(); ResultSet rs = stmt.executeQuery("SELECT a, b, c FROM Table1"); while (rs.next()) { int x = rs.getInt("a"); String s = rs.getString("b"); float f = rs.getFloat("c"); } }
JDBC Product Components
JDBC includes four components:
- The JDBC API — The JDBC™ API provides programmatic access to relational data from the Java™ programming language. Using the JDBC API, applications can execute SQL statements, retrieve results, and propagate changes back to an underlying data source. The JDBC API can also interact with multiple data sources in a distributed, heterogeneous environment. The JDBC API is part of the Java platform, which includes the Java™ Standard Edition (Java™ SE ) and the Java™ Enterprise Edition (Java™ EE). The JDBC 4.0 API is divided into two packages:
java.sql
andjavax.sql.
Both packages are included in the Java SE and Java EE platforms.- JDBC Driver Manager — The JDBC
DriverManager
class defines objects which can connect Java applications to a JDBC driver.DriverManager
has traditionally been the backbone of the JDBC architecture. It is quite small and simple. The Standard Extension packagesjavax.naming
andjavax.sql
let you use aDataSource
object registered with a Java Naming and Directory Interface™ (JNDI) naming service to establish a connection with a data source. You can use either connecting mechanism, but using aDataSource
object is recommended whenever possible.- JDBC Test Suite — The JDBC driver test suite helps you to determine that JDBC drivers will run your program. These tests are not comprehensive or exhaustive, but they do exercise many of the important features in the JDBC API.
- JDBC-ODBC Bridge — The Java Software bridge provides JDBC access via ODBC drivers. Note that you need to load ODBC binary code onto each client machine that uses this driver. As a result, the ODBC driver is most appropriate on a corporate network where client installations are not a major problem, or for application server code written in Java in a three-tier architecture.
This Trail uses the first two of these these four JDBC components to connect to a database and then build a java program that uses SQL commands to communicate with a test Relational Database. The last two components are used in specialized environments to test web applications, or to communicate with ODBC-aware DBMSs.Establishing a Connection
First, you need to establish a connection with the data source you want to use. A data source can be a DBMS, a legacy file system, or some other source of data with a corresponding JDBC driver. Typically, a JDBC application connects to a target data source using one of two classes:Note: The samples in this tutorial use the
DriverManager
: This fully implemented class connects an application to a data source, which is specified by a database URL. When this class first attempts to establish a connection, it automatically loads any JDBC 4.0 drivers found within the class path. Note that your application must manually load any JDBC drivers prior to version 4.0.DataSource
: This interface is preferred overDriverManager
because it allows details about the underlying data source to be transparent to your application. ADataSource
object's properties are set so that it represents a particular data source. See Connecting with DataSource Objects for more information. For more information about developing applications with theDataSource
class, see the latest The Java EE Tutorial.DriverManager
class instead of theDataSource
class because it is easier to use and the samples do not require the features of theDataSource
class. This page covers the following topics:Using the DriverManager Class
Connecting to your DBMS with theDriverManager
class involves calling the methodDriverManager.getConnection
. The following method,JDBCTutorialUtilities.getConnection
, establishes a database connection:public Connection getConnection() throws SQLException { Connection conn = null; Properties connectionProps = new Properties(); connectionProps.put("user", this.userName); connectionProps.put("password", this.password); if (this.dbms.equals("mysql")) { conn = DriverManager.getConnection( "jdbc:" + this.dbms + "://" + this.serverName + ":" + this.portNumber + "/", connectionProps); } else if (this.dbms.equals("derby")) { conn = DriverManager.getConnection( "jdbc:" + this.dbms + ":" + this.dbName + ";create=true", connectionProps); } System.out.println("Connected to database"); return conn; }Overview of SQLException
When JDBC encounters an error during an interaction with a data source, it throws an instance ofSQLException
as opposed toException
. (A data source in this context represents the database to which aConnection
object is connected.) TheSQLException
instance contains the following information that can help you determine the cause of the error:
- A description of the error. Retrieve the
String
object that contains this description by calling the methodSQLException.getMessage
.- A SQLState code. These codes and their respective meanings have been standardized by ISO/ANSI and Open Group (X/Open), although some codes have been reserved for database vendors to define for themselves. This
String
object consists of five alphanumeric characters. Retrieve this code by calling the methodSQLException.getSQLState
.- An error code. This is an integer value identifying the error that caused the
SQLException
instance to be thrown. Its value and meaning are implementation-specific and might be the actual error code returned by the underlying data source. Retrieve the error by calling the methodSQLException.getErrorCode
.- A cause. A
SQLException
instance might have a causal relationship, which consists of one or moreThrowable
objects that caused theSQLException
instance to be thrown. To navigate this chain of causes, recursively call the methodSQLException.getCause
until anull
value is returned.- A reference to any chained exceptions. If more than one error occurs, the exceptions are referenced through this chain. Retrieve these exceptions by calling the method
SQLException.getNextException
on the exception that was thrown.Retrieving Exceptions
The following method,JDBCTutorialUtilities.printSQLException
outputs the SQLState, error code, error description, and cause (if there is one) contained in theSQLException
as well as any other exception chained to it:public static void printSQLException(SQLException ex) { for (Throwable e : ex) { if (e instanceof SQLException) { if (ignoreSQLException( ((SQLException)e). getSQLState()) == false) { e.printStackTrace(System.err); System.err.println("SQLState: " + ((SQLException)e).getSQLState()); System.err.println("Error Code: " + ((SQLException)e).getErrorCode()); System.err.println("Message: " + e.getMessage()); Throwable t = ex.getCause(); while(t != null) { System.out.println("Cause: " + t); t = t.getCause(); } } } } }For example, if you call the methodCoffeesTable.dropTable
with Java DB as your DBMS, the tableCOFFEES
does not exist, and you remove the call toJDBCTutorialUtilities.ignoreSQLException
, the output will be similar to the following:SQLState: 42Y55 Error Code: 30000 Message: 'DROP TABLE' cannot be performed on 'TESTDB.COFFEES' because it does not exist.Instead of outputtingSQLException
information, you could instead first retrieve theSQLState
then process theSQLException
accordingly. For example, the methodJDBCTutorialUtilities.ignoreSQLException
returnstrue
if theSQLState
is equal to code42Y55
(and you are using Java DB as your DBMS), which causesJDBCTutorialUtilities.printSQLException
to ignore theSQLException
:public static boolean ignoreSQLException(String sqlState) { if (sqlState == null) { System.out.println("The SQL state is not defined!"); return false; } // X0Y32: Jar file already exists in schema if (sqlState.equalsIgnoreCase("X0Y32")) return true; // 42Y55: Table already exists in schema if (sqlState.equalsIgnoreCase("42Y55")) return true; return false; }Retrieving Warnings
SQLWarning
objects are a subclass ofSQLException
that deal with database access warnings. Warnings do not stop the execution of an application, as exceptions do; they simply alert the user that something did not happen as planned. For example, a warning might let you know that a privilege you attempted to revoke was not revoked. Or a warning might tell you that an error occurred during a requested disconnection.A warning can be reported on aConnection
object, aStatement
object (includingPreparedStatement
andCallableStatement
objects), or aResultSet
object. Each of these classes has agetWarnings
method, which you must invoke in order to see the first warning reported on the calling object. IfgetWarnings
returns a warning, you can call theSQLWarning
methodgetNextWarning
on it to get any additional warnings. Executing a statement automatically clears the warnings from a previous statement, so they do not build up. This means, however, that if you want to retrieve warnings reported on a statement, you must do so before you execute another statement.The following methods fromJDBCTutorialUtilities
illustrate how to get complete information about any warnings reported onStatement
orResultSet
objects:public static void getWarningsFromResultSet(ResultSet rs) throws SQLException { JDBCTutorialUtilities.printWarnings(rs.getWarnings()); } public static void getWarningsFromStatement(Statement stmt) throws SQLException { JDBCTutorialUtilities.printWarnings(stmt.getWarnings()); } public static void printWarnings(SQLWarning warning) throws SQLException { if (warning != null) { System.out.println("\n---Warning---\n"); while (warning != null) { System.out.println("Message: " + warning.getMessage()); System.out.println("SQLState: " + warning.getSQLState()); System.out.print("Vendor error code: "); System.out.println(warning.getErrorCode()); System.out.println(""); warning = warning.getNextWarning(); } }
No comments:
Post a Comment