科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基于iBatis的通用持久层对象(1)

基于iBatis的通用持久层对象(1)

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

相对Hibernate等“全自动”ORM机制而言,iBatis以SQL开发的工作量和数据库移植性上的让步,为系统设计提供了更大的自由空间。研究过iBaits以后,发现有些通用的方法可以解决企业级应用的常规工作,就是设计一个通用的持久层对象。

作者:fellow99 来源:MATRIX 2007年12月10日

关键字:

  • 评论
  • 分享微博
  • 分享邮件

在本页阅读全文(共3页)

c、在模板sql语句中除了“#”以外,还有“$”,它们两代表的意思当然不同了:

 <statement id=”getProduct” resultMap=”get-product-result”>
select * from PRODUCT order by $preferredOrder$
</statement>
 
“#”在生成sql语句的过程中,会变成“?”,同时在参数表中增加一个参数;

“$”则会直接替换成参数对象对应的值,例如上面的preferredOrder的值可能是“price”,则生成的sql语句就是:

select * from PRODUCT order by price

*需要特别说明的是传入参数这一部分将会是后面正题“通用持久层对象”的核心,怎么个通用法,怎么设计模板sql语句,都是在这部分上。

圈圈3:结果对象跟参数对象差不多,也有两种,resultMap和resultClass,如下:

resultMap就是配置文件中预定义了要取得的字段:

 <resultMap id=”get-product-result” class=”com.iBatis.example.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>
 
resultClass则是通过分析返回的字段,来填充结果对象:

 <statement id="getPerson" parameterClass=”int” resultClass="examples.domain.Person">
SELECT PER_ID as id, PER_FIRST_NAME as firstName
FROM PERSON WHERE PER_ID = #value#
</statement>
 
跟参数对象相反,结果对象一般使用resultMap形式。引用官方的话:使用resultClass的自动映射存在一些限制,无法指定输出字段的数据类型(如果需要的话),无法自动装入相关的数据(复杂属性),并且因为需要ResultSetMetaData的信息,会对性能有轻微的不利影响。但使用resultMap,这些限制都可以很容易解决。

三、正题来了,怎么做“通用持久层对象”

1、表结构

每个表都必须包含两个字段:id和parentId,其他字段按照需求来定义,其他各种索引、约束、关系之类的也按需求定义。

2、通用的持久层对象,CustomPO

 public class CustomPO {
protected String moduleTable; //该PO对应的表名(视图名)
protected int id; //表的id
protected int parentID; //父表的id(如果有的话)
protected Map fieldMap; //字段Map,核心,用于存储字段及其值
public String getModuleTable()
public void setModuleTable(String moduleTable)
public int getId()
public void setId(int id)
public int getParentID()
public void setParentID(int parentID)
public Map getFieldMap()
public void setFieldMap(Map fieldMap)
public void copyFieldMap(Map fieldMap)
//取得字段名列表
public List getFieldList()
//设置字段名列表。如果fieldMap没有相应的字段,则增加,字段值为null;如果有则不增加。
public void setFieldList(List fieldList)
//返回字段的“字段名 - 字段值”列表,使用com.fellow.pub.util.KeyValuePair对象作为存储
public List getFieldValueList()
}

那些成员变量的get/set就没什么说的,主要说说getFieldValueList()这个方法。该方法返回一个列表,列表元素是一个key-value结构,简单来说就是把字段map序列化。在构造模板sql语句时会体现它的用途。

3、iBatis对象配置文件CustomPO.xml

 <sqlMap namespace="CustomPO">
<!--定义别名-->
<typeAlias alias="customPO" type="com.fellow.component.customPO.CustomPO"/>
<!--
通过id查找
特点:iterate这个fieldList列表,生成要输出的字段
-->
<select id="customPO_findByID" resultClass="java.util.HashMap"
    parameterClass="customPO">
SELECT id, parentID
<iterate property="fieldList" conjunction=",">
$fieldList[]$
</iterate>
FROM $moduleTable$ WHERE id = #id#
</select>

<!--
插入一条新纪录
特点:iterate这个fieldValueList列表,分别取得其元素的key和value值
注意$号和#号的使用方法,还有最后怎么取得insert后的id值(各种数据库都可能不同)
-->
<insert id="customPO_insert" parameterClass="customPO">
INSERT INTO $moduleTable$ (parentID
<iterate property="fieldValueList" prepend="," conjunction=",">
$fieldValueList[].key$
</iterate>
)
VALUES (#parentID#
<iterate property="fieldValueList" prepend="," conjunction=",">
#fieldValueList[].value#
</iterate>
)
<selectKey resultClass="int" keyProperty="id">
SELECT last_insert_id()
</selectKey>
</insert>
<!--
更新一条纪录
特点:iterate这个fieldValueList列表,分别取得其元素的key和value值
注意$号和#号的使用方法
-->
<update id="customPO_update" parameterClass="customPO">
UPDATE $moduleTable$ SET
<iterate property="fieldValueList" conjunction=",">
$fieldValueList[].key$ = #fieldValueList[].value#
</iterate>
WHERE id = #id#
</update>
<!--删除一条纪录-->
<delete id="customPO_delete" parameterClass="customPO">
DELETE FROM $moduleTable$ WHERE id = #id#
</delete>

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章