Академический Документы
Профессиональный Документы
Культура Документы
Course Objectives
By the end of this course, you will be able to:
Understand the database connectivity from a Java Program
Understand to execute different types of SQL and PL/SQL
query from Java
Course Contents
1.
JDBC Overview
2.
JDBC Architecture
3.
JDBC API
4.
JDBC Driver
5.
6.
ResultSet
Course Contents
7.
Calling PL/SQL
8.
Batch Update
9.
JDBC Transaction
Introduction
Overview
Call-level interfaces such as JDBC are programming interfaces allowing external
access to SQL database manipulation and update commands.
They allow the integration of SQL calls into a general programming environment
by providing library routines, which interface with the database.
In particular, Java based JDBC has a rich collection of routines which make such an
interface extremely simple and intuitive.
Overview
Here is an easy way of visualizing what happens in a call level interface:
You are writing a normal Java program. Somewhere in the program, you need to
interact with a database. Using standard library routines, you open a connection
to the database. You then use JDBC to send your SQL code to the database, and
process the results that are returned. When you are done, you close the
connection.
Standard
Standard
Sub-Routine
Sub-Routine
Do not forget
to close the
connection when
you are
DONE !!!
JDBC
Architecture
With JDBC, you can count on a standard set of database access features and
(usually) a particular subset of SQL.
The JDBC API defines a set of interfaces that encapsulate major database
functionality, including running queries, processing results, and determining
configuration information.
A database vendor or third-party developer writes a JDBC driver, which is a set of
classes that implements these interfaces for a particular database system. An
application can use a number of drivers interchangeably.
Figure in the next slide shows how an application uses JDBC to interact with one or
more databases without knowing about the underlying driver implementations.
JDBC Architecture
Type 1
Type 1
Type 2
Type 2
Type 3
Type 3
Type 4
Type 4
We will
discuss on type
of database
driver later on
10
What We Need?
Install Java on your machine
Database
11
JDBC API
12
JDBC API
What is an API?
Abbreviation of Application Program Interface, a set of routines and tools for
building software applications.
A good API makes it easier to develop a program by providing all the building
blocks.
A programmer puts the blocks together.
In Java also, we have a set of useful classes and interfaces to implement the
concept of JDBC.
These classes and methods in turn provides number of useful methods to perform
several tasks.
The whole JDBC API is present under java.sql package.
To use them we will use the statement: import java.sql.*;
13
JDBC API
14
DriverManager
This is a very important class.
Its main purpose is to provide a means of managing the different types of JDBC
database driver On running an application, it is the DriverManager's responsibility
to load all the drivers found in the system property jdbc drivers.
For example, this is where the driver for the Oracle database may be defined. This
is not to say that a new driver cannot be explicitly stated in a program at runtime,
which is not included in jdbc drivers.
When opening a connection to a database it is the DriverManager' s role to choose
the most appropriate driver from the previously loaded drivers.
15
Connection
In this case a commit command must follow each SQL statement otherwise
changes will not be saved. An unnatural disconnection from the database during
an SQL statement will automatically result in the rollback of that query, and
everything else back to the last successful commit.
16
Statement
The objective of the Statement interface is to pass the SQL statement as a string to
the database for execution and to retrieve any results from the database in the
form of a ResultSet.
Only one ResultSet can be open per statement at any single point of time.
For example, two ResultSets cannot be compared to each other if both ResultSets
stemmed from the same SQL statement.
If an SQL statement is re-issued for any reason, the old Resultset will automatically
get closed.
Database
ResultSet
17
PreparedStatement
A PreparedStatement object is an SQL statement, which is pre-compiled and
stored.
This object can then be executed multiple times much more efficiently than
preparing and issuing the same statement each time it is needed.
When defining a variable type in JDBC, the program must ensure that the type
corresponds with the database field type for IN and OUT parameters.
We will have
a detail discussion
on this later on.
18
CallableStatement
This interface is used to execute previously stored SQL procedures
Consider this: SELECT cname FROM tname WHERE cname = var;
If this statement were to be stored, the program would need a way to pass the
parameter var into the callable procedure.
Parameters passed into the call are referred to sequentially, by number.
When defining a variable type in JDBC the program must ensure that the type
corresponds with the database field type for IN and OUT parameters
Database
Java Application
Call to procedure
procedure
table
Return value
through its
OUT parameter
19
ResultSet
A ResultSet is the retrieved data from a currently executed SQL statement. The
data from the query is delivered in the form of a table.
A pointer known as a cursor holds the current retrieved record. When a ResultSet
is returned, the logical pointer is positioned before the first record.
The pointer can move in a top-down approach (by default). Special parameters
needs to be set in order to make the pointer move in backward direction.
Once the last row has been retrieved the statement is considered closed, and
this causes the ResultSet to be automatically closed.
SQL query
ResultSet
Database
Database
e
Th
et
S
t
ul
s
Re
Rows
20
MetaData
What Is Metadata?
Metadata is a component of data which describes the data.
It is "data about data."
ResultSetMetaData
This interface allows a program to determine types and properties in any columns
in a ResultSet. It may be used to find out a data type for a particular field before
assigning its variable type.
DatabaseMetaData
This interface supplies information about the database as a whole. MetaData
refers to information held about data. The information returned is in the form of
ResultSet. Normal ResultSet methods, as explained previously, may be used in this
instance. If metadata is not available for the particular request then an
SQLException will occur
21
Driver
What Is Database Driver?
A database driver is nothing but a component which helps the application to get
access over a database.
Driver
For each database driver a class that implements the Driver interface must be
provided. When such a class is loaded it should register itself with the
DriverManager, which will then allow it to be accessed by a program.
We will have
a detail discussion
on Driver later on.
22
23
Advantage
Advantage
24
Advantage
Advantage
25
Advantages
Advantages
* This driver is server-based, so there is no need for any
vendor database library to be present on client machines.
* This driver is fully written in Java and hence Portable. It is
suitable for the web.
* There are many opportunities to optimize portability,
performance, and scalability.
* The net protocol can be designed to make the client JDBC
driver very small and fast to load.
* The type 3 driver typically provides support for features
such as caching (connections, query results, and so on),
load balancing, and advanced system administration such as
logging and auditing.
* This driver is very flexible allows access to multiple
databases using one driver.
* They are the most efficient amongst all driver types.
Disadvantages
Disadvantages
* It requires another server application to install and
maintain. Traversing the resultset may take longer, since the
data comes through the backend server.
26
Advantages
Advantages
27
Driver Type 2
Driver Type 2
28
Driver Type 4
Driver Type 4
29
Load
Loadthe
thedriver
driver
Using
Usingthe
theJDBC-ODBC
JDBC-ODBCBridge
Bridgedriver
driver(Type
(Type1)1)
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Using
Usingthe
theOracle
Oraclethin
thindriver
driver(Type
(Type4)4)
Class.forName("oracle.jdbc.driver.OracleDriver");
Class.forName("oracle.jdbc.driver.OracleDriver");
Established
Establishedthe
theconnection
connection
Step 2
IfIfType
Type11driver
driverhas
hasbeen
beenused
usedthen
thendo
dothe
thefollowing:
following:
Connection
Connectionc=DriverManager.getConnection("jdbc:odbc:dsn",
c=DriverManager.getConnection("jdbc:odbc:dsn","scott",
"scott","tiger");
"tiger");
If Type 4 driver has been used then do the following:
If Type 4 driver has been used then do the following:
Connection c=DriverManager.getConnection("jdbc:oracle:thin:@9iserver:1521:or", "scott", "tiger");
Connection c=DriverManager.getConnection("jdbc:oracle:thin:@9iserver:1521:or", "scott", "tiger");
2015 NetCracker Technology Corporation Confidential
30
database
database
import java.sql.*;
public class TestConnection
{
public static void main (String args[])
{
try
{
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection conn;
conn=DriverManager.getConnection("jdbc:oracle:thin:@oraserver:1521:or", "scott",
"tiger");
// oraserver is the name of the oracle database machine
// or is the name of the host string
System.out.println(Connection Established!!!!!);
}
catch(Exception e) {System.out.println(e.toString());}
}
}
database
31
Now after making the connection its the time to perform certain tasks
(Select/Insert/Update/Delete) on a table. Following are the steps you need to go by:
Step 3
Create
CreateaaStatement
Statementobject
objectusing
usingthe
theavailable
availableConnection
Connectionobject
object
Statement
Statementstmt=conn.createStatement();
stmt=conn.createStatement();
Here
Herestmt
stmtcan
canbe
bethought
thoughtofofasasan
anagent
agenttotohold/carry
hold/carryan
anSQL
SQLstatement.
statement.
Execute
ExecuteaaSelect
Selectquery
queryand
andhold
holdthe
thefetched
fetchedrows
rowsininaaResultSet
ResultSetobject
object
Step 4
ResultSet
ResultSetrs=stmt.executeQuery("select
rs=stmt.executeQuery("selectename,sal
ename,salfrom
fromemp");
emp");
The
logical
record
pointer
will
always
be
there
before
the
first
available
The logical record pointer will always be there before the first availablerow.
row.
Step 5
Now
Nowiterate
iteratethrough
throughaaloop
looptotoextract
extractand
andprint
printthe
thevalues
values
while
while(rs.next())
(rs.next())
{{
System.out.print(rs.getString(1)+"
System.out.print(rs.getString(1)+" ");
");
System.out.println(rs.getFloat(2)+"
System.out.println(rs.getFloat(2)+" ");
");
}}
2015 NetCracker Technology Corporation Confidential
Using Statement
import java.sql.*;
public class TestConnection{
public static void main (String args[]){
try{
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection conn; Statement stmt; ResultSet rs;
conn=DriverManager.getConnection("jdbc:oracle:thin:@oraserver:1521:or", "scott",
"tiger");
System.out.println(Connection Established!!!!!);
stmt=conn.createStatement();
// the method executeQuery needs to be invoked only for a Select Query.
// Later on we will see the use of executeUpdate for Insert/Update/Delete etc.
rs=stmt.executeQuery("select ename,sal from emp");
while (rs.next()){
System.out.print(rs.getString(1)+" ");
System.out.println(rs.getFloat(2)+"
");
}
}
catch(Exception e) {System.out.println(e.toString());}
}
}
2015 NetCracker Technology Corporation Confidential
33
Using PreparedStatement
import java.sql.*;
public class TestConnection
{
public static void main (String args[])
{
try{
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection conn; PreparedStatement pstmt; ResultSet rs;
conn=DriverManager.getConnection("jdbc:oracle:thin:@oraserver:1521:or", "scott",
"tiger");
pstmt=conn.prepareStatement("select ename,sal from emp");
rs=pstmt.executeQuery();
while (rs.next())
{
System.out.print(rs.getString(1)+" ");System.out.println(rs.getFloat(2)+"
");
}
}
catch(Exception e) {System.out.println(e.toString());}
}
}
34
Parse
Parsethe
theincoming
incomingSQL
SQLquery
query
Compile
Compilethe
theSQL
SQLquery
query
Plan/optimize
Plan/optimizethe
thedata
dataacquisition
acquisitionpath
path
Execute
Executethe
theoptimized
optimizedquery
queryand
andreturn
returndata
data
Prepared
Statement
Statement
A Statement will always proceed through the four steps above for each SQL query sent
to the database. A PreparedStatement pre-executes steps 1 to 3 in the execution
process above. Thus, when creating a PreparedStatement some pre-optimization is
performed immediately. The effect is to lessen the load on the database engine at
execution time.
Another advantage of the PreparedStatement class is the ability to create an incomplete
query and supply parameter values at execution time. This type of query is well suited
for filtering queries which may differ in parameter value only.
35
ResultSet
36
Database
e
Th
et
S
t
ul
s
Re
Rows
Limitations
In JDBC 1.0, the resultsets so defined were limited in scope in that the rows in the resultset
could be accessed only in the forward-direction. This means there was no way of moving
back and forth in a resultset or jumping to a particular row identified by a row number.
Also, the resultsets were read-only in that there was no way for inserting new rows into
the resultset, updating a particular row, or deleting a particular row.
2015 NetCracker Technology Corporation Confidential
37
By default the logical record pointer can only move in a top-to-bottom approach.
So, in case we want to move in a upward direction through the ResultSet we need
to do something extra.
We need to invoke the createStatement method with the following two
arguments:
1st
1stargument
argument(resultSetType)
(resultSetType)
2nd
2ndargument
argument(resultSetConcurrency
(resultSetConcurrency) )
e
Th
et
tl S
su
e
R
ResultSet.TYPE_SCROLL_INSENSITIVE
ResultSet.TYPE_SCROLL_INSENSITIVE
ResultSet.CONCUR_READ_ONLY
ResultSet.CONCUR_READ_ONLY
Row for the column
heading
Rows
With
PreparedStatement, this
is not possible
Bi-directional
movement
38
Navigating
through
the
ResultSet
import java.sql.*;import java.awt.*;import java.awt.event.*;
DataNavigator.j
ava
Continued
..
39
Remaining
part
of
the
Navigator
public void actionPerformed(ActionEvent ae)
{
if(ae.getSource().equals(b1)){
try{rs.first();}catch(Exception e){System.out.println(e.toString());} displayValues();
}
if(ae.getSource().equals(b2)) {
try{rs.last();}catch(Exception e){System.out.println(e.toString());} displayValues();
}
if(ae.getSource().equals(b3)){
try{rs.next();}catch(Exception e){System.out.println(e.toString());} displayValues();
}
if(ae.getSource().equals(b4)){
try{rs.previous();}catch(Exception e){System.out.println(e.toString());} displayValues()
}
}
public void displayValues(){
try{
t1.setText(String.valueOf(rs.getInt(1)));
t2.setText(rs.getString(2));
t3.setText(rs.getString(3));
t4.setText(String.valueOf(rs.getInt(4)));
} catch(Exception e){System.out.println(e.toString());}
}
}
40
An object that can be used to get information about the types and properties of the columns
in a ResultSet object.
An example code to show the usage of ResultSetMetaData
import java.sql.*;
public class jdbcinfo
{
Connection conn;Statement stmt;ResultSet rs;ResultSetMetaData rsm;
public jdbcinfo()
{
try{
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
conn=DriverManager.getConnection("jdbc:odbc:oradsn","scott","tiger");
stmt=conn.createStatement();rs=stmt.executeQuery("select * from emp");
rsm=rs.getMetaData();
int val=rsm.getColumnCount();
for(int i=1;i<=val;i++)
{
System.out.print(rsm.getColumnName(i)+" ");
System.out.print(rsm.getColumnTypeName(i)+" ");
}
conn.close();
}
catch(Exception e){System.out.println(e.toString());}
}
public static void main(String args[]){jdbcinfo ji=new jdbcinfo();}}
2015 NetCracker Technology Corporation Confidential
41
Method
getColumnCount()
Return Type
Purpose
int
getColumnName(int col)
String
getColumnType(int col)
int
getColumnTypeName(int col)
String
getPrecision(intcol)
int
getScale(intcol)
int
getTableName(intcol)
String
42
43
Example on DataBaseMetaData
importjava.sql.*;
classDbmd{
publicstaticvoidmain(Stringargs[]){
try{
Class.forName("oracle.jdbc.driver.OracleDriver");
Connectioncon=DriverManager.getConnection(
"jdbc:oracle:thin:@localhost:1521:xe","system","oracle");
DatabaseMetaDatadbmd=con.getMetaData();
System.out.println("DriverName:"+dbmd.getDriverName());
System.out.println("DriverVersion:"+dbmd.getDriverVersion());
System.out.println("UserName:"+dbmd.getUserName());
System.out.println("DatabaseProductName:"+dbmd.getDatabaseProductName());
System.out.println("DatabaseProductVersion:"+dbmd.getDatabaseProductVersion());
con.close();
}catch(Exceptione){System.out.println(e);}
}
}
44
Scrollable ResultSet
45
Scrollable ResultSet
The parameter resultSetType determines whether a resultset is scrollable or not. It can take
one of the following three values only:
ResultSet.TYPE_FORWARD_ONLY
ResultSet.TYPE_SCROLL_INSENSITIVE
ResultSet.TYPE_SCROLL_SENSITIVE
46
Scrollable ResultSet
The second parameter resultSetConcurrency determines whether a resultset is
updateable or not and can take one of the two values only:
ResultSet.CONCUR_READ_ONLY
ResultSet.CONCUR_UPDATEABLE
With these resultset types and two concurrency types, there are six different kinds of
resultsets that can be defined. These are :
Type_Forward_Only/Concur_Read_Only
Type_Forward_only/Concur_Updateable
Type_Scroll_Insensitive/Concur_Read_Only
Type_Scroll_Insensitive/Concur_Updateable
Type_Scroll_Sensitive/Concur_Read_Only
Type_Scroll_Sensitive/Concur_Updateable
47
Scrollable ResultSet
A scrollable resultset allows for random access to its rows. Random access in turn allows for accessing a
particular row directly without having to advance row by row. This direct positioning of control at a
specific row is termed positioning.
To enable scrollability and positioning, in JDBC 2.0, the ResultSet class provides a set of new methods in
addition to the next() method available in JDBC 1.0. These methods are as follows:
first()
Positions the control at the first row in the resultset and returns true. If there are
no rows in the resultset, it returns false.
last()
Positions the control at the last row in the resultset and returns true. If there are
no rows in the resultset, it returns false.
previous()
Positions the control at the previous row in the resultset relative to the current
row. This returns true if the previous row exists. It returns false, if it causes the
resultset to be positioned before the first row.
absolute(int row)
relative(int offset)
Directly jumps to the row specified by the parameter. This is absolute positioning,
meaning it jumps to the row specified starting from the beginning or end
depending on whether the parameter is positive or negative. This returns true if
the row jumped to is valid. If a zero is passed, it throws an exception. Remember
that absolute(1) is same as first() and absolute(-1) is same as last().
Directly jumps to the row starting from the current row by an offset specified by
the parameter. This is relative positioning meaning, it jumps to the row specified
starting from the current row.
48
Assignment
A Frame based modular JDBC demo application
A Frame based modular JDBC demo application
MainModule
SelectModule
InsertModule
UpdateModule
DeleteModule
49
Updateable ResultSet
Updateable resultsets means the ability to update the contents of specific row(s) in the
resultset and propagating these changes to the underlying database.
This capability is supported in JDBC 2.0 only. Also the operations of INSERT and
DELETE are possible. New rows can be inserted into the underlying table and existing
rows can be deleted from both the resultset as well as the underlying table.
The CLASSPATH has to include classes12.zip for using updateable resultsets.
Java Code
Database
TABLE
INSERT
UPDATE
SQL Query
DELETE
Selected Row(s)
ResultSet
50
The following are the steps involved in creating and using an updateable ResultSet:
STEP 1
51
Use the updateXXX() (for example, updateInt() and updateString()) methods on the
ResultSet object to set the values of the resultset columns. JDBC 2.0 has provided these
methods for each of the Java primitive types as well for some SQL types that correspond
to Java objects.
rset.updateFloat(2, new_val);
The use of this method is as follows:
rset.updateFloat(2, new_val);
Propagate the changes made to the resultset to the underlying database table
Propagate the changes made to the resultset to the underlying database table
Use the updateRow() method on the ResultSet object to propagate the changes made to
the resultset to the underlying database table and commit them. This has to be done once
for each row in the resultset that is changed.
The use of this method is as follows:
rset.updateRow();
rset.updateRow();
52
UpdateableResultSetExampl
import java.sql.*;
e.java
public class UpdateableResultSetExample {
public static void main(String[] args) throws SQLException {
int ret_code; Connection conn = null;
try {
DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
String cs="jdbc:oracle:thin:@training:1521:Oracle";
conn = DriverManager.getConnection(cs,scott", "tiger");
int i_deptno = 10;
String sql = "SELECT empno, sal, comm FROM emp_with_type WHERE deptno = ?" ;
PreparedStatement pstmt = conn.prepareStatement(sql, ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_UPDATEABLE);
pstmt.setInt(1, i_deptno); ResultSet rset = pstmt.executeQuery();
while (rset.next()) {
float i_sal = rset.getFloat(2);
float i_comm = rset.getFloat(3);
rset.updateFloat(2, (float)(i_sal+(1.25*i_comm)));
rset.updateRow();
} // End of the while loop.
rset.close(); pstmt.close(); pstmt.close(); conn.close();
} // End of the try block.
catch (SQLException e) { ret_code = e.getErrorCode(); System.err.println(ret_code + e.getMessage());
conn.close();}
} // End of the main method.
} // End of the class.
2015 NetCracker Technology Corporation Confidential
53
A new row can be inserted into the underlying database table through a resultset.
The steps involved are:
STEP 1
Navigate to the insert row. This is done by using the method moveToInsertRow() on the
ResultSet object. The insert row is a special row in the resultset and is different from the
existing rows in the resultset that have been returned by the query. After the insert, the
control can be made to navigate to the current row (i.e., the row before moving to the
new insert row) using the method moveToCurrentRow() on the ResultSet object.
STEP 2
Update the contents of this insert row by using the updateXXX() methods on the
ResultSet object.
STEP 3
Apply the new row to the database by using insertRow() method on the ResultSet
object.
Tips
54
STEP 2
Delete the row using the deleteRow() method on the ResultSet object.
Tips
Deleting a row from the resultset implicitly deletes the corresponding row
Deleting a row from the resultset implicitly deletes the corresponding row
from the database table. This is unlike updating or inserting rows through a
from the database table. This is unlike updating or inserting rows through a
resultset, when the changes made to the resultset have to be explicitly
resultset, when the changes made to the resultset have to be explicitly
applied to the database using updateRow() or insertRow() methods.
applied to the database using updateRow() or insertRow() methods.
55
56
The getClob() method of PreparedStatement is used to get file information from the
database.
Syntax of getClob method
publicClobgetClob(intcolumnIndex){}
CREATETABLE"FILETABLE"
("ID"NUMBER,
"NAME"CLOB
)
/
57
58
2. publicvoidsetBinaryStream(intparamIndex,InputStreamstream,longlength)
throwsSQLException
59
Let's write the jdbc code to store the image in the database. Here we are using
d:\\d.jpg for the location of image. You can change it according to the image
location
60
61
62
CREATETABLE"IMGTABLE"
("NAME"VARCHAR2(4000),
"PHOTO"BLOB
)
Now let's write the code to retrieve the image from the database and write it into
the directory so that it can be displayed.
63
Calling PL/SQL
65
Stored procedures are part and parcel of any database application that enables a lot of
business logic to be stored as application logic in the database in compiled form. This
section highlights the calling of PL/SQL stored procedures.
PL/SQL stored procedures are called from within JDBC programs by means of the
prepareCall() method of the Connection object created above. A call to this method takes
variable bind parameters as input parameters as well as output variables and creates an
object instance of the CallableStatement class.
Java Application
Call to procedure
procedure
table
Return value
through its
OUT parameter
66
import java.sql.*;
public class CallProcedure{
public static void main(String args[]) throws Exception{
String cs = "jdbc:oracle:thin:@oracle9iserver:1521:orcl"; String driver =
"oracle.jdbc.driver.OracleDriver";
String uname = "scott"; String pword = "tiger";
Class.forName(driver); Connection conn = DriverManager.getConnection(cs, uname, pword);
CallableStatement s =conn.prepareCall("{call calcGross(?,?)}");
int no;
for(int i=0; i < args.length;i++){
no = Integer.parseInt(args[i]);
s.setInt (1, no);
s.registerOutParameter (2, Types.INTEGER);
s.executeUpdate();
int totsal = s.getInt(2);
System.out.println(totsal);}}}
2015 NetCracker Technology Corporation Confidential
67
This will display the sal+nvl(comm,0) for empno 7369 and 7844. You can provide n
numbers of empno to display the value of their sal+nvl(comm,0).
Output
68
A REF CURSOR is a weakly typed cursor type that identifies a cursor variable. A variable
A REF CURSOR is a weakly typed cursor type that identifies a cursor variable. A variable
can defined of the REF CURSOR type and then a query can be opened for it. The cursor
can defined of the REF CURSOR type and then a query can be opened for it. The cursor
variable then acts as a pointer to the query or SELECT thus opened. Stored procedures
variable then acts as a pointer to the query or SELECT thus opened. Stored procedures
or functions as well as packaged procedures or functions can return cursor variables of
or functions as well as packaged procedures or functions can return cursor variables of
type REF CURSOR. The output consists of a ResultSet that holds the rows returned by
type REF CURSOR. The output consists of a ResultSet that holds the rows returned by
the REF CURSOR. This output can be captured in a JDBC ResultSet object.
the REF CURSOR. This output can be captured in a JDBC ResultSet object.
Database
Java Application
Call to function
function
Return ref-cursor
table
69
Declares a variable
Declares a variable
print results
70
import java.sql.*;
public class RefCursorExample{
public static void main(String[] args) throws Exception{
int ret_code; Connection conn = null;
try{
DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
conn = DriverManager.getConnection("jdbc:oracle:thin:@sedev1:1521:orcl9","scott","tiger");
int xdeptno = Integer.parseInt(args[0]);CallableStatement cstmt = conn.prepareCall("{? = call get_emp(?)}");
cstmt.registerOutParameter(1, OracleTypes.CURSOR);
cstmt.setInt(2, xdeptno);
cstmt.executeUpdate(); ResultSet rset;
rset = (ResultSet) cstmt.getObject(1); ResultSetMetaData rsmd = rset.getMetaData();
int colcount = rsmd.getColumnCount();
while (rset.next()){
String str = "";
for(int i=1;i<=colcount;i++){
if(i!=colcount)
str=str+rset.getString(i)+" | ";
else
str=str+rset.getString(i);
}
System.out.println(str);
}
rset.close(); cstmt.close(); conn.close();
}
catch (Exception e) {System.out.println(e.toString()); conn.close();}
}
}
2015 NetCracker Technology Corporation Confidential
71
72
One of the more advanced features of JDBC 2.0 is the ability to submit multiple update
statements to the database for processing as a single unit. This batch updating can be
significantly more efficient compared to JDBC 1.0, where each update statement has to be
executed separately.
Connection Channel
Database
Batch of statements
Batch of statements
All the four rows are going
to be inserted with the
invocation of a single
executeBatch() method
table
73
TestBatchUpdate.java
import java.sql.*;
public class TestBatchUpdate
{
public static void main(String args[]) throws SQLException
{
Connection conn=null;
Statement stmt;
try
{
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
conn=DriverManager.getConnection("jdbc:odbc:empdsn","","");
conn.setAutoCommit(false);
stmt = conn.createStatement();
stmt.addBatch("Insert Into emp(empno,ename) Values(1111,Amit)");
stmt.addBatch("Insert Into emp(empno,ename) Values(1112,Binay)");
int result[]=stmt.executeBatch();
conn.commit();
stmt.close();
conn.close();
}
catch(BatchUpdateException e){System.out.println("Exception 1: " + e.toString()); conn.rollback();}
catch(SQLException e){System.out.println("Exception 2: " + e.toString());conn.rollback();}
catch(ClassNotFoundException e){System.out.println("Exception 3: " + e.toString());conn.rollback();}}
74
Jdbc
RowSet
The instance ofRowSetis the java bean component because it has properties and
java bean notification mechanism
75
RowSet by Example
import javax.sql.rowset.JdbcRowSet;
import javax.sql.rowset.RowSetProvider;
public class JdbcRowSetEx {
public static void main(String[] args) throws Exception {
JdbcRowSet rowSet = RowSetProvider.newFactory().createJdbcRowSet();
rowSet.setUrl("jdbc:oracle:thin:@rbmtrain:1521:trng1");
rowSet.setUsername("oracle2");
rowSet.setPassword("ora123");
rowSet.setCommand("select * from emp");
rowSet.execute();
while (rowSet.next()) {
System.out.println(rowSet.getInt(1) + "...." + rowSet.getString(2));
}
}
}
76
Using
Transactions
A transaction is a collection of DML statements that are executed as if they are a single
operation.
A JDBC application that needs to execute multiple SQL statements targeted towards a
specific function, can make use of JDBC's transaction services.
Transactions might need to be grouped in situations where multiple updates are needed
and the entire set of transactions is to be committed or the entire set undone in case of a
single failure.
Transaction services basically include beginning the transaction, executing the SQL
statements that make up the transaction, and either perform a commit on overall success
of each SQL statement or rollback the transaction as a whole if one of the SQL statements
fails.
Transaction management in JDBC is handled to some extent by the Connection object.
Whenever a new Connection is opened, the transaction auto-commit mode is turned on.
In auto-commit mode, every SQL statement is executed as a single transaction that is
immediately committed to the database.
To execute multiple SQL statements as part of a single transaction, the auto-commit is to
be disabled.
2015 NetCracker Technology Corporation Confidential
77
Using Transactions
Committing
The above line of code should appear immediately after the connection has been
established. This is shown below :
//Load and register Oracle driver
DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
//Establish a connection
conn = DriverManager.getConnection("jdbc:oracle:thin:@training:1521:Oracle","scott","tiger");
//Disable auto-commit mode
conn.setAutoCommit(false);
Once the auto-commit mode is turned off, an explicit COMMIT or ROLLBACK should be
done to commit any unsaved database changes. COMMIT or ROLLBACK can be done by
calling the commit() or rollback() methods of the Connection object.
2015 NetCracker Technology Corporation Confidential
78
Transaction
Management
by
Example
import java.sql.*;
import java.sql.*;
public class TransactionExample {
public class TransactionExample {
public static void main(String[] args) throws SQLException {
public static void main(String[] args) throws SQLException {
int ret_code; Connection conn = null;
int ret_code; Connection conn = null;
try{ DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
try{ DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
conn = DriverManager.getConnection("jdbc:oracle:thin:@training:1521:Oracle", "scott", "tiger");
conn = DriverManager.getConnection("jdbc:oracle:thin:@training:1521:Oracle", "scott", "tiger");
conn.setAutoCommit(false); // Disable auto-commit mode
conn.setAutoCommit(false); // Disable auto-commit mode
String sql1 = "SELECT empno FROM emp WHERE empno = ?" ;
String sql1 = "SELECT empno FROM emp WHERE empno = ?" ;
String sql2 = "INSERT INTO emp VALUES (?,?,?,?,?,?,?,?)";
String sql2 = "INSERT INTO emp VALUES (?,?,?,?,?,?,?,?)";
String sql3 = "UPDATE dept_audit SET cnt_emp = nvl(cnt_emp,0) + 1 WHERE deptno = 10";
String sql3 = "UPDATE dept_audit SET cnt_emp = nvl(cnt_emp,0) + 1 WHERE deptno = 10";
PreparedStatement pstmt1 = conn.prepareStatement(sql1);
PreparedStatement pstmt1 = conn.prepareStatement(sql1);
PreparedStatement pstmt2 = conn.prepareStatement(sql2);
PreparedStatement pstmt2 = conn.prepareStatement(sql2);
PreparedStatement pstmt3 = conn.prepareStatement(sql3);
PreparedStatement pstmt3 = conn.prepareStatement(sql3);
pstmt1.setInt(1, 9999); ResultSet rset = pstmt1.executeQuery();
pstmt1.setInt(1, 9999); ResultSet rset = pstmt1.executeQuery();
if(rset.next()){
if(rset.next()){
System.out.println("The employee with empno 9999 already exists."); rset.close();
System.out.println("The employee with empno 9999 already exists."); rset.close();
}
}
else{
pstmt2.setInt(1, 9999);
pstmt2.setString(2, "CHARLIE");
else{
pstmt2.setInt(1, 9999);
pstmt2.setString(2, "CHARLIE");
pstmt2.setString(3, "ANALYST");
pstmt2.setInt(4, 7566);
pstmt2.setString(3, "ANALYST");
pstmt2.setInt(4, 7566);
pstmt2.setString(5, "01-JAN-01");
pstmt2.setFloat(6, 12000);
pstmt2.setString(5, "01-JAN-01");
pstmt2.setFloat(6, 12000);
pstmt2.setFloat(7, (float)10.5);
pstmt2.setInt(8, 10);
pstmt2.setFloat(7, (float)10.5);
pstmt2.setInt(8, 10);
pstmt2.executeUpdate();
pstmt2.executeUpdate();
}
}
pstmt3.executeUpdate();
pstmt1.close();
pstmt2.close();
pstmt3.close();
pstmt3.executeUpdate();
pstmt1.close();
pstmt2.close();
pstmt3.close();
2015 NetCracker Technology Corporation Confidential
>>
79
}
}
}
}
catch (SQLException e)
catch (SQLException e)
{
{
// Rollback all the changes so as to undo the effect of both INSERT and UPDATE
// Rollback all the changes so as to undo the effect of both INSERT and UPDATE
conn.rollback();
conn.rollback();
ret_code = e.getErrorCode();
ret_code = e.getErrorCode();
System.out.println(ret_code + e.getMessage()); conn.close();
System.out.println(ret_code + e.getMessage()); conn.close();
}
}
80
Using Savepoints
The new JDBC 3.0 Savepoint interface gives you additional transactional
control.DBMS support savepoints within their environments such as Oracle's
PL/SQL.
Traditionally, database transactions have been "all or nothing" types of events.
An application would start a transaction, it might insert some rows, do some
updates, and then either make the changes permanent or discard all of the
changes.
Either all of the changes would be made permanent or none of the changes
would be permanent.
With JDBC 3.0, the transactional model is now more flexible. An application
might start a transaction, insert several rows and then create a savepoint.
81
This savepoint serves as a bookmark. With JDBC 2.0, the application would now
have to either commit all the changes or rollback all the changes. With JDBC 3.0,
the application might conclude that the updates made were a bad idea but the
initial inserts were okay.
The application can rollback to the savepoint and, then, commit the group of
inserts as if the updates have never been attempted.
The Connection object has new methods
setSavepoint(String savepointName)
releaseSavepoint(Savepoint savepointName)
rollback (String savepointName)
82
SavePoints by Example
try{
try{
//Assume a valid connection object conn
//Assume a valid connection object conn
conn.setAutoCommit(false);
conn.setAutoCommit(false);
Statement stmt = conn.createStatement();
Statement stmt = conn.createStatement();
//set a Savepoint
//set a Savepoint
Savepoint savepoint1 = conn.setSavepoint("Savepoint1");
Savepoint savepoint1 = conn.setSavepoint("Savepoint1");
String SQL = "INSERT INTO Emp " + "VALUES (7654, Rahim, Syed)";
String SQL = "INSERT INTO Emp " + "VALUES (7654, Rahim, Syed)";
stmt.executeUpdate(SQL);
stmt.executeUpdate(SQL);
//Submit a malformed SQL statement that breaks
//Submit a malformed SQL statement that breaks
String SQL = "INSERTED IN Emp " + "VALUES (8765,Karim, Syed)";
String SQL = "INSERTED IN Emp " + "VALUES (8765,Karim, Syed)";
stmt.executeUpdate(SQL);
stmt.executeUpdate(SQL);
// If there is no error, commit the changes.
// If there is no error, commit the changes.
conn.commit();
conn.commit();
}
}
catch(SQLException se){
catch(SQLException se){
// If there is any error.
// If there is any error.
conn.rollback(savepoint1);
conn.rollback(savepoint1);
}
}
2015 NetCracker Technology Corporation Confidential
83
Connection Pooling
Opening a connection to a database is a time-consuming process. For short queries, it can take
Opening a connection to a database is a time-consuming process. For short queries, it can take
much longer to open the connection than to perform the actual database retrieval. Consequently,
much longer to open the connection than to perform the actual database retrieval. Consequently,
it makes sense to reuse Connection objects in applications that connect repeatedly to the same
it makes sense to reuse Connection objects in applications that connect repeatedly to the same
database.
database.
If a connection is required and an idle connection is available, put it in the list of busy connections
If a connection is required and an idle connection is available, put it in the list of busy connections
and then return it. The busy list is used to check limits on the total number of connections as well
and then return it. The busy list is used to check limits on the total number of connections as well
as when the pool is instructed to explicitly close all connections.
as when the pool is instructed to explicitly close all connections.
One caveat: connections can time out, so before returning the connection, confirm that it is still
One caveat: connections can time out, so before returning the connection, confirm that it is still
open. If not, discard the connection and repeat the process. Discarding a connection opens up a
open. If not, discard the connection and repeat the process. Discarding a connection opens up a
slot that can be used by processes that needed a connection
slot that can be used by processes that needed a connection
when the connection limit had been reached, so use notifyAll to tell all waiting threads to wake up
when the connection limit had been reached, so use notifyAll to tell all waiting threads to wake up
and see if they can proceed.
and see if they can proceed.
If a connection is required, there is no idle connection available, and the connection limit has not
If a connection is required, there is no idle connection available, and the connection limit has not
been reached, then start a background thread to allocate a new connection. Then, wait for the
been reached, then start a background thread to allocate a new connection. Then, wait for the
first available connection, whether or not it is the newly allocated one.
first available connection, whether or not it is the newly allocated one.
This situation occurs when there is no idle connection and youve reached the limit on the number
This situation occurs when there is no idle connection and youve reached the limit on the number
of connections. The natural approach is to use the wait method, which gives up the thread
of connections. The natural approach is to use the wait method, which gives up the thread
synchronization lock and suspends the thread until notifyAll is called.
synchronization lock and suspends the thread until notifyAll is called.
2015 NetCracker Technology Corporation Confidential
84
import java.sql.*;
import java.sql.*;
import java.util.*;
import java.util.*;
public class ConnectionPool
public class ConnectionPool
{
Vector freeconnection; Vector busyconnection; String driver, url, user, password;
{
Vector freeconnection; Vector busyconnection; String driver, url, user, password;
ConnectionPool(String driver, String url, String user, String password)
ConnectionPool(String driver, String url, String user, String password)
{
this.driver=driver; this.url=url;
{
this.driver=driver; this.url=url;
this.user=user;
this.password=password;
this.user=user;
this.password=password;
freeconnection = new Vector(5);
busyconnection = new Vector();
freeconnection = new Vector(5);
busyconnection = new Vector();
for(int i=0; i<5; i++)
for(int i=0; i<5; i++)
{
freeconnection.addElement(createConnection());
{
freeconnection.addElement(createConnection());
}
}
}
}
private Connection getConnection()
private Connection getConnection()
{
try{
Class.forName(driver);
{
try{
Class.forName(driver);
return DriverManager.getConnection(url,user,password);
return DriverManager.getConnection(url,user,password);
}
}
catch(Exception ex){
catch(Exception ex){
System.out.println("1 : "+ex.toString());
System.out.println("1 : "+ex.toString());
return null;
return null;
}
}
}
}
2015 NetCracker Technology Corporation Confidential
85
86
}
End of the connection pool
87
import java.sql.*;
import java.sql.*;
public class TestConnectionPool{
public class TestConnectionPool{
public static void main (String args[]){
public static void main (String args[]){
String driver = "oracle.jdbc.driver.OracleDriver";
String driver = "oracle.jdbc.driver.OracleDriver";
String url ="jdbc:oracle:thin:@10.131.211.116:1521:oracle";
String url ="jdbc:oracle:thin:@10.131.211.116:1521:oracle";
String user="scott"; String password="tiger";
String user="scott"; String password="tiger";
ConnectionPool cp = new ConnectionPool(driver,url,user,password);
ConnectionPool cp = new ConnectionPool(driver,url,user,password);
String s1="Select empno, ename from emp;
String s1="Select empno, ename from emp;
String s2=" Select empno, job from emp where deptno=30;
String s2=" Select empno, job from emp where deptno=30;
String s3=" Select empno, hiredate from emp where deptno=10;
String s3=" Select empno, hiredate from emp where deptno=10;
String s4=" Select empno, sal from emp where deptno=20;
String s4=" Select empno, sal from emp where deptno=20;
String s5=" Select empno, deptno from emp;
String s5=" Select empno, deptno from emp;
String s6=" Select empno, mgr from emp;
String s6=" Select empno, mgr from emp;
new TestConnectionPoolThread(s1,"1st",cp);
new TestConnectionPoolThread(s1,"1st",cp);
new TestConnectionPoolThread(s2,"\t2nd",cp);
new TestConnectionPoolThread(s2,"\t2nd",cp);
new TestConnectionPoolThread(s3,"\t\t3rd",cp);
new TestConnectionPoolThread(s3,"\t\t3rd",cp);
new TestConnectionPoolThread(s4,"\t\t\t4th",cp);
new TestConnectionPoolThread(s4,"\t\t\t4th",cp);
new TestConnectionPoolThread(s5,"\t\t\t\t5th",cp);
new TestConnectionPoolThread(s5,"\t\t\t\t5th",cp);
new TestConnectionPoolThread(s6,"\t\t\t\t\t6th",cp);
new TestConnectionPoolThread(s6,"\t\t\t\t\t6th",cp);
}
}
}
}
2015 NetCracker Technology Corporation Confidential
88
89
Course Summary
With this course completed, you should be able to:
Understand the database connectivity from a Java Program
Understand to execute different types of SQL and PL/SQL
query from Java
90
Thank You!
91