* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Download Java Database Connectivity API
Survey
Document related concepts
Microsoft Access wikipedia , lookup
Serializability wikipedia , lookup
Entity–attribute–value model wikipedia , lookup
Oracle Database wikipedia , lookup
Microsoft SQL Server wikipedia , lookup
Extensible Storage Engine wikipedia , lookup
Ingres (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
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.