Applications often need to access data from mulitple data sources(e.g. database, web service,ldap). Each of the data stores has a different API to access the underlying storage mechanism, along with a whole set of idiosyncrasies.
The DAO pattern is used to hide the unique implementation quirks of these APIs. It provides a simple and common API for application developers so that the consumers of the data can be free of the complexities of the data access APIs.
A simple example of using iBATIS
#1 Dao.xml
The DaoManager class is configured using the Dao.xml configuration file(as below)
<daoConfig>
<context id="example">
<transactionManager type="SQLMAP">
<property name="SqlMapConfigResource"
value="examples/SqlMapConfig.xml"/>
</transactionManager>
<dao interface="examples.dao.AccountDao"
implementation="examples.dao.impl.AccountDao"/>
</context>
</daoConfig>
#2 Java Code for DaoService example
import com.ibatis.dao.client.DaoManager;
import com.ibatis.dao.client.DaoManagerBuilder;
import com.ibatis.common.resources.Resources;
import java.io.Reader;
import java.io.IOException;
public class DaoService {
private static DaoManager daoManager;
public static synchronized DaoManager getDaoManager(){
String daoXmlResource = "dao.xml";
Reader reader;
if (null == daoManager){
try {
reader = Resources.getResourceAsReader(daoXmlResource);
daoManager = DaoManagerBuilder.buildDaoManager(reader);
return daoManager;
} catch (IOException e) {
throw new RuntimeException( "Unable to create DAO manager.", e);
}
} else {
return daoManager;
}
}
public static Dao getDao(Class interfaceClass){
return getDaoManager().getDao(interfaceClass);
}
}
#3 A SQL Map DAO implementation example
public interface AccountDao {
public void insert(Account account);
public void update(Account account);
public int delete(Account account);
public int delete(Integer accountId);
public List<Account> getAccountListByExample(Account account);
public List<Map<String, Object>>
getMapListByExample(Account account);
public List<IdDescription>
getIdDescriptionListByExample(Account account);
public Account getById(Integer accountId);
public Account getById(Account account);
}
#4 a SAMPLE SQL map file
<sqlMap namespace="Account">
<typeAlias alias="Account"
type="${BeanPackage}.Account" />
<typeAlias alias="IdDescription"
type="${BeanPackage}.IdDescription" />
<insert id="insert" parameterClass="Account">
<selectKey keyProperty="accountId" resultClass="int">
SELECT nextVal('account_accountid_seq')
</selectKey>
INSERT INTO Account (
accountId,
username,
password,
firstName,
lastName,
address1,
address2,
city,
state,
postalCode,
country
) VALUES(
#accountId#,
#username:varchar#,
#password:varchar#,
#firstName:varchar#,
#lastName:varchar#,
#address1:varchar#,
#address2:varchar#,
#city:varchar#,
#state:varchar#,
#postalCode:varchar#,
#country:varchar#
)
</insert>
<update id="update">
update Account set
username = #username:varchar#,
password = #password:varchar#,
firstName = #firstName:varchar#,
lastName = #lastName:varchar#,
address1 = #address1:varchar#,
address2 = #address2:varchar#,
city = #city:varchar#,
state = #state:varchar#,
postalCode = #postalCode:varchar#,
country = #country:varchar#
where accountId = #accountId#
</update>
<delete id="delete">
delete from Account
where accountId = #accountId#
</delete>
<sql id="allFields">
accountId as "accountId",
username,
password,
firstName as "firstName",
lastName as "lastName",
address1,
address2,
city,
state,
postalCode as "postalCode",
country
</sql>
<sql id="whereByExample">
<dynamic prepend=" where ">
<isNotEmpty property="city">
city like #city#
</isNotEmpty>
<isNotNull property="accountId" prepend=" and ">
accountId = #accountId#
</isNotNull>
</dynamic>
</sql>
<sql id="getByExample">
select
<include refid="allFields" />
from Account
<include refid="whereByExample" />
</sql>
<select id="getAccountListByExample"
resultClass="Account">
<include refid="getByExample" />
</select>
<select id="getMapListByExample" resultClass="hashmap">
<include refid="getByExample" />
</select>
<select id="getIdDescriptionListByExample"
resultClass="IdDescription">
select
accountId as id,
COALESCE(firstname, '(no first name)')
|| ' '
|| COALESCE(lastname, '(no last name)')
as description
from Account
<include refid="whereByExample" />
</select>
<select id="getById" resultClass="Account">
select
<include refid="allFields" />
from Account
where accountId = #value#
</select>
</sqlMap>
#5 Coding the DAO implementation
SqlMapDaoTemplate
implements AccountDao {
public AccountDaoImpl(DaoManager daoManager) {
super(daoManager);
}
public Integer insert(Account account) {
return (Integer) insert("Account.insert", account);
}
public int update(Account account) {
return update("Account.update", account);
}
public int delete(Account account) {
return delete(account.getAccountId());
}
public int delete(Integer accountId) {
return delete("Account.delete", accountId);
}
public List<Account> getAccountListByExample(Account account) {
return queryForList("Account.getAccountListByExample", account);
}
public List<Map<String, Object>>
getMapListByExample(Account account) {
return queryForList("Account.getMapListByExample", account);
}
public List<IdDescription>
getIdDescriptionListByExample(Account account) {
return queryForList("Account.getIdDescriptionListByExample", account);
}
public Account getById(Integer accountId) {
return (Account)queryForObject("Account.getById", accountId);
}
public Account getById(Account account) {
return getById(account.getAccountId());
}
}
The DAO pattern is used to hide the unique implementation quirks of these APIs. It provides a simple and common API for application developers so that the consumers of the data can be free of the complexities of the data access APIs.
A simple example of using iBATIS
#1 Dao.xml
The DaoManager class is configured using the Dao.xml configuration file(as below)
<daoConfig>
<context id="example">
<transactionManager type="SQLMAP">
<property name="SqlMapConfigResource"
value="examples/SqlMapConfig.xml"/>
</transactionManager>
<dao interface="examples.dao.AccountDao"
implementation="examples.dao.impl.AccountDao"/>
</context>
</daoConfig>
#2 Java Code for DaoService example
import com.ibatis.dao.client.DaoManager;
import com.ibatis.dao.client.DaoManagerBuilder;
import com.ibatis.common.resources.Resources;
import java.io.Reader;
import java.io.IOException;
public class DaoService {
private static DaoManager daoManager;
public static synchronized DaoManager getDaoManager(){
String daoXmlResource = "dao.xml";
Reader reader;
if (null == daoManager){
try {
reader = Resources.getResourceAsReader(daoXmlResource);
daoManager = DaoManagerBuilder.buildDaoManager(reader);
return daoManager;
} catch (IOException e) {
throw new RuntimeException( "Unable to create DAO manager.", e);
}
} else {
return daoManager;
}
}
public static Dao getDao(Class interfaceClass){
return getDaoManager().getDao(interfaceClass);
}
}
#3 A SQL Map DAO implementation example
public interface AccountDao {
public void insert(Account account);
public void update(Account account);
public int delete(Account account);
public int delete(Integer accountId);
public List<Account> getAccountListByExample(Account account);
public List<Map<String, Object>>
getMapListByExample(Account account);
public List<IdDescription>
getIdDescriptionListByExample(Account account);
public Account getById(Integer accountId);
public Account getById(Account account);
}
#4 a SAMPLE SQL map file
<sqlMap namespace="Account">
<typeAlias alias="Account"
type="${BeanPackage}.Account" />
<typeAlias alias="IdDescription"
type="${BeanPackage}.IdDescription" />
<insert id="insert" parameterClass="Account">
<selectKey keyProperty="accountId" resultClass="int">
SELECT nextVal('account_accountid_seq')
</selectKey>
INSERT INTO Account (
accountId,
username,
password,
firstName,
lastName,
address1,
address2,
city,
state,
postalCode,
country
) VALUES(
#accountId#,
#username:varchar#,
#password:varchar#,
#firstName:varchar#,
#lastName:varchar#,
#address1:varchar#,
#address2:varchar#,
#city:varchar#,
#state:varchar#,
#postalCode:varchar#,
#country:varchar#
)
</insert>
<update id="update">
update Account set
username = #username:varchar#,
password = #password:varchar#,
firstName = #firstName:varchar#,
lastName = #lastName:varchar#,
address1 = #address1:varchar#,
address2 = #address2:varchar#,
city = #city:varchar#,
state = #state:varchar#,
postalCode = #postalCode:varchar#,
country = #country:varchar#
where accountId = #accountId#
</update>
<delete id="delete">
delete from Account
where accountId = #accountId#
</delete>
<sql id="allFields">
accountId as "accountId",
username,
password,
firstName as "firstName",
lastName as "lastName",
address1,
address2,
city,
state,
postalCode as "postalCode",
country
</sql>
<sql id="whereByExample">
<dynamic prepend=" where ">
<isNotEmpty property="city">
city like #city#
</isNotEmpty>
<isNotNull property="accountId" prepend=" and ">
accountId = #accountId#
</isNotNull>
</dynamic>
</sql>
<sql id="getByExample">
select
<include refid="allFields" />
from Account
<include refid="whereByExample" />
</sql>
<select id="getAccountListByExample"
resultClass="Account">
<include refid="getByExample" />
</select>
<select id="getMapListByExample" resultClass="hashmap">
<include refid="getByExample" />
</select>
<select id="getIdDescriptionListByExample"
resultClass="IdDescription">
select
accountId as id,
COALESCE(firstname, '(no first name)')
|| ' '
|| COALESCE(lastname, '(no last name)')
as description
from Account
<include refid="whereByExample" />
</select>
<select id="getById" resultClass="Account">
select
<include refid="allFields" />
from Account
where accountId = #value#
</select>
</sqlMap>
#5 Coding the DAO implementation
SqlMapDaoTemplate
implements AccountDao {
public AccountDaoImpl(DaoManager daoManager) {
super(daoManager);
}
public Integer insert(Account account) {
return (Integer) insert("Account.insert", account);
}
public int update(Account account) {
return update("Account.update", account);
}
public int delete(Account account) {
return delete(account.getAccountId());
}
public int delete(Integer accountId) {
return delete("Account.delete", accountId);
}
public List<Account> getAccountListByExample(Account account) {
return queryForList("Account.getAccountListByExample", account);
}
public List<Map<String, Object>>
getMapListByExample(Account account) {
return queryForList("Account.getMapListByExample", account);
}
public List<IdDescription>
getIdDescriptionListByExample(Account account) {
return queryForList("Account.getIdDescriptionListByExample", account);
}
public Account getById(Integer accountId) {
return (Account)queryForObject("Account.getById", accountId);
}
public Account getById(Account account) {
return getById(account.getAccountId());
}
}
Comments
Post a Comment