ibatis总结
程序员文章站
2022-07-15 11:29:50
...
最近项目中用到了ibatis,由于之前也没用过,因此也遇见不少问题,现决定把遇见的问题及解决方法列出来(ibatis2)。
1. 显示sql调试信息:
#显示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
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调试信息:
引用
#显示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
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>
剩下的以后再写。