Escolar Documentos
Profissional Documentos
Cultura Documentos
History:
- The X/Open and SQL Access Group defined the Call Level Interface
(CLI).
- The most important benefit for programmers using the ODBC or JDBC
CLI is the interoperability.
JDBC
JDBC does the following things:
- JDBC is the interface between the database and java end user application, servlet applet.
- JDBC library provides the means for executing SQL statement to access and operate on a
relational database. JDBC Library is a set of classes and interfaces that provide a uniform
API for access to a broad range of databases.
- First of all before connection to a database, we need to have the Driver for that Database. A
Driver is an interface / Bridge between 2 objects, for example between the hardware and
software.
- It is the duty of the Driver to read, store or retrieve data from the back end. The Driver reads
data from the Database and converts it into a known format. So we have different drivers for
different databases.
- SQL is a language used to create, manipulate, examine, and manage relational databases.
- Unfortunately, you must connect to a database before sending SQL commands, and each
database vendor has a different interface, as well as different extensions of SQL.
- Enter ODBC. Microsoft brought about the concept of ODBC, which is preinstalled on all
Windows OS. That is why we can create a DSN directly.
- Sun’s JDBC driver reads from the in-built ODBC Driver. One of the fundamental principals of
JDBC’s design was to make it practical to built JDBC drivers based on other database APIs.
- The advantage of the JDBC – ODBC Bridge is that there is no need for separate Database
Configuration, no need for separate installation and only follow the standard SQL syntax.
- The Limitation of the JDBC – ODBC Bridge is that it can run only on Windows OS and Solaris
OS.
JDBC Driver Models
In this model, the java applet / application interact directly with the database. A JDBC driver is
required to communicate with the particular database management system that is being
accessed. The SQL statements are sent to the database and the results are given to the user.
This type of model is referred to as the client / server configuration where user is the client and
the machine that has the database is called the server.
The reason for the middle tier (Application Server) is and it does the following
a) Collection of SQL statements from the client and handing over the same to the DB
b) Receiving results from the DB to the client
c) Maintaining control over accessing and updating of the data.
Middle tier until recently had been written in C and C++ which enable faster performance. With
the introduction of optimizing compilers that translate java byte codes into machine specific code,
it is not possible to implement the middle tier in java.
- This Driver Bridge is very useful for accessing data in data sources for which no pure JDBC
drives exist.
- This bridge works by translating the JDBC methods into ODBC function calls and has the
advantage of working with a huge number of ODBC Drivers.
- This class of Driver consist of Java Code that access data through native methods – typically
calls to a particular vendor library.
- This class of Driver is very convenient when a C data access library already exists, but it is
not usually very portable
- This driver converts JDBC calls into calls on the client API for Oracle, Sybase, Informix and
other DBMS. But some binary code has to be loaded on all clients like the bridge driver and
again not suitable for large applications.
- This class of Drivers is implemented as “middleware” with the client driver completely
implemented in Java.
- This client driver communicates with a separate middleware component (usually TCP/IP),
which translates JDBC requests into database access calls.
- This form of driver is an extension of the previous class, with the Java and native API
separated into separate client and proxy processes.
- This class of drivers communicates directly to the database server using the server’s native
protocol. Unlike the previous case, where the JDBC calls were converted by the middleware
components into database calls, here the client directly talks to the server.
The only time we are likely to come into contact with the Driver object is when we install
the same. The application need not ever interact directly with the Driver object since the
DriverManager class takes care of communicating with it.
a) ODBC cannot be directly used with Java because it uses a C interface and calls from
java to native C code have a lot of drawbacks in security, implementation, and portability.
b) ODBC makes use of pointers whereas java does not use them.
c) ODBC requires manual installation of the ODBC driver manager and driver on all client
machines. JDBC drivers are written in java and JDBC code is automatically installable,
secure and portable
a) Driver – This is the interface between the application and the database, which stores
and retrieves the data from the DB. This translates API calls into operations for a
specific data source.
b) Driver Manager – It loads the database Drivers, manages the Connections between
the application and the Driver.
f) Result Set – Logical set of columns and rows of data returned by executing a
statement.
Steps in JDBC
8) Close the RS
- The DriverManager class is responsible for establishing connections to the data sources,
accessed through the JDBC Drivers.
- If any JDBC driver has been identified in the “jdbc.drivers” system property on your computer,
then the DriverManager will attempt to load that when it is loaded.
- The System Properties are actually stored in a Properties Object. The Properties class,
defined in the java.util package, associates values with keys in a map and the contents of the
map defines a set of system properties.
- In general each key is supplied as a String and the values corresponding to a key can be any
valid object. So we can use the Properties object to interact with the system properties and
can just set the key / value pairs.
- We can set the “jdbc.drivers” system property by calling the setProperty () method for the
System class
The first argument is the key for the property being set and second is the value.
- Now we can see what are the system properties on our machine by using the following
command.
- In many cases, because of Security Reasons, we cannot set our system property and in such
situations, to include the driver that we want to use, we need to load the driver explicitly by
calling the static forName () method of the Class class and passing a String object as an
argument.
Class.forName ("sun.jdbc.odbc.JdbcOdbcDriver");
The forName () can throw a ClassNotFoundException and hence has to be in a try and
catch block.
- The forName () method ensures that the JDBC Driver class required by our program is
loaded and initialised before our code actually uses the Driver.
- The forName () method causes the Java Interpreter’s class loader to load the class for the
Driver specified by the argument. If we use any native API Drivers, then those are also loaded
in the following way.
- Each Driver class will typically create an instance of itself when it is loaded (into the memory)
and register that instance by calling the DriverManager class automatically.
- We cannot create any instance of the DriverManager since all the methods are static.
- Now we need a Connection Object and for this we will call the static getConnection ()
method of the DriverManager class, which is overloaded.
The getConnection () takes as a parameter the JDBC URL. Here the JDBC URL is
broken up as under:
jdbc:<sub protocol>://<data source identified> // here the data source identifier will have
to be created by the user by using the DSN.
The standard sub protocol used by the JDBC-ODBC Bridge is the odbc Driver.
- Since most of the Databases require a user name and password, we pass the same, when
requesting for a connection. The important thing to remember here is that all the 3
parameters are Strings.
Driver Interface
The Driver processes ODBC function calls, sends SQL statements to a specific data source and
returns results back to the application. When necessary, the driver translates and or optimizes
requests so that the request conforms to the syntax supported by the specific DBMS.
- Writing a JDBC driver class consists of creating java class that implements the driver
interface and therefore every Driver class should implement this Interface.
- When a Driver class is loaded, it should create an instance of itself and register it with the
DriverManager. This means that a user can load and register a driver by calling
Class.forName (" ").
- We can also query the driver for getting information such its version number.
- As seen earlier for getting the Driver, we will have to use the static method of the DM class,
getDriver (), passing the data source (jdbc:odbc:____) as its URL.
Connection Class
- Before you can execute any SQL statements, you must first have a Connection object.
- A Connection object represents an established connection to a particular data source and you
use it to create a Statement object that enables you to define and execute specific SQL
Statements.
- A Connection object can also be used to query the data source for information about the data
in the database (the metadata), including the information about the columns for a particular
table and so on.
a) Statement Object.
b) PreparedStatement Object
c) CallableStatement Object
- It is through the Connection Object that we execute the method createStatement (), which
returns a Statement object.
- Through the Statement object, we will query the database using execute (String SQL), which
will return only a boolean value, whether the SQL Statement is successful or not.
- We can query the database (use select command) by sending SQL statements through the
method executeQuery (String SQL), which will return a ResultSet Object and then iterate
through the ResultSet for getting our information.
- We can also use the method executeUpdate (String SQL) for sending Insert, Update or
Delete commands which will return a int with the number of rows affected by the SQL
Statement.
- If the same SQL is to be used repeatedly, then we will be using the PreparedStatement
objects and it will be done calling the prepareStatement (String SQL) method in the
Connection Class.
- If we have to use the Database Stored Procedures, we should use the CallableStatement
object and this will be done by calling the prepareCall (String SQL) method in the Connection
Class.
- Remember in the createStatement () method, we are not passing any SQL statements, which
is, sent by using the executeQuery (String SQL) method of the Statement object, whereas in
the prepareStatement and prepareCall methods, we give the SQL as the parameters to this
method.
- Presently we are using a createStatement () method without any parameters, but a new
feature is introduce in JDBC 2.0 API wherein we can use the fields as the parameters, which
we will discuss later on.
- By Default, Connection is set to the Auto-Commit mode and incase it is set to false; it is the
duty of the programmer to call commit () specifically.
void commit()
Makes all changes made since the previous commit/rollback
permanent and releases any database locks currently held by the
Connection.
Statement createStatement()
Creates a Statement object for sending SQL statements to the
database.
Statement createStatement(int resultSetType, int resultSetConcurrency)
JDBC 2.0 Creates a Statement object that will generate ResultSet
objects with the given type and concurrency.
boolean getAutoCommit()
Gets the current auto-commit state.
DatabaseMetaData getMetaData()
Gets the metadata regarding this connection's database.
void rollback()
Drops all changes made since the previous commit/rollback and
releases any database locks currently held by this Connection.
void setAutoCommit(boolean autoCommit)
Sets this connection's auto-commit mode.
Statement Class
- For sending SQL Statements, we use the executeQuery (String SQL) method of this
Statement Class.
- We can also use the execute (String SQL) method which will return a boolean value, whether
the same have been executed or not. This is normally used when the statement returns more
than one Result Set.
- We can also use the executeUpdate (String SQL) method, which will return an int value,
which the number of rows updated (that is inserted, deleted, or modified).
- JDBC 2.0 gives us the facility to assemble SQL Statements into a batch and submit them for
processing as a batch to the database and this can be done by using the addBatch () method
in the Statement object. Then we will have to use the method executeBatch () for executing
the batch created.
- As the batch of SQL statements can generate multiple result sets, accessing them is a little
complicated and it involves calling the getResultSet () method for the Statement object to
retrieve the first result set and then using the result set you call getMoreResults () for the
Statement object.
- JDBC provides two kinds of objects that you can use to execute SQL Statements and they
are PreparedStatement and CallableStatement interfaces which are sub-interfaces of the
Statement Interface. The PreparedStatement Interface extends the Statement Interface and
the CallableStatement Interface extends the PreparedStatement interface.
- PreparedStatement objects differ from the Statement objects in that the SQL statement is
pre-compiled and can have placeholders (?) for runtime parameters values.
- The PreparedStatement objects are particularly useful when a statement will be executed
many times (for example, adding new rows) since substantial performance gains can be
achieved.
import java.sql.*;
class DBTest
{
public static void main(String[] args)
{
try
{
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Connection c =
DriverManager.getConnection("jdbc:odbc:oracle","scott","tiger");
Statement s = c.createStatement();
import java.sql.*;
class DBInsert
{
public static void main(String[] args)
{
try
{
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Connection c =
DriverManager.getConnection("jdbc:odbc:oracle","scott","tiger");
Statement s = c.createStatement();
import java.sql.*;
class DBInsertCommand
{
public static void main(String[] arg)
{
try
{
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Connection c =
DriverManager.getConnection("jdbc:odbc:oracle","scott","tiger");
Statement s = c.createStatement();
Example – 4: - This is show how to use prepared statement through GUI way with 3
TFs and 1 button using PreparedStatement.
import java.sql.*;
import java.io.*;
import java.awt.*;
import java.awt.event.*;
PreparedStatement ps;
TextField t;
TextField t1;
TextField t2;
Button b;
Dialog d;
Label l;
Button b2;
DBInsertGUI ()
{
try
{
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Connection c =
DriverManager.getConnection("jdbc:odbc:oracle","scott","tiger");
try
{
ps.setInt(1,Integer.parseInt(t.getText()));
ps.setString(2,t1.getText());
ps.setString(3,t2.getText());
ps.executeUpdate();
d.show();
}
catch(SQLException f)
{
l.setText(f.getMessage());
d.show();
}
}
import java.sql.*;
class DBInsertPrepared
{
public static void main(String[] arg)
{
try
{
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Connection c =
DriverManager.getConnection("jdbc:odbc:oracle","scott","tiger");
ps.setInt(1,13);
ps.setString(2,"Technical");
ps.setString(3,"Hyderebad");
int d = ps.executeUpdate();
System.out.println("Rows inserted "+d);
import java.sql.*;
import java.io.*;
class DBInsertPrepared1
{
public static void main(String[] arg)
{
try
{
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Connection c =
DriverManager.getConnection("jdbc:odbc:oracle","scott","tiger");
String s = br.readLine();
ps.setInt(1,Integer.parseInt(s));
String s1 = br.readLine();
ps.setString(2,s1);
System.out.println("Enter Location");
String s2 = br.readLine();
ps.setString(3,s2);
int d = ps.executeUpdate();
System.out.println("Rows inserted "+d);
import java.sql.*;
class DBSelectRS
{
public static void main(String[] arg)
{
try
{
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Connection c =
DriverManager.getConnection("jdbc:odbc:oracle","scott","tiger");
Statement s = c.createStatement();
while(rs.next())
{
System.out.println(rs.getString(1)+" "+rs.getString(2)+ "
"+rs.getString(3));
}
rs.close();
s.close(); // close st first.
c.close();
}
catch(SQLException e)
{
System.out.println("Datebase Error"+e.getMessage());
}
catch(Exception e)
{
System.out.println("General Error"+e.getMessage());
}
}
}
import java.sql.*;
import java.util.*;
class Jdbc1
{
public static void main(String[] args)
{
try
{
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Connection c = DriverManager.getConnection("jdbc:odbc:oracle","scott","tiger");
Statement st = c.createStatement();
System.out.println("Executing SQL");
try
{
while(rs.next())
{
System.out.println(rs.getInt("pcode")+ " ; ");
System.out.println(rs.getString("pname"));
System.out.println(rs.getString("price"));
}
}
catch(Exception e)
{
System.out.println("Inside "+e);
}
}
catch(Exception e)
{
System.out.println(e);
}
}
}
import java.sql.*;
import java.util.*;
import java.io.*;
class Jdbc2
{
public static void main(String[] args)
{
try
{
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Connection c = DriverManager.getConnection("jdbc:odbc:oracle","scott","tiger");
Statement st = c.createStatement();
try
{
int x = st.executeUpdate("insert into item values("+y+",
"+st1+","+z+")");
System.out.println("Number of rows affected = "+x);
}
catch(Exception e)
{
System.out.println("Inside "+e);
}
}
catch (Exception e)
{
System.out.println(e);
}
}
}
import java.sql.*;
import java.util.*;
class Jdbc3
{
public static void main(String[] args)
{
try
{
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Connection c =
DriverManager.getConnection("jdbc:odbc:oracle","scott","tiger");
Statement st = c.createStatement();
try
{
}
catch(Exception e)
{
System.out.println("Inside "+e);
}
}
catch(Exception e)
{
System.out.println(e);
}
}
}
import java.sql.*;
import java.util.*;
class Jdbc4
{
public static void main(String[] args)
{
try
{
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Connection c =
DriverManager.getConnection("jdbc:odbc:oracle","scott","tiger");
Statement st = c.createStatement();
try
{
}
catch(Exception e)
{
System.out.println("Inside "+e);
}
}
catch(Exception e)
{
System.out.println(e);
}
}
}
PreparedStatement Class
- Each Statement Query is fresh for the backend and it will get compiled for each
statement return the Result and that is the end of work for the backend. But this
becomes a problem, when we need to execute some statements frequently, like
inserting into a database about 1000 entries like insert into <table name> values
(?,?,?,?) wherein each of the ? represent a column in the table.
- Incase of PreparedStatement the argument changes, but the query remains the same.
We will be using the PreparedStatement object (through ps) to insert values into
the database like this.
ps.setInt (1,13);
ps.setString (2,"Technical");
ps.setString (3,"Hyderebad");
Where the first number, indicate the first (?) and in the sequential order.
- IMP: The syntax is checked at the time of creation of the PreparedStatement object
itself. So when we pass values, the onus of checking is upon the programmer to see
what values are entered.
- To check whether the values are properly entered or not, we can run the
executeUpdate() method to check the number of rows properly entered.
-
-
CallableStatement Class
- We use the CallableStatement object for calling the procedures on the database.
- Procedures allow business logic and rules to be defined at the server level, rather than
relying on applications to replicate and enforce those rules. Procedures are pre-
defined sequence of SQL commands that you can call when you want the function
defined by the stored procedure to be carried out.
- The argument to the prepareCall () method is a String object that will enable the
driver to determine that this is not an ordinary SQL statement and it needs to be
transformed into a form that will be understood by the database system.
- Stored procedures can have arguments that specify input values (called IN
parameters) to the operation. In this case the parameter list between parentheses
following the procedure name. Each parameter is denoted by a ?, as for a
PreparedStatement command and you set the values for the parameters using the set
XXX () methods. For Example
- Procedures can also have parameters for returning a result – referred to as the OUT
parameters and you can set these too. The placeholder for an OUT parameter is ? – no
different from an IN parameter, but the process of setting the parameter is
significantly different.
- For each OUT parameter we must identify the type of the output value as one of the
types defined in the java.sql.Types class, by calling the registerOutParameter ()
method of the CallableStatement object. The first argument is the index position of
the OUT parameter and second argument is the type. For Example:
- Once the OUT parameters have been registered, you then execute the procedure call
in the way we have seen. If a RS is returned, we can access the data from it in the
usual way. To get the value for each OUT parameter, you must call the getXXX ()
method for the CallableStatement object that corresponds to the parameter type, so
for the earlier example, it would be retrieved in the following way:
- Finally a stored procedure may return a value – not as part of the parameter list but as
a return value as for a method. In this case, we can specify the same as:
CallableStatement call = connection.prepareCall(“{? = call getData(?,?)}”);
This has two parameter plus a return value specified by the first ? preceding the =
statement in the string. This placeholder is at index position 1 and the other two
parameters will be at index position 2 and 3.
We will not register the type of the value that is returned by the procedure before
we execute the procedure call and this is
call.registerOutParameter (1,Types.DECIMAL)
- a
- a
-
-
ResultSet Class
- The result of executing a SQL query is returned in the form of an object that
implements the ResultSet interface and that contains the table produced by the SQL
query.
- The RS object contains something known as the cursor that you can manipulate to
refer to any particular row in the RS.
- Initially this points before the first row and by calling the next () method for the RS
object, it will move the cursor to the next position.
- Once we have the row in the RS, we can retrieve the value of any column for the
current row using the getXXX, where the XXX is of all primitive data types and
String. We can read all numeric SQL types using the getString () method.
- The getXXX methods retrieve column values for the current row. You can retrieve
values using either the index number of the column or the name of the column. In
general, using the column index will be more efficient. Columns are numbered from 1
onwards.
- For maximum portability, the RS columns within each row should be read in left – to
– right order and each column should be read only once.
- The Column names used as input in getXXX methods are case insensitive. When
performing a getXXX using a column name, if several columns have the same name,
then the value of the first matching column will be returned.
- The column name option should preferably only be used when column names are
used in the query and for columns that are NOT explicitly named in query, it is best to
use column numbers. If column names are used, there is no way for the programmer
to guarantee that they actually refer to the intended column
ResultSetMetaData Class
- The getMetaData () method for the RS object returns a reference to an object of type
ResultSetMetaData that encapsulates the metadata for the RS.
- The ResultSetMetaData interface declares methods that enable you to get items of
metadata for the RS.
- For each column, we can get the column name and column type by calling the
getColumnName () and getColumnType () methods respectively. In both cases, we
need to specify the column by its index value. The column name is returned as a
String object and the column type is returned as a int values that identifies the SQL
type.
- The Types class in the sql package defines public fields of type int that identify the
SQL types and the names of these class data members are the same as the SQL types
they represent – such as CHAR, VARCHAR, DOUBLE, INT, TIME and so on.
- We can also get the type name of a column as a String by calling the
getColumnTypeName () method with the column number as the argument.
Example 12: Creating a query based on runtime keyboard input from user for a
limited number of columns.
import java.sql.*;
class DBSelectKey
{
public static void main(String[] args)
{
try
{
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Connection c =
DriverManager.getConnection("jdbc:odbc:oracle","scott","tiger");
Statement s = c.createStatement();
ResultSet rs = s.executeQuery(query);
while(rs.next())
{
System.out.println(rs.getString(1)+" "+rs.getString(2)+ "
"+rs.getString(3));
}
rs.close();
s.close(); // close st first.
c.close();
}
catch(SQLException e)
{
System.out.println("Datebase Error"+e.getMessage());
}
catch(Exception e)
{
System.out.println("General Error"+e.getMessage());
}
}
}
Example 13: Creating a query for the number of columns (metadata) returned by
the ResultSet based on keyboard input from user.
// this will return all the columns, based on the metadata gathered about the number of
columns.
import java.sql.*;
class DBSelectKey1
{
public static void main(String[] args)
{
try
{
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Connection c =
DriverManager.getConnection("jdbc:odbc:oracle","scott","tiger");
Statement s = c.createStatement();
ResultSet rs = s.executeQuery(query);
int d = rsmd.getColumnCount();
while(rs.next())
{
for ( int i = 1;i <= d ;i++ ) // remember columns always start from 1
{
System.out.print(rs.getString(i)+" ");
}
System.out.println(); // this is for printing the next row
}
rs.close();
s.close(); // close st first.
c.close();
}
catch(SQLException e)
{
System.out.println("Datebase Error"+e.getMessage());
}
catch(Exception e)
{
System.out.println("General Error"+e.getMessage());
}
}
}
Example 14: Using a GUI TextField to enter query and TextArea to display the
result.
import java.sql.*;
import java.awt.*;
import java.awt.event.*;
c = DriverManager.getConnection("jdbc:odbc:oracle","scott","tiger");
s = c.createStatement();
tf = new TextField(100);
ta = new TextArea(50,100);
tf.addActionListener(this);
addWindowListener(new WinClosing());
add(ta);
add("South",tf);
}
catch(SQLException e)
{
System.out.println("Datebase Error"+e.getMessage());
}
catch(Exception e)
{
System.out.println("General Error"+e.getMessage());
}
}
rs = s.executeQuery(query);
rsmd = rs.getMetaData();
int d = rsmd.getColumnCount();
while(rs.next())
{
for ( int i = 1;i <= d ;i++ ) // remember columns always start from 1
{
ta.append(rs.getString(i)+" ");
}
ta.append("\n"); // this is for printing the next row
}
}
catch(SQLException es)
{}
}