9 Java and MySQL
9 Java and MySQL
Prog - 1 Prog - 2
DBMS independence
• It comes as part of the J2SDK
– so we don’t need a special element in classpath
DBMS User User User – but we do need
Views Views Views
• import java.sql.* ;
External/Conceptual Logical data
mapping independence
Conceptual
View • We can call JDBC from a free-standing application, an applet, or a servlet
Conceptual/Internal Physical data
– the structure of the calling code is the same
mapping independence
Internal
View
Prog - 3 Prog - 4
• There are lots of classes in the API: but the most important ones are • Each DBMS has (at least one) Java “driver”
– Connection deals with the link to the DBMS – we load it using an incantation
– Statement deals with a single SQL statement – with its own try/catch block
– ResultSet deals with the rows returned when we execute an SQL try {
Class.forName("com.mysql.jdbc.Driver") ; }
SELECT. It has a “cursor” that moves through the rows catch(Exception e) {
System.out.println("Failed to load driver "
+ e.getMessage()) ;
• The steps that we go through: return ; }
– dynamically load a driver for the DB that we wish to use
– get that driver to establish a connection – there are different strings for different types of database, e.g.
sun.jdbc.odbc.JdbcOdbcDriver
– set up a statement and execute it
oracle.jdbc.driver.OracleDriver
– (if appropriate) loop through the result set
– when finished, close the statement and the connection
• The file containing the driver must be in the run-time classpath (e.g. in the
..\jre\lib\ext folder of the J2SDK)
Prog - 5 Prog - 6
1
What to Import SQLException
• You will need at least the first two, and probably the rest • The rest of the methods all throw SQLException
• So we wrap the rest of the JDBC code in a try/catch block
import java.sql.Connection; import
java.sql.DriverManager; import try {
java.sql.PreparedStatement; import // make the connection
java.sql.ResultSet; // set-up the statement & execute it
// loop through the result-set
import java.sql.SQLException;
}
import java.sql.Statement; catch(SQLException e) {
System.out.println("SQLException: "
+ e.getMessage()) ;
}
finally {
// release any DBMS resources
}
Prog - 7 Prog - 8
• Making the connection involves identifying ourselves to the • Now we have an object (con) of class Connection, we can proceed
particular DB we wish to use – suppose our SQL statement is a SELECT
Prog - 9 Prog - 10
• The so-called getXXX methods will retrieve values from the current row of • Each getXXX method has two forms: we can specify either the column
the result set position or the column name
– in the example on the previous slide – in the previous example, the following would be equivalent:
SELECT This, That FROM MyTab rs.getInt(1)
– suppose the column This has the data type INT and the column rs.getInt("This")
That has the data type CHAR(10)
2
An example all on one slide (once the driver's loaded) Releasing resources
Prog - 13 Prog - 14
Prog - 15 Prog - 16
• The above example exposes the username/password • On slide 9 we had a Statement object that was used on only two lines
kms,pwd stmt = con.createStatement() ;
ResultSet rs = stmt.executeQuery("SELECT ...") ;
– this is not good
• One approach is to have a dummy user e.g. scott/tiger
• The statement object seems to be on-stage very briefly …
• The user rb1 then gives limited access to the dummy user
• But under some circumstances it may be useful (or essential) to work in
GRANT SELECT ON MyTab TO scott ;
three stages
– prepare a statement using placeholders
– and then rewrites the code so that the user is scott/tiger
– fill in the blanks
getConnection(“\\localhost\mydb”,”scott”,”tiger”); – execute the statement
• If the connection is obtained from a pool (previous slide) then the • The class is now PreparedStatement (not Statement): we declare (say)
username/password are hidden anyhow pstmt in the same place (Slide 9)
Prog - 17 Prog - 18
3
Prepared statements, continued Prepared statements, continued
• Fill in the blank(s): • There is a whole family of setXXX methods, one for each type
pstmt.setString(1,"Blue Mountain") ;
• But why would we want to use prepared statements?
Placeholder value
Placeholder number
– there are two main circumstances ...
Prog - 19 Prog - 20
• It can make it easier to manage the transition from Java to SQL CREATE TABLE FileArchive (
– e.g. we no longer need to know how to quote strings in SQL Name VARCHAR2(40),
FDate DATE,
FStoreDate DATE,
Ftext LONG) ;
• It would be unfeasibly hard to turn these into literals in an ordinary INSERT INTO
– (these dates will actually be date-and-time)
• .. and we want to write a program to store a named file in this table
– the Name is easy (just a string)
– the Dates aren’t: we decide to use java.sql.Timestamp
– the file is quite hard!
Prog - 21 Prog - 22
Prog - 23