ibatis 相关

(1)

在数据库持久层的框架中,大家一定听过Hibernate的大名了吧,经典的SSH框架就有它的一份哦!可是我今天要说的却是另外一个持久层的框架,它就是iBatis。与Hibrenate相比,它的主要优势就是简单、小巧、轻量级,但是它的功能却丝毫不亚于Hibernate,下面让我们来看看iBatis在项目中的应用吧!

iBatis确实很简单,它的工作原理就是通过SQLMap映射文件将sql语句和java对象对应起来(如:在利用对象属性的getter从属性中获取值,查询结果后,将各值用setter方法放到对象中).在iBatis中,sql语句是我们手工编写好的,这一点与Hibernate不同,Hibernate是通过映射java对象和数据库表字段来自动生成的sql语句。

(2)

ibatis中的namespace与resultMap

<sqlMapnamespace="admin">在运用时如下:

this.getSqlMapClient().update(“admin.update”,entity);

分析:

ibatis配置文件中的useStatementNamespaces:是否使用Statement命名空间。这里的命名空间指的是映射文件中,sqlMap节点的namespace属性,如:<sqlMapnamespace="User">。这里,指定了此sqlMap节点下定义的操作均从属于"User"命名空间。

在useStatementNamespaces="true"的情况下,Statement调用需追加命名空间,如:sqlMap.update("User.updateUser",user);否则直接通过Statement名称调用即可,如:sqlMap.update("updateUser",user);

好处:

在实际应用中,利用namespace可以防止两个同名的方法而引起冲突。如有两个updateUser,可以通过AupdateUser/B.updateUser来区分。

另一种方法:

但有一种更方便的方法,可以在不采用namspace的情况下,解决上面的问题:即直接在方法的前面直接命名为AupdateUser/B.updateUser。调用时,直接调用AupdateUser/B.updateUser即可。如下:

<sqlMap>

<typeAliastype="com.admin.entity.Admin"alias="Admin"/>

<selectid="Admin.findUserByLoginName"parameterclass="java.lang.String"

resultMap="AdminResult">

select*fromT_ADMINISTRATORSwherelonginName=#value#

andstatus!=4

</select>

调用时,getSqlMapClientTemplate.queryForList(“Admin.findUserByLoginName”,”test”);即可。

请注意:

此时需要保证所有映射文件中,Statement定义无重名。

第二:

resultMap:结果映射,需结合resultMap节点对映射关系加以定义。

<sqlMap>

<typeAliastype="com.admin.entity.Admin"alias="Admin"/>

<resultMapid="AdminResult"class="Admin">

<resultcolumn="staff_id"property="id"/>

<resultcolumn="loginName"property="loginName"/>

<resultcolumn="password"property="password"/>

<resultcolumn="staff_name"property="username"/>

<resultcolumn="status"property="status"/>

<resultcolumn="phone"property="phone"/>

<resultcolumn="email"property="email"/>

</resultMap>

<selectid="Admin.findUserByLoginName"parameterclass="java.lang.String"

resultMap="AdminResult">

select*fromT_ADMINISTRATORSwherelonginName=#value#

andstatus!=4

</select>

</sqlMap>

(3)关于ibatis中输入/输出各种类型的参数分析

在ibatis,输入的参数对象常以parameterClass来定义,输出的结果集常以resultMap来定义。(resultMap:方便JAVABEAN属性及字段的映射,调用JAVABEAN的setter进行设置值。通常我们不采用resultClass属性进行映射,因为它不具备映射数据库表字段的持久化特性。)

在ibateis中,parameterClass的类型大都是:string,int/对象/hashmap

resultclass/resultMap的类型大都是:对象/hashmap

当parameterClass为string,int时,可用#value#表示或直接用传入的值名表示。

当parameterClass/resultMap的类型是对象时,用#属性#表示。程序会调用JAVABEAN的getter方法,进行获取属性值。

当parameterClass/resultMap的类型是hashmap(Map是key-value结构的)时,那程序会直接通过key来分析取参数。

具体请见以下两部分:

ibatis各种参数数据集

原型参数

<selectid="select1"parameterclass="java.lang.String"resultclass="AppLog">

select

IDasid,

TYPEastype,

DESCRasdescr

fromAPP_LOG

whereID=#id#

</select>

sqlMapper.queryForObject("select0",id);

--参数名与传入值名称一样。--应该也可用参数#value#表示

Map类参数

<selectid="select2"parameterclass="java.util.HashMap"resultclass="AppLog">

select

IDasid,

TYPEastype,

DESCRasdescr

fromAPP_LOG

whereID=#ids#

</select>

map.put("ids",id);

AppLoglog=(AppLog)sqlMapper.queryForObject("select0",map);

--通过key来获取值

对象参数

<selectid="select3"parameterclass="AppLog"resultclass="AppLog">

select

IDasid,

TYPEastype,

DESCRasdescr

fromAPP_LOG

whereID=#id#

</select>

AppLogp=newAppLog();

p.setId(id);

AppLoglog=(AppLog)sqlMapper.queryForObject("select3",p);

动态字段、表

<selectid="selectd"resultclass="java.util.HashMap"parameterclass="java.util.HashMap"

remapResults="true">

select$fieldList$

from$table$

whereID=#id#

</select>

Mapp=newHashMap();

p.put("id",id);

p.put("table","APP_LOG");

p.put("fieldList","ID,TYPE,DESCR");

Mapmap=(Map)sqlMapper.queryForObject("selectd",p);

Stringid1=(String)map.get("ID");

Stringtype=(String)map.get("TYPE");

Stringdescr=(String)map.get("DESCR");

注意:#与$区别:

1.#是把传入的数据当作字符串,如#field#传入的是id,则sql语句生成是这样,orderby"id",这当然会报错..

2.$传入的数据直接生成在sql里,如#field#传入的是id,则sql语句生成是这样,orderbyid,这就对了.

$方式一般用于传入数据库对象.例如传入表名.

#方式一般用于传入插入/更新的值或查询/删除的where条件

ibatis各种返回数据集

别名映射->实体类+resultClass

<selectid="selectAll"resultclass="AppLog">

select

IDasid,

TYPEastype,

DESCRasdescr

fromAPP_LOG

whereID=#id#

</select>

Listlist=sqlMapper.queryForList("selectAll");

for(inti=0;i<list.size();i){

AppLoglog=(AppLog)list.get(i);

//addyourcodehere;

}

注意:

为什么定义了resultclass="AppLog",而queryForList出来的是list?

这里的resultclass="AppLog",是指查询出来的每条记录的格式是AppLog。

当我们queryForList时,系统会将各条记录(即各个AppLog放到list中)传回给我们。当我们queryForObject时,就只传回一个AppLog。

别名映射->Map类+resultClass--》把每条记录放于map中,字段名为key,值为value.

<selectid="selectAll"resultclass="java.util.HashMap">

select

IDasid,

TYPEastype,

DESCRasdescr

fromAPP_LOG

whereID=#id#

</select>

Listlist=sqlMapper.queryForList("selectAll");

for(inti=0;i<list.size();i){

Mapmap=(Map)list.get(i);

Stringid=(String)map.get("id");

Stringtype=(String)map.get("type");

Stringdescr=(String)map.get("descr");

//addyourcodehere;

}

无映射

<selectid="selectAll3"resultclass="java.util.HashMap">

select*fromAPP_LOG

</select>

Listlist=sqlMapper.queryForList("selectAll3");

for(inti=0;i<list.size();i){

Mapmap=(Map)list.get(i);

Stringid=(String)map.get("ID");

Stringtype=(String)map.get("TYPE");

Stringdescr=(String)map.get("DESCR");

}

显式映射->实体类:resultMap

<resultMapid="AppLogResult"class="AppLog">

<resultproperty="id"column="ID"/>

<resultproperty="type"column="Type"/>

<resultproperty="descr"column="DESCR"/>

</resultMap>

<selectid="selectAll"resultMap="AppLogResult">

select*fromAPP_LOG

</select>

Listlist=sqlMapper.queryForList("selectAll");

for(inti=0;i<list.size();i){

AppLoglog=(AppLog)list.get(i);

//addyourcodehere;

}

显式映射->Map类:resultMap--》把每条记录放于map中,字段名为key,值为value.

<resultMapid="map-result"class="java.util.HashMap">

<resultproperty="id"column="ID"/>

<resultproperty="type"column="Type"/>

<resultproperty="descr"column="DESCR"/>

</resultMap>

<selectid="selectAll2"resultMap="map-result">

select*fromAPP_LOG

</select>

Listlist=sqlMapper.queryForList("selectAll2");

for(inti=0;i<list.size();i){

Mapmap=(Map)list.get(i);

Stringid=(String)map.get("id");

Stringtype=(String)map.get("type");

Stringdescr=(String)map.get("descr");

}

又如:

map.put("appIds",Ids);

executor.update("Device.OpenClientApp",map);

下面的property属性及循环变量,都是对应map的key名。

-----证明,ibatis对于hashmap,都是通过key来获取值的。所以,所有参数须用key来表示!!!

如下:

<updateid="Device.OpenClientApp"parameterclass="java.util.HashMap">

updateT_Device_App_R_InfosetOpr='1'whereApp_IDin

<iterateconjunction=","open="("close=")"property="appIds">

#appIds[]#

</iterate>

</update>

例子:

<statementid=”statementName”parameterClass=”examples.domain.Product”>

insertintoPRODUCTvalues(#id#,#description#,#price#,#classify.id#)

</statement>

蓝色部分#classify.id#翻译过来实际是product.getClassify().getId(),classify是Product对象的一个子对象。

(4)关于参数的三种设置方法及ParameterMap用法

前提:有一个user的javabean.

一,自动参数映射:

<insertid="insertUser7"parameterclass="user">

<![CDATA[

INSERTINTOt_user(ID,NAME,PASS)VALUES(#id#,#name#,#pass#)

]]>

</insert>

二,内联参数映射:

<insertid="insertUser8"parameterclass="user">

<![CDATA[

INSERTINTOt_user(ID,NAME,PASS)VALUES(#id:INT#,#name:VARCHAR#,#pass:VARCHAR#)

]]>

</insert>

备注:好像将属性对应的数据类型故意写错,程序也可正常执行,没报错.

三,外联参数映射:

以上二种方式都用paramClass,但此处用parameterMap.

<parameterMapid="parameterMap"class="user">

<parameterproperty="id"jdbcType="INTEGER"/>

<parameterproperty="name"jdbcType="VARCHAR"/>

<parameterproperty="pass"jdbcType="VARCHAR"/>

</parameterMap>

<insertid="insertUser9"parameterMap="parameterMap">

<![CDATA[

INSERTINTOt_user(ID,NAME,PASS)VALUES(?,?,?)

]]>

</insert>

若此处的对象不是javabean,而是一个hashMap.用法也一样,只是id,name,pass不是javabean的属性,而是hashMap的key.

String[]ids;

...........

map.put("devId",ids[0]);

map.put("appId",ids[1]);

<!--自动参数映射方式-->

<insertid="DAPermit.addAppDevMapping"parameterclass="java.util.HashMap">

insertintoT_Device_App_R_Info(Device_ID,App_ID,Opr)values(#devId#,#appId#,'2');

</insert>

<!--

内联方式:

<insertid="DAPermit.addAppDevMapping"parameterclass="java.util.HashMap">

insertintoT_Device_App_R_Info(Device_ID,App_ID,Opr)values(#devId:varchar#,#appId:varchar#,'2');

</insert>

外联方式:

<parameterMapid="dapermitParams"class="java.util.HashMap">

<parameterproperty="devId"jdbcType="VARCHAR"/>

<parameterproperty="appId"jdbcType="VARCHAR"/>

</parameterMap>

<insertid="DAPermit.addAppDevMapping"parameterMap="dapermitParams">

insertintoT_Device_App_R_Info(Device_ID,App_ID,Opr)values(?,?,'2');

</insert>

-->

四,利用parameterMap调用存储过程:

<!--example11:存储过程-->

<resultMapid="returnResultMap"class="user">

<resultproperty="id"column="ID"/>

</resultMap>

<parameterMapid="paramUser"class="java.util.Map">

<parameterproperty="name"jdbcType="VARCHAR"javaType="string"mode="IN"/>

<parameterproperty="pass"jdbcType="VARCHAR"javaType="string"mode="IN"/>

<parameterproperty="id"jdbcType="INT"javaType="Integer"mode="INOUT"resultMap="returnResultMap"/>

</parameterMap>

<procedureid="pro_insertUser11"parameterMap="paramUser"resultclass="int">

<![CDATA[

{callproc_userinsert(?,?,?)}

]]>

</procedure>

然后在UserDaoTest.java中增加如下一个方法:

publicstaticvoidexample11()throwsException{

try{

Mapmap=newHashMap();

map.put("name","procedure");

map.put("pass","123456");

IntegerreturnValue=(Integer)sqlMapClient.insert("pro_insertUser11",map);

System.out.println(returnValue);

}catch(Exceptione){

e.printStackTrace();

}

}

相关推荐