530 likes | 683 Views
Database applications with JDBC. Jiafan Zhou. DBMS. Database management systems (DBMS) is an organised collection of data. Usually database stores data on hard drives, so data will not get lost after a system reboot.
E N D
Database applications with JDBC Jiafan Zhou
DBMS • Database management systems (DBMS) is an organised collection of data. • Usually database stores data on hard drives, so data will not get lost after a system reboot. • SQL is the language program interacts with the database to perform the CRUD operations (Create, Read, Update and Delete) • There are many database products, open source or commercial, available in the market place. • Just to name a few: • Oracle • SQL Server • DB2 • Sybase • MySQL • PostgreSQL • Apache Derby (Java DB)
Java DB • In this course, we will use the Java DB, which comes with the latest version of the Java SDK. (Installed in the db directory of the JDK installation) • Java DB is Oracle’s supported distribution of the Apache Derby open source database. • Java DB supports standard ANSI/ISO SQL through the JDBC. • To start Java DB: In Windows: c:\Java\jdk1.7.0_25\db\bin> startNetworkServer.batIn Unix/Linux:[ejiafzh@elx1411ctr-yp:/opt/java/jdk1.7.0_40/db/bin]$ ./startNetworkServer Tue Sep 17 14:35:28 BST 2013 : Security manager installed using the Basic server security policy. Tue Sep 17 14:35:31 BST 2013 : Apache Derby Network Server - 10.8.2.2 - (1181258) started and ready to accept connections on port 1527 • By default, the database server starts on the listening port 1527. • To stop Java DB: (Enter ctrl c)Terminate batch job (Y/N)? y
Create table in Java DB • Let us first connect to the Java DB using ij (the Java DB tool), create a table and add some data into the table. • Open another cmd or terminal: c:\Java\jdk1.7.0_25\db\bin> ij ij version 10.8 ij> connect 'jdbc:derby://localhost:1527/c:\temp\db;create=true'; ij> create table students(id integer, name varchar(20), age integer, city varchar(50)); ij> insert into students values(1, 'david', 22, 'Dublin'); 1 row inserted/updated/deleted ij> insert into students values(2, 'peter', 25, 'Galway'); 1 row inserted/updated/deleted ij> insert into students values(3, 'frank', 28, 'Limerick'); ij> alter table students alter column id NOT NULL; Ij> alter table students add primary key (id); 1 row inserted/updated/deleted ij> select * from students; ID |NAME |AGE |CITY ------------------------------------------------------------ 1 |david |22 |Dublin 2 |peter |25 |Galway 3 |frank |28 |Limerick 3 rows selected
Connect to Java DB using ij • Similar to create the database, but without the ‘create=true’ clause • All the data is saved in the hard drive in c:\temp\db • Open another cmd or terminal: c:\Java\jdk1.7.0_25\db\bin> ij ij version 10.8 ij> connect 'jdbc:derby://localhost:1527/c:\temp\db'; ij> select * from students; ID |NAME |AGE |CITY ------------------------------------------------------------ 1 |david |22 |Dublin 2 |peter |25 |Galway 3 |frank |28 |Limerick 3 rows selected
JDBC driver • Java DB already comes with a JDBC driver. If using other database, then a JDBC driver must be downloaded/installed first in order for Java program to connect to the database, and the driver must be registered in the code • e.g. For MySQL database, the JDBC driver must be registered first: Class.fornName(“com.mysql.jbdc.Driver”); Connection conn = DriverManager .getConnection(“jdbc:mysql://localhost:3306/mydb”, “username”, “pasword”); • Check Internet to obtain a proper JDBC driver for your DBMS. • In Java DB, there is no need to register JDBC driver, it is already included.
JDBC API • The Java Database Connectivity API (JDBC) provides a universal data access from the Java programming language. • Using the JDBC API, we can access any data source, from relational database to excel spreadsheet or even flat files. • The JDBC API is comprised of the following two packages:java.sqljavax.sql • A JDBC driver is needed to mediate between JDBC technology and the database.
Process SQL with JDBC • In general, to process SQL statement with JDBC, the steps as below are needed: • Establish a db connectionTo establish a connection with the data source, which can be a DBMS with a corresponding JDBC driver. • Create an SQL statementA statement is an interface that represents an SQL statement. • Execute the statementTo execute an SQL statement and it generates results. • Process the ResultSet Object if requiredA table of data representing a database result set. • Close the connectionRelease the resources it is using.
1. Establish a db connection • First is to establish a connection with the data source. • In order to include the derby JDBC driver, it is necessary to include the $JAVA_HOME/db/lib/derbyclient.jar in the project classpath. • Typically, a JDBC application connects to a target data source using one of the following two classes: • DriverManagerConnects an application to a data source, which is specified by a database URL. A database URL is a string that the JDBC driver uses to connect to a database. When this class first attempts to establish a connection, it automatically loads any JDBC drivers found within the class path.Connection conn =DriverManager.getConnection("jdbc:derby://localhost:1527/c:/temp/db"); • DataSource// alternatively, it is possible to use DataSource to get db connection // notice ClientDataSource is a subtype of DataSource ClientDataSource ds =new ClientDataSource(); ds.setPortNumber(1527); ds.setServerName("localhost"); ds.setDatabaseName("c:/temp/db"); Connection conn = ds.getConnection();
2. Create an SQL statement • A statement is an interface that represents an SQL statement. The program executes the Statement object, generating a ResultSet objects, which is a table of data representing a database result set. • Need a Connection object to create a Statement objectStatement stmt = conn.createStatement(); • There are three different kinds of statements: • StatementUsed for simple SQL statements without parameters. • PreparedStatementUsed for statements that might contain input parameters. • CallableStatementUsed to execute stored procedures that may contain input/output parameters.
3. Execute the statement • To execute a query, simply call an execute method from the Statement String sql ="select * from students"; ResultSet rs = stmt.executeQuery(sql); • There are three available execute methods can be used: • execute()Returns true if the first object that the query returns is a ResultSet. Use this method if the query could return one or more ResultSet objects. • executeQuery()Returns the ResultSet object. • executeUpdate()Returns an integer representing the number of rows affected by the SQL statement. (Use this method if using with INSERT, DELETE or UPDATE SQL)
4. Process the ResultSet Object • Access the data in a ResultSet object through a cursor. • The cursor is a pointer that points to one row of data in the ResultSet object • Initially, the cursor is positioned before the first row • Call the next() to move the cursor forward by one row. while(rs.next()){ int id = rs.getInt("id"); String name = rs.getString("name"); int age = rs.getInt("age"); String city = rs.getString("city"); System.out.println(id +"\t"+ name +"\t"+ age +"\t"+ city); } • When reaching the line row of the ResultSet object, the next() will return a false.
5. Close the connection • When finished using a Statement, call the method Statement.close() to immediately release the resources it is using. • When this method is called, the ResultSet objects are closed. • Alternatively, it is also possible to close the database connection. finally{ try{ conn.close(); } catch(SQLException e){ e.printStackTrace(); } } Note: In Java 7, it is possible to use the try-with resources statement to automatically close the Statement or database connection.
StudentDaoDemo.java • publicclass StudentDaoDemo { • publicstaticvoid viewStudents(Connection conn){ • String sql ="select * from students"; • try{ • Statement stmt = conn.createStatement(); • ResultSet rs = stmt.executeQuery(sql); • while(rs.next()){ • int id = rs.getInt("id"); • String name = rs.getString("name"); • int age = rs.getInt("age"); • String city = rs.getString("city"); • System.out.println(id +"\t"+ name +"\t"+ age +"\t"+ city); • } • } • catch(SQLException ex){ • ex.printStackTrace(); • } • finally{ • try{ • conn.close(); • } • catch(SQLException e){ • e.printStackTrace(); • } • } • } • publicstaticvoid main(String[] args)throwsException{ • Connection conn =DriverManager • .getConnection("jdbc:derby://localhost:1527/c:/temp/db"); • viewStudents(conn); • } • }
RowSet • Compared with ResultSet, JDBC RowSet object holds tabular data in a way that makes it more flexible and easier to use. • For some more popular uses of a RowSet, RowSet has sub interfaces. • Programmers are free to write their own versions of the RowSet interface and the implementations. But many programmers will probably find the existing RowSet interfaces already fit their need.
RowSet Features • RowSet is derived from the ResultSet and therefore share its capability. • RowSet extended the ResultSet in the following two ways: • Function as JavabeansFor all RowSet objects, three events trigger notifications. Components that have implemented the RowSetListener interface will be noticed when any of the three events occurs: • A cursor movement • The update, insertion or deletion of a row • A change to the entire RowSet contents • Scrollability or UpdatabilityA RowSet object is scrollable and updatable by default.
RowSet Types • A RowSet object is considered either connected or disconnected. • A connected RowSet object uses a JDBC driver to make a connection to a relational database and maintains the connection. • JdbcRowSet • A disconnected RowSet object makes a connection to a data source only when read/write data to the data source is needed. • CachedRowSet • WebRowSet • JoinRowSet • FilteredRowSet In this course, we will only discuss the connected RowSet, i.e. the JdbcRowSet. Check the documentations for other types of disconnected RowSet.
JdbcRowSet Basics • A JdbcRowSet is an enhanced ResultSet object, and maintains the connection to the data source. • It has a set of properties and a listener notification mechanism. • To make a ResultSet object scrollable and updatable. • There are many ways to create a JdbcRowSet object: • Invoke the JdbcRowSetImpl constructor that takes a ResultSet objectStatementstmt=conn.createStatement();ResultSetrs=stmt.executeQuery(sql);JdbcRowSetrowSet = newJdbcRowSetImpl(rs); • Invoke the JdbcRowSetImpl constructor that takes a Connection objectConnection conn = …;JdbcRowSetrowSet = newJdbcRowSetImpl(conn); • Invoke the JdbcRowSetImpl default constructorJdbcRowSetrowSet = newJdbcRowSetImpl(); • Using an instance of RowSetFactory, which is created from the class RowSetProvierRowSetFactorymyRowSetFactory = RowSetProvider.newFactory();JdbcRowSetrowSet = myRowSetFactory.createJdbcRowSet();
Using JdbcRowSet • The command property must be set which is the query that determines what data the JdbcRowSet object will hold. rowSet.setCommand("select * from students"); • After setting the command property, invoke the execute() method: rowSet.execute(); • To add listeners: rowSet.addRowSetListener(new RowSetListener(){ @Override publicvoid rowSetChanged(RowSetEvent event){ System.err.println("RowSet changed..."); } @Override publicvoid rowChanged(RowSetEvent event){ System.err.println("Row changed... "); } @Override publicvoid cursorMoved(RowSetEvent event){ System.err.println("Cursor moved..."); } });
Navigating JdbcRowSet • A ResultSet can only use the next() method to move the cursor forward. • A JdbcRowSet can use all of the cursor movement methods defined in the ResultSet interface. • The previous() method move the cursor to the previous row • The absolute(int n) method moves the cursor directly to the n row // get the third row rowSet.absolute(3); displayRow(rowSet); // then get the previous row, i.e. the second row rowSet.previous(); displayRow(rowSet); • JdbcRowSetNavigate.java example.
Insert row JdbcRowSet • JdbcRowSet is updatable, inserting a row involves moving the cursor to the insert row, use the appropriate updater method to set value for each column and call the insertRow() method. rowSet.moveToInsertRow(); rowSet.updateInt("id", 4); rowSet.updateString("name", "enda"); rowSet.updateInt("age", 35); rowSet.updateString("city", "moat"); rowSet.insertRow(); • JdbcRowSetInsert.java example
Update/Delete row JdbcRowSet • JdbcRowSet is updatable, deleting a row involves moving the cursor to the last row, and call the deleteRow() method. rowSet.last(); rowSet.deleteRow(); • JdbcRowSet is updatable, updating a row involves moving the cursor to the target row, use the appropriate updater method to update value for each column and call the updateRow() method. rowSet.first(); rowSet.updateString("name", "jason"); rowSet.updateRow(); • JdbcRowSetDelete.java example • JdbcRowSetUpdate.java example
Prepared Statements • PreparedStatement objects can be used most often for SQL statements that take parameters. • The advantage of using parameters is that you can use the same statement and supply it with different values each time it is executed it. • Creating a PreparedStatement Object:String sql = "update students set name = ? where id = ?";PreparedStatement stmt = conn.prepareStatement(sql); • Supplying values for PreparedStatement parameters:stmt.setString(1, name); stmt.setInt(2, id); • Executing PreparedStatement Objectsint rowsAffected = stmt.executeUpdate(); • PreparedStatementDemo.java
Transactions • There are many cases that several database statements need to take effect at the same time. One statement needs to take effect until another one completes. • For instance, a number of students need to be registered in the database students table. These students come as a group from another country. The registration require adding all students into the database in one go. • The purpose is to ensure data integrity. • The way to ensure that either multiple actions occur or none action occurs is to be said a database transaction. • A database transaction is a set of one or more statements that is executed as a unit, so either all of the statements are executed, or none of the statements is executed.
Transactions – Auto Commit • By default, when a connection is created, the auto-commit mode is enabled. • Auto commit means that each individual SQL statement is treated separately as a transaction, and is automatically committed after it is executed. • The way to allow two or more statements to be grouped into a transaction is to disable the default auto-commit mode.conn.setAutoCommit(false); • After disabling the auto commit mode, no SQL statements are committed until you explicitly call the method commit and committed together as a unit.conn.commit(); • Don’t forget to get the auto commit mode back to true when the transaction is completed. • It is advisable to disable the auto-commit mode only during the transaction mode. • AutoCommitModeDemo.javaTransactionFailedDemo.java
Transactions – locks • Transactions can also help to preserve the integrity of the data in a table. • Transaction provides some level of protection against conflicts that arise when two users access data at the same time.e.g. What if one user changes a student’s name while another one view the student’s name. • To avoid conflicts during a transaction, a DBMS uses locks, mechanisms for blocking access by others to the data that is being accessed by the transaction. • How locks are set is determined by what is called a transaction isolation level, which can range from not supporting transactions at all to supporting the strict access rules transactions. • In order to understand this concept, we need to understand different types of reads in the database transaction.
Transactions – Reads • There are basically three types of reads (hazards) in transactions that can occur.Notice if there is no transaction, there are no reads. • Dirty ReadsOccurs when transaction A retrieves a row, transaction B subsequently updates the row. The data retrieved by transaction A is different from the data in database. • Non-repeatable ReadsOccurs when transaction A retrieves a row. Transaction B subsequently updates the row, and transaction A later retrieves the same row again. Transaction A retrieves the same row twice but sees different data. • Phantom ReadsOccurs when transaction A retrieves a set of rows satisfying a given condition, transaction B subsequently inserts or updates a row such that the row now meets the condition in transaction A, and transaction A later repeats the conditional retrieval. Transaction A now sees an additional row. This row is referred to as a phantom.
Transactions – Isolation Level • The JDBC has five different values that represent the transaction isolation levels
Transactions – Isolation Level • Usually, you don’t need to worry about the transaction isolation level, you can just use the default one for your DBMS. • Different DBMS has different default transaction isolation level. • JDBC driver might not support all transaction isolation levels. If a driver does not support the isolation level specified in an invocation of setTransactionIsolation, the driver can substitute a higher, more restrictive transaction isolation level. • The default transaction level for Java DB is TRANSACTION_READ_COMMITED. • TransactionIsolationLevelDemo.java
Advanced Data • Advanced data types give a relational database more flexibility in what can be used as a value for a table column. • For example, a column can be used to store BLOB (binary large object) values, which can store very large amounts of data as raw bytes. Or CLOB (character large objects), which is capable of storing very large amounts of data in character format. • You retrieve, store and update advanced data types the same way you handle other data types. You can use either ResultSet.getDataTypeor CallableStatement.getDataTypemethods to retrieve them. • The following table shows which methods to use
Using Stored Procedures • Stored procedures are supported by most database management systems (DBMS), but differs large in their syntax and capability. • A stored procedure is a group of SQL statements that form a logical unit and perform a particular task. For example, operations related to employee database (hire, fire, promote, lookup) could be coded as stored procedures executed. • CallableStatement is used to execute stored procedures that may contain input/output parameters.
Homework • Update your banking system to persist data into the database. • All the user data should be persisted. • Implement some user interface to retrieve the persisted data. • Peek at some ORM solutions like Hibernate.