AACS 3104 Chapter 4 Database Programming with JDBC page 1 of 24
AACS 3104 Chapter 4 Database Programming with JDBC
1 1. .0 0 T Th he e D De es si ig gn n a an nd d U Us se e o of f J JD DB BC C x The Java API (Application Programming Interface) for developing Java Database applications is called JDBC. x JDBC provides Java programmers with a uniform interface for accessing and manipulating a wide range of relational databases. x Using the JDBC API, applications written in Java programming language can execute SQL statements, retrieve results, present data in a user friendly interface, and propagates changes back to the database. x The relationship between Java program, JDBC API, JDBC drivers, and relational database are shown in Figure 4.1 below.
Figure 4.1 Java Programs access and manipulates databases through JDBC drivers
x JDBC API is a set of interfaces and classes used to write Java programs for accessing and manipulating relational databases. x JDBC drivers are database-specific and are normally provided by the database vendors. Database Database Driver MySQL MySQL JDBC driver (can be downloaded online) Oracle Oracle JDBC drivers (can be downloaded online) Ms Access JDBC-ODBC driver ( included in JDK )
Java Programs JDBC API MySQL JDBC Driver MySQL Database Microsoft Access Database Oracle Database JDBC-ODBC Bridge Driver Oracle JDBC Driver Microsoft ODBC Driver AACS 3104 Chapter 4 Database Programming with JDBC page 2 of 24
x ODBC is a technology developed by Microsoft for accessing databases on the Windows platform x An ODBC driver is preinstalled on Windows. x The JDBC-ODBC bridge driver allows a Java program to access any ODBC data source.
2 2. .0 0 C Co on nn ne ec ct ti in ng g t to o a an nd d q qu ue er ry yi in ng g a a d da at ta ab ba as se e 2.1 JDBC Application Programming Interface (API) x The JDBC API consists of classes and interfaces for o Establishing connections with databases, o Sending SQL statements to databases, o Processing the results of the SQL statements and etc. x Four (4) key interfaces are needed to develop any database application using Java: 1. Driver 2. Connection 3. Statements 4. ResultSet x These interfaces define framework for generic SQL database access. x The JDBC API defines these interfaces x The JDBC driver vendors provide implementation for them. Programmers use the interfaces. x The relationship of these 4 interfaces is shown in Figure 4.2.
Figure 4.2: Relationships between Driver, Connection, Statement and ResultSet. ** NOTE: Some Statements object do not return resultset, such as SQL data modification statement ( e.g INSERT, UPDATE, DELETE SQL Statements.)
Loading drivers Establishing connections Processing ResultSet Creating and executing statements This chapter will only demonstrate how to connect to Microsoft Access database. AACS 3104 Chapter 4 Database Programming with JDBC page 3 of 24
2.2 Steps in connecting and querying a database x The JDBC interfaces and classes are the building blocks in the development of Java database programs x A typical Java program takes the following steps to access the database:
Steps TODO JDBC API involved 1 Loading drivers Driver 2 Establishing connection Connection class 3 Creating & Executing statements Statements & ResultSet class 4 Processing ResultSet ResultSet class
x Lets take a close look on how to actually perform the steps.
Step 1: Loading Driver What?
x An appropriate driver must be loaded using the statement shown below before connecting a database. x The Driver class for MS Access is sun.jdbc.odbc.JdbcOdbcDriver Syntax
Class.forName(JDBCDriverClass);
Example
Class.forName(sun.jdbc.odbc.JdbcOdbcDriver);
Step 2: Establishing Connection
What?
x A connection is like a cable that links your program to a database. x To connect to a database, use the static method getConnection(databaseURL) in the DriverManager class
Where databaseURL = unique identifier of the database on the Internet.
Additional Information JDBC URLs Databse URL Pattern MS Access jdbc:odbc:<dataSource> Example: Suppose a data source named CustomerDB has been created for a MS Access database, we create the connection as follows:
AACS 3104 Chapter 4 Database Programming with JDBC page 4 of 24
Step 3: Creating and Executing Statements What? x An object of Statement can be viewed as a cart that delivers SQL statements for execution by the database and brings back the result back to the program. x Once a Connection object is created, you can create statements for executing SQL statements.
SQL Types Statement method used INSERT, UPDATE and DELETE executeUpdate(String sql) SELECT query NOTE: query result is stored in ResultSet object executeQuery(String sql)
Example Lets assume that we have a table called Customers with the following fields:
Customers(cust_ID, cust_Name, cust_Address)
To INSERT new customer:
Statement stmtInsert = conCustomer.createStatement(); stmtInsert.executeUpdate(INSERT INTO Customers VALUES(C100, Adam, KL));
To query (SELECT)customer record
Statement stmtSelect = conCustomer.createStatement(); ResultSet rsCustomer; // declare ResultSet object to store query result
// select all customer record rsCustomer = stmtSelect.executeQuery(SELECT * FROM Customers);
// then we can process the result in rsCustomer later, see step 4
AACS 3104 Chapter 4 Database Programming with JDBC page 5 of 24
Step 4: Processing ResultSet object What? x The ResultSet maintains a table whose current row can be retrieved. x The initial row position is null. x A default ResultSet object is NOT updatable and has a cursor that moves forward ONLY.
Useful Methods
Methods Description next(): boolean x Moves the cursor to the next row. x Returns false if there are no more rows in the ResultSet object
getInt(int colIndex): int Retrieves the value of the designated column as integer type getInt(String colName): int Retrieves the value of the designated column as integer type getDouble(int colIndex): double Retrieves the value of the designated column as double type getDouble(String colName): double Retrieves the value of the designated column as double type getString(int colIndex): String Retrieves the value of the designated column as String type getString(int colName): String Retrieves the value of the designated column as String type
NOTE: column index starts from 1 (one).
Example Lets assume that we have a table called Customers with the following fields:
Customers(cust_ID, cust_Name, cust_Address)
To query (SELECT)customer record
Statement stmtSelect = conCustomer.createStatement(); ResultSet rsCustomer; // declare ResultSet object to store query result
// select all customer names rsCustomer = stmtSelect.executeQuery(SELECT cust_Name FROM Customers);
// loop through the resultset and display the customer names while(rsCustomer.next() ) { // display customer name on the console System.out.println(name: + rsCustomer.getString(1) ); }
AACS 3104 Chapter 4 Database Programming with JDBC page 6 of 24
2.3 Example: connecting and querying MS Access Database
Example 1: x The program in Listing 4.1 below connects to an ODBC data source named CustomerDB and makes query to all customers record. (See Appendix A [ Page 22 ] on how to create ODBC data source) x It then displays all the customer names in the console. x The Customers table in CustomerDB is as follows: Customers( Cust_ID, Cust_Name, Cust_Address )
public static void main(String[] args) throws SQLException, ClassNotFoundException {
// load the JDBC driver Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); System.out.println("driver loaded");
// establish a connection Connection conStudent = DriverManager.getConnection("jdbc:odbc:CustomerDB"); System.out.println("Database Connnected...");
// create a statement Statement stmtCustomer= conStudent.createStatement();
// execute a statement ResultSet rsCustomer= stmtCustomer.executeQuery("SELECT * FROM Customers");
// loop through the resultset and print student names while(rsCustomer.next()) { System.out.println(rsCustomer.getString("Cust_Name") ); }
} // end main } // end class
AACS 3104 Chapter 4 Database Programming with JDBC page 7 of 24
Example 2 x The program in Listing 4.2 below demonstrates how to connect and make query to database in GUI application x The program allows user to enter customer id to look for customer details. x The sample output of program in Listing 4.2 is shown in Figure 4.3 below.
Figure 4.3: Search customer details in GUI application
public class SearchCustomer extends JFrame { JTextField jtfCustomerID = new JTextField(10); JLabel jlblCustomerName = new JLabel(); JLabel jlblCustomerAddress = new JLabel(); JButton jbtSearch = new JButton("Search Customer"); JButton jbtClear = new JButton("Clear");
Statement stmtCustomer; // declare Statement object here
public static void main(String args [ ] ) { SearchCustomer frame = new SearchCustomer(); frame.pack(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setLocationRelativeTo(null); frame.setVisible(true); } // end main } // end class
Example 3: Retrieve data from Database and bind them to a Combo Box
The code segment below binds the Combo Box jcboCustID to all the Cust_ID fields in from the Customers table in CustomerDB database.
ResultSet rsCustomer= stmtCustomer.executeQuery("SELECT Cust_ID FROM Customers");
while(rsCustomer.next() ) { String custID = rsCustomer.getString(1); // get Cust_ID value
// need to convert String value to Object , // this is because the addItem(Object o) method only accept Object type value jcboCustomerID.addItem( (Object)custID); }
AACS 3104 Chapter 4 Database Programming with JDBC page 10 of 24
3 3. .0 0 P Pr re ep pa ar re ed d S St ta at te em me en nt t x The Statement interface is used to execute static (fixed) SQL statements that contains no parameters x In order words, you MUST already specified the values in the condition in the WHERE clause. x However, Java also provides the PreparedStatement, which extending Statement and can be used to execute a precompiled SQL statement with or without parameters. x Since the SQL statements are precompiled, they are efficient for repeated executions
x The PreparedStatement object is created using the prepareStatement(String sql) method in the Connection interface.
x The Insert statement has 3 question marks (?) as placeholders for parameters representing values for Cust_ID, Cust_Name, Cust_Address in a record of the Customer table. x PreparedStatement interface provides methods to set the values of the parameters in the object of PreparedStatement. x In general, the set methods have the following name and signature:
x The following codes pass the parameters C007, Jeverson , PJ to the placeholder for Cust_ID, Cust_Name and Cust_Address in the PreparedStatement pstmt declared just now.
String sqlSelect = Insert Into Customer (Cust_ID, Cust_Name, Cust_Address) Values(?, ?, ? ); PreparedStatement pstmt = connection.prepareStatement(sqlSelect); setX( int parameterIndex, X value);
where parameterIndex is the index of the parameter in the statement X is the type of the parameter
For example: setString(2 , adam ); // set the 2 nd parameter value to a String value adam setString(1 , C007 ); setString(2 , Jeverson ); setString(3 , PJ );
AACS 3104 Chapter 4 Database Programming with JDBC page 11 of 24
x After setting the parameters, you can execute the prepared statement by calling executeQuery() [ for SELECT statement] and executeUpdate() [ for UPDATE, INSERT and DELETE statement ].
Example 4: Insert Customer record using PreparedStatement
x The program below accepts Customer ID, Name and Address from Text Fields and then adds them into Customers Table by using the PreparedStatement.
pstmtCustomer.executeUpdate(); JOptionPane.showMessageDialog(null, "new Customer added!"); } catch(SQLException ex) { JOptionPane.showMessageDialog(null, "Customer record already existed!"); } } // end addCustomer method
public static void main(String[] args) { InsertCustomerPreparedStatement frame = new InsertCustomerPreparedStatement(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); AACS 3104 Chapter 4 Database Programming with JDBC page 13 of 24
93 94 95 96 97
frame.pack(); frame.setVisible(true);
} }
Sample Ou t pu t
Figure 4.4: Sample output for insert new Customer record.
How does it wor k?
x From line 8 12, the necessary JTextFields and JButtons are declared. x In line 15, a PreparedStatement object called pstmtCustomer is declared. It is declared here so that its lifetime and scope starts when the program starts and ends when the program ends. x Then in the constructor, it does the following: 1. call the initializedDB() method x From line 49 65, 1 st load the driver, then establish the connection. x Then create a String object to store the INSERT SQL statement. x Then create the PreparedStatement object pstmtCustomer object by calling the prepareStatement() method from Connection object and pass in the SQL string value. 2. setup GUI components, add them to JFrame 3. addActionListener for the 2 buttons, namely jbtAdd and jbtClear x in addCustomer method for jbtAdd ` get textfield value accordingly ` Call setString() method of PreparedStatement object to set the parameter values. ` Call executeUpdate() method to update the INSERT statement to database.
AACS 3104 Chapter 4 Database Programming with JDBC page 14 of 24
4 4. .0 0 S Sc cr ro ol ll la ab bl le e a an nd d U Up pd da at te ea ab bl le e R Re es su ul lt tS Se et t x The ResultSet used in the preceding examples are sequentially forward reading. x Sequential forward reading means the resultset maintains a cursor pointing to its current row of data. Initially the cursor is positioned before the 1 st row. The next() method moves the cursor forward to the next row. There is NO WAY to move backward or update the resultset and have the changes automatically reflected in the database x With JDBC 2, you can scroll the row both forward and backward and move the cursor to a desired location. x You can also insert, delete or update a row in a result set and have the changes automatically reflected in the database. x To obtain scrollable and updateable result set, you must first create a statement with an appropriate type and concurrency mode.
For a static Statement object, use
Statement stmt = connection.createStatement( int resultType, int resultsetConcurrency);
For a preparedStatement object, use
PreparedStatement pstmt = connection.prepareStatement( String sql, int resultType, int resultsetConcurrency); Where
resultType Possible values: ResultSet.TYPE_FORWARD_ONLY x The result set is accessed forward sequential only
ResultSet.TYPE_SCROLL_INSENSITIVE x The result set is scrollable, but not sensitive to changes in the database
ResultSet.TYPE_SCROLL_SENSITIVE x The result set is scrollable, and sensitive to changes made by others x Use this type if you want to the result set to be scrollable and updateable.
resultsetConcurrency Possible values:
ResultSet.CONCUR_READ_ONLY x The result set can not be used to update the database
ResultSet.CONCUR_UPDATABLE x The result set can be used to update the database.
AACS 3104 Chapter 4 Database Programming with JDBC page 15 of 24
x For example, if you want the result set to be scrollable and updateable, you can create a statement as follows:
x Then, you can use the various useful method in ResultSet interface to scroll (move ) around result or make changes to the resultset and have the changes automatically reflected in the database.
TO Scroll or move cu r s or a r ou n d r es u lt s et Methods Description first() Move cursor to the 1 st row next() Move cursor to the next row previous() Move cursor to the previous row last() Move cursor to the last row absolute(int row) Move cursor to the specified row
TO Ret rie ve valu e of a s pecified field in th e cu r ren t r ow Methods Description getXxx(int columnIndex) Retrieve the Xxx type value of a field specified by columnIndex. [ field index starts from 1 ] getXxx( Sring columnName) Retrieve the Xxx type value of a field specified by columnName. [ same as field name in the database ]
TO dele t e t h e cu r r en t r ow in t h e r es u lt s et delete() Delete the current row in the result set, changes will automatically reflected in the database
AACS 3104 Chapter 4 Database Programming with JDBC page 16 of 24
To ins ert a n ew r ow in t h e res u lt s et Steps to insert a row:
1. Call the moveToInsertRow() to move the cursor to a special row that serves as a staging area for building a row to be inserted.
2. Then, update the columns using the updateXxx(int columnIndex, Xxx value) or updateXxx( String columnName, Xxx value) method. NOTE: Xxx = type of the value, for example: String, int, double, and etc.
3. Finally, insert the row using the insertRow() method.
For example, the following code insert a new row with the new values
rsCustomer.moveToInsertRow(); // MUST move cursor to the insert row
rsCustomer.insertRow(); // insert the row with update done..
TO updat e a r ow in t h e res u lt s et Steps to update a row
1. Move the cursor to desire row. You can use the absolute(int row) method.
2. call the updateXxx() method to write new value to the field at the current row
3. finally, call the updateRow() method to update row in the data source
For example, the code below updates the address of the 3 rd row to Taman TBR
rsCustomer.absolute(3); // move cursor to the 3 rd row
rsCustomer.updateString(Cust_Address, Taman TBR); // updates the columns
rsCustomer.updateRow(); // updates the row in the data source
Ot h er us e ful met h od in t h e Res u lt Set in t er face cancelRowUpdates() Cancels the updates made to a row close() Closes the result set and releases its resources. isFirst() : boolean To check whether the cursor is at the 1 st row in the result set isLast() : boolean To check whether the cursor is at the last row in the result set getRow(): int Return the current row number. The 1 st row is 1, 2 for 2 nd
and so on. AACS 3104 Chapter 4 Database Programming with JDBC page 17 of 24
Example 5: Using Scrollable and Updateable Result Set
The program in Listing 4.4 below demonstrates using scrollable and updateable result set to scroll customer record and insert new customer record.
Figure 4.5: Sample output for viewing customer record using scrollable and updateable result set.
JTextField jtfCustID = new JTextField(10); JTextField jtfCustName = new JTextField(10); JTextField jtfCustAddress = new JTextField(10);
JButton jbtFirst = new JButton("First"); JButton jbtLast = new JButton("Last"); JButton jbtPrevious = new JButton("Previous"); JButton jbtNext = new JButton("Next");
JButton jbtAdd = new JButton("Add Customer"); JButton jbtClear = new JButton("Clear");
jbtFirst.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { showRecord("First"); } });
jbtLast.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { showRecord("Last"); } });
jbtPrevious.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { try { // if current row is 1st row, no need to move if(rsCustomer.isFirst()) JOptionPane.showMessageDialog(null, "Already at the First record"); else showRecord("Previous"); } catch(SQLException ex) { JOptionPane.showMessageDialog(null, "Error in moving cursor"); } } });
jbtNext.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { try AACS 3104 Chapter 4 Database Programming with JDBC page 19 of 24
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 { // if current is last row, then no need to move if(rsCustomer.isLast()) JOptionPane.showMessageDialog(null, "Already at the Last record"); else showRecord("Next"); } catch(SQLException ex) { JOptionPane.showMessageDialog(null, "Error in moving cursor"); } } });
jbtAdd.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { addCustomer(e); } });
jbtClear.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { jtfCustID.setText(""); jtfCustName.setText(""); jtfCustAddress.setText(""); } });
rsCustomer = stmtCustomer.executeQuery("Select * From Customers");
showRecord("First"); // show 1st record on JTextFields } catch(Exception e) // just accept any exception { AACS 3104 Chapter 4 Database Programming with JDBC page 20 of 24
try { rsCustomer.moveToInsertRow(); // move cursor to the insert row rsCustomer.updateString(1, custID); rsCustomer.updateString(2, custName); rsCustomer.updateString(3, custAddress);
rsCustomer.insertRow(); // insert the row to result set JOptionPane.showMessageDialog(null, "new Customer added!"); } catch(SQLException ex) { JOptionPane.showMessageDialog(null, "Customer record already existed!"); } }
AACS 3104 Chapter 4 Database Programming with JDBC page 21 of 24
AACS 3104 Chapter 4 Database Programming with JDBC page 22 of 24
5 5. .0 0 A Ap pp pe en nd di ix x A A: : H Ho ow w t to o c cr re ea at te e O OD DB BC C D Da at ta a S So ou ur rc ce e
Creating an ODBC Data Source To use the JDBC-ODBC driver to access databases in Java, two drivers must be installed on the client machine: a universal JDBC-ODBC bridge driver and a vendor- specific ODBC driver. To access the MS Access database, you have to create an ODBC data source. Here are the steps to create an ODBC data source:
1. From the Windows Start button, choose Setting, Control Panel to bring up the Control Panel dialog box. Double-click Administrative Tools, and then double-click Data Sources (ODBC) to display the ODBC Data Source Administrator dialog box, as shown in Figure 1. Figure 1 The ODBC Data Source Administrator is the main dialog box to manage the data source and the drivers.
AACS 3104 Chapter 4 Database Programming with JDBC page 23 of 24
2. Click Add to bring up the "Create New Data Source" dialog box, as shown in Figure 2. Figure 2 Select a proper driver for the data source in the "Create New Data Source" window.
3. Select Microsoft Access Driver and Press Finish to bring the ODBC Microsoft Access Setup dialog window, as shown in Figure 3. Figure 3: Specify the Data Source Name to associate it with a database in the ODBC Microsoft Access Setup window.
Select Microsoft Access Driver (*.mdb) AACS 3104 Chapter 4 Database Programming with JDBC page 24 of 24 4. Type CustomerDB (for example) in the Data Source Name field, Then, click Select to bring up the Select Database dialog window, as shown in Figure 4. Figure 4: Select the physical database file name for the data source name in the Select Database window.
5. Select exampleMDB.mdb from the directory c:\CsutomerDB.mdb. Press OK to close the Select Database dialog window, click OK to close the ODBC Microsoft Access Setup window, and click OK to close the ODBC Data Source Administrator window. Thats all! You have successfully created an ODBC data source. You can now write Java program to access to the data source.
[ Back to Lecture Note on page 6 ]
6 6. .0 0 A Ap pp pe en nd di ix x B B: : O On nl li in ne e R Re es so ou ur rc ce e
Useful links for classes in Package java.sql http://java.sun.com/j2se/1.4.2/docs/api/java/sql/package-summary.html