Download Java Database Connectivity API

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts

Microsoft Access wikipedia , lookup

Serializability wikipedia , lookup

Entity–attribute–value model wikipedia , lookup

IMDb wikipedia , lookup

Oracle Database wikipedia , lookup

SQL wikipedia , lookup

Microsoft SQL Server wikipedia , lookup

PL/SQL wikipedia , lookup

Extensible Storage Engine wikipedia , lookup

Ingres (database) wikipedia , lookup

Database wikipedia , lookup

Concurrency control wikipedia , lookup

Microsoft Jet Database Engine wikipedia , lookup

Relational model wikipedia , lookup

Open Database Connectivity wikipedia , lookup

Database model wikipedia , lookup

Clusterpoint wikipedia , lookup

Versant Object Database wikipedia , lookup

ContactPoint wikipedia , lookup

Transcript
Java Database Connectivity API
Java Database Connectivity (JDBC)
Introduction to Java Database Connectivity API
Christopher M. Bourke
[email protected]
I
General API (using interfaces) for Java client code to
connect/interact with a database
I
Database providers (IBM, Oracle, etc.) provide drivers
I
Driver: specific implementation of the API for interacting with a
particular database
Support for
I
I
I
I
I
JDBC: basic step-by-step
Connection
PreparedStatement
ResultSet
Common Java data types ( Integer, Double, String )
JDBC
Reflectively loading a driver
1. Load the database JDBC driver
Note: your particular driver (.jar file) must be in the class or build
path of your project
2. Make a connection to the database
3. Formulate your query(ies) & prepare your statement (set parameters)
4. Execute your query
5. If its a SELECT query:
5.1 Get your result set
5.2 Process your results
6. Clean up your resources (close resources, close connection)
I
For portability, applications written toward JDBC API, not a
particular driver
I
Driver is loaded at run time through reflection
I
Could be made configurable or delegated by some controller
1
2
3
4
5
6
7
8
9
try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
} catch (InstantiationException e) {
...
} catch (IllegalAccessException e) {
...
} catch (ClassNotFoundException e) {
...
}
JDBC
JDBC
Connection
Transactions
Java provides connectivity through java.sql.Connection :
1
2
3
4
5
6
7
8
9
String url = "jdbc:mysql://cse.unl.edu/cselogin";
String u = "cselogin";
String p = "mysqlpasswd";
Connection conn = null;
try {
conn = DriverManager.getConnection(url, u, p);
} catch (SQLException sqle) {
...
}
I
By default, all queries are auto-commit
I
To change this, use conn.setAutoCommit(false)
I
No changes committed until conn.commit() is called
I
Implicitly: new transaction after each commit
I
Able to explicitly rollback using conn.rollback()
I
Some drivers may also support conn.setReadOnly(true)
JDBC
Prepared Statement
Querying – Prepared Statement
Writing to the Database
1
2
3
I
Always good to use PreparedStatement
I
Can define parameters using ?
I
Parameters indexed by 1..n
7
I
Can be reused (parameters reset and required)
8
I
Parameters are safe!
10
I
Special characters are escaped
11
I
Potentially unsafe SQL code is sanitized
4
5
6
9
String query = "INSERT INTO Author " +
"(firstName, lastName) VALUES (?, ?);";
PreparedStatement ps = null;
try {
ps = conn.prepareStatement(query);
ps.setString(1, "Miles");
ps.setString(2, "O’Brien");
ps.executeUpdate();
} catch (SQLException sqle) {
...
}
I
Use executeUpdate() for INSERT , UPDATE , and DELETE
statements
I
Method returns an int (number of affected rows).
Prepared Statement I
Prepared Statement II
Reading from the Database
Reading from the Database
1
2
3
4
5
6
7
8
9
10
11
12
String query = "SELECT title AS booktitle " +
"FROM Book WHERE isbn = ?";
PreparedStatement ps = null;
ResultSet rs = null;
try {
ps = conn.prepareStatement(query);
ps.setString(1, "9788371502118");
rs = ps.executeQuery();
...
} catch (SQLException sqle) {
...
}
Prepared Statement III
I
executeQuery() is for read-only ( SELECT statements)
I
Return a set of results: collections of columns and rows
I
Results are encapsulated in a Java ResultSet object
I
Initially a result set “points” just before the first row
I
Iterating through a ResultSet : rs.next()
I
Returns a boolean: true if the iteration was successful, false
otherwise
I
If successful, the “current” result row is now pointed to
I
Columns can be referenced by name (or alias) using a String
I
Standard getters provide functionality to get-and-cast columns
Cleaning Up
Reading from the Database
1
2
3
4
5
6
7
8
9
10
11
12
13
String query = "SELECT title, numCopies FROM Book";
try {
ps = conn.prepareStatement();
rs = ps.executeQuery();
while(rs.next()) {
String title = rs.getString("title");
Integer numCopies = rs.getInt("numCopies")
System.out.println("We have " + numCopies +
" of " + title);
}
} catch (SQLException sqle) {
...
}
I
Objects hold onto valuable external resources
I
Network traffic (keep alive), limited connection pool, etc.
I
Release resources as soon as they are no longer needed: close()
method
1
2
3
4
5
6
7
8
9
10
try {
if(rs != null && !rs.isClosed())
rs.close();
if(ps != null && !ps.isClosed())
ps.close();
if(conn != null && !conn.isClosed())
conn.close();
} catch (SQLException e) {
...
}
Full Demonstration
JDBC
Full Example Demonstration
Write methods to connect to our Book-Author database and:
I
Retrieve all authors
A full demonstration is available in the unl.cse.jdbc package in the
SVN.
I
Retrieve one book by ISBN
Demonstration based on the student/course enrollment database.
I
Retrieve all books
Best Practice 1
Best Practice Tip 2
Catch & Rethrow Exceptions
ALWAYS use Prepared Statements
I
Most methods explicitly throw SQLException
I
This is a checked exception that must be caught and handled
I
Occurs with DB errors or program bugs
I
Little can be done either way
I
Good to catch, log and rethrow
I
Even better: use a logging utility like log4j
1
...
} catch (SQLException sqle) {
log.error("SQLException: ", sqle);
throw new RuntimeException(sqle);
}
2
3
4
5
When available, in any framework or language, always use prepared
statements
I
Safer
I
Better for batch queries
I
Protects against injection attacks
I
Using just one method: more uniform, less of a chance of a mistake
Injection Attack
Injection Attack
Example
Example
I
Say we pull a string value from a web form ( lastName )
I
Not using a prepared statement:
1
2
String query = "SELECT primaryEmail FROM user " +
"WHERE last = ’"+lastName+"’";
I
Without sanitizing the input, say a user enters:
I
Actual query run:
a’;DROP TABLE user;
SELECT primaryEmail FROM user WHERE last = ’a’;DROP TABLE user;
Good Practice Tip 3
Additional Issues
Enumerate fields in SELECT statements
Additional Issues
I
Using SELECT * ... grabs all fields even if you don’t use them
I
Be intentional about what you want/need, only the minimal set
I
Allows the database to optimize, reduces network traffic
I
Protects against table changes
I
Security Issues
I
I
I
I
Efficiency Issues
I
I
I
Resources
Where/how should database passwords be stored?
Good security policy: assume an attacker has your password & take
the necessary precautions (secure the server and network)
Do not store sensitive data unencrypted
Repeat: close your resources
Connection Pools
Good normalization, design, & practice
Log4j I
I
MySQL 5.1 Reference Manual
(http://dev.mysql.com/doc/refman/5.1/en/index.html)
I
Home: http://logging.apache.org/
I
MySQL Community Server (http://www.mysql.com/downloads/)
I
I
MySQL Workbench – a MySQL GUI (http://wb.mysql.com/)
Standard output is not appropriate for deployed applications (may not
exist, certainly no one is “listening” to it)
I
Connector/J – MySQL JDBC connector
(http://www.mysql.com/downloads/connector/j/)
I
Logging provides valuable debugging, metrics, and auditing
information
I
Stanford’s Introduction to Databases free online course:
http://db-class.com/
I
Provides runtime configuration, formatting, rolling files, etc.
Log4j II
Exercise
I
Supports granularity in different levels of logging ( ERROR to DEBUG )
I
Usage: give each loggable class a static logger:
1
2
private static org.apache.log4j.Logger log =
Logger.getLogger(MyClass.class);
I
Then use it: log.error("SQLException: ", e);
I
Configure using a log4j.properties file (must be in the class path)
I
Or: call BasicConfigurator.configure(); in your main to have a
default setup
Write basic CRUD methods for the Employee / Person tables
by writing static methods to insert, delete, retrieve and update
records in both tables.