YOU ARE HERE: Home > Tech > J2EE > Article

Using iBATIS and struts
By John Henry Xu This article was rated:
 
Printer Version Printer Friendly | Add As Favorite | Link to Article (Page 1 of 2)|1||2|Next

About the Author

Dr. John Xu (also known as Jack Xu) is a seasoned system architect. He was chief architect for large distributed portals. He also developed search engine and Java forums. He can be reached by email xixu@yahoo.com.

In previous articles about iBATIS, we have made step-by-step instructions how to install iBATIS and use iBATIS in web application. To focus on iBATIS, we use iBATIS simply in a JSP file. In real applications, it is better move iBATIS code to some java beans.

In this article, we explore the way of using iBATIS and struts together.

You should have installed struts and iBATIS. If you don??t know how to install these software, please refer to previous struts and iBATIS articles for instructions.

You should also have installed MySQL database and created the table user_info2.

The steps for using iBATIS and struts are divided into MVC, Model, View, and Controller. We discuss View, Controller and Model in turn.

As we found in our applications, when validation framework has been used and if the data in database is not conformed to the rules of validation, there will be problems in redirections from struts. For example, suppose we have an invalid email address "test" in database and we tried to delete this item from application, the forward page can be redirected to an input page to validate this input. Thus it is required to be consistent to validate a particular data field in your application. In reality, I found some web sites that uses struts had wrong redirection due to this data inconsistency.

1. View

In this application, JSP and ActionForms are the View components. We have three JSP files, which create, update, insert and show registered users.

In this application you have records.jsp, createuser.jsp, deleteRecord.jsp, and editRecord.jsp. records.jsp shows all registered users; createuser.jsp adds a new user record; deleteRecord.jsp deletes a particular user record; editRecord.jsp lets user edit his record.

List 1.1 createuser.jsp

<%@ taglib uri="/tags/struts-html" prefix="html" %>
<%@ taglib uri="/tags/struts-bean" prefix="bean" %>
<%@ taglib uri="/tags/struts-logic" prefix="logic" %>
<html:html>
<head>
<title>http://www.usanalyst.com</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<h1><bean:message key="title.user.add"/></h1>
<logic:present name="usanalyst.success" scope="request" >
<font color=blue size=4><bean:write name="usanalyst.success"
property="strSuccess" /></font>
</logic:present>
<html:form action="/myapp-submit.do?method=insert" onsubmit="return validateRegisterForm
(this);">
<table width="62%" border="0">
<tr>
<td width="49%">
<div align="right"><b>Email</b></div>
</td>
<td width="51%">
<html:text property="email" />
</td>
</tr>
<tr>
<td width="49%">
<div align="right"><b>First Name</b></div>
</td>
<td width="51%">
<html:text property="firstName" />
</td>
</tr>
<tr>
<td width="49%">
<div align="right"><b>Last Name</b></div>
</td>
<td width="51%">
<html:text property="lastName" />
</td>
</tr>
<tr>
<td width="49%">
<div align="right"><b>Phone</b></div>
</td>
<td width="51%">
<html:text property="phone" />
</td>
</tr>
<tr>
<td width="49%"> </td>
<td width="51%">
<html:submit>
<bean:message key="button.insert"/>
</html:submit>
</td>
</tr>
</table>
<!-- Begin Validator Javascript Function-->
<html:javascript formName="registerForm"/>
<!-- End of Validator Javascript Function-->
</html:form>
</html:html>


List 1.2 records.jsp

<%@ taglib uri="/tags/struts-html" prefix="html" %>
<%@ taglib uri="/tags/struts-bean" prefix="bean" %>
<%@ taglib uri="/tags/struts-logic" prefix="logic" %>
<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %>
<%@ page import="java.util.*" %>
<%@ page import="com.usanalyst.hibernate.*" %>
<jsp:useBean id="HbRecordModel" scope="request" class="com.usanalyst.struts.HbRecordModel"
/>
<html:html>
<head>
<title>http://www.usanalyst.com</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<h1><bean:message key="title.user.record"/></h1>
<html:link page="/createuser.jsp"><bean:message
key="link.user.add"/></html:link>
<p>
<logic:present name="usanalyst.success" scope="request" >
<font color=blue size=4><bean:write name="usanalyst.success"
property="strSuccess" /></font>
</logic:present>
<logic:present name="usanalyst.update" scope="request" >
<font color=blue size=4><bean:write name="usanalyst.update"
property="strSuccess" /></font>
</logic:present>
<logic:present name="usanalyst.remove" scope="request" >
<font color=blue size=4><bean:write name="usanalyst.remove"
property="strSuccess" /></font>
</logic:present>
<%
List mylist=HbRecordModel.ViewRecordByHibernate();
pageContext.setAttribute("mylist", mylist);
int i0=0;
%>
<table>
<c:forEach var="user" items="${mylist}" varStatus="status" >
<% i0=(i0+1)%2; %>
<tr <%if(i0==1) {%> bgcolor="#ff0000" <%}else{%> bgcolor="#ffff00" <%}%>

>
<td>
<a href="/hibernateapp3/editRecord.do?recordId=<c:out value="${user.userId}"/>" >
Edit
</a>
</td>
<td>
<c:out value="${user.email}"/>
</td>
<td>
<c:out value="${user.firstName} ${user.lastName}"/>
</td>
<td>
<c:out value="${user.phone}"/>
</td>
<td>
<a href="/hibernateapp3/deleteRecord.do?recordId=<c:out value="${user.userId}"/>" >
Remove
</a>
</td>
</tr>
</c:forEach>
</table>
</html:html>

List 1.3 deleteRecord.jsp

<%@ taglib uri="/tags/struts-html" prefix="html" %>
<%@ taglib uri="/tags/struts-bean" prefix="bean" %>
<%@ taglib uri="/tags/struts-logic" prefix="logic" %>
<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %>
<%@ page import="com.usanalyst.hibernate.*" %>
<jsp:useBean id="HbRecordModel" scope="request" class="com.usanalyst.struts.HbRecordModel"
/>
<html:html>
<head>
<title>http://www.usanalyst.com</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<logic:present name="usanalyst.success" scope="request" >
<font color=blue size=4><bean:write name="usanalyst.success"
property="strSuccess" /></font>
</logic:present>
<h1><bean:message key="link.user.remove"/></h1>
<%
String recordId=request.getParameter("recordId");
Object myObject=HbRecordModel.ViewRecordById(recordId);
pageContext.setAttribute("myObject", myObject);
%>
<html:form action="/myapp-submit.do?method=deleteRecord">
<input type=hidden name="userId" value="<c:out value="${myObject.userId}"/>" />
<input type=hidden name="email" value="<c:out value="${myObject.email}"/>" />
<input type=hidden name="firstName" value="<c:out value="${myObject.firstName}"/>"
/>
<input type=hidden name="lastName" value="<c:out value="${myObject.lastName}"/>" />
<input type=hidden name="phone" value="<c:out value="${myObject.phone}"/>" />
<table width="62%" border="0">
<tr>
<td width="49%">
<div align="right"><b>Email</b></div>
</td>
<td width="51%">
<c:out value="${myObject.email}"/>
</td>
</tr>
<tr>
<td width="49%">
<div align="right"><b>First Name</b></div>
</td>
<td width="51%">
<c:out value="${myObject.firstName}"/>
</td>
</tr>
<tr>
<td width="49%">
<div align="right"><b>Last Name</b></div>
</td>
<td width="51%">
<c:out value="${myObject.lastName}"/>
</td>
</tr>
<tr>
<td width="49%">
<div align="right"><b>Phone</b></div>
</td>
<td width="51%">
<c:out value="${myObject.phone}"/>
</td>
</tr>
<tr>
<td width="49%"> </td>
<td width="51%">
<html:submit />
</td>
</tr>
</table>
</html:form>
</html:html>

List 1.4 editRecord.jsp

<%@ taglib uri="/tags/struts-html" prefix="html" %>
<%@ taglib uri="/tags/struts-bean" prefix="bean" %>
<%@ taglib uri="/tags/struts-logic" prefix="logic" %>
<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %>
<%@ page import="com.usanalyst.hibernate.*" %>
<jsp:useBean id="HbRecordModel" scope="request" class="com.usanalyst.struts.HbRecordModel"
/>
<html:html>
<head>
<title>http://www.usanalyst.com</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<logic:present name="usanalyst.success" scope="request" >
<font color=blue size=4><bean:write name="usanalyst.success"
property="strSuccess" /></font>
</logic:present>
<h1><bean:message key="title.user.edit"/></h1>
<%
String recordId=request.getParameter("recordId");
Object myObject=HbRecordModel.ViewRecordById(recordId);
pageContext.setAttribute("myObject", myObject);
%>
<html:form action="/myapp-submit.do?method=update" onsubmit="return validateRegisterForm
(this);">
<input type=hidden name="userId" value="<%=((user_info)myObject).getUserId()%>" />
<table width="62%" border="0">
<tr>
<td width="49%">
<div align="right"><b>Email</b></div>
</td>
<td width="51%">
<html:text property="email" value="<%=((user_info)myObject).getEmail()%>" />
</td>
</tr>
<tr>
<td width="49%">
<div align="right"><b>First Name</b></div>
</td>
<td width="51%">
<html:text property="firstName" value="<%=((user_info)myObject).getFirstName()%
>" />
</td>
</tr>
<tr>
<td width="49%">
<div align="right"><b>Last Name</b></div>
</td>
<td width="51%">
<html:text property="lastName" value="<%=((user_info)myObject).getLastName()%>"
/>
</td>
</tr>
<tr>
<td width="49%">
<div align="right"><b>Phone</b></div>
</td>
<td width="51%">
<html:text property="phone" value="<%=((user_info)myObject).getPhone()%>" />
</td>
</tr>
<tr>
<td width="49%"> </td>
<td width="51%">
<html:submit />
</td>
</tr>
</table>
<!-- Begin Validator Javascript Function-->
<html:javascript formName="registerForm"/>
<!-- End of Validator Javascript Function-->
</html:form>
</html:html>

Above are the source code of the JSP files that user inputs information and interacts with.

In this application, we use the DynaValidatorForm that is configured within struts-config.xml
file, so we don't need compose subclasses of ActionForms.

For registration form, we add the following form definition

List 1.5 Form bean definition

<!-- Form Bean Definitions -->
<form-beans>
<form-bean name="registerForm"
type="org.apache.struts.validator.DynaValidatorForm">
<form-property name="userId" type="java.lang.String"/>
<form-property name="email" type="java.lang.String"/>
<form-property name="firstName" type="java.lang.String"/>
<form-property name="lastName" type="java.lang.String"/>
<form-property name="phone" type="java.lang.String"/>
<form-property name="method" type="java.lang.String"/>
</form-bean>
<form-bean name="forForm" type="org.apache.struts.validator.DynaActionForm">
</form-bean>
</form-beans>


2. Controller


In struts, ActionServlets is the controller, working with Action subclasses. We can use one action form to insert, update and delete in one action class by utilizing subclass from DispatchAction.

Here is the class:

List 2.1 MyDispatchAction.java

package com.usanalyst.struts;

import java.util.Map;

import javax.servlet.*;
import javax.servlet.http.*;
import org.apache.struts.action.*;
import org.apache.struts.actions.DispatchAction;
import org.apache.struts.util.MessageResources;
import org.apache.commons.beanutils.PropertyUtils;

import org.apache.struts.validator.DynaValidatorForm;

public final class MyDispatchAction extends DispatchAction {

private MyappAttributes mAttr=null;
private DynaActionForm myForm =null;
private iBatisModel mModel=null;

private void init(ActionForm form) {
mAttr=new MyappAttributes();
myForm = (DynaActionForm)form;
Map map=myForm.getMap();
// mModel=new HbappModel();
mModel=new iBatisModel();
mModel.setMap(map);
}

public ActionForward insert(ActionMapping mapping, ActionForm form, HttpServletRequest

request,
HttpServletResponse response)

throws Exception {

init(form);
mModel.insert();
mAttr.setStrSuccess("Your record has been saved.");
request.setAttribute("usanalyst.success",mAttr);
request.removeAttribute(mapping.getAttribute());

return (mapping.findForward("NotifySave"));
}

public ActionForward update(ActionMapping mapping, ActionForm form, HttpServletRequest

request,
HttpServletResponse response)

throws Exception {
System.out.println("update");
init(form);
mModel.update();
mAttr.setStrSuccess("Your record has been updated.");
request.setAttribute("usanalyst.update",mAttr);
request.removeAttribute(mapping.getAttribute());

return (mapping.findForward("UpdateSuccess"));
}

public ActionForward deleteRecord(ActionMapping mapping, ActionForm form,

HttpServletRequest request,
HttpServletResponse response)

throws Exception {
System.out.println("remove");
init(form);
mModel.delete();
mAttr.setStrSuccess("One record has been removed.");
request.setAttribute("usanalyst.remove",mAttr);
request.removeAttribute(mapping.getAttribute());

return (mapping.findForward("RemoveSuccess"));
}
}

Class MyDispatchAction.java has methods insert, update, and deleteRecord that creating new record, update an existing record, and deleting a record respectively. In MyDispatchAction.java, we used a class HbappModel.java. HbappModel.java is the model class that we will discuss in Model section. And HbappModel.java acts as a DAO object persisting data in database.
In struts-config.xml, you need to add some action mapping for multiple action mappings. The complete struts-config.xml is shown as


List 2.2 struts-config.xml

<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE struts-config PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 1.2//EN"
"http://jakarta.apache.org/struts/dtds/struts-config_1_2.dtd">

<struts-config>

<!-- Form Bean Definitions -->

<form-beans>
<form-bean name="registerForm"
type="org.apache.struts.validator.DynaValidatorForm">
<form-property name="userId" type="java.lang.String"/>
<form-property name="email" type="java.lang.String"/>
<form-property name="firstName" type="java.lang.String"/>
<form-property name="lastName" type="java.lang.String"/>
<form-property name="phone" type="java.lang.String"/>
<form-property name="method" type="java.lang.String"/>
</form-bean>
<form-bean name="forForm" type="org.apache.struts.validator.DynaActionForm">
</form-bean>
</form-beans>
<!-- Action Mapping Definitions -->
<action-mappings>

<action
path="/deleteRecord"
type="org.apache.struts.actions.ForwardAction"
name="forForm"
parameter="/deleteRecord.jsp"
scope="request"
validate="false"
input="/records.jsp"
>
</action>

<action
path="/editRecord"
type="org.apache.struts.actions.ForwardAction"
name="forForm"
parameter="/editRecord.jsp"
scope="request"
validate="false"
input="/records.jsp"
>
</action>

<action
path="/myapp-submit"
type="com.usanalyst.struts.MyDispatchAction"
parameter="method"
name="registerForm"
scope="request"
validate="true"
input="/createuser.jsp"
>
<forward
name="NotifySave"
path="/records.jsp" />
<forward
name="UpdateSuccess"
path="/records.jsp"/>
<forward
name="RemoveSuccess"
path="/records.jsp"/>
</action>

</action-mappings>

<!-- Controller Configuration -->
<controller
processorClass="org.apache.struts.tiles.TilesRequestProcessor"/>

<!-- Message Resources Definitions -->
<message-resources parameter="MessageResources" />

<!-- Plug Ins Configuration -->
<plug-in className="org.apache.struts.tiles.TilesPlugin" >
<!-- Path to XML definition file -->
<set-property property="definitions-config"
value="/WEB-INF/tiles-defs.xml" />
<!-- Set Module-awareness to true -->
<set-property property="moduleAware" value="true" />
</plug-in>

<!-- Validator plugin -->
<plug-in className="org.apache.struts.validator.ValidatorPlugIn">
<set-property
property="pathnames"
value="/WEB-INF/validator-rules.xml,/WEB-INF/validation.xml"/>
</plug-in>
</struts-config>


3. Model


Using iBatis, you need set up iBATIS configuration files. You need sqlMap-config.xml file in %TOMCAT_HOME%\webapps\ibatisapp1\WEB-INF\classes\com\usanalyst\struts folder.


List 3.1 sqlMap-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="com/usanalyst/struts/connection.properties" />
<transactionManager type="JDBC">
<dataSource type="JNDI">
<property name="DataSource" value="${DbJNDIPath}"/>
</dataSource>
</transactionManager>
<sqlMap resource="com/usanalyst/struts/user_info.xml" />
</sqlMapConfig>

List 3.1 refers to SQL mapping file user_info.xml and connection.properties property file.


List 3.2 connection.properties

DbJNDIPath=java:comp/env/jdbc/getjobs


List 3.3 user_info.xml

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

<sqlMap namespace="user">
<resultMap class="com.usanalyst.struts.user_info" id="selectAll">
<result property="userId" column="userId" />
<result property="email" column="email" />
<result property="firstName" column="firstName" />
<result property="lastName" column="lastName" />
<result property="phone" column="phone" />
<result property="requestTime" column="requestTime" />
</resultMap>

<select id="getAllUsers" resultMap="selectAll">
select * from user_info2 order by userId
</select>

<select id="getUser" parameterClass="int"

resultClass="com.usanalyst.struts.user_info">
SELECT
userId as userId,
email as email,
firstName as firstName,
lastName as lastName,
phone as phone,
requestTime as requestTime
FROM user_info2
WHERE userId=#userId#
</select>

<insert id="insertUser" parameterClass="com.usanalyst.struts.user_info">
INSERT INTO user_info2 (userId,email,firstName,lastName,phone,requestTime)
values (#userId#,#email#,#firstName#,#lastName#,#phone#,#requestTime#)
<selectKey keyProperty="userId" resultClass="int">
select last_insert_id()
</selectKey>
</insert>

<update id="updateUser" parameterClass="com.usanalyst.struts.user_info">
UPDATE user_info2
SET email=#email#,
firstName=#firstName#,
lastName=#lastName#,
phone=#phone#,
requestTime=#requestTime#
WHERE userId=#userId#
</update>

<delete id="deleteUser" parameterClass="com.usanalyst.struts.user_info">
DELETE from user_info2
WHERE userId=#userId#
</delete>

</sqlMap>

And you have two java files that use iBATIS and database.


List 3.4 iBatisRecordModel.java

package com.usanalyst.struts;
import java.io.Reader;
import java.sql.SQLException;
import java.io.IOException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.ibatis.common.resources.Resources;

import java.sql.*;
import java.util.HashMap;
import java.util.Map;
import java.util.List;
import com.ibatis.sqlmap.client.*;
import com.ibatis.sqlmap.client.event.*;
import java.util.Date;

public class iBatisRecordModel {

private static SqlMapClient sqlMap = null;

static {
try{
String resource="com/usanalyst/struts/sqlMap-config.xml";
Reader reader=Resources.getResourceAsReader(resource);
sqlMap = SqlMapClientBuilder.buildSqlMapClient(reader);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("Error initializing sqlMap");
}
}

private List listRecord=null;

public List ViewRecords() {
try {
listRecord=sqlMap.queryForList("getAllUsers",null);
} catch (SQLException e) {
}
return listRecord;
}

public Object ViewRecordById(String Id) {
Object myObject=null;
try {
myObject=(Object)sqlMap.queryForObject("getUser",Integer.valueOf(Id));
} catch (SQLException e) {
}
return myObject;
}
}


List 3.5 iBatisModel.java

package com.usanalyst.struts;
import java.io.Reader;
import java.sql.SQLException;
import java.io.IOException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.ibatis.common.resources.Resources;

import java.sql.*;
import java.util.HashMap;
import java.util.Map;
import com.ibatis.sqlmap.client.*;
import com.ibatis.sqlmap.client.event.*;
import java.util.Date;

public class iBatisModel extends MyappModel {

Map map=null;

private SqlMapClient sqlMap = null;

private String resource="com/usanalyst/struts/sqlMap-config.xml";

public void setMap(Map map) {
this.map=map;
}

public void insert() {
try {
Reader reader=Resources.getResourceAsReader(resource);
sqlMap = SqlMapClientBuilder.buildSqlMapClient(reader);

sqlMap.startTransaction();

user_info user = new user_info();
user.setEmail((String)map.get("email"));
user.setFirstName((String)map.get("firstName"));
user.setLastName((String)map.get("lastName"));
user.setPhone((String)map.get("phone"));
user.setRequestTime(new Date());
sqlMap.insert("insertUser", user);
sqlMap.commitTransaction();
} catch (IOException ioe) {
System.out.println("Throw IO exception.");
} catch (SQLException sqle) {
System.out.println("Throw SQL exception");
} finally {
try {
sqlMap.endTransaction();
} catch (SQLException isqle) {
System.out.println("Throw SQL exception for end transaction.");
}
}
}

public void update() {
try {
Reader reader=Resources.getResourceAsReader(resource);
sqlMap = SqlMapClientBuilder.buildSqlMapClient(reader);

sqlMap.startTransaction(); 

Continue...

(Page 1 of 2)  |1||2|Next

Was this article helpful to you?yesno
2 of 2 people found this article helpful.



Related Publications
 
Using iBATIS and struts
Using iBATIS in web applications
Using Struts and Hibernate (Part III)
Using Struts and Hibernate (Part II)
Using Struts and Hibernate (Part I)
Using Hibernate In J2EE Applications (Part I)
Effective Ant Build For Developers
Introduction To Struts By Example
How To Build Custom JSP Tags (Part II)
How To Build Custom JSP Tags (Part I)
Configuring SSL on BEA WebLogic Server 8.1

(Registered users can post questions/comments)

 
 TLINKS SEARCH
Advanced Search
Help
 Recommended Links
Red Cross
Responding to hurricane katrina relieve. Donate today. It's a Great Feeling to Help.
http://www.redcross.org
Getusjobs.com
Getusjobs.com is the job site focused on American jobs. See the results that put us on top.
http://www.getusjobs.com
Database Tool
TLinkSoft® tools empowers developers, integrators and DBAs to be more productive.
http://www.cppunit.org/download.jsp
USAnalyst.com
USAnalyst.com provide a community for database analysts, business analysts, developer analysts and managers.
http://www.cppunit.org/article

Powered by Tlinks Systems