ppt

advertisement

JDBC:

Java Database Connectivity

1

Introduction to JDBC

• JDBC is used for accessing databases from Java applications

• Information is transferred from relations to objects and vice-versa

– databases optimized for searching/indexing

– objects optimized for engineering/flexibility

2

Compilation

• When executing an SQL statement via

JDBC, it is not checked for errors until it is run (Not checked during compilation)

3

Why Access a Database with

Java?

• There are queries that can not be computed in SQL:

– Given a table Bus(Source, Destination) find all pairs of places that it is possible to travel between (paths of any length)

• Java allows for a convenient user interface to the database

4

Six Steps

• Load the driver

• Establish the Connection

• Create a Statement object

• Execute a query

• Process the result

• Close the connection

5

Packages to Import

• In order to connect to the Oracle database from java, import the following packages:

– java.sql.*; (usually enough)

– javax.sql.* (for advanced features, such as scrollable result sets)

6

JDBC Architecture

Driver

Manager

Application Driver

The application creates a driver instance and registers it with the DriverManager.

The DriverManager connects a driver to the DB

The DriverManager keeps track of registered driver instances and their connections to DB’s.

The Driver “talks” to a particular database through the connection

Connecting

Driver

Manager

Application

Driver

1. Initializing a driver: new oracle.jdbc.driver.OracleDriver()

2. Registering it with the DriverManager:

DriverManager.registerDriver(…)

3. Getting a connection:

DriverManager.getConnection(URL)

Note:

• Stages 1+2 may be combined with

Class.forName(“oracle.jdbc.driver.OracleDriver");

• In Stage 3, the Manager tries all drivers and assigns a connection to the first driver that succeeds.

8

Connecting to the Database

String path = "jdbc:oracle:thin:";

String host = "sol4";

String port = "1521";

String db = "stud";

String login = “gidi";

String password = “password”;

String url = path + login + "/" + password +

"@" + host +":" + port + ":" + db;

Class.forName("oracle.jdbc.driver.OracleDriver");

Connection con = DriverManager.getConnection(url);

9

Query methods

1. Statement createStatement()

returns a new Statement object

“prepared” because it already includes the query string

2. PreparedStatement prepareStatement(String sql)

returns a new PreparedStatement object

• Both are used to send SQL commands to the DB

• Both are created by the connection

Statements

• Statements are used for queries that are only issued once.

• A statement can activate:

1.

executeQuery(String query) : for queries that don’t change the DB (select)

2.

executeUpdate(String query) : for queries which affect the DB (create, delete, drop, etc.)

11

executeQuery

String queryStr =

"SELECT * FROM Sailors " +

"WHERE Name = 'joe smith'";

No semicolon(;) !!!

Statement stmt = con.createStatement();

ResultSet rs = stmt.executeQuery(queryStr);

• The executeQuery method returns a ResultSet object representing the query result.

12

executeUpdate

String deleteStr =

“DELETE FROM Sailors " +

"WHERE sid = 15";

Statement stmt = con.createStatement(); int delnum = stmt.executeUpdate(deleteStr);

No semicolon(;) !!!

• executeUpdate returns the number of rows modified.

13

PreparedStatement motivation

• Suppose we would like to run the query

SELECT * FROM Emp where name=‘moshe’;

• But we would like to run this for all employees

(separately), not only moshe…

• Could we create a variable instead of ‘moshe’ which would get a different name every time??..

14

Prepared Statements

• Prepared Statements are used for queries that are executed many times with possibly different contents.

• A PreparedStatement object includes the query and is prepared for execution.

• Question marks can be inserted as variables.

-setString(i, value)

-setInt(i, value)

The i-th question mark is set to the given value.

15

Querying with PreparedStatement

String queryStr =

"SELECT * FROM Sailors " +

"WHERE Name = ? and Rating < ?”;

PreparedStatement pstmt = con.prepareStatement(queryStr); pstmt.setString(1, “Joe”); pstmt.setInt(2, 8);

Value to insert

1 st question mark

ResultSet rs = pstmt.

executeQuery ();

16

Affecting the DB with

PreparedStatement

String deleteStr =

“DELETE FROM Boats " +

"WHERE Name = ? and Color = ?”;

PreparedStatement pstmt = con.prepareStatement(deleteStr); pstmt.setString(1, “Fluffy”); pstmt.setString(2, "red"); int delnum = pstmt.

executeUpdate ();

17

Statements vs.

PreparedStatements: Be Careful !

• Are these the same? What do they do?

String val = “Joe”;

PreparedStatement pstmt = con.prepareStatement(“select * from Sailors where sname=?”); pstmt.setString(1, val);

ResultSet rs = pstmt.executeQuery();

String val = “Joe”;

Statement stmt = con.createStatement( );

ResultSet rs = stmt.executeQuery(“select * from

Sailors where sname=” + val);

18

Statements vs.

PreparedStatements: Be Careful !

• Will this always work?

Statement stmt = con.createStatement( );

ResultSet rs = stmt.executeQuery(“select * from R where A =‘ ” + val + “ ’ ”);

• The moral: When getting input from the user, always use a PreparedStatement

19

Statements vs.

PreparedStatements: Be Careful !

• Will this work?

PreparedStatement pstmt = con.prepareStatement(“select * from ?”); pstmt.setString(1, "Sailors");

No! will attempt to insert ‘sailors’, and result in:

Select * from ‘sailors’

We can put ? only instead of values

20

Statement

ExecuteQuery(String Q)

ResultSet createStatement()

Statement

Connection

ExecuteUpdate(String Q) int

Prepared

Statement setString(int num,String val)

ExecuteQuery() prepareStatement

(String Q)

Prepared

Statement

Connection

ExecuteUpdate()

ResultSet int

21

ResultSet

• A ResultSet is an object which contains the result of a query- a “table”.

• Only one ResultSet per Statement can be open at once(!).

• A ResultSet maintains a cursor pointing to its current row of data.

• The ' next ' method moves the cursor to the next row

• As of JDBC 2.0, scrollable ResultSets are available, which also include ‘ previous ’, ’ first ’,

‘ last ’, etc..

ResultSet cont.

• Any methods on the resultSet will occur on the current row.

• The cursor is positioned before the first row upon creation.

Statement stmt=con.createStatement();

ResultSet rs = stmt.executeQuery

("SELECT * FROM Table1"); while (rs.next()) {

//something…

}

ResultSet methods

• Getting the value in some column (for the current row):

getString(int columnNum);

String s = rs.getString(“column1");

getString(String columnName);

getInt(int columnNum);

getInt(String columnName);

Etc…

To check if null was returned, you have to use wasNull() on the ResultSet after getting the value.

The driver maps SQL types (varchar, number,…) to the appropriate Java method (getString, getInt…)

24

Mapping Java

Types to SQL

Types

SQL type

Java method

25

Example revisited

Statement stmt = con.createStatement();

ResultSet rs = stmt.executeQuery("SELECT a, b, c FROM

Table1");

// retrieve and print the values for the current row while (rs.next()) { int i = rs.getInt("a");

String s = rs.getString("b"); float f = rs.getFloat("c");

System.out.println("ROW = " + i + " " + s + " " + f);

}

26

Advanced ResultSets

1. TYPE_FORWARD_ONLY: The default, simple RS.

2. TYPE_SCROLL_INSENSITIVE : Scrollable RS, does not modify when the DB is modified

3. TYPE_SCROLL_SENSITIVE : Scrollable RS, if its values are changed in the DB, they will also change in the RS.

In addition, a ResultSet may be either:

1. CONCUR_READ_ONLY: the programmer cannot change the ResultSet (default)

2. CONCUR_UPDATABLE: the programmer can change the ResultSet

27

Creating advanced ResultSets

For Statement:

Statement stmt = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,

ResultSet.CONCUR_UPDATABLE);

ResultSet rs = stmt.executeQuery( "SELECT * from emp");

For PreparedStatement:

PreparedStatement pstmt= con.prepareStatement("SELECT * FROM Emp where Eid=?” ,

ResultSet.TYPE_SCROLL_SENSITIVE,

ResultSet.CONCUR_UPDATABLE); pstmt.setInt(1, "1000010");

ResultSet rs = stmt.executeQuery();

28

ResultSetMetaData

An object created by the ResultSet which holds information about its columns

ResultSetMetaData rsmd = rs.getMetaData(); int numcols = rsmd.getColumnCount();

} for (int i = 1 ; i <= numcols; i++) { if (i > 1) System.out.print(",");

System.out.print(rsmd.getColumnLabel(i));

29

Printing Query Output:

Result Set (2)

} while (rs.next()) { for (int i = 1 ; i <= numcols; i++) { if (i > 1) System.out.print(",");

System.out.print(rs.getString(i));

}

System.out.println("");

30

Cleaning Up After Yourself

• Remember to close the Connections,

Statements, PreparedStatements and

ResultSets

Highly recommended con.close(); stmt.close(); pstmt.close(); rs.close();

Recommended

Optional (Will otherwise be closed by its calling statement)

31

Dealing With Exceptions

• An exception may be chained: catch (SQLException e) { while (e != null) {

//human readable message about the exception

System.out.println(e.getMessage());

//String describing the reason of the exception

System.out.println(e.getSQLState());

} }

//driver-dependant code for the exception

System.out.println(e.getErrorCode()); e = e.getNextException();

32

What will this output?

String table1=“create table table1(col1 integer, col2 integer)”;

Statement st=con.createStatement(); int resCreate=st.executeUpdate(table1);

PreparedStatement ps1 = con.prepareStatement(“insert into Table1 values(?,?)”); for(int i=0;i<10;i++){ ps1.setInt(1,i); ps1.setInt(2,i*i); ps1.executeUpdate();

}

Statement st2=con.createStatement();

ResultSet rs=executeQuery(“select col2 from Table1”); while(rs.next()){

System.out.println(rs.getInt(1)); }

33

Timeout

• You can use Stmnt.setQueryTimeOut(int secs) to set a timeout for the driver to wait for a statement to be completed

• If the operation is not completed in the given time, an SQLException is thrown

34

Transactions in JDBC

35

Transactions

• Transaction = 2 or more statements which must all succeed (or all fail) together

• If one fails, the system must reverse all previous actions

• Also can’t leave DB in inconsistent state halfway through a transaction

• COMMIT = complete transaction

• ROLLBACK = abort

36

Example

• Suppose we want to transfer money from bank account 13 to account 72:

PreparedStatement pstmt = con.prepareStatement(“update BankAccount set amount = amount + ?

where accountId = ?”); pstmt.setInt(1,-100); pstmt.setInt(2, 13); pstmt.executeUpdate(); pstmt.setInt(1, 100); pstmt.setInt(2, 72); pstmt.executeUpdate();

What happens if this update fails?

37

Transaction Management

• The connection has a state called AutoCommit mode

• if AutoCommit is true, then every statement is automatically committed

• if AutoCommit is false, then every statement is added to an ongoing transaction

• Default: true

38

AutoCommit

con.setAutoCommit(boolean val)

• If you set AutoCommit to false, you must explicitly commit or rollback the transaction using Connection.commit() and

Connection.rollback()

39

Fixed Example

con.setAutoCommit(false); try {

PreparedStatement pstmt = con.prepareStatement(“update BankAccount set amount = amount + ?

where accountId = ?”); pstmt.setInt(1,-100); pstmt.setInt(2, 13); pstmt.executeUpdate();

} pstmt.setInt(1, 100); pstmt.setInt(2, 72); pstmt.executeUpdate(); con.commit(); catch (Exception e) { con.rollback();

40

• Useful link regarding JDBC: http://java.sun.com/j2se/1.3/docs/guide/jdbc/ getstart/GettingStartedTOC.fm.html

41

Download