Level: Intermediate Gilles Roux (groux@us.ibm.com), Information Management Software Engineer, IBM
20 Jan 2005 Developing an Apache Derby application involves performing many tasks, such as creating and connecting to a database, writing a Java™ Database Connectivity (JDBC) client application and stored procedures, and deploying the resulting pieces to a production environment. Discover how you can use the various Eclipse-based Apache Derby tools together to ease your development process.
Overview
In this article, learn how to develop an Apache Derby application on the Eclipse integrated development environment (IDE) using several tools, including the Java development tools, the IBM® DB2® plug-ins for Eclipse, and the IBM Integration plug-in for Derby.
Cover the whole development cycle of a typical Derby application, starting with database creation, moving to the JDBC client application development, the stored procedure and function development, and finally the deployment of the solution. Also, find out how you can replace an Apache Derby database with a DB2 Universal Database (UDB).
This article assumes you have a basic understanding of the Apache Derby database, the Eclipse platform and the DB2 plug-ins for Eclipse. I strongly recommend that you read the two parts of the "Using DB2 plug-ins for Eclipse with Apache Derby" article listed in Resources.
To illustrate the various tasks involved in the application development process, you are provided with concrete examples and step-by-step instructions on how to build a sample application. In this example, you want to develop a command line application to perform the inventory for a bookstore. The database of the bookstore stores the various books the store carries, together with the available quantity.
With your new application, you can access and change the quanity of the data. For example, if a set of books is received from a supplier, the application will be used to increase the quantity for the books received. If the quantity rises above or drops below a certain limit, you want the manager to be notified by e-mail so he can take the necessary action.
The development environment
The tools
The Java Development Tools (JDT) is a set of plug-ins built-in to Eclipse that provide a way to edit, compile, debug, execute, and deploy general-purpose Java applications.
The DB2 plug-ins for Eclipse provides features to connect to various databases, including IBM Cloudscape and Apache Derby. The plug-in is composed of the following components:
- Connection Wizard: Creates and connects to DB2, Cloudscape or Derby databases
- Database Explorer View: Browses the database objects
- SQL Scrapbook: Edits and executes single SQL statements
- Database Output View: Samples the content of a table or views the result of the execution of a SQL statement
- Migration Wizard: Automatically migrates an existing Derby database to DB2 UDB
The IBM Integration plug-in for Derby integrates many useful Derby tools into the Eclipse environment. The major features provided are:
- Apache Derby Nature: Enables an Eclipse project to perform Derby tasks
- Network Server: Configures and launches a Derby Network Server directly from the Eclipse project
- IJ: Launches the Derby command line utility directly in the Eclipse console, either in interactive mode or in script mode
- Sysinfo: Displays the Derby system information associated with the project
The DB2 plug-ins for Eclipse and the IBM Integration plug-in for Derby are two independent tools that complement each other very well. The first one provides general database connectivity, and the second one gives access to many Derby-specific features. Many tasks can be performed interchangeably by either of these tools. In this article, various different ways to perform a given task are mentioned, so that you can pick your preferred way of working.
Install the tools
First download and install the DB2 plug-ins for Eclipse. This product includes the DB2 plug-ins and is based on Eclipse 3.0, which itself includes the JDT.
Then download the Apache Derby plug-in on Apache.org and install it on top of the previous installation.
Finally, download the IBM Integration plug-in for Derby and install it on top of the Eclipse installation. This plug-in includes the JCC JDBC driver and the Derby integration tools.
Set up the development environment
As mentioned earlier, you will use several different tools to develop your application: The DB2 plug-ins for Eclipse, the IBM Integration plug-in for Derby and the JDT. These tools are all Eclipse-based which allow them to integrate nicely into a single development environment.
While developing the application you will typically establish several connections to the database:
- Browse the database using the Database Explorer
- Execute statements using the Derby IJ command line utility
- The application itself will connect to the database while being tested
The Derby database engine can run in several configurations. The simplest one is the embedded configuration but it is not appropriate here because you want to make connections from several tools running in different Java Virtual Machines. Also, in a production environment you would probably want to access the database from multiple applications. Therefore, use the Network Server configuration. The IBM Integration plug-in for Derby features an option to very easily start a Derby Network Server on the local machine, in the directory of the Eclipse project. Next configure the application and the other tools to connect to this network server. The following image illustrates this configuration.
Figure 1. Development environment configuration
The first step to set up the environment is to create your project. Select 'File->New->Project->Java Project' and enter bookstore as the project name. This creates a Java project and switches to the Java perspective. Right-click on the project and select 'Apache Derby->Add Apache Derby nature'. This enables your project to use Apache Derby features, and sets the build path of the Java project so the application has access to the Derby database and JDBC driver.
The DB2 plug-ins for Eclipse are usually accessible from the Data perspective and do not require association to a particular project. In order to simplify the development process and avoid switching between the Java and Data perspective, add the DB2 plug-ins views to the Java perspective: specifically the Database Explorer view and the DB Output view. You can do this through the Show View->Other menu. The following image shows this aspect of your development environment.
Figure 2. Development environment layout
Create the database
Before starting to write the actual application code, it is necessary to create the database that will be used by the application, or simply to connect to an existing database.
First, start the Derby Network Server by right-clicking on the project and selecting 'Apache Derby->Start Derby Network Server'. This needs to be done each time Eclipse is restarted. A green arrow on the project icon indicates that the server is running.
Create the database
Creating a Derby database is very similar to connecting to an existing database: including the create=true attribute in the URL that instructs the database engine to create the database the first time you try to connect to it. This can be done using the Connection Wizard of the DB2 plug-ins for Eclipse. The following table shows the parameters that should be used in the wizard.
Table 1. Connection parameters
| Connection name | bookstoredb | | | Database Manager | Apache Derby v10.0 | | | JDBC Driver | IBM DB2 Universal | Needed to connect to a network server | | Database | bookstoredb | Name of the database to create | | Host | localhost | The network server runs on the local machine | | Port Number | 1527 | Default port number | | Class Location | e.g.: C:\eclipse\plugins\ com.ibm.cloudscape.ui_1.0.0\db2jcc_license_c.jar;C:\eclipse\plugins\com.ibm.cloudscape.ui_1.0.0 \db2jcc.jar | | Create database if required | yes | Needed to create the database on the first connection | | User ID | bookstore | The authentication is not enabled on the database so any user can be used, but the user name will define the default schema | | Password | aaa | The authentication is not enabled on the database so any password can be used |
Figure 3. Creating the database using the Connection Wizard
After the wizard is dismissed, the database is created and a connection is added to the Database Explorer View. The database can be browsed by expanding the nodes of the connection, but is obviously empty at this point.
The database is created in the current directory of the Derby network server, which is the directory of the Eclipse project you created earlier. Refreshing the project by right-clicking on its name and selecting Refresh will reveal a new bookstoredb/ directory that contains the files for the database. Do not attempt to alter these files or the database will become corrupted.
Create the database objects
The next step is to create the database objects that will be used by the application. For now, simply create a table using the SQL Scrapbook. The SQL Scrapbook is invoked by right-clicking the connection name in the Database explorer and selecting 'Open SQL Scrapbook'. A new editor is opened, where you can type the SQL statement to issue:
Listing 1. The CREATE TABLE statement
create table books(
id int,
title varchar(128),
author varchar(128),
price decimal(6,2),
quantity int,
status int
)
|
Please note that the SQL Scrapbook can only be used to execute a single SQL statement. Also, do not terminate this statement with a semi-colon. You can then press the ?Execute SQL statement? button of the main Eclipse button bar. The DB Output view should show that the result was successful. You can also refresh the connection and verify that the database now contains the newly created table.
Figure 4. Creating the table using the SQL Scrapbook
Create some test data
Now populate the books table with some test data, by executing INSERT statements. You could do this by using the SQL Scrapbook but use the 'Run SQL script using ij' feature of the IBM Integration plug-in for Derby. This feature allows executing a SQL script using the Derby command line utility and seeing the result in the Eclipse output view. The big advantage of this method is that it allows executing several statements at once. Also, this method requires you to include a connect statement at the beginning of the script, which gives you more control over the connection URL.
Table 2. Differences between the SQL Scrapbook and the IJ script
| SQL Scrapbook | Execute IJ script | | Statements are stored in a file | No | Yes | | Can Execute several statement at once | No | Yes | | Statement terminator | No terminator allowed | Semi-colon | | Editing facilities | Syntax highlighting, content assist | No | | Connection to the database | The SQL scrapbook is tied to a given connection | The first statement should be a connect to the desired database |
An easy way of building the URL is to simply copy the URL that is used by the Connection Wizard: Right-click on the connection in the database explorer, select 'Edit Connection' and refer to the 'Connection URL field. It is necessary to add the user name and password as URL attributes.
Use Eclipse to create a text file called data.sql in your project and type in the following commands:
Listing 2. The INSERT INTO statements
connect 'jdbc:derby:net://localhost:1527/bookstoredb:user=bookstore;password=aaa;';
insert into books values(1, 'East Of Eden', 'John Steinbeck', 7.20, 3, 0);
insert into books values(2, 'Hard-Boiled Wonderland and the End of the World',
'Haruki Murakami', 10.50, 9, 0);
insert into books values(3, 'SQL for Dummies', 'Allen G. Taylor', 16.49, 6, 0);
disconnect;
|
You can then right-click on the file in the Project Explorer and select 'Apache Derby->Run SQL script using ij'. The console output view of Eclipse will display the result of the execution, which should be successful. You can then select the table in the Database Explorer, and select ?Sample Content? to ensure that the data was actually inserted into the table.
Figure 5. Executing the SQL script to insert data
Write a Derby Client JDBC application
Load the JDBC driver
Writing a JDBC application can easily be done using the Eclipse JDT and the Derby JDBC driver. First create an Inventory class in a bookstoreapp.clientside package, using the JDT Class wizard and add a main() method in it. The JAR files containing the JDBC driver and the Derby classes are already on the class path for the project since you enabled the Derby nature.
Before connecting to a Derby database it is necessary to load the appropriate JDBC driver using the Class.forName(jdbcDriverClassName) method. This loads the JDBC Driver class whose name is passed as argument, and registers it for the next JDBC connection.
Two different JDBC drivers can be used depending on the Derby configuration:
Table 3. The Derby JDBC drivers
| Configuration | Embedded Server | Network Server | | Required JAR files | derby.jar | db2jcc.jar;db2jcc_license_c.jar | | Class name | org.apache.derby.jdbc.EmbeddedDriver | com.ibm.db2.jcc.DB2Driver |
The example is based on a network server configuration so use the jcc JDBC driver. If you have doubt, the correct class name can easily be identified by copying it from the Connection wizard:
Listing 3. Loading the jcc JDBC driver
Class.forName("com.ibm.db2.jcc.DB2Driver");
|
Connect to the database
The DriverManager.getConnection(url) method is used to establish a connection to the database. It assumes a connection URL and returns a Connection object that can be used to query the database.
A good way of obtaining the connection URL is to edit the Derby connection in the Database Explorer view and copy the connection URL that is automatically constructed from the various connection attributes. For security reasons, the user name and password are not displayed there so it is necessary to add them manually at the end of the URL in the application code.
Figure 6. Using the connection wizard to build the connection URL
Other options can also be added at the end of the URL. For example the retrieveMessagesFromServerOnGetMessage=true options instructs the JDBC driver to retrieve readable error messages from the Derby server, which is very useful when debugging an application connecting to a remote Derby database.
In your example, connect to the Derby Database using the following code:
Listing 4. Connecting to the database
String url = "jdbc:derby:net://localhost:1527/bookstoredb";
url += ":user=bookstore;password=aaa;";
url += "retrieveMessagesFromServerOnGetMessage=true;";
Connection con = DriverManager.getConnection(url);
|
Query the database
Once the connection is established, it is possible to query the database by simply using the JDBC API. For example you can create a Statement object and use it to execute a SQL query on the database. This returns a ResultSet object that is used to iterate over the result set of the query:
Listing 5. Executing a query and iterating over the result set
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM bookstore.books");
while (rs.next()) {
System.out.print(rs.getString(1) + ", ");
System.out.print(rs.getString(2) + ", ");
System.out.print(rs.getString(3) + ", ");
System.out.print(rs.getString(4) + ", ");
System.out.print(rs.getString(5) + ", ");
System.out.println(rs.getString(6));
}
rs.close();
stmt.close();
|
Figure 7. Running the JDBC application
For more information on using JDBC you can refer to the JDBC tutorials listed in the Resources section of this article.
You can download the complete source code for the
Inventory class. This class implements a simple text interface to list the books and update the quantity for a given book of the bookstore.
Here is an example of the application output:
Figure 8. Sample output of the Inventory application
Write Java functions and procedures
The JDBC application discussed in the previous section is very useful to develop a front-end application for the user. However, implementing important application logic in this layer may be a bad idea because the logic resides outside of the database which could make the database more vulnerable. For example if another JDBC application connects to the same database, it is necessary to make sure that it implements the same logic. A solution to this problem is to implement the database rules in the database itself, through the use of triggers, stored procedures, and functions.
Write the Java code
Since Derby is a Java database, it does not have a stored procedure/function language of its own, but uses the Java language instead. Creating a Derby stored procedure or function (generically refered as routine) can be done by creating a Java method, and then declaring a Derby procedure or function that is based on the Java method. Calling the Derby routine will cause the invocation of the Java method.
For this invocation to be successful it is important that the declaration of the Derby and Java routine match. The following tables show the mapping between Derby and Java features that should be used.
Table 4. Feature mapping used to write Java functions and procedures
| Derby | Java | | Procedure | Public static method with no return value | | Function | Public static method with a return value | | Input parameter (procedures or functions) | Method parameter | | Output parameter (procedures) | Single entry array parameter | | Input/Output parameter (procedures) | Single entry array parameter | | Return value (function) | Return value | | Returned result Set | Additional single entry java.sql.ResultSet[] parameter |
Table 5. Type mapping used to write Java functions and procedures
| Derby | Java | | SMALLINT | short | | INTEGER | int | | BIGINT | long | | DECIMAL(p,s) | java.math.BigDecimal | | REAL | float | | DOUBLE PRECISION | double | | CHAR(n) | String | | VARCHAR(n) | String | | LONG VARCHAR | *unsupported* | | CHAR(n) FOR BIT DATA | byte[] | | VARCHAR(n) FOR BIT DATA | byte[] | | LONG VARCHAR FOR BIT DATA | *unsupported* | | CLOB(n) | *unsupported* | | BLOB(n) | *unsupported* | | DATE | java.sql.Date | | TIME | java.sql.Time | | TIMESTAMP | java.sql.Timestamp |
There is no restriction on the content of the Java method itself, so any valid Java code can be invoked as a Derby procedure or function. An interesting application is to establish a JDBC connection to the Derby database, using the standard derby:default:connection URL, in order to query the database that initiated the call. It is also possible to connect to another database using its full JDBC URL.
For the purpose of your application,create a DerbyFunctions class in a bookstoreapp.serverside package to hold all the Java methods that will be run by the database server. You can then create an updateQuantity method that will be called when the quantity for a book is updated. This method expects the ID, title and author of the book, as well as the old and new quantity. It also returns an integer value to indicate if a quantity limit was reached.
The declaration of the Java method is therefore:
Listing 6. Declaration of the Java method
public static int updateQuantity(int id, String title, String author,
int oldQuantity, int newQuantity)
|
The purpose of the function is to send an email if the quantity reaches a low or high limit. You therefore declare LOW_LIMIT and HIGH_LIMIT constants, and test if the old quantity was below the low limit and the new quantity above, or similarly for the low limit. If this condition is met, you call another Java method that takes care of sending the email. In this example, simply print a debug message instead of sending an actual email.
Below is the full code:
Listing 7. DerbyFunctions class
package bookstoreapp.serverside;
public class DerbyFunctions
{
public static final int LOW_LIMIT = 2;
public static final int HIGH_LIMIT = 10;
public static int updateQuantity(int id, String title, String author,
int oldQuantity, int newQuantity)
{
if ( oldQuantity<HIGH_LIMIT && newQuantity>=HIGH_LIMIT )
sendEMailAlert("High limit reached", "title: "+title+", author: "+author);
else if ( oldQuantity>LOW_LIMIT && newQuantity<=LOW_LIMIT )
sendEMailAlert("Low limit reached", "title: "+title+", author: "+author);
if (newQuantity>=HIGH_LIMIT)
return +1;
else if (newQuantity<=LOW_LIMIT)
return -1;
else
return 0;
}
public static void sendEMailAlert(String subject, String msg)
{
System.out.println("Sending email: " + subject);
System.out.println(msg);
}
}
|
It is usually a good idea to test the Java method by simply calling it from a main method.
Create the Derby function
Creating a Derby stored procedure or function is easy. Simply specify the name, arguments, return value, as well as the fully qualified name of the corresponding Java method. It is important that the signature of the Derby routine matches the signature of the Java method so that the database can successfully invoke the Java code.
The CREATE statement could easily be issued from the SQL Scrapbook but in this case it is better to use the ij utility for that. Using the ij utility lets you specify the connection URL explicitly, which allows us to include the retrieveMessagesFromServerOnGetMessage=true attribute. This option causes the JDBC driver to retrieve the full error messages from the server, which is very helpful in case the execution of the statement fails.
Here are the commands to issue in ij:
Listing 8. Creating the Java function in Derby
connect 'jdbc:derby:net://localhost:1527/bookstoredb
:user=bookstore;password=aaa;retrieveMessagesFromServerOnGetMessage=true;';
create function updateQuantity(id int, title varchar(128), author varchar(128),
oldQuantity int, newQuantity int) returns int
PARAMETER STYLE JAVA NO SQL LANGUAGE JAVA
EXTERNAL NAME 'bookstoreapp.serverside.DerbyFunctions.updateQuantity';
|
The creation of the Derby function should be successful, but it is sometimes difficult to get the statement right the first time. Here are common errors that can occur:
-
ERROR 42962: Long column type column or parameter 'I' not permitted in declared global temporary tables or procedure definitions.
This error occurs if you declare a Derby procedure or function using an argument type that is not supported.
-
ERROR 42X50: No method was found to be able to match method call pack.A.p(int), even tried all combinations of object and primitive types and any possible type conversion for any parameters the method call may have. It may be that the method exists, but it is not public and/or static, or that the parameter types are not method invocation convertible.
This error occurs when you make a call to a procedure/function, if Derby is not able to find the Java method that matches the procedure/function declaration. The error message mentions the signature of the Java method that could not be found.
Please note that if you change the Java code of the method, it is necessary to stop and restart the Derby network server, so that the class loader of the database engine loads the new code.
Once the Derby routine is created successfully you can test it by calling it through the ij command line. A derby procedure can be invoked using a CALL statement but in this case you want to test a function so issue the following command:
Listing 9. Calling the Java method in Derby
values(updateQuantity(1, 'title', 'author', 5, 15));
|
IJ displays the return value, which is 1, because the high limit was reached. Since the Java method is running in the Derby server JVM, the debug message will be printed in the server?s standard output. Use the eclipse console view to switch to the Derby network server console and you should see a Sending email... message.
You can also try calling the Derby function directly from your JDBC application using the following code:
Listing 10. Calling the Java method from the client application
stmt.executeQuery("values(updateQuantity(1, 'title', 'author', 5, 15)); ");
|
The result should be the same as in your previous test.
Call the function from a Derby trigger
The last step of this section is to configure Derby to call the previously declared function each time the quantity of a book is updated. This can be done with a trigger.
A derby trigger contains information about the action to perform, as well as when to execute this action.
Table 6. The clauses of the CREATE TRIGGER statement
| INSERT, DELETE or UPDATE | UPDATE | | REFERENCING clause | OLD AS OLD, NEW AS NEW. You want to be able to refer to the old and new quantity to call the function | | FOR EACH clause | FOR EACH ROW. The function will be called for each row even if several rows are updated | | Action | update books set status = updateQuantity(?) where id = NEW.id; |
Here is the statement to issue in ij to create the trigger:
Listing 11. CREATE TRIGGER statement
create trigger updateQuantityTrig after update of quantity on books
referencing OLD as OLD NEW as NEW for each row mode db2sql
update books set status = updateQuantity(NEW.id, NEW.title, NEW.author,
OLD.quantity, NEW.quantity) where id = NEW.id;
|
An easy way to check if the trigger work is to update the book table from within the ij tool using the following command: update books set quantity=10 where id=1; The table modification will trigger the invocation of the function, which will cause the execution of the Java method. This will update the status of the book and send a message that can be viewed by switching to the network server consol view.
Since the trigger is stored directly in the database, it will be invoked consistently regardless of how the data is updated. For this reason, if you try updating quantities using your client application, you will see that the email message is generated when appropriate, without having to make changes to the application.
The following images display the output of the client application, using the initial data. Notice that this time, the status of the book is updated, and a message is generated:
Figure 9. Sample output of the Inventory application
Figure 10. Sample output of the Network Server
Deploy the application
At this point, you have a fully functional database and client application, but they both run from within your Eclipse environment, which is not acceptable on a production system. It is therefore necessary to perform the deployment of your application.
Store the Java function in the database
As mentioned earlier, a Derby Java function or procedure is executed by the database engine itself. The Java class must therefore be accessible by the engine. In this case, this works because the Derby network server runs within the Eclipse project, and uses the project?s class path, which includes all the Java classes you created.
In a typical production environment, you do not want to modify the class path for the Derby network server. Derby provides several procedures that solve this problem:
- The
sqlj.install_jar procedure installs a JAR file into the database itself. Once installed, the JAR file cannot be modified but you can use the sqlj.remove_jar and sqlj.replace_jar to remove or update the JAR.
- The
derby.database.classpath property contains additional classpath entries that will be used by the database. This property can be updated using the syscs_util.syscs_set_database_property procedure to update the property and include the installed JAR.
For the purpose of this example, you first create a JAR file containing your DerbyFunctions class. This can be done in Eclipse by right-clicking on the class and selecting Export->JAR file.
You can then install the JAR file into your database and add it to the class path, using the following commands (in ij):
Listing 12. Storing a JAR file in the Derby database
CALL sqlj.install_jar('functions.jar', 'bookstore.functionsjar', 0);
CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY(
'derby.database.classpath', 'bookstore.functionsjar');
|
Once this is done, the Java code belongs to the database which makes it very easy to move and start the database. The entire database directory can simply be moved to a completely different environment and will still run as expected.
Network server configuration
While developing your application you used the network server configuration so deploying it is just a matter of packaging the various components the correct way.
On the server side, you need to install:
-
derby.jar containing the Derby database engine
-
derbynet.jar containing the network server
-
bookstoredb/ directory which contains the database, including the JAR file with the functions.
These components can be copied on any machine that has a JVM, and the network server can be started using the following command:
Listing 13. Starting the Derby network server
java -cp derby.jar;derbynet.jar org.apache.derby.drda.NetworkServerControl start
|
And stopped using:
Listing 14. Stopping the Derby network server
java -cp derby.jar;derbynet.jar org.apache.derby.drda.NetworkServerControl shutdown
|
On the client side, you need to install:
-
db2jcc.jar and db2jcc_license_c.jar for the JDBC driver
-
inventory.jar that contain your application classes. This JAR file can be easily created using the eclipse export feature on the application package.
These components can be copied to any machine that has a JVM. Once the network server is running, the application can be started using the following command:
Listing 15. Starting the client application
java -cp db2jcc.jar;db2jcc_license_c.jar;inventory.jar bookstoreapp.clientside.Inventory
|
The following image illustrates the deployment of your application in the network server configuration:
Figure 11. Network server deployment configuration
The following images show the execution of the application in the production environment:
Figure 12. Execution of the deployed network server
Figure 13. Execition of the deployed client application
Embedded server configuration
The network server configuration is probably the most appropriate for this type of application but you could also decide to use the embedded server configuration, for performance reasons for example.
Before deploying the application, it is necessary to make a change in the code so that the connection is made to an embedded server rather than a remote one. This can be done by simply changing the JDBC driver class name, and the connection URL:
Listing 16. New connection code
Class.forName("org.apachy.derby.jdbc.EmbeddedDriver");
String url = "jdbc:derby:bookstoredb";
|
Once this change is made, you can simply JAR the application classes using the Eclipse export feature and deploy the following files on the production machine:
-
derby.jar containing the Derby database engine and JDBC driver
-
inventory.jar containing the application classes
-
bookstoredb/ directory containing the database, including the JAR file with the stored procedures and functions
The Application can be started using the following command:
Listing 17. Starting the application
java -cp derby.jar;inventory.jar bookstoreapp.clientside.Inventory
|
The following image illustrates the deployment of your application in the embedded server configuration:
Figure 14. Embedded server deployment configuration
Migrate to DB2
Although Apache Derby is a very robust and scalable database, there might be reasons to switch to an enterprise database such as DB2 UDB:
- Missing features
- Performance limitations
- Need to be integrated with other databases
The migration can be fairly easy done thanks to the DB2 plug-ins for Eclipse and because the client application is based on the standard JDBC interface.
Migrate the database
The first step is to migrate the database itself. The DB2 plug-ins for Eclipse features a tool to automatically migrate an Apache Derby database to DB2 for Linux, Unix and Windows.
First create a DB2 database by issuing a create database bookstoredb command in the DB2 CLP
The migration tool can then be invoked by right-clicking on the derby database item in the Database Explorer view you created earlier, and selecting ?Migrate to DB2 UDB?? action. Make sure your DB2 server is started and follow the instructions to create the DB2 database, migrate the database objects and migrate the actual data.
Figure 15. Migrating the Derby database using the DB2 plug-ins for Eclipse
Manually migrate the unsupported objects
Once the database migration is complete, the tool shows a report indicating that the migration was successful but that some objects could not be migrated. The current version of the tool does not support triggers and functions so it is necessary to migrate these objects manually.
The Apache Derby SQL language is compatible with DB2 so you can simply reuse your previous SQL statements to create the missing objects. Right-click on the DB2 connection in the Database Explorer, and open a new SQL Scrapbook.
Installing the JAR file for the Java function is done the same way as with Derby, except it is not necessary to add the JAR file to the class path. Open a SQL scrapbook from the DB2 connection, and type in the following command:
Listing 18. Installing the JAR file in DB2
CALL sqlj.install_jar('functions.jar', 'bookstore.jar1', 0)
|
To create the function and trigger you simply copy and paste the previously used SQL statement into the SQL scrapbook. Remember that you can execute only one statement at a time and that you should not use a colon character as terminator.
Listing 19. Creating the function and the trigger in DB2
create function bookstore.updateQuantity(id int, title varchar(128), author varchar(128),
oldQuantity int, newQuantity int) returns int
PARAMETER STYLE JAVA NO SQL LANGUAGE JAVA
EXTERNAL NAME 'bookstoreapp.StoredProcs.updateQuantity'
create trigger bookstore.updateQuantityTrig after update of quantity on books
referencing OLD as OLD NEW as NEW for each row mode db2sql
VALUES(updateQuantity(NEW.id, NEW.title, NEW.author, OLD.quantity, NEW.quantity))
|
Migrate the client application
Migrating the client application is mainly a matter of changing the code that established the database connection:
- Right click on the bookstore project and select 'Apache Derby->Remove Apache Derby nature' since you are not using Derby anymore. This will remove the Derby JAR files from the build path.
- Edit the Java build path of the project, and add the DB2 JDBC driver jar files:
db2jcc.jar and db2jcc_license_cisuz.jar, that can usually be found under the C:\Program Files\IBM\SQLLIB\java\ directory , for a Windows machine
- In the Java code change the class name of the JDBC driver to
com.ibm.db2.jcc.DB2Driver
- Also change the connection URL to:
jdbc:db2://localhost:50000/BOOKSTORE and change the user name and password
- Since you probably don?t have a bookstore user name, it is necessary to change the DB2 default schema. This can be done by issuing the following command at the initialization of the client application:
stmt.execute("SET CURRENT SCHEMA = bookstore");
Although the JDBC API allows you to connect to any database the same way, the actual SQL queries that are sent to the database must conform to the database SQL language. Migrating a JDBC application therefore requires the rewriting of certain SQL queries. In this case, the Derby language is a subset of the DB2 language so this is not an issue, and you do not need to make any modifications to the SQL queries.
The application should now compile and run successfully on the DB2 database. It can also be deployed in a similar way as with the Derby network server configuration.
Summary
After reading this article, you should be able to effectively develop Apache Derby applications using the various Eclipse-based tools available for Derby. You should also be able to perform related tasks such as deploying the application in the various possible configurations, or to migrate the database and application to DB2 UDB.
Download | Description | Name | Size | Download method |
|---|
| Java source code for the Inventory application | Inventory.java | 2 KB | HTTP |
|---|
Resources
About the author  | 
|  | Gilles Roux is an Information Management software engineer in the IBM DB2 organization. His main focus is to develop database migration tools. |
Rate this page
|