Cao RuO Shen (ruoshen_c@sjtu.edu.cn), graduate student of computer science, Shanghai Jiao Tong University
August 31, 2007
At the end of 2006, Sun released the final official version of Java Standard Edition 6 (Java SE 6), codenamed Mustang (Mustang ). Compared with Tiger (Java SE 5), Mustang has a good performance improvement. Compared with the significant enhancement of tiger in the api library, although mustang has fewer new features in the api library, it also provides many practical and convenient functions: In script, WebService, XML, compiler API, database, JMX, network and instrumentation all have good new features and enhanced functions.This seriesThis article mainly introduces some new features of Java SE 6 in the api library. Through some examples and explanations, it helps developers better use Java SE 6 in programming practices and improve development efficiency.
This article is the first in a series of articles and introduces the new features of Java SE 6 in database programming.
For a long time, since a large number of (or even almost all) Java applications rely on databases, it has been a hot topic for programmers to use the Java language to access databases efficiently, reliably, and concisely. The newly released Java SE 6 is also upgraded in this regard, providing programmers with many useful new features. Specifically, Java SE 6 has an embedded 100% database system written in Java. In addition, Java 6 began to support a series of new features and attributes of JDBC 4.0. In this way, Java SE is more easy to use and powerful in accessing persistent data.
Java db: databases in Java 6
Programmers who have installed JDK 6 may find that in addition to the traditional bin and JRE directories, JDK 6 adds a directory named dB. This is a new member of Java 6: java db. This is a pure Java-implemented, open-source database management system (DBMS), originated from the project Derby under the Apache Software Foundation (ASF. It is only 2 MB in size, which is a pocket-sized database compared to the database with frequent access to G. However, this does not prevent Derby from being fully functional and supports the features required by almost all database applications. What's even more valuable is that, relying on the strong community power of ASF, Derby is supported by large companies including IBM and sun and excellent programmers from around the world. It is no wonder that Sun chose to include its 10.2.2 version in JDK 6 as an embedded database. This seems to inject a brand new vitality into JDK: Java programmers no longer need to spend a lot of energy installing and configuring databases, so they can perform secure, easy-to-use, standard, and free database programming. In this chapter, we will first look at the world of java db to explore how to use it to compile programs with rich functions.
Hello, java db: derby in Embedded Mode
Now that we have an embedded database, let's start with a simple example (the code is listed in Listing 1) and try to use it. This program performs operations that most database applications may perform: Create a database named hellodb In the DBMS, and create a data table named hellotable; insert two pieces of data into the table. Then, query the data and print the result on the console. Finally, delete the table and database and release the resource.
Listing 1. hellojavadb code
public class HelloJavaDB { public static void main(String[] args) { try { // load the driver Class.forName("org.apache.derby.jdbc.EmbeddedDriver").newInstance(); System.out.println("Load the embedded driver"); Connection conn = null; Properties props = new Properties(); props.put("user", "user1"); props.put("password", "user1"); //create and connect the database named helloDB conn=DriverManager.getConnection("jdbc:derby:helloDB;create=true", props); System.out.println("create and connect to helloDB"); conn.setAutoCommit(false); // create a table and insert two records Statement s = conn.createStatement(); s.execute("create table hellotable(name varchar(40), score int)"); System.out.println("Created table hellotable"); s.execute("insert into hellotable values('Ruth Cao', 86)"); s.execute("insert into hellotable values ('Flora Shi', 92)"); // list the two records ResultSet rs = s.executeQuery( "SELECT name, score FROM hellotable ORDER BY score"); System.out.println("name/t/tscore"); while(rs.next()) { StringBuilder builder = new StringBuilder(rs.getString(1)); builder.append("/t"); builder.append(rs.getInt(2)); System.out.println(builder.toString()); } // delete the table s.execute("drop table hellotable"); System.out.println("Dropped table hellotable"); rs.close(); s.close(); System.out.println("Closed result set and statement"); conn.commit(); conn.close(); System.out.println("Committed transaction and closed connection"); try { // perform a clean shutdown DriverManager.getConnection("jdbc:derby:;shutdown=true"); } catch (SQLException se) { System.out.println("Database shut down normally"); } } catch (Throwable e) { // handle the exception } System.out.println("SimpleApp finished"); }} |
Then, run the following command in the command line (in this example, the Windows platform, of course, you can make a slight change to other systems:
Listing 2. Run the hellojavadb command
java –cp .;%JAVA_HOME%/db/lib/derby.jar HelloJavaDB |
The program will be executed as we expected. Figure 1 is part of the execution result:
Figure 1. Execution result of the hellojavadb Program
The above procedures are no different from those in the past. The difference is that we don't need to worry about DBMS configuration, because Derby has automatically created a directory named hellodb under the current directory to physically store data and logs. All you need to do is pay attention to the naming problem: in Embedded mode, the driver name should beorg.apache.derby.jdbc.EmbeddedDriver
When creating a new database, you must addcreate=true
. In addition, you can use the following code to shut down all databases and Derby engines:
Listing 3. disabling all databases and Derby Engines
DriverManager.getConnection("jdbc:derby:;shutdown=true"); |
If you only want to close a database, you can call:
Listing 4. Closing a database
DriverManager.getConnection("jdbc:derby:helloDB;shutdown=true "); |
In this way, the cost of maintaining and managing databases using the Derby embedded mode is close to zero. This is good news for those who want to concentrate on writing code. However, some people may wonder why most DBMS systems do not adopt the embedded mode? You may wish to do a small experiment. When we run the hellojavadb program in two command line windows at the same time. The result of one result is the same as that of the previous one, but the other has an error, as shown in figure 2.
Figure 2. Limitations of the embedded Mode
The cause of the error is actually very simple: when using the embedded mode, Derby itself does not run in an independent process, but runs in the same Java Virtual Machine (JVM) together with the application. Therefore, Derby becomes a part of the application just like other jar files used by the application. This makes it easy to understand why our example program runs smoothly by adding the Derby JAR file to the classpath. This also shows that only one JVM can start the database: two applications running in different JVM instances naturally cannot access the same database.
In view of the limitations mentioned above and the need for multiple connections from different JVMs to access a database, the next section will introduce another Derby mode: network server ).
Network Server Mode
As mentioned above, the network server mode is a more traditional Client/Server mode. We need to start a derby network server to process client requests, whether from the same JVM instance or from another machine on the network. In addition, the client uses the drda (Distributed Relational database architecture) Protocol to connect to the server. This is a database interaction standard advocated by the Open Group. Figure 3 shows the general structure of the mode.
As Derby developers strive to reduce the difference between the network server mode and the embedded mode, we only need to modify the program in Listing 1. As shown in listing 5, a new function and some string variables are added to hellojavadb. It is not hard to see that the new Code only changes some strings that are specifically pointed out in the previous section: the driver class isorg.apache.derby.jdbc.ClientDriver
The database connection protocol becomesjdbc:derby://localhost:1527/
. This is a URL-like string. In fact, the connection format of the Derby network client is:jdbc:derby://server[:port]/databaseName[;attributeKey=value]
. In this example, we use the simplest local machine as the server, and the port is Derby's default port 1527.
Figure 3. Derby network server mode Architecture
Listing 5. hellojavadb in network server mode
public class HelloJavaDB { public static String driver = "org.apache.derby.jdbc.EmbeddedDriver"; public static String protocol = "jdbc:derby:"; public static void main(String[] args) { // same as before } private static void parseArguments(String[] args) { if (args.length == 0 || args.length > 1) { return; } if (args[0].equalsIgnoreCase("derbyclient")) { framework = "derbyclient"; driver = "org.apache.derby.jdbc.ClientDriver"; protocol = "jdbc:derby://localhost:1527/"; } }} |
Of course, it is not enough to have only clients. We also need to start the network server. In Derby, the class that controls the network server isorg.apache.derby.drda.NetworkServerControl
, Enter the following command. To learn more about networkservercontrolstart
You can see the help information after removing the parameter. All Network Server implementations are included in derbynet. Jar by derby.
Listing 6. Start a network server
java -cp .;"C:/Program Files/Java/jdk1.6.0/db/lib/derby.jar";"C:/Program Files/Java/jdk1.6.0/db/lib/derbynet.jar" org.apache.derby.drda.NetworkServerControl start |
Correspondingly, the implementation of the network client is included in derbyclient. jar. Therefore, you only need to add the JAR file to the classpath, and the modified client can read data smoothly. Try again using two command line windows to connect to the database, and you will be able to get the correct result. If you no longer need a server, you can use the shutdown parameter of networkservercontrol to disable the server.
More
So far, this article introduces Java dB (Derby), a new member of Java SE 6, and how to use java db in the embedded mode and network server mode. Of course, this is just a short taste. More advanced options need to be found in Sun and Derby documents. At the end of this chapter, we will briefly introduce several java db gadgets to speed up development. They are all located in the org. Apache. Derby. Tools Package. You need to obtain information or test them during development.
- IJ: A tool used to run SQL scripts;
- Dblook: Schema extraction for the Derby database to generate the DDL tool;
- Sysinfo: Tool class for Displaying System and Derby information;
JDBC 4.0: new function, new API
If the previous chapter introduces a new member in Java 6, it already exists, but is not added to JDK. In this chapter, we will focus on what new features and corresponding new APIs are added in JDBC 4.0.
Automatic driver Loading
Before JDBC 4.0, you must add the following ugly code to compile JDBC programs:
Listing 7. register the JDBC driver
Class.forName("org.apache.derby.jdbc.EmbeddedDriver").newInstance(); |
Java.sql.DriverManager
The internal implementation mechanism of determines the appearance of such code. OnlyClass.forName
Find the class file of the specific driver,DriverManager.getConnection
Methods can be used to smoothly obtain the connection between Java applications and databases. This Code adds unnecessary burden for programming, and JDK developers are aware of this. Starting from Java 6, the application no longer needs to explicitly load the driver, and drivermanager can automatically perform this task. As a test, we can delete the relevant code in Listing 1 and re-compile it and run it in JRE 6.0. The result is the same as that of the original program.
Curious readers may ask why drivermanager can automatically load data? This is due to a new mechanism called service provider. Programmers familiar with Java security programming may already be familiar with it, and it now appears in the JDBC module. According to the JDBC 4.0 specification, all JDBC 4.0 driver jar files must contain onejava.sql.Driver
In the META-INF/Services Directory of the JAR file. Each line in this file describes a corresponding driver class. In fact, writing this file is similar to writing a properties file with only a key but no value. Similarly, the text after '#' is considered as a comment. With this description, drivermanager can find the classes it should load from the driver file in classpath. If we do not have any JDBC 4.0 driver file in classpath, the code in listing 8 will outputsun.jdbc.odbc.JdbcOdbcDriver
Type object. While carefully browsing the JDK 6 directory, this type is exactly in%JAVA_HOME%/jre/lib/resources.jar
Under the META-INF/Services Directoryjava.sql.Driver
File. That is to say, this is the default driver in JDK. If developers want to make their drivers available to drivermanager, they only need to add the corresponding JAR file to classpath. Of course, we can only explicitly load the drivers before JDBC 4.0.
Listing 8. List the JDBC drivers on the local machine
Enumeration<Driver> drivers = DriverManager.getDrivers();while(drivers.hasMoreElements()) { System.out.println(drivers.nextElement());} |
Rowid
Those familiar with large DBMS such as DB2 and Oracle will not be unfamiliar with the concept of rowid: it is a "hidden" column in the data table, and is the unique identifier of each row, indicates the physical or logical location of the row. The rowid type is widely used.java.sql.RowId
To allow JDBC programs to access the rowid type in SQL. It is true that not all DBMS support the rowid type. Different rowids have different lifecycles. ThereforeDatabaseMetaData.getRowIdLifetime
To determine the type of life cycle is a good practical experience. The following code is added after the connection is obtained in the program in Listing 1 to understand the support of the rowid type.
Listing 9. Understanding the support of the rowid type
DatabaseMetaData meta = conn.getMetaData();System.out.println(meta.getRowIdLifetime()); |
In the Java SE 6 API specification,java.sql.RowIdLifetime
Five different life cycles are defined:ROWID_UNSUPPORTED
,ROWID_VALID_FOREVER
,ROWID_VALID_OTHER
,ROWID_VALID_SESSION
AndROWID_VALID_TRANSACTION
. Literally, it is hard to understand that they do not support rowid, and rowid is always valid. For more information, see related javadoc. The reader can try to connect to Derby for testing. The running result isROWID_UNSUPPORTED
That is, Derby does not support rowid.
Since new data types are provided, some new APIs for obtaining and updating data table content are also added in Java 6. Same as other existing typesResultSet
OrCallableStatement
Then, call the get/set/update method to get/set/update the rowid object. The sample code is shown in listing 10.
Listing 10. Get/set the rowid object
// Initialize a PreparedStatementPreparedStatement pstmt = connection.prepareStatement( "SELECT rowid, name, score FROM hellotable WHERE rowid = ?");// Bind rowid into prepared statement. pstmt.setRowId(1, rowid);// Execute the statementResultSet rset = pstmt.executeQuery(); // List the recordswhile(rs.next()) { RowId id = rs.getRowId(1); // get the immutable rowid object String name = rs.getString(2); int score = rs.getInt(3);} |
Given the different implementations of different DBMS, rowid objects are usually not portable between different data sources. Therefore, the JDBC 4.0 API specification does not recommend that you retrieve a rowid object from connection A and use it in Connection B to avoid undefinable errors caused by different systems. As for DBMS that does not support rowid like Derby, the program will directly throwSQLFeatureNotSupportedException
.
SQLXML
SQL: the 2003 standard introduces SQL/XML as an extension of the SQL standard. SQL/XML defines how the SQL language interacts with XML: How XML data is created, and how XQuery expressions are embedded in SQL statements. Java 6 is added as part of JDBC 4.0java.sql.SQLXML
. JDBC applications can use this type to initialize, read, and store XML data.java.sql.Connection.createSQLXML
Method To create a blank SQLXML object. After obtaining this object, you can usesetString
,setBinaryStream
,setCharacterStream
OrsetResult
To initialize the XML data. TosetCharacterStream
For example, listing 11 shows how to obtain a SQLXML object.java.io.Writer
Object To Read content from external XML files row by row to complete initialization.
Listing 11. Using setcharacterstream to initialize SQLXML objects
SQLXML xml = con.createSQLXML();Writer writer = xml.setCharacterStream();BufferedReader reader = new BufferedReader(new FileReader("test.xml"));String line= null;while((line = reader.readLine() != null) { writer.write(line);} |
Because SQLXML objects may be associated with various external resources and keep holding these resources in a transaction. To prevent applications from consuming resources, Java 6 provides the Free Method to release their resources. Similar Design injava.sql.Array
,Clob
.
As for how to use SQLXML to interact with databases, the method is very similar to other types. You can refer to the example in the rowid section to find the corresponding get/set/update method in SQLXML in the Java SE 6 API specification to build a similar program.
Sqlexcpetion Enhancement
Before Java SE 6, there are no more than 10 exception types related to JDBC. This does not seem to be enough to describe the increasingly complex database exceptions. Therefore, the Java SE 6 designerjava.sql.SQLException
The root exception system has been greatly improved. First, sqlexception is implementedIterable<Throwable>
Interface. Listing 12 implements the Exception Handling Mechanism of the program in Listing 1. In this way, every sqlexception and its potential causes (cause) are concisely traversed ).
Listing 12. sqlexception for-each loop
// Java 6 codecatch (Throwable e) { if (e instanceof SQLException) { for(Throwable ex : (SQLException)e ){ System.err.println(ex.toString()); } }} |
In addition, figure 4 shows all sqlexception exception systems. Except the original sqlexception subclass, the exception classes added in Java 6 are divided into three types:SQLReoverableException
,SQLNonTransientException
,SQLTransientException
. InSQLNonTransientException
AndSQLTransientException
There are also several sub-classes, which are detailed in the various errors that may occur in the JDBC program. Most subclasses have corresponding standards.SQLState
Value, which combines the SQL standard with the Java 6 class library.
Figure 4. sqlexception exception system
Among the many exception classesSQLFeatureNotSupportedException
To indicate that the JDBC driver does not support a JDBC feature. For example, if you run the program in listing 10 in Derby, you can find that the derby driver does not support the rowid feature. It is also worth mentioning that,SQLClientInfoException
Directly inherited from sqlexception, indicating the exception that occurs when some client properties cannot be set to a database connection.
Summary: more new features and prospects
In this article, we have introduced some of the most important new features of JDBC in Java SE 6: they include a part of java db (Derby) and JDBC 4.0 Embedded in JDK. Of course, there are many new features not covered in this article. For exampleNCHAR
,NVARCHAR
,LONGNVARCHAR
AndNCLOB
Type support; in the database connection pool environment for managementStatement
Objects provide more flexible and convenient methods.
In addition, the annotation query feature was included in the beta version of Java SE 6. This feature defines a series of query and dataset interfaces that allow programmers to customize queries and obtain custom dataset results by writing annotation. However, due to the fact that this specific reference implementation cannot meet the quality requirements of JDK, Sun reluctantly canceled its release plan in Java SE 6. We have reason to believe that in future JDK versions, this feature and more new features will be included, and applications that use the Java language to build databases will become more natural and smooth.
References
- ReadJava SE 6 new feature seriesA complete list of articles to learn about other important enhancements of Java SE 6.
- Java SE 6 Document: Specification document of Java SE 6, which can be found in the official description of most new features.
- Refer to the jdbc api reference documents of Sun's Java SE 6: Java. SQL and javax. SQL.
- Developerworks Apache Derby Project Resource Center: more technical articles and tutorials on the Apache Derby Project.
- Java db at a Glance: java db introduction.
- Apache Derby: Quick Start manual for Apache derby.
- Refer to the JDBC 4.0 API specification.
About the author
|
|
|
Cao Ruo-Shen is a graduate student at the computer department of Shanghai Jiao Tong University. She is interested in Java SE Class Library Development and RIA programming, and has participated in some related projects. You can contact her via ruoshen_c@sjtu.edu.cn. |