36
CE203 - Application Programming Autumn 2013 CE203 Part 5 1 Part 5

CE203 - Application Programming Autumn 2013CE203 Part 51 Part 5

Embed Size (px)

Citation preview

Page 1: CE203 - Application Programming Autumn 2013CE203 Part 51 Part 5

CE203 - Application Programming

Autumn 2013 CE203 Part 5 1

Part 5

Page 2: CE203 - Application Programming Autumn 2013CE203 Part 51 Part 5

CE203 Part 5 2Autumn 2013

Using JDBC 1

JDBC (Java Database Connectivity) allows Java programs to access and manipulate relational databases using statements written in the SQL language.

The JDBC application programming interface makes no assumption about the database other than that it can be accessed using SQL. Any database supporting SQL may, in theory, be used (we will use MySQL).

Page 3: CE203 - Application Programming Autumn 2013CE203 Part 51 Part 5

CE203 Part 5 3Autumn 2013

Using JDBC 2

Communication to the database is by Strings containing SQL statements.

Communication from the database is in rows of a ResultSet from the relations queried.

Page 4: CE203 - Application Programming Autumn 2013CE203 Part 51 Part 5

CE203 Part 5 4Autumn 2013

Using JDBC 3

SQL is not as standard as one would like. Functionality varies and syntax varies across DBMSs.

JDBC ignores this problem!

It allows any String to be passed through to the underlying DBMS driver. This gives the application maximum scope for sending SQL statements, but it runs the risk that a statement may be in error on one DBMS but not on another.

Page 5: CE203 - Application Programming Autumn 2013CE203 Part 51 Part 5

JDBC – General Idea

Autumn 2013 CE203 Part 5 5

http://www.dbvis.com/doc/6.0/doc/ug/getConnected/getConnected.html

Page 6: CE203 - Application Programming Autumn 2013CE203 Part 51 Part 5

CE203 Part 5 6Autumn 2013

Using JDBC 4

Programs that use JDBC should import the relevant classes from the java.sql package:

import java.sql.*;

To use JDBC it is necessary to load a JDBC driver for the database system, establish a connection and create a Statement object which will be used to execute SQL statements.

Page 7: CE203 - Application Programming Autumn 2013CE203 Part 51 Part 5

CE203 Part 5 7Autumn 2013

Using JDBC 5

The first step in the use of JDBC is loading a driver class for the database system – drivers are available for many different systems. The driver class for MySQL is called com.mysql.jdbc.Driver.To load an external class we use the forName method from the Class class – this takes a string argument, the name of the class to be loaded, and will throw an exception of type ClassNotFoundException if the file containing the class cannot be found in the class path. (Note that the driver will not be found in the Java libraries so its location needs to be specified in the class path when running the program.)

Page 8: CE203 - Application Programming Autumn 2013CE203 Part 51 Part 5

CE203 Part 5 8Autumn 2013

Using JDBC 6

Having loaded the driver it is then necessary to establish a connection with the database – this is done using a getConnection method from the DriverManager class in the java.sql package. The simplest such method takes just a string argument, a database URL in the form jdbc:protocol:databaseid. (For MySQL the protocol is mysql.) An exception of type SQLException will be thrown if the connection cannot be established.The next slide shows a typical initialisation phase of a program using JDBC.

Page 9: CE203 - Application Programming Autumn 2013CE203 Part 51 Part 5

CE203 Part 5 9Autumn 2013

Using JDBC 7

Connection connection = null;try{ Class.forName("com.mysql.jdbc.Driver"); connection = DriverManager.getConnection( "jdbc:mysql://localhost/mydatabase");}catch (ClassNotFoundException e){ System.out.println("driver not found");}catch (SQLException e){ System.out.println("connection failed"); }

Page 10: CE203 - Application Programming Autumn 2013CE203 Part 51 Part 5

CE203 Part 5 10Autumn 2013

Using JDBC 8

User identification and a password are often needed to access a database; if this is the case a different version of the getConnection method must be used. This version has three string arguments, the database URL, the user id and the password:connection = DriverManager.getConnection( "jdbc:mysql://localhost/mydatabase", "fredsmith", "1234");

Page 11: CE203 - Application Programming Autumn 2013CE203 Part 51 Part 5

CE203 Part 5 11Autumn 2013

Using JDBC 9

Having established a connection to the database we need to create a Statement object to execute SQL statements. This is done using the createStatement method declared in the Connection interface. An exception of type SQLException may again be thrown if there are problems accessing the database.

Page 12: CE203 - Application Programming Autumn 2013CE203 Part 51 Part 5

CE203 Part 5 12Autumn 2013

Using JDBC 10

Statement statement = null;try{ statement = connection.createStatement();}catch (SQLException e){ System.out.println( "failed to access database"); }

Page 13: CE203 - Application Programming Autumn 2013CE203 Part 51 Part 5

CE203 Part 5 13Autumn 2013

Executing Queries 1

Once a Statement object has been created it can be used as many times as required to perform SQL queries and updates. Queries are performed using the executeQuery method, which takes a string argument and returns a result of type ResultSet: ResultSet rs = statement.executeQuery( "SELECT name FROM employees");

An exception of type SQLException may be thrown if the string is not a valid SQL query.

Page 14: CE203 - Application Programming Autumn 2013CE203 Part 51 Part 5

CE203 Part 5 14Autumn 2013

Executing Queries 2

The result of an SQL query will normally be a set of rows of database entries. We can use the result set object to access these in a style similar to the use of iterators, although the place marker is positioned at a row rather than between adjacent ones. The ResultSet interface declares a method called next which will advance to the next row if there is one, returning a boolean value that can be used to detect whether there are any rows left.Note that an initial call to next must be made to get to the first row, and to guarantee correct behaviour processing of the result set must be completed before any other result set is retrieved using the Statement object.

Page 15: CE203 - Application Programming Autumn 2013CE203 Part 51 Part 5

CE203 Part 5 15Autumn 2013

Executing Queries 3

The entries in the current row of the result set can be accessed by applying the method getObject. This method takes one argument, indicating the column. Note that the first column has the index 1, not 0.The method returns an object whose type will depend on the type of the database entry.The code on the next slide will print the names and salaries of the employees from a database table and also the total of the salaries. (We assume that salaries are stored in the database as integers.)

Page 16: CE203 - Application Programming Autumn 2013CE203 Part 51 Part 5

CE203 Part 5 16Autumn 2013

Executing Queries 4

ResultSet rs = statement.executeQuery( "SELECT name,salary FROM employees");int totalSal = 0;while (rs.next()){ System.out.print("Name: " + rs.getObject(1)); System.out.println("; Salary: " + rs.getObject(2)); totalSal += ((Integer)rs.getObject(2)).intValue();}System.out.println("Total Salary: " + totalSal);

Page 17: CE203 - Application Programming Autumn 2013CE203 Part 51 Part 5

CE203 Part 5 17Autumn 2013

Using Metadata 1

We can apply the method getMetaData to a result set to obtain information about the results obtained from the database, such as the number of columns, their names and the types of the objects.The method returns an object of type ResultSetMetaData to which we can apply methods such as getColumnCount and getColumnName.The code on the next slide will print details of all employees with a salary of more than £30000 – we do not need to know anything about the table other than its name and the name and format of the salary column, since the information about columns is extracted from the metadata.

Page 18: CE203 - Application Programming Autumn 2013CE203 Part 51 Part 5

CE203 Part 5 18Autumn 2013

Using Metadata 2

ResultSet rs = statement.executeQuery( "SELECT * FROM employees WHERE salary>30000");ResultSetMetaData md = rs.getMetaData();while (rs.next()){ int i; for (i = 1; i<=md.getColumnCount(); i++) System.out.print( md.getColumnName(i) + ": " + rs.getObject(i)); System.out.println();}

Page 19: CE203 - Application Programming Autumn 2013CE203 Part 51 Part 5

CE203 Part 5 19Autumn 2013

Executing Updates

To update a table in a database using SQL INSERT, UPDATE or DELETE statements we must apply the executeUpdate method to a Statement object. This method returns a value of type int, which indicates the number of rows in the table after the update:int i = statement.executeUpdate( "DELETE FROM employees WHERE salary<1000");System.out.println( "Employees table now has " + i + " rows");

Page 20: CE203 - Application Programming Autumn 2013CE203 Part 51 Part 5

CE203 Part 5 20Autumn 2013

Using the execute Method 1

If it is necessary to perform actions such as creating a new table or removing a table the execute method from the Statement interface should be used. This method can be used with any SQL statement as an argument so it could potentially generate a result set. Since in most cases it will not do so, the method does not return a result set, but instead returns a boolean value indicating whether a result set has been generated. If a set has been generated it can be retrieved using the getResultSet method.

Page 21: CE203 - Application Programming Autumn 2013CE203 Part 51 Part 5

CE203 Part 5 21Autumn 2013

Using the execute Method 2

To use the execute method to create a new table we would simply use a statement such asstatement.execute( "CREATE TABLE employees(………)");

To apply an arbitrary SQL command we might use code of the formif (statement.execute(s)){ ResultSet r = statement.getResultSet(……); // use metadata to find out about result set}

Page 22: CE203 - Application Programming Autumn 2013CE203 Part 51 Part 5

CE203 Part 5 22Autumn 2013

Closing Connections

After access to a database has been completed it is desirable to close connections to release resources. The close method should be applied to any Statement objects that were created and then to the Connection object:try{ statement.close(); connection.close();}catch (SQLException e){ System.out.println( "problems closing database"); }

Page 23: CE203 - Application Programming Autumn 2013CE203 Part 51 Part 5

CE203 Part 5 23Autumn 2013

Prepared Statements 1

These are really Parameterised Statements (or Stored Procedures). The idea is that you can write an SQL statement with question marks as placeholders. e.g.:

String updateString = "update COFFEES " + "set SALES = ? " "where COF_NAME

like ?";

has two placeholders.

Page 24: CE203 - Application Programming Autumn 2013CE203 Part 51 Part 5

CE203 Part 5 24Autumn 2013

Prepared Statements 2

Suppose we have the declaration:

PreparedStatement updateSales;

Then, having created a connection, say con, we can prepare a PreparedStatement by writing:

updateSales = con.prepareStatement(updateString);

(nothing has gone to the database yet!)

Page 25: CE203 - Application Programming Autumn 2013CE203 Part 51 Part 5

CE203 Part 5 25Autumn 2013

Prepared Statements 3

Suppose we want to put the prepared statement in a loop, and each time round the loop a different value from an array is to be substituted for the parameters or placeholders, e.g.:

for (int i = 0; i < len; i++) {updateSales.setInt(1,salesForWeek[i]);updateSales.setString(2, coffees[i]);updateSales.executeUpdate();

}

(the first parameter of the setXXX method is the index of the placeholder to be set.)

Page 26: CE203 - Application Programming Autumn 2013CE203 Part 51 Part 5

CE203 Part 5 26Autumn 2013

Transactions 1

You often want to ensure that for a group of statements either all succeed or none succeed. To have just some succeed would leave the database in an inconsistent state. Such a group of statements is called a transaction.

Normally, each individual statement is treated as a transaction. This is called auto-commit mode.

To disable auto-commit mode for a Connection con to a database, write:

con.autoCommit(false);

Page 27: CE203 - Application Programming Autumn 2013CE203 Part 51 Part 5

CE203 Part 5 27Autumn 2013

Transactions 2

To re-enable auto-commit, write:con.autoCommit(true);

To implement a transaction consisting of statements s1; s2;...;sn first disable auto-commit and then write:

s1;s2;...sn;con.commit();

Page 28: CE203 - Application Programming Autumn 2013CE203 Part 51 Part 5

CE203 Part 5 28Autumn 2013

Rollback

Because the JDBC methods executeXXX throw SQLExceptions (see the documentation) the sequence above must be in a try block with an appropriate catch to catch the exception.

If an exception occurs in the sequence, access should be prevented to the partially processed database in the current program. This is done by calling:

con.rollback();

Page 29: CE203 - Application Programming Autumn 2013CE203 Part 51 Part 5

CE203 Part 5 29Autumn 2013

Database Meta Data

Many properties of the database itself may be obtained through the DatabaseMetaData interface.

The meta data is obtained from the connection:

DatabaseMetaData dbmd = con.getMetaData();

This allows you to retrieve information such as: – Database Product Name

– Types of table supported by database

– Driver Name

– Whether Transactions are supported.

Page 30: CE203 - Application Programming Autumn 2013CE203 Part 51 Part 5

CE203 Part 5 30Autumn 2013

JTables

JTable is a complex class (see on-line documentation). It is not only used as a means of sending data to the user, but also as a means of getting user feedback into a program. For example, the JTable and associated classes and interfaces can be used to build a spread-sheet.

Here is a screenshot from Sun’s Java JDBC tutorial:

Page 31: CE203 - Application Programming Autumn 2013CE203 Part 51 Part 5

JDBC: API

Autumn 2013 CE203 Part 5 31

http://www.eeng.dcu.ie:8888/ee557/g2/584-EE.html

Page 32: CE203 - Application Programming Autumn 2013CE203 Part 51 Part 5

JDBC: API

Autumn 2013 CE203 Part 5 32

http://java.boot.by/ocpjp7-upgrade/ch02s05.html

Page 33: CE203 - Application Programming Autumn 2013CE203 Part 51 Part 5

CE203 Part 5 33Autumn 2013

JDBC Reading

JDBC Tutorial:

http://docs.oracle.com/javase/tutorial/jdbc/index.html

Use of JTables with JDBC:

http://docs.oracle.com/javase/tutorial/uiswing/components/table.html

Page 34: CE203 - Application Programming Autumn 2013CE203 Part 51 Part 5

CE203 Part 5 34Autumn 2013

JDBC Issues 1

Remember … • SQL is not as standard as one would like. Functionality

varies and syntax varies across DBMSs.

• JDBC ignores this problem!

It allows any String to be passed through to the underlying DBMS driver. This gives the application maximum scope for sending SQL statements, but it runs the risk that a statement may be in error on one DBMS but not on another.

Page 35: CE203 - Application Programming Autumn 2013CE203 Part 51 Part 5

CE203 Part 5 35Autumn 2013

JDBC Issues 2

More importantly…

• Consider security issues such as SQL Injection• Explore this issue (e.g. start with Wikipedia) and then try

to break your own JDBC code• Start with an applet that allows user input which is then

passed to a database via JDBC (e.g. Liang, chapter 37)• There will be much more on security issues in the guest

lecture

Page 36: CE203 - Application Programming Autumn 2013CE203 Part 51 Part 5

Alternatives to JDBC

• Object Databases

(e.g. db4objects: http://www.db4o.com/)• Object-relational mapping• XML output• Object serialization• NoSQL (see http://nosql-database.org)

... Collections framework

...

Exercise: Explore pros and cons of each of these approaches.

Autumn 2013 CE203 Part 5 36