JDBC - Java Database Connectivity


Overview

JDBC environment model


Configuring the JDBC

These procedures have been tested with JDK 1.1.1, which includes the JDBC and the JDBC-ODBC bridge driver. Check the Javasoft JDBC site for a description of the most recent changes made to the JDBC.

If you are using JDK 1.02, go to the Javasoft JDBC site for instructions on installing the JDBC and the JDBC-ODBC Bridge driver with this release of the JDK.

To use the JDBC, you must first obtain an appropriate driver for your database. There are several vendors with various types of JDBC drivers available on the commercial market. A list of vendors is available at the Javasoft JDBC site. Refer to the vendor's instructions to activate their driver in your application.

The JDBC-ODBC Bridge

As noted earlier, the JDBC comes delivered with a JDBC-ODBC bridge driver. This driver serves as an intermediary, or bridge, for allowing the JDBC to interface with a database using ODBC. The examples provided throughout this web site incorporate the JDBC-ODBC bridge, using ODBC to connect to a Microsoft Access 7.0 database under Windows 95.

To use the JDBC-ODBC bridge, you must install an ODBC driver for your particular database. In the case of Microsoft Access 7.0, the ODBC driver is must be installed using the Microsoft Office setup procedure.

Once the ODBC driver is installed, you need to configure it to recognize your physical database. ODBC uses a "data source name" to reference the database. This name may or may not be the same as the physical name given to your database.

The ODBC configuration procedures are specific to the vendor providing your driver, so you should refer to their instructions. If you are using Microsoft Access 7.0, you may use the 32-bit ODBC setup contained within the Windows 95 Control Panel to add your data source. If you are not sure how to add a data source for your database, then follow the online instructions contained within the 32-bit ODBC setup by clicking on its Help button.

System Environment

To proceed with the JDBC and JDBC-ODBC bridge, be sure your PATH and CLASSPATH variables contain the location of your JDK (or JRE) binary executables, class libraries, and JDBC driver. If you are using the Solaris operating system, be sure also to set the LD_LIBRARY_PATH variable to point to the JDBC driver and ODBC load modules.


Connecting to a Database

Connection to a database is done through the DriverManager class and Connection interface. To establish a connection, follow the steps listed below:

Invoke the JDBC Package:
import java.sql.*;

Load the Appropriate Database Driver:
// Use the JDBC-ODBC bridge as an example
Class.forName ("sun.jdbc.odbc.JdbcOdbcDriver");

(Throws a ClassNotFoundException error.)

Create a Database URL:
// The database URL takes the form jdbc:subprotocol:subname
String url = "jdbc:odbc:dsn"

Assign the User ID and Password:
String user = "guest";
String password = "guest";

Open a Connection:

// Call the Driver Manager to open a database connection
Connection con = DriverManager.getConnection(url, user, password);

(Throws a SQLException error.)

Other Settings:
// Transactions are automatically committed when executed
con.setAutoCommit(true);

// Put connection in read-only mode
con.setReadOnly(true).

(Throws a SQLException error.)

Close a Connection:
con.close();

(Throws a SQLException error.)


Issuing a SQL Query

SQL queries are performed through the Statement and ResultSet interfaces.

Create a Statement Object:
Statement stmt = con.createStatement ();

(Throws a SQLException error.)

Set the Query String:
String query = "SELECT * FROM TABLE_NAME";

Execute the Query and Create a Result Set Object:
ResultSet rs = stmt.executeQuery (query);

(Throws a SQLException error.)


Processing a Result Set

The result of an SQL query is retrieved through a ResultSet object. The methods provided within this object are used to extract the actual rows and columns from the query.

Read the Next Row:
boolean found = rs.next();    // returns true of row is read, false if end of result set

(Throws a SQLException error.)

Extract the Column Values:
/** Issue a getXXXX() call for each column, based on its data type.
  *
  * Common data types are:
  * INTEGER         getInt() or getBigDecimal(,0)
  * NUMBER          getBigDecimal()
  * VARCHAR         getString()
  * LONGVARCHAR     getAsciiStream()
  * TIMESTAMP       getDate(), getTime(), or getTimestamp()
  *
  * Columns may be accessed through a relative position within the row (e.g. column 1, 2, 3, ...)
  * or through its actual column name.
  *
  * SQL NULL values will result in the Java null value being assigned to the Java variable.
  */
int    personKey = rs.getInt(1);                     // first column in the row
String lastName  = rs.getString("LAST_NAME");        // column name provided
String firstName = rs.getString("FIRST_NAME");       // column name provided
Date   birthDate = rs.getDate(4);                    // fourth column in the row

(Throws a SQLException error.)

Close the Result Set:
// Close the result set object after row processing is complete
rs.close();

(Throws a SQLException error.)

Close the Statement:
// Close the statement object when row processing is complete
stmt.close();

(Throws a SQLException error.)


Issuing an Update Transaction

A SQL INSERT, UPDATE, OR DELETE is issued similar to the general query. The only differences are in the name of the method called and the type of result received.

Create a Statement Object:
Statement stmt = con.createStatement ();

(Throws a SQLException error.)

Set the Update Command:
String query = "INSERT INTO TABLE_NAME VALUES (1, 'SMITH', 'JOHN', NULL)";

Execute the Update:
int rowsUpdated = stmt.executeUpdate (query);  // returns number of rows updated

(Throws a SQLException error.)

Commit the Transaction:
con.commit();

(Throws a SQLException error.)

Rollback the Transaction:
con.rollback();

(Throws a SQLException error.)

Close the Statement Object:
// Close the statement object after update is complete
stmt.close();

(Throws a SQLException error.)


Calling a Stored Procedure

Calls to Stored Procedures and Functions are a bit more involved than SQL queries and updates. These calls are performed using the CallableStatement interface, which is an extension of the PreparedStatement interface. Parameters passed to and from the stored procedure are identified using ? placeholder symbols. These placeholders must be registered as IN our OUT data elements, using data types from the Types class.

Create the Command with Placeholders:
// Stored procedure call
String command = "{call PROCEDURENAME(?,?,?,?)}";     // 4 placeholders

// Stored function call
String command = "{? = call FUNCTIONNAME(?,?,?,?)}";  // 4 placeholders + 1 return value

Create a Callable Statement Object:
CallableStatement cstmt = con.prepareCall (command);

(Throws a SQLException error.)

Register the IN and OUT Placeholders:
// Assign IN parameters (use positional placement)
cstmt.setInt(1, 50);       // first placeholder has an integer value of 50
cstmt.setString(2, "Smith");  // second placeholder has a string value of "Smith"
cstmt.registerOutParameter(3, Types.NUMERIC);    // NUMERIC is preferred over INTEGER with some databases
cstmt.registerOutParameter(4, Types.VARCHAR);    // fourth placeholder is an OUT field of type VARCHAR.

(Throws a SQLException error.)

  • Note: INOUT fields may be registered using the setXXXX() and registerOutParameter() methods for the same placeholder position. Array parameters (i.e. PL/SQL Tables) used in Oracle stored procedure and function calls are not supported by the JDBC.
  • Execute the Procedure or Function Call:
    cstmt.execute();

    (Throws a SQLException error.)

    Process the OUT Placeholders:
    /** Use proper getXXXX() method based on parameter data type.
      * Placeholder 3 will receive a NUMERIC value as a BigDecimal object with 0 decimal places.
      * Placeholder 4 will receive a VARCHAR value as a String object.
      */
    BigDecimal num = cstmt.getBigDecimal(3,0);
    String str = cstmt.getString(4);

    (Throws a SQLException error.)

    Close the CallableStatement Object:
    // Close the call object after update is complete
    cstmt.close();

    (Throws a SQLException error.)


    Accessing Metadata

    Metadata refers to the descriptive information about the data, structures, and connections within database. Examples of metadata include:

    Additionally, metadata is available with query results. Examples of meta related to queries include:

    Accessing the metadata is done through two interface objects: DatabaseMetaData and ResultSetMetaData.

    DatabaseMetaData dmeta = con.getMetaData();

    ResultSetMetaData rsmeta = rs.getMetaData();

    Refer to the JDBC API under the DatabaseMetaData and ResultSetMetaData interfaces for additional information on the methods used to retrieve database and result set metadata.


    Connect to a database via JDBC-ODBC

    You have to keep in mind that the bridge JDBC-ODBC is only useful in an Application, you can't use it with JAVA Applet because ODBC requires some DLL on the client machine (forbidden for security reason).
    import java.net.URL;
    import java.sql.*;
    
    class JDBCapp  {
      static myConnection theConn;
    
      public static void main (String args[]) {
         theConn = new myConnection();
         theConn.Connect2Db("dbPROFILE", "dba", "sql");
         }
      }
    
    class myConnection {
       Connection dbConn = null;
       void Connect2Db(String db, String user, String passw) {
         try {
          // using the driver
          Driver d =
            (Driver)Class.forName
              ("sun.jdbc.odbc.JdbcOdbcDriver").newInstance();
          // URL corresponding to the ODBC profile
          String URL = "jdbc:odbc:" + db;
          // DB logon
          dbConn =
             DriverManager.getConnection(URL, user, passw);
          }
         catch (java.lang.Exception e) {
            System.out.println("** myConnection **");
            e.printStackTrace();
          }
         }
    
      void Disconnect2Db() {
         try { dbConn.close(); }
         catch (java.lang.Exception e) {e.printStackTrace();}
         }
      }
    


    SELECT data from a table

    note:the myConnection object was used to connect to the DB
    
    // with a Prepared Statement (only 1 row)
    String id = cust_id.getText();
    try {
      PreparedStatement prepstmt;
      boolean found = false;
      prepstmt = theConn.dbConn.prepareStatement
        ("select custName, CustAddr from tCust where custId = :id");
      prepstmt.setString(1, id);
    
      ResultSet rs;
      rs = prepstmt.executeQuery();
    
      found = rs.next();
      if (found)
          System.out.println(rs.getString(1));
      else
          System.out.println("Customer " + id + " not found!");
       prepstmt.close();
       rs.close();
       }
    catch (java.lang.Exception e) {
       e.printStackTrace();
       }
    
    // with a Statement (many rows)
    String name = cust_name.getText();
    try {
      Statement stmt;
      String sql;
    
      sql =  "select custName from tCust where custName = "
         += "'" + name + "'";
      stmt = createStatement();
    
      ResultSet rs;
      rs = stmt.executeQuery();
    
      while (rs.next()) {
        System.out.println(rs.getString("custName"));
        }
       stmt.close();
       rs.close();
       }
    catch (java.lang.Exception e) {
       e.printStackTrace();
       }
    


    INSERT data into a table

    note:the myConnection object was used to connect to the DB
    
    Statement stmt;
    String sql;
    int rows;
    
    sql = "INSERT INTO tCust "
        + "(custId, custName, custAddr) "
        + "VALUES "
        + "('" + custId   + "',"
        + "('" + custName + "',"
        + "('" + custAddr + "')";
    
    stmt = theConn.dbConn.createStatement();
    rows = stmt.executeUpdate(sql);
    theConn.dbConn.commit();
    stmt.close();
    
    
    note:a PreparedStatement is used to insert data containing QUOTES
    
    PreparedStatement stmt = null;
    String sql;
    int rows;
    
    try {
      sql = "INSERT INTO tCust"
            + "(custName) "
            + "VALUES "
            + "(:p1)";
      stmt = theConn.dbConn.prepareStatement(sql);
      stmt.setString(1, "Name with \" are permitted!");
      rows = stmt.executeUpdate();
      theConn.dbConn.commit();
      stmt.close();
      System.out.println(sql);
      }
    catch (SQLException esql){
       System.out.print(esql);
       }
    
    
    
    
    
    


    MODIFY data in a table

    note:the myConnection object was used to connect to the DB
    
    PreparedStatement prepstmt;
    try {
      prepstmt = theConn.dbConn.prepareStatement
       ("UPDATE tCust SET custName = :p1 "+
        " WHERE custId = :p2");
      prepstmt.setString(1,"Smith");
      prepstmt.setString(2, cust_id.getText());
      prepstmt.executeUpdate();
    
      theConn.dbConn.commit();
      prepstmt.close();
      }
    catch (java.lang.Exception e) {
      e.printStackTrace();
      }
    


    DELETE data in a table

    note:the myConnection object was used to connect to the DB
    
    PreparedStatement prepstmt;
    try {
      prepstmt = theConn.dbConn.prepareStatement
        ("DELETE FROM tCust "+
         " WHERE custId = :p1");
    
      prepstmt.setString(1,cust_id.getText());
      prepstmt.executeUpdate();
    
      theConn.dbConn.commit();
      prepstmt.close();
      }
    catch (java.lang.Exception e) {
      e.printStackTrace();
      }
    


    Connect to an Oracle database w/o JDBC

    It is possible for a JAVA client to connect to a special process on the Web server via socket, send a request and receive the results. All this without JDBC or special driver. This architecture is called 3-tier because the actual Database server can be on different machine and the process is simply acting as a bridge between the client, the Web server et the Database server.

    At http://www.vincent.se/Products/JOCIGateway/JOCIGateway.html, you can download the OCI/Gateway. With this package, it will be possible to access an Oracle database without special driver. Your application will be a Thin client. The drawback is that you lose the functionality of JDBC.
    // connection  host address, port
    OCIDataBase database = OCI.createConnection("127.0.0.1", 1540);
    
    // logon  user/password
    database.olog("data/data");
    
    // sql statement
    String sql = "SELECT custName FROM tCust "
               + "WHERE custId = "
    	   + cust_id.getText();
    
    // define the field
    OCIStringParam pname = new OCIStringParam();
    pname.wantIndp();
    pnoprp.indp[0] = -1;
    
    // parse the SQL statement
    OCICursor cursor = database.oopen();
    cursor.oparse(sql);
    
    // bind the result
    cursor.odefin(1,  pnoprp);
    
    // execute
    cursor.oexec();
    try {
      cursor.ofetch();
      cust_name = pname.value;
      cursor.oclose();
      database.ologof();
      OCI.closeConnection(database);
      }
    catch (Exception esql) {
      System.out.println(esql.toString());
      }
    


    Connect to an Oracle database with JDBC

    Oracle Corporation has released a free 100% JAVA driver. It is available at their Web site. According to the security rule, the Oracle server must be on the same machine as the Web server, since the communication with the Applet is done through Sockets. This is not always possible, so you will need something called a Connection Manager (from Oracle) or DBAnywhere from Symantec (demo version available for testing) to act as a bridge between the client, the Web server and the Database server.
    import java.sql.*;
    
    public class connectToOracle extends java.applet.Applet {
       Driver driver;
       Connection conn = null;
       static String driverUsed =
          "oracle.jdbc.driver.OracleDriver";
       static String serverAddress =
          "jdbc:oracle:thin:scott/tiger@www.myCompany.com:1243:myInstance";
          // jdbc:oracle:thin is the driver used
          // scott/tiger is user/password
          // www.myServer.com  is  the same machine from where the Applet was loaded
          // 1234  is the port used
          // myInstance  is  where my data is
    
       public void init(){
          makeConnection(serverAddress);
          }
    
       public void makeConnection(String svr) {
          try {
             System.out.println("Loading ... " + driverUsed);
             driver =
                   (Driver)Class.forName(driverUsed).newInstance();
             System.out.println("Connecting ... " + svr);
             conn =
                   DriverManager.getConnection(svr);
             System.out.println("Ready.");
             }
          catch (Exception e) {
             e.printStackTrace();
             }
          }
       }
    

    NOTE: With Microsoft IEv4, you may have an Exception talking about "No more data on socket", simply *TURN OFF* the JIT to solve the problem.

    Get JDBC driver for major database vendors

    DB2 Universal Server JDBC Drivers
    Oracle JDBC Drivers
    Sybase JDBC Drivers
    InterBase JDBC Drivers
    MS SQL Server
    Web Logic suites of JDBC Drivers
    Borland DataGateway
    dbAnywhere middleware
    Intersolv plugin to access ODBC database through a browser

    Get the current date in SQL format

    java.util.Date today    =        new java.util.Date();
    java.sql.Date  sqlToday =        new java.sql.Date( today.getTime() );