iBatis习惯用的16条SQL语句
iBatis简介:
iBatis是apache的一个开源项目,一个O/RMapping解决方案,iBatis最大的特点就是小巧,上手很快。如果不需要太多复杂的功能,iBatis是能够满足你的要求又足够灵活的最简单的解决方案,现在的iBatis已经改名为Mybatis了。
官网为:http://www.mybatis.org/
1.输入参数为单个值
<deleteid="com.fashionfree.stat.accesslog.deleteMemberAccessLogsBefore" parameterClass="long"> deletefrom MemberAccessLog where accessTimestamp=#value# </delete> <deleteid="com.fashionfree.stat.accesslog.deleteMemberAccessLogsBefore" parameterClass="long"> deletefrom MemberAccessLog where accessTimestamp=#value# </delete>
2.输入参数为一个对象
<insertid="com.fashionfree.stat.accesslog.MemberAccessLog.insert" parameterClass="com.fashionfree.stat.accesslog.model.MemberAccessLog> insertintoMemberAccessLog ( accessLogId,memberId,clientIP, httpMethod,actionId,requestURL, accessTimestamp,extend1,extend2, extend3 ) values ( #accessLogId#,#memberId#, #clientIP#,#httpMethod#, #actionId#,#requestURL#, #accessTimestamp#,#extend1#, #extend2#,#extend3# ) </insert> <insertid="com.fashionfree.stat.accesslog.MemberAccessLog.insert" parameterClass="com.fashionfree.stat.accesslog.model.MemberAccessLog> insertintoMemberAccessLog ( accessLogId,memberId,clientIP, httpMethod,actionId,requestURL, accessTimestamp,extend1,extend2, extend3 ) values ( #accessLogId#,#memberId#, #clientIP#,#httpMethod#, #actionId#,#requestURL#, #accessTimestamp#,#extend1#, #extend2#,#extend3# ) </insert>
3.输入参数为一个java.util.HashMap
<selectid="com.fashionfree.stat.accesslog.selectActionIdAndActionNumber" parameterClass="hashMap" resultMap="getActionIdAndActionNumber"> select actionId,count(*)ascount from MemberAccessLog where memberId=#memberId# andaccessTimestamp>#start# andaccessTimestamp<=#end# groupbyactionId </select> <selectid="com.fashionfree.stat.accesslog.selectActionIdAndActionNumber" parameterClass="hashMap" resultMap="getActionIdAndActionNumber"> select actionId,count(*)ascount from MemberAccessLog where memberId=#memberId# andaccessTimestamp>#start# andaccessTimestamp<=#end# groupbyactionId </select>
4.输入参数中含有数组
<insertid="updateStatusBatch"parameterClass="hashMap"> update Question set status=#status# <dynamicprepend="wherequestionIdin"> <isNotNullproperty="actionIds"> <iterateproperty="actionIds"open="("close=")"conjunction=","> #actionIds[]# </iterate> </isNotNull> </dynamic> </insert> <insertid="updateStatusBatch"parameterClass="hashMap"> update Question set status=#status# <dynamicprepend="wherequestionIdin"> <isNotNullproperty="actionIds"> <iterateproperty="actionIds"open="("close=")"conjunction=","> #actionIds[]# </iterate> </isNotNull> </dynamic> </insert>
说明:actionIds为传入的数组的名字;使用dynamic标签避免数组为空时导致sql语句语法出错;使用isNotNull标签避免数组为null时ibatis解析出错
5.传递参数只含有一个数组
<selectid="com.fashionfree.stat.accesslog.model.StatMemberAction.selectActionIdsOfModule" resultClass="hashMap"> select moduleId,actionId from StatMemberAction <dynamicprepend="wheremoduleIdin"> <iterateopen="("close=")"conjunction=","> #[]# </iterate> </dynamic> orderby moduleId </select> <selectid="com.fashionfree.stat.accesslog.model.StatMemberAction.selectActionIdsOfModule" resultClass="hashMap"> select moduleId,actionId from StatMemberAction <dynamicprepend="wheremoduleIdin"> <iterateopen="("close=")"conjunction=","> #[]# </iterate> </dynamic> orderby moduleId </select>
说明:注意select的标签中没有parameterClass一项
另:这里也可以把数组放进一个hashMap中,但增加额外开销,不建议使用
6.让ibatis把参数直接解析成字符串
<selectid="com.fashionfree.stat.accesslog.selectSumDistinctCountOfAccessMemberNum" parameterClass="hashMap"resultClass="int"> select count(distinctmemberId) from MemberAccessLog where accessTimestamp>=#start# andaccessTimestamp<#end# andactionIdin$actionIdString$ </select> <selectid="com.fashionfree.stat.accesslog.selectSumDistinctCountOfAccessMemberNum" parameterClass="hashMap"resultClass="int"> select count(distinctmemberId) from MemberAccessLog where accessTimestamp>=#start# andaccessTimestamp<#end# andactionIdin$actionIdString$ </select>
说明:使用这种方法存在sql注入的风险,不推荐使用
7.分页查询(pagedQuery)
<selectid="com.fashionfree.stat.accesslog.selectMemberAccessLogBy" parameterClass="hashMap"resultMap="MemberAccessLogMap"> <includerefid="selectAllSql"/> <includerefid="whereSql"/> <includerefid="pageSql"/> </select> <selectid="com.fashionfree.stat.accesslog.selectMemberAccessLogBy.Count" parameterClass="hashMap"resultClass="int"> <includerefid="countSql"/> <includerefid="whereSql"/> </select> <sqlid="selectAllSql"> select accessLogId,memberId,clientIP, httpMethod,actionId,requestURL, accessTimestamp,extend1,extend2, extend3 from MemberAccessLog </sql> <sqlid="whereSql"> accessTimestamp<=#accessTimestamp# </sql> <sqlid="countSql"> select count(*) from MemberAccessLog </sql> <sqlid="pageSql"> <dynamic> <isNotNullproperty="startIndex"> <isNotNullproperty="pageSize"> limit#startIndex#,#pageSize# </isNotNull> </isNotNull> </dynamic> </sql> <selectid="com.fashionfree.stat.accesslog.selectMemberAccessLogBy" parameterClass="hashMap"resultMap="MemberAccessLogMap"> <includerefid="selectAllSql"/> <includerefid="whereSql"/> <includerefid="pageSql"/> </select> <selectid="com.fashionfree.stat.accesslog.selectMemberAccessLogBy.Count" parameterClass="hashMap"resultClass="int"> <includerefid="countSql"/> <includerefid="whereSql"/> </select> <sqlid="selectAllSql"> select accessLogId,memberId,clientIP, httpMethod,actionId,requestURL, accessTimestamp,extend1,extend2, extend3 from MemberAccessLog </sql> <sqlid="whereSql"> accessTimestamp<=#accessTimestamp# </sql> <sqlid="countSql"> select count(*) from MemberAccessLog </sql> <sqlid="pageSql"> <dynamic> <isNotNullproperty="startIndex"> <isNotNullproperty="pageSize"> limit#startIndex#,#pageSize# </isNotNull> </isNotNull> </dynamic> </sql>
说明:本例中,代码应为:
HashMaphashMap=newHashMap(); hashMap.put(“accessTimestamp”,someValue); pagedQuery(“com.fashionfree.stat.accesslog.selectMemberAccessLogBy”,hashMap);
pagedQuery方法首先去查找名为com.fashionfree.stat.accesslog.selectMemberAccessLogBy.Count的mappedstatement来进行sql查询,从而得到com.fashionfree.stat.accesslog.selectMemberAccessLogBy查询的记录个数,再进行所需的pagedsql查询(com.fashionfree.stat.accesslog.selectMemberAccessLogBy),具体过程参见utils类中的相关代码
8.sql语句中含有大于号>、小于号<1.将大于号、小于号写为:><如:
<deleteid="com.fashionfree.stat.accesslog.deleteMemberAccessLogsBefore"parameterClass="long"> deletefrom MemberAccessLog where accessTimestamp<=#value# </delete> Xml代码 <deleteid="com.fashionfree.stat.accesslog.deleteMemberAccessLogsBefore"parameterClass="long"> deletefrom MemberAccessLog where accessTimestamp<=#value# </delete>
将特殊字符放在xml的CDATA区内:
<deleteid="com.fashionfree.stat.accesslog.deleteMemberAccessLogsBefore"parameterClass="long"> <![CDATA[ deletefrom MemberAccessLog where accessTimestamp<=#value# ]]> </delete> <deleteid="com.fashionfree.stat.accesslog.deleteMemberAccessLogsBefore"parameterClass="long"> <![CDATA[ deletefrom MemberAccessLog where accessTimestamp<=#value# ]]> </delete>
推荐使用第一种方式,写为<和>(XML不对CDATA里的内容进行解析,因此如果CDATA中含有dynamic标签,将不起作用)
9.include和sql标签将常用的sql语句整理在一起,便于共用:
<sqlid="selectBasicSql"> select samplingTimestamp,onlineNum,year, month,week,day,hour from OnlineMemberNum </sql> <sqlid="whereSqlBefore"> wheresamplingTimestamp<=#samplingTimestamp# </sql> <selectid="com.fashionfree.accesslog.selectOnlineMemberNumsBeforeSamplingTimestamp"parameterClass="hashmap"resultClass="OnlineMemberNum"> <includerefid="selectBasicSql"/> <includerefid="whereSqlBefore"/> </select> <sqlid="selectBasicSql"> select samplingTimestamp,onlineNum,year, month,week,day,hour from OnlineMemberNum </sql> <sqlid="whereSqlBefore"> wheresamplingTimestamp<=#samplingTimestamp# </sql> <selectid="com.fashionfree.accesslog.selectOnlineMemberNumsBeforeSamplingTimestamp"parameterClass="hashmap"resultClass="OnlineMemberNum"> <includerefid="selectBasicSql"/> <includerefid="whereSqlBefore"/> </select>
注意:sql标签只能用于被引用,不能当作mappedstatement。如上例中有名为selectBasicSql的sql元素,试图使用其作为sql语句执行是错误的:
sqlMapClient.queryForList(“selectBasicSql”);×
10.随机选取记录
<sqlid=”randomSql”> ORDERBYrand()LIMIT#number# </sql>
从数据库中随机选取number条记录(只适用于MySQL)
11.将SQLGROUPBY分组中的字段拼接
<sqlid=”selectGroupBy> SELECT a.answererCategoryId,a.answererId,a.answererName, a.questionCategoryId,a.score,a.answeredNum, a.correctNum,a.answerSeconds,a.createdTimestamp, a.lastQuestionApprovedTimestamp,a.lastModified,GROUP_CONCAT(q.categoryName)ascategoryName FROM AnswererCategorya,QuestionCategoryq WHEREa.questionCategoryId=q.questionCategoryId GROUPBYa.answererId ORDERBYa.answererCategoryId </sql> <sqlid=”selectGroupBy> SELECT a.answererCategoryId,a.answererId,a.answererName, a.questionCategoryId,a.score,a.answeredNum, a.correctNum,a.answerSeconds,a.createdTimestamp, a.lastQuestionApprovedTimestamp,a.lastModified,GROUP_CONCAT(q.categoryName)ascategoryName FROM AnswererCategorya,QuestionCategoryq WHEREa.questionCategoryId=q.questionCategoryId GROUPBYa.answererId ORDERBYa.answererCategoryId </sql>
注:SQL中使用了MySQL的GROUP_CONCAT函数
12.按照IN里面的顺序进行排序
①MySQL:
<sqlid=”groupByInArea”> select moduleId,moduleName, status,lastModifierId,lastModifiedName, lastModified from StatModule where moduleIdin(3,5,1) orderby instr(',3,5,1,',','+ltrim(moduleId)+',') </sql> <sqlid=”groupByInArea”> select moduleId,moduleName, status,lastModifierId,lastModifiedName, lastModified from StatModule where moduleIdin(3,5,1) orderby instr(',3,5,1,',','+ltrim(moduleId)+',') </sql>
②SQLSERVER:
<sqlid=”groupByInArea”> select moduleId,moduleName, status,lastModifierId,lastModifiedName, lastModified from StatModule where moduleIdin(3,5,1) orderby charindex(','+ltrim(moduleId)+',',',3,5,1,') </sql> <sqlid=”groupByInArea”> select moduleId,moduleName, status,lastModifierId,lastModifiedName, lastModified from StatModule where moduleIdin(3,5,1) orderby charindex(','+ltrim(moduleId)+',',',3,5,1,') </sql>
说明:查询结果将按照moduleId在in列表中的顺序(3,5,1)来返回
MySQL:instr(str,substr)
SQLSERVER:charindex(substr,str)返回字符串str中子字符串的第一个出现位置ltrim(str)返回字符串str,其引导(左面的)空格字符被删除
13.resultMapresultMap负责将SQL查询结果集的列值映射成JavaBean的属性值
<resultMapclass="java.util.HashMap"id="getActionIdAndActionNumber"> <resultcolumn="actionId"property="actionId"jdbcType="BIGINT"javaType="long"/> <resultcolumn="count"property="count"jdbcType="INT"javaType="int"/> </resultMap> Xml代码 <resultMapclass="java.util.HashMap"id="getActionIdAndActionNumber"> <resultcolumn="actionId"property="actionId"jdbcType="BIGINT"javaType="long"/> <resultcolumn="count"property="count"jdbcType="INT"javaType="int"/> </resultMap>
使用resultMap称为显式结果映射,与之对应的是resultClass(内联结果映射),使用resultClass的最大好处便是简单、方便,不需显示指定结果,由iBATIS根据反射来确定自行决定。而resultMap则可以通过指定jdbcType和javaType,提供更严格的配置认证。
14.typeAlias
<typeAliasalias="MemberOnlineDuration"type="com.fashionfree.stat.accesslog.model.MemberOnlineDuration"/> <typeAlias>
允许你定义别名,避免重复输入过长的名字
15.remap
<selectid="testForRemap"parameterClass="hashMap"resultClass="hashMap"remapResults="true"> select userId <isEqualproperty="tag"compareValue="1"> ,userName </isEqual> <isEqualproperty="tag"compareValue="2"> ,userPassword </isEqual> from UserInfo </select> <selectid="testForRemap"parameterClass="hashMap"resultClass="hashMap"remapResults="true"> select userId <isEqualproperty="tag"compareValue="1"> ,userName </isEqual> <isEqualproperty="tag"compareValue="2"> ,userPassword </isEqual> from UserInfo </select>
此例中,根据参数tag值的不同,会获得不同的结果集,如果没有remapResults="true"属性,iBatis会将第一次查询时的结果集缓存,下次再执行时(必须还是该进程中)不会再执行结果集映射,而是会使用缓存的结果集。
因此,如果上面的例子中remapResult为默认的false属性,而有一段程序这样书写:
HashMap<String,Integer>hashMap=newHashMap<String,Integer>(); hashMap.put("tag",1); sqlClient.queryForList("testForRemap",hashMap); hashMap.put("tag",2); sqlClient.queryForList("testForRemap",hashMap);
Java代码
HashMap<String,Integer>hashMap=newHashMap<String,Integer>(); hashMap.put("tag",1); sqlClient.queryForList("testForRemap",hashMap); hashMap.put("tag",2); sqlClient.queryForList("testForRemap",hashMap);
则程序会在执行最后一句的query查询时报错,原因就是iBATIS使用了第一次查询时的结果集,而前后两次的结果集是不同的:(userId,userName)和(userId,userPassword),所以导致出错。如果使用了remapResults="true"这一属性,iBATIS会在每次执行查询时都执行结果集映射,从而避免错误的发生(此时会有较大的开销)。
16.dynamic标签的prependdynamic标签的prepend属性作为前缀添加到结果内容前面,当标签的结果内容为空时,prepend属性将不起作用。
当dynamic标签中存在prepend属性时,将会把其嵌套子标签的第一个prepend属性忽略。例如:
<sqlid="whereSql"> <dynamicprepend="where"> <isNotNullproperty="userId"prepend="BOGUS"> userId=#userId# </isNotNull> <isNotEmptyproperty="userName"prepend="and"> userName=#userName# </isNotEmpty> </dynamic> </sql> <sqlid="whereSql"> <dynamicprepend="where"> <isNotNullproperty="userId"prepend="BOGUS"> userId=#userId# </isNotNull> <isNotEmptyproperty="userName"prepend="and"> userName=#userName# </isNotEmpty> </dynamic> </sql>
此例中,dynamic标签中含有两个子标签<isNotNull>和<isNotEmpty>。根据前面叙述的原则,如果<isNotNull>标签中没有prepend="BOGUS"这一假的属性来让dynamic去掉的话,<isNotEmpty>标签中的and就会被忽略,会造成sql语法错误。
注意:当dynamic标签没有prepend属性时,不会自动忽略其子标签的第一个prepend属性。
以上所述是小编给大家介绍的iBatis习惯用的16条SQL语句,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对毛票票网站的支持!