Oracle Applications Using Java & JDBC
Oracle Applications Using Java & JDBC
Oracle Applications Using Java & JDBC
APPLICATIONS USING
JAVA & JDBC
CIS 612 Topics on Advanced Database Systems
Victor Matos
What is JDBC ?
2
JDBC Architecture
Components
3
JDBC
JDBC 4.0
4.0 Specification.
Specification. JSR
JSR 221
221
Lance
Lance Andersen,
Andersen, Specification
Specification
Lead
Lead
November
November 7,
7, 2006
2006
The row result set has metadata that describes the names of
the columns and their types.
Example
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery (select * from employee);
3.
Class.forName("oracle.jdbc.OracleDriver");
String URL = "jdbc:oracle:thin:@localhost:1521:XE";
Connection con = DriverManager.getConnection(
URL, "myUserName", "myPassword");
while (rs.next()) {
String fName = rs.getString("fName");
float salary = rs.getFloat("salary");
//... Do some work with the data
}
(Oracle)
http://java.sun.com/products/jdbc/overview.html
(MySQL)
http://www.mysql.com/products/connector/j/
10
<installation
directory>\sqljdbc_<version>\<language>\sqljdbc.jar
The following is an example of the CLASSPATH statement that is
used for a Windows application:
11
"user=MyUserName;password=*****;" ;
Connection con = DriverManager.getConnection(connectionUrl);
JDBC Drivers
12
13
Disadvantages
14
Server Machine
Application
JDBC-ODBC
Bridge
ODBC Drive
Vendor DB
Library
Database
Server
Disadvantages
With type 4 drivers, the user needs a different driver for each
database.
Client Machine
Server Machine
Application
JDBC
Native
Protocol Pure
Java Driver
Database
Server
Connection Overview
A Connection object represents a link/pipe leading to/from a
database.
A connection session includes the SQL statements that are executed
and the results that are returned over that connection.
A single application can have one or more connections with a single
database, or it can have connections with many different databases.
Opening a Connection
The typical way to establish a connection with a database is to call
the method DriverManager.getConnection (URL,).
The DriverManager class attempts to locate a driver that can
connect to the database represented by that URL.
The DriverManager class maintains a list of registered Driver
classes, and when the method getConnection is called, it checks
with each driver in the list until it finds one that can connect to the
database specified in the URL.
1.
2.
3.
Executing Statements
The Statement interface provides three different methods for
executing SQL statements: executeQuery, executeUpdate, and
execute.
Statement Completion
When a connection is in auto-commit mode, the
statements being executed within it are committed
or rolled back when they are completed.
Closing Statements
Statement objects will be closed automatically by
the Java garbage collector.
The 4th row of the result set is fetched. The 1st column
(DNAME) is changed to International Sales, its 3 rd column
(MGRSSN) is changed to 123456789. All the changes to the
row are committed with the .updateRow() method.
(cont.)
Assume the DEPARTMENT table schema is as follows
< DNAME, DNUMBER, MGRSSN, MGRSTARTDATE >
The following statements locally update the rs result set that
is produced after evaluating a SQL query. The .updateRow
(or .cancelRowUpdates) method is used to commit (or rollback) the changes.
rs.absolute(4);
rs.updateString ("DNAME", "International Sales");
rs.updateLong ("MGRSSN", 123456789);
rs.updateRow();
The 4th row of the result set is fetched. The 1st column
(DNAME) is changed to International Sales, its 3 rd column
(MGRSSN) is changed to 123456789. All the changes to the
row are committed with the .updateRow() method.
Deleting a Row
rs.first();
rs.deleteRow();
Inserting Rows
New rows may be inserted into an updatble result set and into the underlying
database table using the insertRow method.
The moveToInsertRow call positions the cursor on the insert row.
updateXXX methods add column values to the insert row.
When all of the columns of the row to be inserted have been set, the
application calls the method insertRow. This method adds the insert row to
both the result set and the underlying database simultaneously.
Finally, the application needs to position the cursor on a row back in the result
set.
Example. The following code fragment demonstrates these steps for inserting
a row from an application written in the Java programming language.
rs.moveToInsertRow();
rs.updateObject (1, myListPeople);
rs.updateInt (2, 101);
rs.updateString (3, "Automation Project");
rs.insertRow();
rs.first();
Batch Updates
32
JDBC PreparedStatement
Object
String mySQL = "select hours from works_on where sex= ? And pno= ?
";
PreparedStatement pstmt = conn.prepareStatement( mySQL,
ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_UPDATABLE);
pstmt.setFetchSize(25);
pstmt.setString(1, "F");
pstmt.setInt(2, 10);
ResultSet rset = pstmt.executeQuery();
The variable rset contains the HOURS value for the row where the SSN
33
JDBC PreparedStatement
Object
pstmt.setInt(1, F);
pstmt.setInt(2, 10);
JDBC CallableStatements
34
CallableStatement Overview
{ O? = call FunctionProcName ( ? ) }
U
T
I
N
JDBC CallableStatements
35
JDBC CallableStatements
36
DBMS
Data
+
Stored
Procedures
Mmm
Mmm
m
Mmm
m
mmm
m
Mmm
m
mmm
Mmm
m
Mmm
m
Mm m
JDBC CallableStatements
37
I
N
2
ResultSet Object
38
39
ResultSet
Object
ResultSet Object
40
ResultSet Objects
41
ResultSet Objects
42
Types of ResultSets
TYPE_FORWARD_ONLY
TYPE_SCROLL_INSENSITIVE
The result set is non-scrollable; its cursor moves forward only, from top to
bottom.
The result set is scrollable: Its cursor can move forward or backward and can be
moved to a particular row or to a row whose position is relative to its current
position.
Changes made to the underlying database are not reflected in the ResulSet while
it is open.
TYPE_SCROLL_SENSITIVE
The result set is scrollable; its cursor can move forward or backward and can be
moved to a particular row or to a row whose position is relative to its current
position.
The result set is sensitive to changes made to the underlying database while it is
open.
ResultSet Objects
43
Concurrency Types
A result set is by default READ_ONLY may however this
could be changed.
CONCUR_READ_ONLY
This allow users to read (unlocked) data but not to
change it.
CONCUR_UPDATABLE
Indicates a result set that can be updated
programmatically. Updatable results sets may use
write-only locks so that only one user at a time has
access to a data item.
Cursor Movement
next() moves the cursor forward one row. Returns true if the cursor is now
positioned on a row and false if the cursor is positioned after the last row.
previous() moves the cursor backwards one row. Returns true if the cursor
is now positioned on a row and false if the cursor is positioned before the first
row.
first() moves the cursor to the first row in the ResultSet object. Returns true
if the cursor is now positioned on the first row and false if the ResultSet object
does not contain any rows.
last() moves the cursor to the last row in the ResultSet object. Returns true
if the cursor is now positioned on the last row and false if the ResultSet object
does not contain any rows.
beforeFirst() positions the cursor at the start of the ResultSet object, before
the first row. If the ResultSet object does not contain any rows, this method has
no effect.
afterLast() positions the cursor at the end of the ResultSet object, after
the last row. If the ResultSet object does not contain any rows, this method has no
effect.
relative(int rows) moves the cursor relative to its current position.
absolute(int row) positions the cursor on the row-th row of the ResultSet
object.
ResultSet Objects
45
NULL values
49
null-for those getXXX methods that return objects in the Java programming
language (getString, getBigDecimal, getBytes, getDate, getTime, getTime-stamp,
getAsciiStream, getCharacterStream, getUnicodeStream, getBinary-Stream,
getObject, getArray, getBlob, getClob, and getRef)
0 (zero)-for getByte, getShort, getInt, getLong, getFloat, and getDouble
false-for getBoolean
double c = rs.getDouble("Commission");
boolean b = rs.wasNull();
The method wasNull checks only the last value retrieved. If b is true, the
value stored in the third column of the current row of rs is JDBC NULL.
Transaction Processing
50
Committing Changes
By default, data manipulation language (DML) operations are
committed
automatically as soon as they are run. This is known as the
(Oracle) auto-commit mode. However, you can disable autocommit mode with the following method call on the Connection
object:
conn.setAutoCommit(false);
If you disable the auto-commit mode, then you must manually
commit or roll back changes with the appropriate method call on
the Connection object:
conn.commit();
or:
conn.rollback();
Note: A COMMIT or ROLLBACK operation affects all DML
statements run since the last COMMIT or ROLLBACK.
C:\JDeveloper11G\jlib\dms.jar
C:\JDeveloper11G\jlib\ojdl.jar
C:\JDeveloper11G\jlib\orai18n.jar
C:\JDeveloper11G\jdbc\lib\ojdbc5dms.jar
http://www.oracle.com
http://java.sun.com/javase/technologies/database/
index.jsp
53
54
Exampe1.
public class JavaJDBCDemo1 {
Use an ODBC-JDBC Bridge to reach
public static void main(String[] args)
Oracle and create, populate, query,
{
and drop a table.
try {
//create a jdbc to odbc bridge
Assuming ODBC data source already
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
set.
import java.sql.*;
String database =
"jdbc:odbc:myOracleODBC";
catch (Exception e) {
System.out.println("Error: " + e);
}
}//end main
}//end class
rs.getInt("myCol1") +
rs.getString("myCol2"));
Exampe1.
Use an ODBC-JDBC
Bridge to reach
Oracle and create,
populate, query,
and drop a table
Exampe1.
Use an ODBC-JDBC Bridge to reach
Oracle and create, populate, query,
and drop a table
58
Exampe1.
Use an ODBC-JDBC Bridge to reach Oracle
and create, populate, query, and drop a
table
We will modify the previous Example1 to by-pass the local ODBC data
source and directly go to the database server using the Thin JDBC driver.
This approach should be more efficient. You need to make the following
code changes:
Class.forName ("oracle.jdbc.OracleDriver");
String database = "jdbc:oracle:thin:@localhost:1521:XE";
Connection con =
DriverManager.getConnection( database ,"csuPerson","euclid");
You must add the Oracle JDBC driver to the applications path. For
example, in this case we added all the .jar files from the folder
c:\Jdeveloper\jdbc\lib
59
60
Example2.
Use the JDBC Thin Driver to create a ResultSet
holding the SSN and name of each employee in the
COMPANY database.
try {
conn =
DriverManager.getConnection ("jdbc:oracle:thin:@localhost:1521:XE",
"csuperson", "euclid");
if (conn != null) {
System.out.println("Connection created for CSUPERSON/EUCLID");
} else {
System.out.println("***No connection was created");
}
// Create a Statement
Statement stmt = conn.createStatement ();
System.out.println("***Statement created");
// Select the FNAME column from the EMPLOYEE table
ResultSet rset = stmt.executeQuery (
" select (FNAME || ' ' || LNAME) as FullName " +
"
from EMPLOYEE " +
" where SEX in ('F', 'M') ");
System.out.println("***OK. Query executed");
// Iterate through the result and print the employee names
while (rset.next ()) {
System.out.println (Full name:
" + rset.getString (1));
}
}
61
Example2.
Use the JDBC Thin Driver to create a ResultSet
holding the SSN and name of each employee in the
COMPANY database.
catch (SQLException e) {
System.out.println("Test threw a " + e.getClass() + "\n with message: " +
e.getMessage() + " : Error code (" +
e.getErrorCode() + ")" );
}
// Clean up connection is there was one
finally
{
if(conn != null) {
conn.close();
System.out.println("***Connection closed");
}
else {
System.out.println("***There was no connection");
}
}
}
}
//TRY THIS:
//connecting to a remote Oracle11g (ORCL) server located in SANCHO.CSUOHIO.EDU
conn =
DriverManager.getConnection( "jdbc:oracle:thin:@sancho.csuohio.edu:1521:ORCL",
"csuperson", "euclid");
Connection Strings
62
Connection Strings
63
64
Example3. Calling a
PL/SQLFunction
Example3.
Use1/5
the JDBC Thin Driver to invoke a PL/SQL function
that accepts a SSN value and returns the employees
full name
IN
BEGIN
select count(*) into theTotal from employee
if (theTotal = 0) then
RETURN('');
else
select (FName || ' ' || Lname) into theName
from employee
where SSN = theSSN;
RETURN (theName);
end if;
EXCEPTION
when others then
return ('***ERROR***');
END;
65
Example3. Calling a
PL/SQLFunction
package JavaAccessDB3StoredProc;
Example3.
Use2/5
the JDBC Thin Driver to invoke a PL/SQL function
that accepts a SSN value and returns the employees
full name
import java.sql.*;
import java.io.*;
import oracle.jdbc.driver.*;
public class JavaAccessDB3StoredProc
{
public static void main(String[] args) throws SQLException, ClassNotFoundException
{
/* ------------------------------------------------------------------------Calling a stored procedure/function from Java.
The query string can be in Oracle format or standard JDBC callable syntax.
1. If you are using the Oracle syntax, the query string is:
BEGIN ? := getName(?); END;
2. If you are using the JDBC syntax, the query string is:
{ call ? := getName(?) }
OUT parameter must be registered to be of type OracleTypes.CURSOR.
You must use the method: getObject() to retrieve the result set.
---------------------------------------------------------------------------*/
66
Example3. Calling a
PL/SQLFunction
Example3.
Use3/5
the JDBC Thin Driver to invoke a PL/SQL function
that accepts a SSN value and returns the employees
full name
conn =
DriverManager.getConnection
("jdbc:oracle:thin:@localhost:1521:XE,"csuperson","euclid");
if (conn != null) {
System.out.println("***Connection created for CSUPERSON/EUCLID ***");
} else {
System.out.println("***No connection was created");
}
String myQuery = " BEGIN ? := getName(?); END; ";
CallableStatement stmt = conn.prepareCall(myQuery);
// register the type of the OUT parameter using an Oracle specific type
//Example: stmt.registerOutParameter(1, OracleTypes.CURSOR);
stmt.registerOutParameter(1, OracleTypes.VARCHAR);
67
Example3. Calling a
PL/SQLFunction
Example3.
Use
4/5the JDBC Thin Driver to invoke a PL/SQL function
that accepts a SSN value and returns the employees
full name
68
Example3. Calling a
PL/SQLFunction
Example3.
Use
5/5the JDBC Thin Driver to invoke a PL/SQL function
that accepts a SSN value and returns the employees
full name
catch (SQLException e) {
System.out.println("Test threw a " + e.getClass() +
"\n with message: " +
e.getMessage() + " : Error code (" +
e.getErrorCode() + ")" );
}
// Clean up connection is there was one
finally
{
if(conn != null) {
conn.close();
System.out.println("***Connection closed");
}
else {
System.out.println("***There was no connection");
}
}
}
}
Example4.
Use the JDBC Thin Driver to invoke a PL/SQL stored
procedure. The proc. accepts a dept nunmber and returns
a list of employees on that dept.
Example4.
Use the JDBC Thin Driver to invoke a PL/SQL stored
procedure. The proc. accepts a dept nunmber and returns
a list of employees on that dept.
package JavaAccessDB4StoredProcCursor;
import java.sql.*;
import java.io.*;
import oracle.jdbc.driver.*;
public class JavaAccessDB4StoredProcCursor
{
public static void main(String[] args) throws SQLException,
ClassNotFoundException
{
/* --------------------------------------------------------------------------Calling a stored procedure/function from Java.
The query string can be in Oracle format or standard JDBC callable syntax.
1. If you are using the Oracle syntax, the query string is:
BEGIN ? := getName(?); END;
2. If you are using the JDBC syntax, the query string is:
{ call ? := getName(?) }
OUT parameter must be registered to be of type OracleTypes.CURSOR.
You must use the method: getObject() to retrieve the result set.
-----------------------------------------------------------------------------*/
Example4.
Use the JDBC Thin Driver to invoke a PL/SQL stored
procedure. The proc. accepts a dept nunmber and returns
a list of employees on that dept.
71
DriverManager.getConnection ("jdbc:oracle:thin:@localhost:1521:XE",
"csuperson", "euclid");
if (conn != null) {
System.out.println("Connection created for CSUPERSON/EUCLID");
} else {
System.out.println("***No connection was created");
}
String myQuery = " BEGIN ? := getPeopleByDept(?); END; ";
CallableStatement stmt = conn.prepareCall(myQuery);
Example4.
Use the JDBC Thin Driver to invoke a PL/SQL stored
procedure. The proc. accepts a dept nunmber and returns
a list of employees on that dept.
72
Example4.
Use the JDBC Thin Driver to invoke a PL/SQL stored
procedure. The proc. accepts a dept nunmber and returns
a list of employees on that dept.
73
catch (SQLException e) {
System.out.println("Test threw a " + e.getClass() +
"\n with message: " +
e.getMessage() + " : Error code (" +
e.getErrorCode() + ")" );
}
74
75
Example5: Updatable
ResultSet
package OracleJDBCDemo5.client;
import java.sql.*;
import oracle.jdbc.*;
//update salary (increase by $1)
public class OracleJDBCDemo5 {
public static void main(String[] args) throws SQLException,
ClassNotFoundException {
System.out.print("Connecting to the database...");
try {
// Load the Oracle JDBC driver
Class.forName("oracle.jdbc.OracleDriver");
System.out.println("Driver manager created");
Connection conn = null;
//you may replace "localhost" by "127.0.0.1" (or real TCP
address)
conn =
DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:X
E",
"csuperson",
"euclid");
if (conn != null) {
System.out.println("Connection created for
CSUPERSON/EUCLID");
} else {
System.out.println("***No connection was created");
return;
}
//Create a statement returning data for UPDATE
Statement stmt =
conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE,
ResultSet.CLOSE_CURSORS_AT_COMMIT);
System.out.println("Updateble ResultSet was created");
ResultSet rset = stmt.executeQuery("select Salary, Fname from
employee");
while(rset.next()){
//modify the employee's salary (add $1 )
System.out.println("Name ==> " +
rset.getString("Fname"));
double oldSalary = rset.getDouble("Salary");
System.out.println("Old salary ==> " + oldSalary);
double newSalary = oldSalary + 1;
rset.updateDouble("Salary", newSalary);
rset.updateRow();
System.out.println("New salary ==> " + newSalary);
}
// close the result set, the statement and connect
rset.close();
stmt.close();
conn.close();
System.out.println("Adios.");
} //end try
catch (SQLException e) {
System.out.println(e.getMessage());
} //end catch
} //end main
} //end class
76
Example6. Prepared
Statement
package JavaAccessDB5PreparedStmt;
while (rset.next()){
import java.sql.*;
rset.getString("fName"));
}//end whileloop
}
catch (Exception e) {
Class.forName("oracle.jdbc.OracleDriver");
String url = "jdbc:oracle:thin:@sancho.csuohio.edu:1521:ORCL";
String user = "CSUPERSON";
System.out.println(e);
}
}//end main
}//end class
References
77
Basic Tutorial
http://java.sun.com/docs/books/tutorial/jdbc/basics/index.html
Advanced Tutorial
http://java.sun.com/developer/Books/JDBCTutorial/index.html
Rowset Tutorial
http://java.sun.com/j2se/1.5/pdf/jdbc-rowset-tutorial-1.5.0.pdf
JDBC 4.0 Specification JSR 22, by Lance Andersen, Specification Lead. Sun
Microsystems. November 7, 2006 November 2006 Final v1.0
JDBCtm API Tutorial and Reference, Second Edition: Universal Data Access
for the Javatm 2 Platform, published by Addison Wesley as part of the Java
series, ISBN 0-201-43328-1.
Wikipedia.com Page: JDBC, Consulted on 1-March-2008.
78
Appendix A.
Creating a Trusted User for Logging on a
SQL-Server
1. Log on the SQL-Server
2. Click on Security > Logins
3. Right-click on Logins, select New login
79
Appendix A.
Creating a Trusted User for Logging on a
SQL-Server
4.
5.
6.
7.
8.
9.
80
Appendix A.
Creating a Trusted User for Logging on a
SQL-Server
db datareader,
db datawriter,
db ddladmin,
db public.
12. Click the OK button.
13. The user: csuperson / euclid
can now log into the SQLserver as a trusted user.
14. Use the credentials provided
by this user / password to
setup a JDBC connection
object.
81
Appendix A.
Creating a Trusted User for Logging on a
SQL-Server
82
Appendix A.
Creating a Trusted User for Logging on a
SQL-Server