最近项目中用到了ibatis,由于之前也没用过,因此也遇见不少问题,现决定把遇见的问题及解决方法列出来(ibatis2)。
1. 显示sql调试信息:
[quote]
#显示ibatis底层sql语句
log4j.logger.com.ibatis=debug
log4j.logger.com.ibatis.common.jdbc.SimpleDataSource=debug
log4j.logger.com.ibatis.common.jdbc.ScriptRunner=debug
log4j.logger.com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate=debug
log4j.logger.java.sql=debug
[/quote]
2.关于resultMap的问题。
typeAlias与resultMap不能与其它的sqlmap.xml共享,有时候为了简单,可以这样写:
但实际上存入map的是别名的大写形式,所以在外面访问的时候还是要用:
也就是说,对于map来说,as别名没什么作用,至少在2.3.0.66是这样的。不过在家里面又试了下,结果map里面装的key值就是UserName,而不是USERNAME,还真是有些奇怪,可能小版本间的差异吧。
3.如果查询出来的字段数据需要替换,则先要在先在实体对象中多定义个属性,如gender,在数据库存为1或0,1表示男,0表示女,为了在外面显示男女,需要在User类中定义个genderName,再定义个resultMap,不然其它select * 查数据时也要查出genderName才行。
User类:
虽然也可以在页面进行判断替换,但那样如果每个页面都需要替换,然后会用jstl判断替换,也比较麻烦。
4.更新的时候最好使用dynamic来设置需要更新的字段:
这样如果字段内容为空就不会再更新此字段。
5.关于service、dao层的抽象。crud操作最好是单独提取出来,可以建立四个类,分别是BaseService,BaseServiceImpl,BaseDao,BaseDaoImpl这几个类,有个缺点就是定义的方法要抽象一些,但是这个代价并不大,可以接受。具体细节下次讲。
6.增加数据时最好将ID取出来再赋值,而不是直接使用自动增加的值。在oracle中,可以使用如select sequence from dual,在mysql中使用select last_insert_id()都是可行的,这点很重要,很多时候插入记录时都需要此记录的ID标识。
5.参数列表查询。在查询或删除多个ID数据时会使用where in用法,用法如下:
剩下的以后再写。
1. 显示sql调试信息:
[quote]
#显示ibatis底层sql语句
log4j.logger.com.ibatis=debug
log4j.logger.com.ibatis.common.jdbc.SimpleDataSource=debug
log4j.logger.com.ibatis.common.jdbc.ScriptRunner=debug
log4j.logger.com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate=debug
log4j.logger.java.sql=debug
[/quote]
2.关于resultMap的问题。
<typeAlias alias="user" type="com.User"/>
<resultMap id="userResult" class="user" >
<result column="USER_NAME" property="userName" jdbcType="VARCHAR" />
.............
............
</resultMap>
typeAlias与resultMap不能与其它的sqlmap.xml共享,有时候为了简单,可以这样写:
<!-- 查询 -->
<select id="org_getUser"
resultMap="userResult"
parameterClass="string">
<![CDATA[
select
u.*
from User u where u.USER_ID=#userId#
]]>
</select>
但是这个要求userResult与select查询出来的数据能对应起来,如果select只查询部分字段,就不能再用reulstMap,而要用resultClass="user"。当然也可以用resultMap="hashmap",这个方式的话,要注意map的访问方式,虽然与对象的访问方式一样,如:
<select id="org_getUser"
resultMap="userResult"
parameterClass="string">
<![CDATA[
select
u.USERNAME as UserName,u.USERID as userId
from User u where u.USER_ID=#userId#
]]>
</select>
但实际上存入map的是别名的大写形式,所以在外面访问的时候还是要用:
<c:forEach items="${users}" var="user">
<option value="${user.USERID}" >${user.USERNAME}</option>
</c:forEach>
也就是说,对于map来说,as别名没什么作用,至少在2.3.0.66是这样的。不过在家里面又试了下,结果map里面装的key值就是UserName,而不是USERNAME,还真是有些奇怪,可能小版本间的差异吧。
3.如果查询出来的字段数据需要替换,则先要在先在实体对象中多定义个属性,如gender,在数据库存为1或0,1表示男,0表示女,为了在外面显示男女,需要在User类中定义个genderName,再定义个resultMap,不然其它select * 查数据时也要查出genderName才行。
User类:
private String genderName;
<resultMap id="userResultGenderName" class="org" extends="userResult">
<!-- 下面的列用于显示数字或字母对应显示值,表中并不存在此这些列-->
<result column="GENDERNAME" jdbcType="VARCHAR" property="genderName" />
</resultMap>
<!-- 查询 -->
<select id="org_getUser"
resultMap="userResult"
parameterClass="string">
<![CDATA[
select
u.*,
(case
when ORG_NATURE ='0' then '女'
when ORG_NATURE ='1' then '男'
end) as genderName
from User u where u.USER_ID=#userId#
]]>
</select>
虽然也可以在页面进行判断替换,但那样如果每个页面都需要替换,然后会用jstl判断替换,也比较麻烦。
4.更新的时候最好使用dynamic来设置需要更新的字段:
<update id="updateOrgType" parameterClass="orgType" >
update ORG_TYPE
<dynamic prepend="set" >
<isNotNull prepend="," property="orgTypeCode" >
ORG_TYPE_CODE = #orgTypeCode:VARCHAR#
</isNotNull>
<isNotNull prepend="," property="orgTypeName" >
ORG_TYPE_NAME = #orgTypeName:VARCHAR#
</isNotNull>
</dynamic>
where ORG_TYPE_ID = #orgTypeId:DECIMAL#
</update>
这样如果字段内容为空就不会再更新此字段。
5.关于service、dao层的抽象。crud操作最好是单独提取出来,可以建立四个类,分别是BaseService,BaseServiceImpl,BaseDao,BaseDaoImpl这几个类,有个缺点就是定义的方法要抽象一些,但是这个代价并不大,可以接受。具体细节下次讲。
6.增加数据时最好将ID取出来再赋值,而不是直接使用自动增加的值。在oracle中,可以使用如select sequence from dual,在mysql中使用select last_insert_id()都是可行的,这点很重要,很多时候插入记录时都需要此记录的ID标识。
5.参数列表查询。在查询或删除多个ID数据时会使用where in用法,用法如下:
<select id="select-test" resultMap="MyTableResult" parameterClass="list">
select * from my_table where col_1 in
<iterate open="(" close=")" conjunction=",">
#[]#
</iterate>
</select>
剩下的以后再写。