Top Banner
Improve persistence with Apache Derby and iBATIS, Part 1: Initial configuration, semantics, and a simple test Skill Level: Intermediate Daniel Wintschel ([email protected]) Freelance writer 24 Jan 2006 The iBATIS database-mapping framework -- a popular Java™ framework for object-relational (OR) mapping -- is now an Apache open source project. This tutorial is the first in a three-part series demonstrating how to combine Apache Derby's power as a small-footprint embeddable database with iBATIS and use this combination to improve persistence in your database-driven Java applications. In Part 1, you learn about iBATIS's advantages as a persistence mechanism and focus on the iBATIS Data Mapper framework. Section 1. Before you start About this series This tutorial is the first in a three-part series that introduces you to the iBATIS Data Mapper and Data Access Objects (DAO) frameworks and shows you how to use iBATIS with Apache Derby. Part 1 discusses the concepts underlying iBATIS, including descriptions of the Data Mapper and DAO frameworks, and outlines the semantics and terminology that iBATIS uses. You look at some basic examples of how to configure Apache Derby with iBATIS and perform simple object-relational (OR) mapping using Data Mapper. Part 2 focuses on the DAO framework, from the application layer down to the Initial configuration, semantics, and a simple test © Copyright IBM Corporation 1994, 2008. All rights reserved. Page 1 of 23
23

Improve persistence with Apache Derby and iBATIS, Part 1 ... · iBATIS Data Access Objects framework (DAO framework) The DAO framework's main goal is to abstract the how and where

Jul 22, 2020

Download

Documents

dariahiddleston
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Improve persistence with Apache Derby and iBATIS, Part 1 ... · iBATIS Data Access Objects framework (DAO framework) The DAO framework's main goal is to abstract the how and where

Improve persistence with Apache Derby andiBATIS, Part 1: Initial configuration, semantics, anda simple testSkill Level: Intermediate

Daniel Wintschel ([email protected])Freelance writer

24 Jan 2006

The iBATIS database-mapping framework -- a popular Java™ framework forobject-relational (OR) mapping -- is now an Apache open source project. This tutorialis the first in a three-part series demonstrating how to combine Apache Derby'spower as a small-footprint embeddable database with iBATIS and use thiscombination to improve persistence in your database-driven Java applications. InPart 1, you learn about iBATIS's advantages as a persistence mechanism and focuson the iBATIS Data Mapper framework.

Section 1. Before you start

About this series

This tutorial is the first in a three-part series that introduces you to the iBATIS DataMapper and Data Access Objects (DAO) frameworks and shows you how to useiBATIS with Apache Derby.

Part 1 discusses the concepts underlying iBATIS, including descriptions of the DataMapper and DAO frameworks, and outlines the semantics and terminology thatiBATIS uses. You look at some basic examples of how to configure Apache Derbywith iBATIS and perform simple object-relational (OR) mapping using Data Mapper.

Part 2 focuses on the DAO framework, from the application layer down to the

Initial configuration, semantics, and a simple test© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 1 of 23

Page 2: Improve persistence with Apache Derby and iBATIS, Part 1 ... · iBATIS Data Access Objects framework (DAO framework) The DAO framework's main goal is to abstract the how and where

data-access and Derby database layers. You use the DAO framework with the DataMapper framework through the JPetStore application. Using the DAO with the DataMapper provides you with a clean and consistent way of accessing your application'sunderlying data structure.

Part 3 uses the Data Mapper to cover transaction handling, data caching, andcreating dynamic SQL statements. It also takes a brief look at, and provides anexample of, how to use the DAO framework without the Data Mapper framework tointegrate it as a stand-alone framework within an application.

About this tutorial

As a developer, you've likely had the frequent responsibility of mapping your Javaobjects to relational database tables for persistence. Persistence is the ability to readobjects from, write objects to, and delete objects from permanent storage -- a topicdiscussed ad infinitum in the Java community. This is where iBATIS comes in. It's asimple and powerful framework that does a great job of OR mapping, letting yousolve business problems instead of mucking around with boilerplate code.

iBATIS consists of two frameworks, one of which -- the Data Mapper -- pertainsspecifically to OR mapping. The Data Mapper is this tutorial's main focus. You'll usethe versatile Apache Derby as an embedded database for your persistence layer inthe tutorial's example exercises.

Prerequisites

This tutorial assumes that you're comfortable working with basic SQL statements,that you understand basic XML semantics, and that you don't have any troublereading through Java code. You need to know how to run Apache Ant to follow thetutorial's examples and create the database.

System requirements

To run the example code in this tutorial, perform the following steps:

1. Download and install the following applications:

• Apache Derby 10.1.1.0

• Apache Ant 1.6.5

• Java 2 Platform, Standard Edition (J2SE) 1.4.2_09You don't need to download iBATIS separately, because the necessary

developerWorks® ibm.com/developerWorks

Initial configuration, semantics, and a simple testPage 2 of 23 © Copyright IBM Corporation 1994, 2008. All rights reserved.

Page 3: Improve persistence with Apache Derby and iBATIS, Part 1 ... · iBATIS Data Access Objects framework (DAO framework) The DAO framework's main goal is to abstract the how and where

.jar files are included with the source code for this tutorial, which youdownload in step 3.

2. Make sure that the environmental variables outlined in Table 1 aredefined in your shell.Table 1. Setting the environmental variables

Variable name Required setting

DERBY_HOME Set to the root folder of your Derbyinstallation.

ANT_HOME Set to the root folder of your Antinstallation.

JAVA_HOME Set to the root folder of your Javainstallation.

PATH Ensure that ANT_HOME/bin is inyour path.

3. Extract the supplied .zip file (see the Download section) to your preferredlocation. (This is the project root.) The project is laid out in Listing 1:Listing 1. Project layout

/iBATIS//lib/ ' iBATIS JAR files to be included in the classpath/sql/ ' file containing DDL to create your database/src/ ' Java source code and iBATIS XML configs/build.xml ' Ant build file

4. Modify the /src/properties/database.properties file to specify where youwould like Derby to create your database. I've set the url property in thedatabase.properties file to be jdbc:derby:c:/temp/ibatis. See thedatabase.properties file, shown in Listing 2, and change the path toinclude something appropriate for your file system.Listing 2. The database.properties file

##################################### Database Connectivity Properties####################################

driver=org.apache.derby.jdbc.EmbeddedDriverurl=jdbc:derby:c:/temp/ibatisusername=password=

Make sure that the value you specify is an existing empty directory. Youcan leave the username and password blank, as they are. If you're on aUNIX® or Linux® system, your path looks something like /tmp/ibatis, but

ibm.com/developerWorks developerWorks®

Initial configuration, semantics, and a simple test© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 3 of 23

Page 4: Improve persistence with Apache Derby and iBATIS, Part 1 ... · iBATIS Data Access Objects framework (DAO framework) The DAO framework's main goal is to abstract the how and where

you can create this directory wherever you want.

Section 2. What is iBATIS?

This section describes the separate APIs within iBATIS and why you might usethem, and identifies iBATIS's advantages over other database-mapping frameworks.

The iBATIS frameworks

Simply put, iBATIS consists of two separate frameworks. You use the Data Mapperframework specifically for OR mapping, which is the mapping of your Java domainobjects to relational tables in a database. The DAO framework gives your applicationa clean and consistent way to access underlying data.

iBATIS Data Mapper framework (Data Mapper)

The Data Mapper is the framework that executes your SQL and maps the resultsback to objects, saving you from having to do this manually.

The Data Mapper framework doesn't require you to make any special version of yourJava objects. You don't need to implement any interfaces or generate any code. Youdon't need to subclass some other base object or perform any strange rituals. Andyou don't need to learn a secondary query language specific to the framework.

You use a simple and straightforward XML format to define the manner in whichiBATIS maps your Java objects to the database. You can define the exact query youneed directly in SQL and optionally use any proprietary SQL that is specific to thedatabase engine you're using. This capability lets you map your objects exactly theway you want and perform joins exactly the way you want.

iBATIS Data Access Objects framework (DAO framework)

The DAO framework's main goal is to abstract the how and where of yourapplication's data-access or persistence layer from the application's business logic.The DAO framework lets you define interfaces in your application that areresponsible for data-centric operations.

For example, if your application uses straight-up Java Database Connectivity(JDBC) for persistence, the DAO framework's goal is to abstract the use of classesand interfaces, such as Connection, PreparedStatement, and ResultSet,

developerWorks® ibm.com/developerWorks

Initial configuration, semantics, and a simple testPage 4 of 23 © Copyright IBM Corporation 1994, 2008. All rights reserved.

Page 5: Improve persistence with Apache Derby and iBATIS, Part 1 ... · iBATIS Data Access Objects framework (DAO framework) The DAO framework's main goal is to abstract the how and where

away from your application and move it down into a persistence layer instead.

If your application for some reason uses HTTP GETs and POSTs to get and storedata, then the DAO framework's purpose becomes to abstract the use of classes,such as HttpUrlConnection, away from your application's business layer. Yourapplication can then use the DAO interfaces to perform operations on your data, andthe implementations of these interfaces are abstracted away from your businesslogic. The implementations can retrieve data from a database, a Web service, or anyother source.

The DAO framework doesn't depend on the use of the Data Mapper framework. Youcan use both frameworks in a project should you choose (and they pair quite nicely),or you can use each one independently. This tutorial series shows the advantages ofusing the frameworks alone and together.

Advantages of iBATIS

iBATIS has some advantages over other OR mapping tools:

• iBATIS doesn't use its own proprietary query language; it just uses SQL.Some OR mapping tools, such as Hibernate, use their own querylanguages in addition to SQL.

• All the queries and updates you want to perform are written in SQL (andstored in .xml files). Some people might consider this a disadvantage,wanting the database abstracted from them completely to avoid needingto write any SQL code. This is one reason a lot of developers likeHibernate. But you might prefer to have fine-grained control over exactlywhat SQL is being executed when you access your objects, rather thanhaving it unpredictably generated for you in a manner dependent on theunderlying OR mapping framework. You can fine-tune your queries andother statements based on recommendations by a database administrator(DBA) or by access plans or query optimizers provided by the toolssupplied with your relational database management system (RDBMS).Another benefit of having direct access over the SQL that is written forthis layer is that you can take advantage of any proprietary SQL offeredby your database.

• It's easy to use.

• The project is well documented.

• It has no external dependencies. Some of the other OR mappingframeworks ship with 15 to 20 .jar files and are dependent on specificversions of these files just to let the framework run. You don't need orwant that kind of a headache when developing applications, so the fact

ibm.com/developerWorks developerWorks®

Initial configuration, semantics, and a simple test© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 5 of 23

Page 6: Improve persistence with Apache Derby and iBATIS, Part 1 ... · iBATIS Data Access Objects framework (DAO framework) The DAO framework's main goal is to abstract the how and where

that you can use iBATIS without any external dependencies is a hugeplus. (Note that some optional configurations let you enable things like anexternal connection pool or bytecode enhancement, but none of them isrequired.)

Now it's time to dive into some more specific iBATIS concepts and semantics, whicheventually lead to some coding and examples.

Section 3. iBATIS Data Mapper semantics

The remainder of this tutorial examines the Data Mapper framework almostexclusively. (Part 2 covers the DAO framework in depth.) This section covers DataMapper semantics.

Mapped Statements

The Data Mapper's core functionality revolves around the concept of MappedStatements. A Mapped Statement can have what are called Parameter Maps(basically, data input) and Result Maps (data output). So a Mapped Statement isessentially an XML element that contains an SQL statement responsible forperforming some action and mapping input/output parameters to Java objects.Listing 3 shows a simple SQL Mapped Statement that comes from the JPetStoredemo (see Resources for a link to the download).

Listing 3. A simple SQL Mapped Statement

<select id="getUsernameList"resultClass="string"parameterClass="account">

select USERNAME as value from SIGNON</select>

The Mapped Statement in Listing 3 is responsible for querying for all values of theUSERNAME column from the SIGNON table. There are several different types ofMapped Statements. As you can see, this particular Mapped Statement is a<select>. In addition to <select>, you can take advantage of <statement>,<insert>, <update>, <delete>, and <procedure> Mapped Statementelements when using the iBATIS framework. The iBATIS documentation coverseach of these in more detail (see Resources for a link to the iBATIS Web site).

Parameter Maps and inline parameters

developerWorks® ibm.com/developerWorks

Initial configuration, semantics, and a simple testPage 6 of 23 © Copyright IBM Corporation 1994, 2008. All rights reserved.

Page 7: Improve persistence with Apache Derby and iBATIS, Part 1 ... · iBATIS Data Access Objects framework (DAO framework) The DAO framework's main goal is to abstract the how and where

Parameter Maps in the iBATIS framework provide data-input parameters to aMapped Statement. Parameter Maps are not often used in and of themselves(usually inline parameters are used instead), but Listing 4 shows an example of howthey work, with an example Parameter Map and a Mapped Statement from thedocumentation.

Listing 4. Parameter Maps in the iBATIS framework

<parameterMap id="insert-product-param" class="com.domain.Product"><parameter property="id" jdbcType="NUMERIC"

javaType="int" nullValue="-9999999"/><parameter property="description" jdbcType="VARCHAR"

nullValue="NO_ENTRY"/></parameterMap>

<statement id="insertProduct" parameterMap="insert-product-param">insert into PRODUCT (PRD_ID, PRD_DESCRIPTION) values (?,?);</statement>

You can see that the Mapped Statement in Listing 4 references the Parameter Mapby name and that it contains two placeholder question marks. (You'll recognize theseas standard placeholders for JDBC PreparedStatements.) It applies the values itretrieves from the Parameter Map, in the order in which they are defined, to theseplaceholders.

The Parameter Map in Listing 4 defines that the com.domain.Product class's idproperty -- getId() -- maps to the first placeholder (question mark) in any MappedStatement that uses this Parameter Map. It goes on (with the next parameterelement) to state that the com.domain.Product class's descriptionproperty -- getDescription() -- maps to the second placeholder (questionmark) in any Mapped Statement that uses it. Within a parameterMap, the order inwhich parameter elements appear is the same order in which they are applied tothe placeholder question marks within the Mapped Statement that uses theparameterMap.

More commonly, input parameters are mapped with inline parameters (see Listing5).

Listing 5. Inline parameters

<statement id="insertProduct" parameterClass="com.domain.Product">insert into PRODUCT (PRD_ID, PRD_DESCRIPTION)values (#id#, #description#);

</statement>

This syntax replaces #id# with the value returned by getId() from thecom.domain.Product class, while #description# is replaced by the valuereturned by getDescription() of com.domain.Product. You can take a lookat the iBATIS documentation for how to specify null values.

ibm.com/developerWorks developerWorks®

Initial configuration, semantics, and a simple test© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 7 of 23

Page 8: Improve persistence with Apache Derby and iBATIS, Part 1 ... · iBATIS Data Access Objects framework (DAO framework) The DAO framework's main goal is to abstract the how and where

Result Maps

Result Maps are like Parameter Maps but are used for output. Result Maps let youdefine the manner in which you would like your Mapped Statements (typicallyqueries) mapped back into a Java object. Listing 6 provides a quick look at anexample from the iBATIS documentation.

Listing 6. Result Maps

<resultMap id="get-product-result" class="com.domain.Product"><result property="id" column="PRD_ID"/><result property="description" column="PRD_DESCRIPTION"/>

</resultMap>

<statement id="getProduct" resultMap="get-product-result">select * from PRODUCT

</statement>

You can see that the Mapped Statement with the id of getProduct specificallyreferences the Result Map entitled get-product-result and tells the MappedStatement to map the PRD_ID database column to the Java id property of thecom.domain.Product class, and also states to map the PRD_DESCRIPTIONdatabase column to the Java description property of the com.domain.Productclass.

I always like to specify the exact columns I'm selecting (rather than use SELECT *FROM, for example).

TransactionManager

The TransactionManager element within the Data Mapper framework lets youconfigure what you want the transaction services to be like for a given configuration.The currently supported types for this element are:

• JDBC - The JDBC transaction manager controls transactions internally viathe java.sql.Connection interface's commit() and rollback()methods.

• JTA - A global Java Transaction API (JTA) transaction is used andrequires a UserTransaction to be available via the Java Naming andDirectory Interface (JNDI) -- or whatever other means.

• EXTERNAL - You manage transactions on your own. This is also a fineoption for nontransactional data sources for which you must manage anytransactions yourself anyway.

Part 3 of this tutorial series examines transactions in more detail.

developerWorks® ibm.com/developerWorks

Initial configuration, semantics, and a simple testPage 8 of 23 © Copyright IBM Corporation 1994, 2008. All rights reserved.

Page 9: Improve persistence with Apache Derby and iBATIS, Part 1 ... · iBATIS Data Access Objects framework (DAO framework) The DAO framework's main goal is to abstract the how and where

Section 4. Configure Derby and iBATIS

This section covers everything you need to do to get a basic Derby and iBATISconfiguration up and running. (As mentioned previously, this tutorial covers the DataMapper framework and saves the Data Access Object configuration and use for Part2.)

JAR files

One of the great things about using Apache Derby and iBATIS together is the sheerlack of dependencies. The only things you need here are the derby.jar file to runDerby and the ibatis-common-2.jar and ibatis-sqlmap-2.jar files. (If you were usingthe DAO framework you would also need the ibatis-dao-2.jar file, but that isn'tdemonstrated in this tutorial.)

Note that if you want to take advantage of some of iBATIS's additional capabilities,such as bytecode enhancement or centralized/distributed caching, you need toinclude the libraries that iBATIS uses (CGLIB and OS Cache, respectively, in thesecases). These additional components are usually not necessary.

Configuration files

iBATIS requires little configuration to get up and running. The Data Mapperframework requires a single XML configuration file (typically calledsql-map-config.xml) that defines items pertaining to transaction management andhow to connect to the database. It's also where you specify the list of .xml files thatcontain your Mapped Statements, Result Maps, and so on. Take a quick look at thesql-map-config.xml file that you'll use in the simple example for this tutorial (seeListing 7).

Listing 7. The sql-map-config.xml

<!DOCTYPE sqlMapConfig PUBLIC"-//ibatis.apache.org//DTD SQL Map Config 2.0//EN""http://ibatis.apache.org/dtd/sql-map-config-2.dtd">

<sqlMapConfig>

<properties resource="properties/database.properties"/>

<settings cacheModelsEnabled="true" enhancementEnabled="false"maxSessions="64" maxTransactions="8" maxRequests="128"/>

ibm.com/developerWorks developerWorks®

Initial configuration, semantics, and a simple test© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 9 of 23

Page 10: Improve persistence with Apache Derby and iBATIS, Part 1 ... · iBATIS Data Access Objects framework (DAO framework) The DAO framework's main goal is to abstract the how and where

<transactionManager type="JDBC"><dataSource type="SIMPLE"><property value="${driver}" name="JDBC.Driver"/><property value="${url}" name="JDBC.ConnectionURL"/><property value="${username}" name="JDBC.Username"/><property value="${password}" name="JDBC.Password"/><property value="15" name="Pool.MaximumActiveConnections"/><property value="15" name="Pool.MaximumIdleConnections"/><property value="1000" name="Pool.MaximumWait"/>

</dataSource></transactionManager>

<sqlMap resource="net/humandoing/invoicing/domain/sql/Sequence.xml"/><sqlMap resource="net/humandoing/invoicing/domain/sql/Product.xml"/>

</sqlMapConfig>

In Listing 7 you have only one .xml file that describes mappings -- in this caseProduct.xml. Typically, you would define this information in several files, brokendown to perhaps one .xml file per domain object. Also, note how the XML filereferences a database.properties file, which contains information on how to connectto the database. Listing 8 shows an example database.properties file.

Listing 8. A database.properties file

##################################### Database Connectivity Properties####################################

driver=org.apache.derby.jdbc.EmbeddedDriverurl=jdbc:derby:c:/temp/ibatisusername=password=

Here you've provided just the fully qualified name of the embedded Derby driver toiBATIS as well as a valid JDBC URL. You don't specify a username and password,because you aren't concerned with security in this example.

Other than the configuration file in Listing 7, the Data Mapper framework requiresonly whatever .xml files you define that describe your database queries and how tomap your objects to and from the database. Upcoming sections discuss theProduct.xml file for your example application.

Although you won't be using it in this tutorial, the DAO framework also requires asingle, simple .xml configuration file (typically called dao.xml) and contains a list ofitems similar to those in the Data Mapper configuration. This includestransaction-management information and a list of DAO interface and implementationpairs. (Part 2 of this tutorial series discusses this at length.)

Setting iBATIS up for Derby

Because you'll use Derby's embedded mode, and because iBATIS abstracts all thedatabase access, you only need to provide iBATIS with the right driver and the right

developerWorks® ibm.com/developerWorks

Initial configuration, semantics, and a simple testPage 10 of 23 © Copyright IBM Corporation 1994, 2008. All rights reserved.

Page 11: Improve persistence with Apache Derby and iBATIS, Part 1 ... · iBATIS Data Access Objects framework (DAO framework) The DAO framework's main goal is to abstract the how and where

database URL. iBATIS boots the database for you and subsequently providesaccess to the database any time you make database-specific calls to the iBATISframework.

With that simple setup done, you're ready to use the Data Mapper framework tobuild a simple sample application.

Section 5. Test Derby and iBATIS

When you're done with Part 1 of this tutorial series, you'll use theJPetStore application for Parts 2 and 3. The JPetStore application isa sample iBATIS application that can be downloaded along with theframework. If you want to do some extra reading or fiddling aroundwith iBATIS, you can download it from the iBATIS Web site (seeResources for a link).

Now that you know some of the fundamentals of iBATIS and the concepts behind it,you can put it to good use in a little example. In this section, you create a simpleProduct class and a Sequence class. You use the Sequence class as aprimary-key generator for defining unique keys for your products. The followingtakes you through the example component by component and then brings it alltogether at the end of this section.

Define objects

First, define the Java objects that you want to persist to the database. There'snothing special here, because iBATIS doesn't require you to extend any superclassor implement any interfaces. Listing 9 defines the Sequence class.

Listing 9. The Sequence class

public class Sequence {private String sequenceName;private int nextId;

public Sequence(String sequenceName, int nextId) {this.nextId = nextId;this.sequenceName = sequenceName;

}

public Sequence() {}

public int getNextId() {return nextId;

}

ibm.com/developerWorks developerWorks®

Initial configuration, semantics, and a simple test© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 11 of 23

Page 12: Improve persistence with Apache Derby and iBATIS, Part 1 ... · iBATIS Data Access Objects framework (DAO framework) The DAO framework's main goal is to abstract the how and where

public void setNextId(int nextId) {this.nextId = nextId;

}

public String getSequenceName() {return sequenceName;

}

public void setSequenceName(String sequenceName) {this.sequenceName = sequenceName;

}}

Listing 10 shows the Product class.

Listing 10. The Product class

public class Product {private int productId;private String productName;private String productDesc;private int quantity;

public Product(int productId, String productName,String productDesc,int quantity) {

this.productDesc = productDesc;this.productId = productId;this.productName = productName;this.quantity = quantity;

}

public Product() {}

public int getProductId() {return productId;

}

public void setProductId(int productId) {this.productId = productId;

}

public String getProductName() {return productName;

}

public void setProductName(String productName) {this.productName = productName;

}//...

}

As you can see, both of these classes are just plain JavaBeans with getter/settermethods and a few members. You want these classes mapped to some tables in thedatabase, so now define the database tables.

Define tables

You need a table to store products and also one from which you can get and

developerWorks® ibm.com/developerWorks

Initial configuration, semantics, and a simple testPage 12 of 23 © Copyright IBM Corporation 1994, 2008. All rights reserved.

Page 13: Improve persistence with Apache Derby and iBATIS, Part 1 ... · iBATIS Data Access Objects framework (DAO framework) The DAO framework's main goal is to abstract the how and where

increment your product sequence, which you use as a primary key. Listing 11 showsthe data model that Derby kindly takes care of for you.

Listing 11. The data model

CREATE TABLE SEQUENCE(SEQUENCE_NAME VARCHAR(32) NOT NULL,NEXT_ID INTEGER NOT NULL,CONSTRAINT SEQ_PK PRIMARY KEY (SEQUENCE_NAME)

);

CREATE TABLE PRODUCT (PRODUCT_ID INTEGER,PRODUCT_NAME VARCHAR(128),PRODUCT_DESC VARCHAR(512),QUANTITY INTEGER,CONSTRAINT PROD_PK PRIMARY KEY (PRODUCT_ID)

);

INSERT INTO SEQUENCE (SEQUENCE_NAME, NEXT_ID)VALUES ('ProductSeq', 1000);

Now you have a SEQUENCE table from which you select and increment to generateprimary keys for your PRODUCT table. You've inserted one row into the SEQUENCEtable, and you'll start the product sequence at 1000. You also have a PRODUCT tablethat contains a few columns that depict some (but by no means all) of a product'stypical attributes.

Create SQL Map

Now you need to create the SQL Maps that describe the database operation youwant to be able to perform on your Product and Sequence objects. Thesedatabase operations generally include inserts, queries, updates, and deletes.

Listing 12 shows the SQL Map for your Product class.

Listing 12. The SQL Map for the Product class

<!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN""http://ibatis.apache.org/dtd/sql-map-2.dtd">

<sqlMap namespace="Product">

<typeAlias alias="product"type="net.humandoing.invoicing.domain.Product"/>

<resultMap id="productResult" class="product"><result property="productId" column="PRODUCT_ID"/><result property="productName" column="PRODUCT_NAME"/><result property="productDesc" column="PRODUCT_DESC"/><result property="quantity" column="QUANTITY"/>

</resultMap>

<update id="updateProduct" parameterClass="product">

ibm.com/developerWorks developerWorks®

Initial configuration, semantics, and a simple test© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 13 of 23

Page 14: Improve persistence with Apache Derby and iBATIS, Part 1 ... · iBATIS Data Access Objects framework (DAO framework) The DAO framework's main goal is to abstract the how and where

update PRODUCT set PRODUCT_NAME = #productName#,PRODUCT_DESC = #productDesc#,QUANTITY = #quantity# wherePRODUCT_ID = #productId#

</update>

<select id="getProduct" resultMap="productResult"parameterClass="product">

select PRODUCT_ID, PRODUCT_NAME, PRODUCT_DESC, QUANTITYfrom PRODUCT where PRODUCT_ID = #productId#

</select>

<insert id="insertProduct" parameterClass="product">insert into PRODUCT (product_id, product_name, product_desc, quantity)values (#productId#, #productName#, #productDesc#, #quantity#)

</insert>

</sqlMap>

Note the typeAlias element. It simply lets you reference a class by a shorter alias(in this case, product) instead of the fully qualified class name.

You can also see in Listing 12 that you have a resultMap element that describeshow you want to map the ResultSet obtained by executing a query back into aProduct object. This particular resultMap maps the PRODUCT_ID column in thedatabase to the productId property of the Product class, and maps thePRODUCT_NAME column in the database to the productName property of theProduct class, and so on.

Now take a quick look at the SQL Map for the Sequence class, shown in Listing 13.

Listing 13. The SQL Map for the Sequence class

<?xml version="1.0" encoding="UTF-8" standalone="no"?><!DOCTYPE sqlMap PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN"

"http://www.ibatis.com/dtd/sql-map-2.dtd">

<sqlMap namespace="Sequence">

<typeAlias alias="sequence"type="net.humandoing.invoicing.domain.Sequence"/>

<resultMap id="sequenceResult" class="sequence"><result property="sequenceName" column="SEQUENCE_NAME"/><result property="nextId" column="NEXT_ID"/>

</resultMap>

<select id="getSequence" resultMap="sequenceResult"parameterClass="sequence">

select SEQUENCE_NAME, NEXT_ID from SEQUENCEwhere SEQUENCE_NAME = #sequenceName#

</select>

<update id="updateSequence" parameterClass="sequence">update SEQUENCE set NEXT_ID = #nextId#where SEQUENCE_NAME = #sequenceName#

</update>

</sqlMap>

developerWorks® ibm.com/developerWorks

Initial configuration, semantics, and a simple testPage 14 of 23 © Copyright IBM Corporation 1994, 2008. All rights reserved.

Page 15: Improve persistence with Apache Derby and iBATIS, Part 1 ... · iBATIS Data Access Objects framework (DAO framework) The DAO framework's main goal is to abstract the how and where

Here you have two Mapped Statements: one for getting a sequence and one forupdating the sequence. You also have a resultMap element describing how tomap the SEQUENCE table columns to the Sequence Java object.

Your testing code

Just to make things easy for you, all the testing has been included as a few targetsin the Ant build file. So you can simply run the tests by executing these targets.Before running the tests, take a look at the sql-map-config.xml file that does the workof initializing the Data Mapper framework for use (see Listing 14).

Listing 14. The sql-map-config.xml

<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE sqlMapConfig PUBLIC "-//iBATIS.com//DTD SQL Map Config 2.0//EN""http://www.ibatis.com/dtd/sql-map-config-2.dtd">

<sqlMapConfig>

<properties resource="properties/database.properties"/>

<settings cacheModelsEnabled="true" enhancementEnabled="false"maxSessions="64" maxTransactions="8" maxRequests="128"/>

<transactionManager type="JDBC"><dataSource type="SIMPLE"><property value="${driver}" name="JDBC.Driver"/><property value="${url}" name="JDBC.ConnectionURL"/><property value="${username}" name="JDBC.Username"/><property value="${password}" name="JDBC.Password"/><property value="15" name="Pool.MaximumActiveConnections"/><property value="15" name="Pool.MaximumIdleConnections"/><property value="1000" name="Pool.MaximumWait"/>

</dataSource></transactionManager>

<sqlMap resource="net/humandoing/invoicing/domain/sql/Sequence.xml"/><sqlMap resource="net/humandoing/invoicing/domain/sql/Product.xml"/>

</sqlMapConfig>

The configuration is simple and straightforward. The iBATIS documentation has afew exceptional examples and describes the configuration elements in detail. Themain thing to notice is that you are pulling the database connection information fromthe file located at properties/database.properties (which is relative to the root of theclasspath) and that you are informing the Data Mapper of two different SQL Mapsthat you would like it to load -- Sequence and Product.

Listing 15 shows the few lines of Java source code (pulled from the Test class)required to get the Data Mapper framework started. Notice that most of the codeconsists of exception handling.

Listing 15. The Java source code involved in getting the Data Mapperframework started

ibm.com/developerWorks developerWorks®

Initial configuration, semantics, and a simple test© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 15 of 23

Page 16: Improve persistence with Apache Derby and iBATIS, Part 1 ... · iBATIS Data Access Objects framework (DAO framework) The DAO framework's main goal is to abstract the how and where

private static SqlMapClient dataMapper = null;//...

Reader reader = null;try {reader = Resources.getResourceAsReader(

"net/humandoing/invoicing/domain/sql/sql-map-config.xml");dataMapper = SqlMapClientBuilder.buildSqlMapClient(reader);

} catch (Exception e) {e.printStackTrace();

}

The important bits in Listing 15 are in bold. Reader is just a java.io.Reader thatuses the Resources utility class that comes with iBATIS to get thesql-map-config.xml from the classpath, because it makes life easy for you.

The SqlMapClient instance is intended to be a long-lived object (presumably forthe life of your application), so you probably want to have a static initializer for thissomewhere and then allow access to the instance either via a staticgetInstance() method type somewhere, or perhaps bound into JNDI.

Now look at a few other snippets of code from the Test class that interact with theData Mapper framework, and then take a look at some screen captures that includeoutput from the Ant test targets.

Here is a query for a Sequence:

Sequence sequence = new Sequence("ProductSeq", -1);sequence = (Sequence)dataMapper.queryForObject("getSequence", sequence);That's it. This query creates a Sequence object with the sequence nameProductSeq. If you remember the Mapped Statement getSequence (from theSequence.xml file), you'll remember that the SELECT statement executes a querybased on the SEQUENCE_NAME. In this case, the iBATIS framework takes over andexecutes the following SQL statement against the Derby database:

select SEQUENCE_NAME, NEXT_ID from SEQUENCEwhere SEQUENCE_NAME = "ProductSeq"After you've executed the above code, you want to hold onto the sequence valuereturned, because you use it as the primary key for a new product that's created inthe Derby database. But you also want to update the sequence by incrementing theNEXT_ID column (see Listing 16).

Listing 16. Incrementing the NEXT_ID column

int nextId = sequence.getNextId();

//Update the sequence by incrementing the NEXT_ID//column.sequence.setNextId(sequence.getNextId() + 1);

developerWorks® ibm.com/developerWorks

Initial configuration, semantics, and a simple testPage 16 of 23 © Copyright IBM Corporation 1994, 2008. All rights reserved.

Page 17: Improve persistence with Apache Derby and iBATIS, Part 1 ... · iBATIS Data Access Objects framework (DAO framework) The DAO framework's main goal is to abstract the how and where

dataMapper.update("updateSequence", sequence);

Here you've saved the next valid ID in the nextId variable and then incrementedthe value and asked the Data Mapper framework to update the record in Derby. Nowcreate a product, as shown in Listing 17.

Listing 17. Creating a product

Product product = new Product(nextId,"iBATIS Sandwich","A Yummy Sandwich",24);

product = (Product) dataMapper.insert("insertProduct", product);

Voila! You now have a product saved in the database as well. Last but not least, doa query just to make sure the product got saved to the database. After all,programmers are skeptics. Any data-mapping framework that's this easy to usealmost seems too good to be true.

Product queryProd = new Product();queryProd.setProductId(nextId);queryProd = (Product) dataMapper.queryForObject("getProduct",queryProd);In this query, you create a new Product object and set the productId (to thesame value of the product you just inserted). You then go on to ask the Data Mapperframework to execute the Mapped Statement with the ID of getProduct, whichreturns a fully populated Product object that it queried from the Derby database.

Now take a quick look at how you can run some of these tests yourself.

Running the tests

The first thing you want to do is create the tables you need in the Derby database.The sample includes an Ant target for that. Just run ant create-database(making sure your current directory is at the project root) in a terminal window orIDE, and you should get something like output shown in Figure 1.

Figure 1. Ant output from the create-database target

ibm.com/developerWorks developerWorks®

Initial configuration, semantics, and a simple test© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 17 of 23

Page 18: Improve persistence with Apache Derby and iBATIS, Part 1 ... · iBATIS Data Access Objects framework (DAO framework) The DAO framework's main goal is to abstract the how and where

BUILD SUCCESSFUL -- that's something everyone likes to see. Now that your tableshave been created, do a quick query of the PRODUCT table to see if there's anythingthere. Run ant get-products, which queries for all rows within the PRODUCTtable of your Derby database. You should receive some output like that shown inFigure 2.

Figure 2. Ant output from the get-products target

All you can see here is that there are no products in the database; you see thecolumn headings, but no products. Now run the test that gets a Sequence, updatesit, creates a Product, and then queries for the product. The Ant target you want forthis one is ant run-test. The results are shown in Figure 3.

Figure 3. Ant output from the run-test target

developerWorks® ibm.com/developerWorks

Initial configuration, semantics, and a simple testPage 18 of 23 © Copyright IBM Corporation 1994, 2008. All rights reserved.

Page 19: Improve persistence with Apache Derby and iBATIS, Part 1 ... · iBATIS Data Access Objects framework (DAO framework) The DAO framework's main goal is to abstract the how and where

You have queried for the Sequence named ProductSeq, which has a NEXT_ID of1000 from the database. You then create a Product, and the output you see inFigure 3 is the result of using the Data Mapper framework to query for the productafter it has been inserted into the database. You can run the ant run-test targetas many times as you like. It continues to insert iBATIS Sandwiches into your Derbydatabase and continues to increment the sequence.

Finally, get rid of that skepticism by running the ant get-products target again toquery the database for all the product rows. You can see the result in Figure 4.

Figure 4. Ant output from the get-products target after a product has beeninserted

You can see in Figure 4 that your iBATIS Sandwich has indeed been successfully

ibm.com/developerWorks developerWorks®

Initial configuration, semantics, and a simple test© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 19 of 23

Page 20: Improve persistence with Apache Derby and iBATIS, Part 1 ... · iBATIS Data Access Objects framework (DAO framework) The DAO framework's main goal is to abstract the how and where

added to the Derby database by the iBATIS Data Mapper framework.

Section 6. Summary

This tutorial introduced the concepts and semantics behind the iBATIS Data Mapperframework. You examined configuration files and learned how to configure iBATISfor use with Derby. Lastly, you built a small example of database persistence thatused the Data Mapper framework. This exercise allowed you to experience the easewith which iBATIS lets you perform database persistence and operations within aJava application.

The iBATIS and Derby pair stands as a phenomenal way to develop Java-baseddatabase-driven applications, and serves as an excellent example of well-writtenand superbly documented open source projects.

In Part 2, you learn about the DAO framework, using it with the Data Mapperframework and the JPetStore application.

developerWorks® ibm.com/developerWorks

Initial configuration, semantics, and a simple testPage 20 of 23 © Copyright IBM Corporation 1994, 2008. All rights reserved.

Page 21: Improve persistence with Apache Derby and iBATIS, Part 1 ... · iBATIS Data Access Objects framework (DAO framework) The DAO framework's main goal is to abstract the how and where

Downloads

Description Name Size Download method

Part 1 source code iBATIS.part1source.zip335KB HTTP

Information about download methods

ibm.com/developerWorks developerWorks®

Initial configuration, semantics, and a simple test© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 21 of 23

Page 22: Improve persistence with Apache Derby and iBATIS, Part 1 ... · iBATIS Data Access Objects framework (DAO framework) The DAO framework's main goal is to abstract the how and where

Resources

Learn

• Read "DB2® UDB, WebSphere, and iBATIS" developerWorks, February 2005),which covers the iBATIS syntax, accessing data sources, and setting up IBMWebSphere® Studio Application Developer, Version 5.1.2 projects to supportiBATIS.

• Check out "Tired of hand coding JDBC? Use iBATIS as a data mappingframework instead" (developerWorks, October 2005) to learn about the use ofiBATIS as a data-mapping framework.

• Read the article "Using iBATIS SQL Maps for Java Data Access," whichdemonstrates how the latest production release (1.3.1) of SQL Maps works.

• Visit the official iBATIS site.

• Go to the iBATIS Wiki for up-to-date information on the most recent releases ofthe iBATIS framework.

• See the step-by-step tutorial, "Object-Relational Mapping with SQLMaps," onusing the iBATIS SQL Maps framework.

• Check out "iBatis DAO" for a step-by-step guide on how to use the iBATIS DAOframework in your application.

• See "The Design of a Robust Persistence Layer for Relational Databases" foran excellent discussion of persistence.

• Read "Interview: Bruce Tate on the 'Politics of Persistence'" for a comparison ofsome of the major Java persistence frameworks, including iBATIS.

• Visit the developerWorks Open source zone for extensive how-to information,tools, and project updates to help you develop with open source technologiesand use them with IBM's products.

• Check out the developerWorks Apache Derby project area for articles, tutorials,and other resources to help you get started developing with Derby today.

• Browse all the Apache articles and free Apache tutorials available in thedeveloperWorks Open source zone.

• Visit the Apache Derby Project Web site.

Get products and technologies

• Download the JPetStore demo from the iBATIS Web site.

• Innovate your next open source development project with IBM trial software,available for download or on DVD.

developerWorks® ibm.com/developerWorks

Initial configuration, semantics, and a simple testPage 22 of 23 © Copyright IBM Corporation 1994, 2008. All rights reserved.

Page 23: Improve persistence with Apache Derby and iBATIS, Part 1 ... · iBATIS Data Access Objects framework (DAO framework) The DAO framework's main goal is to abstract the how and where

• Download the Apache Derby 10.1.2.1 release.

• Download IBM Cloudscape™, Version 10.1.

Discuss

• Get involved in the developerWorks community by participating indeveloperWorks blogs.

About the author

Daniel WintschelDaniel Wintschel is a regular guy who derives great excitement from solving businessproblems, streamlining processes, and writing all sorts of Java code. He loves coffeeand is currently seeking development opportunities on a telecommuting basis fromSingapore. You can contact the author at [email protected].

ibm.com/developerWorks developerWorks®

Initial configuration, semantics, and a simple test© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 23 of 23