* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Download driver
Commitment ordering wikipedia , lookup
Microsoft Access wikipedia , lookup
Entity–attribute–value model wikipedia , lookup
Ingres (database) wikipedia , lookup
Serializability wikipedia , lookup
Oracle Database wikipedia , lookup
Extensible Storage Engine wikipedia , lookup
Microsoft SQL Server wikipedia , lookup
Concurrency control wikipedia , lookup
Microsoft Jet Database Engine wikipedia , lookup
Clusterpoint wikipedia , lookup
Versant Object Database wikipedia , lookup
Relational model wikipedia , lookup
Java Database Connectivity: JDBC Representation and Management of Data on the Internet Database Connectivity Relational databases ◦ Manage all information generated by businesses ◦ Centric to business applications ◦ Established and Mature Application developers require standard interface to relational databases ◦ Change in database vendor should not require change in application programs Relational Database Properties Fundamental Properties ◦ Tables, Indexes, Triggers, Stored Procedures, Transactions ◦ ACID Properties – Atomicity, Consistency, Isolation, Durability Data Definition (DDL) ◦ Manage Database Objects ◦ For example, Create and delete tables, indexes, stored procs Queries (DML) ◦ Read, write, or delete information between one or more related tables ◦ SQL ACID Properties Atomic ◦ Updates in a transaction either occur or don’t occur Consistent ◦ Transaction always preserves the system state Isolated ◦ Concurrent transactions occur as if occurring in isolation (there is no partial view of another transaction) Durable ◦ Committed transactions survive failures of any type (e.g., communication, server). Transaction logging allows recovery. SQL Statements (DML) Insert INSERT into Course(CourseID, Name, ProfessorID) values (162, ‘Java101’, 12); Update UPDATE Course set NumStudents = 0; Delete DELETE from Course where (ProfessorID = 100 ); Select SELECT Name from Course where CourseID = 162; Relational DBs and Objects Persistent objects must be mapped to relation tables Relation Tables Class Diagram Professor ProfID Name Student 0..* 0..* teaches Professor 1 takes Course 1..* 0..* prereq Course CourseID ProfID Name Location Time Student StudentID Name BillingInfo 0..* Prereq CourseID PrereqCourseID Takes StudentID CourseID What is JDBC? A pure Java API for database communication similar to ODBC (JDBC created in 1995) ◦ JDBC and ODBC are based on the same standard: X/Open's SQL Call-Level Interface A set of classes that perform database transactions ◦ Connect to relational databases ◦ Send SQL commands ◦ Process results JDBC2 has been defined (part of Java 2 in 1998) ◦ NOT universally supported ◦ Additional features such as scrollable cursors, batch updates Benefits of JDBC No proprietary DB code (although passthrough is supported) Don’t have to rely on single vendor...ever Don’t need to make DB vendor decision early Easier for DB vendors ◦ Don’t need to provide a query language, only implement API ◦ Only low-level support JDBC Architecture Java Application JDBC API JDBC Driver Manager JDBC Driver API (T1) JDBCODBC Bridge ODBC Driver (T2) Java Portion Native Portion (T3) Java Client Server Component Proprietary, vendor-specific database access protocol (T4) Java Driver to vendor's protocol JDBC Drivers Provided with Sun's JDK JDBC Classes java.sql.* provides classes used by an application <<Interface>> Statement <<Singleton>> DriverManager <<Interface>> Connection <<Interface>> PreparedStatement <<Interface>> ResultSet <<Interface>> DatabaseMetaData <<Interface>> CallableStatement <<Interface>> ResultSetMetaData JDBC Statement Types (2) Callable Statements ◦ Vendor specific invocation of stored procedures String sql = “begin ? := Class.registerStudent(?, ?, ?, ?); CallableStatement stmt = connection.prepareCall(sql); stmt.registerOutParameter(1,Types.Integer); stmt.setInt(2, studentID); stmt.setString(3, classList); stmt.registerOutParameter(3, OracleTypes.CURSOR); stmt.registerOutParameter(4, OracleTypes.CURSOR); stmt.execute(); int numClasses = stmt.getInt(1); ResultSet classList = stmt.getObject(3); ResultSet unavailableClassList = stmt.getObject(4); … classList.close(); unavailableClassList .close(); stmt.close(); - Close ALL result sets !!! Result Sets Contain rows from query results Greatly enhanced in JDBC 2.0 (Java 2) ◦ ResultSet maintains the current row ◦ Can obtain an item from any column in the current row ◦ Can move forward, not backward ◦ Scrollable ◦ Updatable the database ◦ Batch Updates - move forward and backward - write through the ResultSet to - submit multiple update statements for performance improvement ◦ RowSets - disconnect then reconnect to Database using optimistic concurrency control ◦ Others Features - Connection Pooling, JNDI Naming Statement SQL Insert String insertStmt = "INSERT into Course(CourseID, Name, ProfessorID) " +"values (162, ‘Java101’, 12)"; stmt.executeUpdate(insertStmt); Update String depositStmt = "UPDATE Course set NumStudents = 0"; stmt.executeUpdate(depositStmt); Delete String deleteStmt = "DELETE from Course where (ProfessorID = " + terminatedProfessor + ”)"; stmt.executeUpdate(deleteStmt); Example - Schema Assume the tables shown below. Write a program that displays all the students and the courses they take. JDBC Summary Three Statement Types ◦ Statement – simplest, slowest (for repeated calls), Difficult handling of quotes ◦ PreparedStatement – Allows DB to cache parsed SQL ◦ CallableStatement – Executes DB stored Procedure Basic Steps ◦ Load Driver(s) (typically with Class.forName) ◦ Obtain a connection (DriverManager.getConnection()) ◦ Get Statement from connection connection.createStatement - Statement connection.prepareStatement - PreparedStatement connection.prepareCall - CallableStatement ◦ stmt.executeQuery , stmt.executeUpdate, or stmt.execute What is ODBC? ODBC is (Open Database Connectivity): A standard or open application programming interface (API) for accessing a database. SQL Access Group, chiefly Microsoft, in 1992 By using ODBC statements in a program, you can access files in a number of different databases, including Access, dBase, DB2, Excel, and Text. It allows programs to use SQL requests that will access databases without having to know the proprietary interfaces to the databases. ODBC handles the SQL request and converts it into a request the individual database system understands. More on ODBC You need: ◦ the ODBC software, and ◦ a separate module or driver for each database to be accessed. Library that is dynamically connected to the application. Driver masks the heterogeneity of DBMS operating system and network protocol. E.g. (Sybase, Windows/NT, Novell driver) ODBC Architecture Application ODBC driver manager Driver (DBMS/OS/network) Data Source JDBC Architecture Oracle Driver Oracle Java Application JDBC DB2 Driver DB2 Network Postgres Driver Postgres JDBC Architecture (cont.) Application JDBC Driver Java code calls JDBC library JDBC loads a driver Driver talks to a particular database Can have more than one driver -> more than one database Ideal: can change database engines without changing any application code 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 What is JDBC? JDBC is: Java Database Connectivity ◦ is a Java API for connecting programs written in Java to the data in relational databases. ◦ consists of a set of classes and interfaces written in the Java programming language. ◦ provides a standard API for tool/database developers and makes it possible to write database applications using a pure Java API. ◦ The standard defined by Sun Microsystems, allowing individual providers to implement and extend the standard with their own JDBC drivers. JDBC: ◦ establishes a connection with a database ◦ sends SQL statements ◦ processes the results. JDBC vs ODBC ODBC is used between applications JDBC is used by Java programmers to connect to databases With a small "bridge" program, you can use the JDBC interface to access ODBCaccessible databases. JDBC allows SQL-based database access for EJB persistence and for direct manipulation from CORBA, DJB or other server objects JDBC API The JDBC API supports both two-tier and threetier models for database access. Two-tier model -- a Java applet or application interacts directly with the database. Three-tier model -- introduces a middle-level server for execution of business logic: ◦ the middle tier to maintain control over data access. ◦ the user can employ an easy-to-use higher-level API which is translated by the middle tier into the appropriate low-level calls. JDBC Architectures Java Application JDBC driver manager JDBC/native bridge JDBC/ODBC bridge Native driver (DBMS specific) ODBC Driver JDBC Driver (DBMS Specific) DBMS JDBC middleware (various DBMS) The JDBC Steps 1. Importing Packages 2. Registering the JDBC Drivers 3. Opening a Connection to a Database 4. Creating a Statement Object 5. Executing a Query and Returning a Result Set Object 6. Processing the Result Set 7. Closing the Result Set and Statement Objects 8. Closing the Connection Loading the Driver We can register the Driver indirectly using the Java statement: Class.forName(“oracle.jdbc.driver.OracleDriver"); Calling Class.forName causes the Driver class to be loaded When this class is loaded, it automatically ◦ creates an instance of itself ◦ registers this instance with the DriverManager Another Option Another option is to create an instance of the driver and register it with the Driver Manager: Driver driver = new oracle.jdbc.OracleDriver(); DriverManager.registerDriver(driver); An Example // A driver for imaginary1 Class.forName("ORG.img.imgSQL1.imaginary1Driver"); // A driver for imaginary2 Driver driver = new ORG.img.imgSQL2.imaginary2Driver(); DriverManager.registerDriver(driver); //A driver for oracle Class.forName("oracle.jdbc.driver.OracleDriver"); imaginary1 imaginary2 Oracle Registered Drivers 1: Importing Packages // // Program name: LecExample_1a.java // Purpose: Basic selection using prepared statement // //Import packages import java.sql.*; //JDBC packages import java.math.*; import java.io.*; import oracle.jdbc.driver.*; 2: Registering JDBC Drivers class LecExample_1a { public static void main (String args []) throws SQLException { // Load Oracle driver DriverManager.registerDriver (new oracle.jdbc.driver.OracleDriver()); Connecting to the Database Every database is identified by a URL Given a URL, DriverManager is asked to find the driver that can talk to the corresponding database DriverManager tries all registered drivers, until a suitable one is found Connecting to the Database Connection con = DriverManager. getConnection("jdbc.imaginaryDB1"); acceptsURL(“jdbc.imaginaryDB1”)? a r imaginary1 imaginary2 r Oracle Registered Drivers Read more in DriverManager API 3: Opening connection to a Database //Prompt user for username and password String user; String password; user = readEntry("username: "); password = readEntry("password: "); // Connect to the local database Connection conn = DriverManager.getConnection ("jdbc:oracle:thin:@aardvark:1526:teach ", user, password); Interaction with the Database We use Statement objects in order to ◦ Extract data from the database ◦ Update the database Three different interfaces are used: Statement, PreparedStatement, CallableStatement All are interfaces, thus cannot be instantiated They are created by the Connection Querying with Statement String queryStr = "SELECT * FROM Member " + "WHERE Lower(Name) = 'harry potter'"; Statement stmt = con.createStatement(); ResultSet rs = stmt.executeQuery(queryStr); • The executeQuery method returns a ResultSet object representing the query result. •Will be discussed later… Changing DB with Statement String deleteStr = “DELETE FROM Member " + "WHERE Lower(Name) = ‘harry potter’"; Statement stmt = con.createStatement(); int delnum = stmt.executeUpdate(deleteStr); executeUpdate is used for data manipulation: insert, delete, update, create table, etc. (anything other than querying!) executeUpdate returns the number of rows modified 4. Creating a Statement Object // Query the hotels table for resort = 'palma nova’ // Please notice the essential trim PreparedStatement pstmt = conn.prepareStatement ("SELECT hotelname, rating FROM hotels WHERE trim(resort) = ?"); pstmt.setString(1, "palma nova"); About Prepared Statements Prepared Statements are used for queries that are executed many times They are parsed (compiled) by the DBMS only once Column values can be set after compilation Instead of values, use ‘?’ Hence, a Prepared Statement is statement that contains placeholders to be substituted later with actual values Querying with PreparedStatement String queryStr = "SELECT * FROM Items " + "WHERE Name = ? and Cost < ?”; PreparedStatement pstmt = con.prepareStatement(queryStr); pstmt.setString(1, “t-shirt”); pstmt.setInt(2, 1000); ResultSet rs = pstmt.executeQuery(); Changing DB with PreparedStatement String deleteStr = “DELETE FROM Items " + "WHERE Name = ? and Cost > ?”; PreparedStatement pstmt = con.prepareStatement(deleteStr); pstmt.setString(1, “t-shirt”); pstmt.setInt(2, 1000); int delnum = pstmt.executeUpdate(); Statements vs. PreparedStatements: Be Careful! Are these the same? What do they do? String val = “abc”; PreparedStatement pstmt = con.prepareStatement(“select * from R where A=?”); pstmt.setString(1, val); ResultSet rs = pstmt.executeQuery(); String val = “abc”; Statement stmt = con.createStatement( ); ResultSet rs = stmt.executeQuery(“select * from R where A=” + val); Statements vs. PreparedStatements: Be Careful! Will this work? PreparedStatement pstmt = con.prepareStatement(“select * from ?”); pstmt.setString(1, myFavoriteTableString); No!!! A ‘?’ can only be used to represent column value WHY? a Timeout Use setQueryTimeOut(int seconds) of Statement 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 What is it good for? 5. Executing a Query, Returning a Result Set Object & 6. Processing the Result Set ResultSet rset = pstmt.executeQuery(); // Print query results while (rset.next()) System.out.println (rset.getString (1)+" "+ rset.getString(2)); 7. Closing the Result Set and Statement Objects 8. Closing the Connection // close the result set, statement, and the connection rset.close(); pstmt.close(); conn.close(); } Mapping Data Types There are data types specified to SQL that need to be mapped to Java data types if the user expects Java to be able to handle them. Conversion falls into three categories: ◦ SQL type to Java direct equivalents SQL INTEGER direct equivalent of Java int data type. ◦ SQL type can be converted to a Java equivalent. SQL CHAR,VARCHAR, and LONGVARCHAR can all be converted to the Java String data type. ◦ SQL data type is unique and requires a special Java data class object to be created specifically for their SQL equivalent. SQL DATE converted to the Java Date object that is defined in java.Date especially for this purpose. ResultSet A ResultSet provides access to a table of data generated by executing a Statement Only one ResultSet per Statement can be open at once The table rows are retrieved in sequence ◦ A ResultSet maintains a cursor pointing to its current row of data ◦ The 'next' method moves the cursor to the next row ResultSet Methods boolean next() ◦ activates the next row ◦ the first call to next() activates the first row ◦ returns false if there are no more rows void close() ◦ disposes of the ResultSet ◦ allows you to re-use the Statement that created it ◦ automatically called by most Statement methods ResultSet Methods Type getType(int columnIndex) ◦ returns the given field as the given type ◦ fields indexed starting at 1 (not 0) Type getType(String columnName) ◦ same, but uses name of field ◦ less efficient int findColumn(String columnName) ◦ looks up column index given column name ResultSet Methods String getString(int columnIndex) boolean getBoolean(int columnIndex) byte getByte(int columnIndex) short getShort(int columnIndex) int getInt(int columnIndex) long getLong(int columnIndex) float getFloat(int columnIndex) double getDouble(int columnIndex) Date getDate(int columnIndex) Time getTime(int columnIndex) Timestamp getTimestamp(int columnIndex) ResultSet Methods String getString(String columnName) boolean getBoolean(String columnName) byte getByte(String columnName) short getShort(String columnName) int getInt(String columnName) long getLong(String columnName) float getFloat(String columnName) double getDouble(String columnName) Date getDate(String columnName) Time getTime(String columnName) Timestamp getTimestamp(String columnName) ResultSet Example Statement stmt = con.createStatement(); ResultSet rs = stmt. executeQuery("select name,age from Employees"); // Print the result while(rs.next()) { System.out.print(rs.getString(1) + ”:“); System.out.println(rs.getShort(“age”)+”“); } Null Values In SQL, NULL means the field is empty Not the same as 0 or “” In JDBC, you must explicitly ask if a field is null by calling ResultSet.isNull(column) For example, getInt(column) will return 0 if the value is either 0 or null!! Null Values When inserting null values into placeholders of Prepared Statements: ◦ Use the method setNull(index, sqlType) for primitive types (e.g. INTEGER, REAL); ◦ You may also use the setXXX(index, null) for object types (e.g. STRING, DATE). ResultSet Meta-Data A ResultSetMetaData is an object that can be used to get information about the properties of the columns in a ResultSet object. An example: write the columns of the result set ResultSetMetaData rsmd = rs.getMetaData(); int numcols = rsmd.getColumnCount(); for (int i = 1 ; i <= numcols; i++) { System.out.print(rsmd.getColumnLabel(i)+” “); } Many more methods in the ResultSetMetaData API Database Time Times in SQL are notoriously non-standard Java defines three classes to help java.sql.Date ◦ year, month, day java.sql.Time ◦ hours, minutes, seconds java.sql.Timestamp ◦ year, month, day, hours, minutes, seconds, nanoseconds ◦ usually use this one Cleaning Up After Yourself Remember to close the Connections, Statements, PreparedStatements and ResultSets con.close(); stmt.close(); pstmt.close(); rs.close() Dealing With Exceptions An exception can have more exceptions in it. catch (SQLException e) { while (e != null) { System.out.println(e.getSQLState()); System.out.println(e.getMessage()); System.out.println(e.getErrorCode()); e = e.getNextException(); } } LOBs: Large OBjects Two types: ◦ CLOB: Character large object (a lot of characters) ◦ BLOB: Binary large object (a lot of bytes) Actual data is not stored in the table with the CLOB/BLOB column. Only a pointer to the data is stored there I will show how to use a BLOB; CLOBs are similar Retrieving a BLOB create table userImages( user varchar(50), image BLOB ); ResultSet rs = stmt.executeQuery(“select image from userImages”); while (rs.next) { Blob b = rs.getBlob(“image”); InputStream stream = b.getBinaryStream(); doSomething(stream); } Inserting a BLOB PreparedStatement pstmt = con.prepareStatement(“insert into userImages values(‘snoopy’, ?)”); File file = new File(“snoopy.jpg”); InputStream fin = new FileInputStream(file); pstmt.setBinaryStream (1, fin, file.length()); pstmt.executeUpdate(); Transactions and JDBC Transaction = more than one statement 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 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(); What happens if this pstmt.setInt(1, 100); update fails? pstmt.setInt(2, 72); pstmt.executeUpdate(); Transaction Management Transactions are not explicitly opened and closed 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 AutoCommit setAutoCommit(boolean val) If you set AutoCommit to false, you must explicitly commit or rollback the transaction using Connection.commit() and Connection.rollback() In order to work with LOBs, you usually have to set AutoCommit to false, while retrieving the data Note: DDL statements in a transaction may be ignored or may cause a commit to occur. The behavior is DBMS dependent 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(); } Isolation Levels How do different transactions interact? Do they see what another has written? Possible problems: ◦ Dirty Reads: a transaction may read uncommitted data ◦ Unrepeatable Reads: two different results are seen when reading a tuple twice in the same transaction ◦ Phantom Reads: tuples are added to a table between two readings of this table in a single transaction Isolation Levels JDBC defines four isolation modes: Level Read Uncommited Dirty Read Yes Unrepeatable Read Yes Phantom Read Yes Read Commited No Yes Yes Repeatable Read No No Yes Serializable No No No Isolation Levels Set the transaction mode using setTransactionIsolation() of class Connection Oracle only implements: ◦ TRANSACTION_SERIALIZABLE An exception may be thrown if serializability isn’t possible ◦ TRANSACTION_READ_COMMITED This is the default Level: READ_COMMITED Transaction 1: insert into A values(1) insert into A values(2) commit Transaction 2: select * from A select * from A Question: Is it possible for a transaction to see 1 in A, but not 2? 1 2 Table: A Question: Is it possible for the 2 queries to give different answers for level SERIALIZABLE? Mapping Java Types to SQL Types SQL type Java Type CHAR, VARCHAR, LONGVARCHAR String NUMERIC, DECIMAL java.math.BigDecimal BIT boolean TINYINT byte SMALLINT short INTEGER int BIGINT long REAL float FLOAT, DOUBLE double BINARY,VARBINARY, LONGVARBINARY byte[] DATE java.sql.Date TIME java.sql.Time TIMESTAMP java.sql.Timestamp