Using iBATIS in the Sample Application

The SpringBlog application comes with an applicationContext-ibatis.xml file that allows you to use iBATIS as implementation for the data access interfaces. If you want to use iBATIS, you need to modify the web.xml file to make sure you are using the applicationContext-ibatis.xml in the contextConfigLocation element (see Listing 10-43).

Listing 10-43: web.xml for iBATIS Data Access Layer Implementaion

image from book
<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE web-app PUBLIC     "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"     "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app>     <context-param>         <param-name>contextConfigLocation</param-name>         <param-value>             /WEB-INF/applicationContext.xml              /WEB-INF/applicationContext-db.xml              /WEB-INF/applicationContext-ibatis.xml          </param-value>     </context-param>          <!-- the rest of the file omitted -->      </web-app>
image from book

The applicationContext-ibatis.xml file contains a definition for the SqlMapClientFactoryBean bean, which is used in the subsequent iBATIS DAO implementations. The only configuration setting we used in Listing 10-43 is the configLocation property, which specifies the location of the master mapping file. The bean definition is shown in Listing 10-44.

Listing 10-44: sqlMapClient Bean Definition

image from book
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans>     <!-- SqlMap setup for iBATIS Database Layer -->     <bean bold">sqlMapClient"          >         <property name="configLocation">             <value>WEB-INF/sql-map-config.xml</value>         </property>     </bean> </beans> 
image from book

The sql-map-config.xml file is located in /data/src/ibatis and it references the Attachment.xml, Audit.xml, Comment.xml, Entry.xml, and User.xml files that contain mapping definitions for the respective domain objects. The build.xml Ant script packages the sql-map-config.xml file to the WEB-INF directory. Because iBATIS loads the mapping file names specified in the sql-map-config.xml file (shown in Listing 10-45) using the current classpath, the Attachment.xml, Audit.xml, Comment.xml, Entry.xml, and User.xml files are packaged to the WEB-INF/classes directory.

Listing 10-45: sql-map-config.xml File

image from book
<?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>     <sqlMap resource="Comment.xml" />     <sqlMap resource="User.xml" />     <sqlMap resource="Entry.xml" />     <sqlMap resource="Audit.xml" />     <sqlMap resource="Attachment.xml" /> </sqlMapConfig> 
image from book

The implementation classes are located in the com.apress.prospring.data.ibatis package. All iBATIS DAO implementation classes extend the SqlMapClientDaoSupport class to get access to the utility methods, namely the getSqlMapClientTemplate(). This is why we need to set a reference to the sqlMapClient bean, as shown in Listing 10-46.

Listing 10-46: iBATIS DAO Bean Definitions

image from book
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"  "http://www.springframework.org/dtd/spring-beans.dtd"> <beans>     <!-- SqlMap setup for iBATIS Database Layer -->     <bean bold">sqlMapClient"          >         <property name="configLocation">             <value>WEB-INF/sql-map-config.xml</value>         </property>     </bean>          <bean          >         <property name="dataSource"><ref bean="dataSource"/></property>         <property name="sqlMapClient"><ref local="sqlMapClient"/></property>     </bean>          <!-- other beans similar -->      </beans>
image from book

Unlike the JDBC implementation, the SqlMapClientEntryDao class does not require references to the AttachmentDao and CommentDao implementations. Instead, the mapping file for the Entry domain object specifies how to select the data needed to create domain objects that will be added to the attachments and comments properties. Listing 10-47 shows the mapping for the Entry domain object.

Listing 10-47: Mapping File for the Entry Domain Object

image from book
<?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>     <typeAlias type="com.apress.prospring.domain.Entry" alias="entry"/>     <resultMap  >         <result property="entryId" column="EntryId"/>         <result property="subject" column="Subject"/>         <result property="body" column="Body"/>         <result property="postDate" column="PostDate" javaType="java.util.Date"/>         <result property="attachments" column="entryId"              select="getAttachmentByEntry"/>         <result property="comments" column="entryId"              select="getCommentByEntry"/>     </resultMap> </sqlMap>
image from book

The getAttachmentByEntry and getCommentByEntry select elements are declared in the Attachment.xml and Comment.xml mapping files. As expected, they return a List of Attachment and Comment objects. Therefore, selecting a single Entry object results in three select statements issued to the database, demonstrating the N+1 problem, as discussed in the "Selecting Data" section.

Another piece of code that deserves special attention includes the insert elements of the mapping files. Each insert element in the iBATIS mapping files can include a selectKey element, which specifies code required to select or generate the primary key value. An example of how to use the selectKey element is shown in Listing 10-48.

Listing 10-48: Using the selectKey Element

image from book
<?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>     <typeAlias type="com.apress.prospring.domain.Entry" alias="entry"/>     <insert  parameter>         insert into Entries (Subject, Body, PostDate)              values (#subject#, #body#, #postDate#)         <selectKey keyProperty="entryId" result>             select LAST_INSERT_ID() as value         </selectKey>     </insert> </sqlMap>
image from book

In Listing 10-48, we use the approach we explained in the "Inserting Data" section of the chapter to implement the mapping files in the SpringBlog application. Because we used select LAST_INSERT_ID() as value in the selectKey element, our mapping files are specific to the MySQL database. If you want to use a different database, most likely you will need to modify this code.

If the database you are using supports sequences, it is much better to move the selectKey element before the insert code to make sure the primary key is set correctly. Listing 10-49 shows how to do this in PostgreSQL.

Listing 10-49: Using Sequences in the selectKey Element

image from book
<?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>     <typeAlias type="com.apress.prospring.domain.Entry" alias="entry"/>     <insert  parameter>         <selectKey keyProperty="entryId" result>             select nextval('entries_entryid_         </selectKey>         insert into Entries (EntryId, Subject, Body, PostDate)              values (#entryId#, #subject#, #body#, #postDate#)     </insert> </sqlMap>
image from book

This mapping clearly shows that we first retrieve the primary key value from the entries_entryid_seq sequence and then insert a new row with the primary key already set. Further discussion of this topic is in Chapter 8.

For the remaining iBATIS data access layer implementation details, refer to the source code because it uses only features discussed in this chapter.



Pro Spring
Pro Spring
ISBN: 1590594614
EAN: 2147483647
Year: 2006
Pages: 189

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net