IBATIS常见用法(isEmpty、isNotEmpty、isNull、isNotNull等)
CreateTime--2017年5月29日13:56:15
Author:Marydon
一、IBATIS
iBATIS一词来源于“internet”和“abatis”的组合,是一个由Clinton Begin在2002年发起的开放源代码项目。于2010年6月16号被谷歌托管,改名为MyBatis。是一个基于SQL映射支持Java和·NET的持久层框架。
(一)配置
1.1.1 ibatis配置文件常用配置
<sqlMapConfig> <settings cacheModelsEnabled="true" lazyLoadingEnabled="true" enhancementEnabled="true" useStatementNamespaces="true" statementCachingEnabled="true" classInfoCacheEnabled="true" /> </sqlMapConfig>
参数说明:
cacheModelsEnabled //是否启动ibatis中的缓存功能; lazyLoadingEnabled //是否同时懒加载带来极大的性能提升; useStatementNamespaces //是否使用 domain xml 文件中 namespace 别名配置 //iBATIS的默认是不会启动命名空间的,若使用,需声明该值为true enhancementEnabled //是否需要POJO启动Java字节码增强功能,可以提升getter/setter的调用效能避免Java反射所带来的性能开销。 剩下两个默认值都为true classInfoCacheEnabled /*With this setting enabled, iBATIS will maintain a cache of introspected classes. This will lead to a significant reduction in startup time if many classes are reused.*/ statementCachingEnabled (iBATIS 2.3.0以后版本中有) /*With this setting enabled, iBATIS will maintain a local cache of prepared statements. This can lead to significant performance improvements.*/
1.1.2 ibatis的总配置有且只能有一个,总配置文件直接引用各个SQLMap文件,不能像struts一样,a总配置文件-->引用b子配置文件-->...n层-->各个配置文件。
举例:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE sqlMapConfig PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN" "http://ibatis.apache.org/dtd/sql-map-config-2.dtd"> <sqlMapConfig> <settings cacheModelsEnabled="true" errorTracingEnabled="true" enhancementEnabled="true" lazyLoadingEnabled="true" maxRequests="512" maxSessions="384" maxTransactions="256" useStatementNamespaces="true" /> <!-- 特别注意:只能直接引用SQLMap文件,不能通过:引用子配置文件,子配置文件去引用SQLMap文件的方式实现, 否则,最终会找不到SQLMap文件 --> <!-- 患者信息 --> <sqlMap resource="telemedicine/service/domain/entites/oracle/patient/PATIENT_INFO.xml" /> </sqlMapConfig>
(二)常用标签
CreateTime--2016年12月9日17:45:21
iBATIS的isNotNull和isNotEmpty的区别
<isNotNull prepend="," property="FREMARK"> FREMARK = #FREMARK# </isNotNull> <isNotEmpty prepend="," property="FBEGINDATE"> FBEGINDATE = TO_DATE(#FBEGINDATE#,'yyyy-MM-dd') </isNotEmpty>
isNotNull相当于
if(FREMARK != null){// 可以为空'' FREMARK = #FREMARK# }
该字段内容可以为空,即FREMARK=''
isNotEmpty相当于
if(FREMARK != null && FREMARK != ""){ FREMARK = #FREMARK# }
前台传过来的字段中不仅要包括FREMARK,并且FREMARK的内容不能为空,才会执行
UpdateTime--2017年1月22日15:15:03
1.2.1 字段不等于具体的值:column=="value"
语法:
<isEqual prepend="" property="" compareValue=""></isEqual>
举例:
<isEqual prepend="and" property="FCOMLVL" compareValue="-1"> FCOMLVL IS NULL </isEqual>
1.2.2 字段等于具体的值:column!="value"
语法:
<isNotEqual prepend="" property="" compareValue=""></isNotEqual>
举例:
<isNotEqual prepend="and" property="FPLVCODE" compareValue="1"> FPLVCODE=#FPLVCODE# </isNotEqual>
1.2.3 字段不为空:column!=null
语法:
<isNotNull prepend="" property=""></isNotNull>
举例:
<isNotNull prepend="," property="FJCMYEAR"> FJCMYEAR=#FJCMYEAR# </isNotNull>
1.2.4 字段非空且不是空字符串:column!=null && column!=""
语法:
<isNotEmpty prepend="" property=""></isNotEmpty>
举例:
<isNotEmpty prepend="and" property="FICDFM"> FICDFM=#FICDFM# </isNotEmpty>
1.2.5 字段不存在或字段值为空:column==null || column==""
语法:
<isEmpty prepend="" property=""></isEmpty>
举例:
<isNotEmpty property="CLICOM" > order by A.FCLINHITS DESC,length(A.FZJM) ASC,FICDCODE </isNotEmpty> <isEmpty property="CLICOM"> <isNotEmpty property="HOSCOM" > order by A.FINHOSHITS DESC,length(A.FZJM) ASC,FICDCODE </isNotEmpty> <isEmpty property="HOSCOM"> order by A.FINHOSHITS DESC,length(A.FZJM) ASC,FICDCODE </isEmpty> </isEmpty>
1.2.6 字段不存在:column==null
语法:
<isNull prepend="" property=""></isNull>
1.2.7 XML文件中如何使用">"和"<"
方法一:
使用
<![CDATA[
]]>
举例:
<![CDATA[ X1.ORGDEGREE <= #ORGDEGREE_Z# ]]>
方法二:
大于用 > 表示,小于用 < 表示
UpdateTime--2017年8月8日09:08:03
1.2.8 关于prepend
以<isNotNull prepend="and" property="firstName">为例
生成的语句不会有多余的and,因为dynamic有一个隐藏的属性:removeFirstPrepend="true", 所以一般要写上prepend="and",需要的时候它会自动去掉。
(三)常用操作
UpdateTime--2017年6月15日08:15:36
1.3.1 增
<insert id="insertTSORGDIAITEM" parameterClass="map"> INSERT INTO 表名 </insert>
举例:
<insert id="insertTDOCTORORG" parameterClass="map"> <selectKey keyProperty="FID" resultClass="java.lang.Long"> SELECT SEQ_1.NEXTVAL FROM DUAL </selectKey> INSERT INTO TDOCTORORG (FID, FDOCTORCODE, FDOCTORNAME, FZJM, FRCODE, FORGID, FDOCTORCODE_CENTER, FREMARK, FDEPTCODE) VALUES (#FID#, #FDOCTORCODE#, #FDOCTORNAME#, #FZJM#, #FRCODE#, #FORGID#, #FDOCTORCODE_CENTER#, #FREMARK#, #FDEPTCODE#) </insert>
转换成SQL
INSERT INTO TDOCTORORG (FID, FDOCTORCODE, FDOCTORNAME, FZJM, FRCODE, FORGID, FDOCTORCODE_CENTER, FREMARK, FDEPTCODE) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) --[142929, 001, test, 001, 410122, 0, , null, null]
<update id="updateTDICTICDCODE" parameterClass="map"> UPDATE 表名 </update>
举例:
<update id="updateFDOCTORCODE" parameterClass="map"> UPDATE TDOCTORORG SET FDOCTORCODE_CENTER = #FDOCTORCODE_CENTER#, FDOCTORNAME = #FDOCTORNAME#, FZJM = #FZJM#, FDEPTCODE = #FDEPTCODE# WHERE FDOCTORCODE = #FDOCTORCODE# AND FRCODE = #FRCODE# AND FORGID = #FORGID# </update>
转换成SQL
UPDATE TDOCTORORG SET FDOCTORCODE = ?, FDOCTORCODE_CENTER = ?, FDOCTORNAME = ?, FZJM = ?, FDEPTCODE = ? WHERE FID = ? AND FRCODE = ? AND FORGID = ? --[001, , test1, 001, null, 142929, 410122, 0]
<delete id="delTSORGDIAITEM" parameterClass="map"> DELETE FROM 表名 </delete>
<select id="getTSORGDIAITEM" parameterClass="map" remapResults="true" resultClass="java.util.HashMap" cacheModel="cacheTSORGDIAITEM"> SELECT 字段 FROM 表名 </select>
举例:
<select id="getPrint" resultClass="map"> SELECT T1.PATIENT_NAME, T1.SEX, T1.BIRTH_DAY, T1.OUTPAT_CODE, TO_CHAR(T2.CONSULT_DATE, 'yyyy-MM-dd HH24:mi') CONSULT_DATE, T2.CONSULT_CLASS, T2.CONSULT_TYPE, T3.CONSULT_DIAGNOSIS, T3.TREATMENT_PLAN, T3.REMARK, T3.CONSULT_PEOPLE FROM OUTPATIENT_INFO T1, OUTPATIENT_CONSULT_INFO T2, OUTPATIENT_CONS_ASSESSMENTINFO T3 WHERE T1.PATIENT_INFO_ID = #PATIENT_INFO_ID# AND T2.CONSULT_APPLY_ID = #CONSULT_APPLY_ID# AND T1.PATIENT_INFO_ID = T2.PATIENT_INFO_ID AND T2.CONSULT_APPLY_ID = T3.CONSULT_APPLY_ID </select>
转换成SQL
SELECT T1.PATIENT_NAME, T1.SEX, T1.BIRTH_DAY, T1.OUTPAT_CODE, TO_CHAR(T2.CONSULT_DATE, 'yyyy-MM-dd HH24:mi') CONSULT_DATE, T2.CONSULT_CLASS, T2.CONSULT_TYPE, T3.CONSULT_DIAGNOSIS, T3.TREATMENT_PLAN, T3.REMARK, T3.CONSULT_PEOPLE FROM OUTPATIENT_INFO T1, OUTPATIENT_CONSULT_INFO T2, OUTPATIENT_CONS_ASSESSMENTINFO T3 WHERE T1.PATIENT_INFO_ID = ? AND T2.CONSULT_APPLY_ID = ? AND T1.PATIENT_INFO_ID = T2.PATIENT_INFO_ID AND T2.CONSULT_APPLY_ID = T3.CONSULT_APPLY_ID --[51CE27E4269418A9E0530100007FCD14, 51CE27E4269518A9E0530100007FCD14]
注意:
1.使用iBATIS进行增、改操作时,parameterClass映射到SQL时:
若parameterClass中不存在参数,如:FDOCTORCODE_CENTER,iBATIS进行ORM映射时,会自动将该字段对应的值置为NULL,执行该SQL时不会发生异常;
若parameterClass中存在参数,如:FDOCTORCODE_CENTER,但对应的值为空,iBATIS进行ORM映射时,会自动将该字段对应的值置为空字符串""。
2.使用TO_CHAR(),TO_DATE()等函数时千万别忘了给该字段起别名!
1.3.5 动态拼接WHERE查询条件
第一步:声明动态WHERE条件
<sql id="isReported_where"> <dynamic prepend="where"> <isNotEmpty prepend=" " property="FPROVLEVELLIMIT"> x1.FPROVLEVELLIMIT=#FPROVLEVELLIMIT# </isNotEmpty> <isNotEmpty prepend="and" property="FCOUNLEVELLIMIT"> x1.FCOUNLEVELLIMIT=#FCOUNLEVELLIMIT# </isNotEmpty> <isNotEmpty prepend="and" property="FTOWNLEVELLIMIT"> x1.FTOWNLEVELLIMIT=#FTOWNLEVELLIMIT# </isNotEmpty> <isNotEmpty prepend="and" property="FVILLLEVELLIMIT"> x1.FVILLLEVELLIMIT=#FVILLLEVELLIMIT# </isNotEmpty> </dynamic> </sql>
注意:
a.dynamic prepend="值",这个地方的值视情况而定,一般为""或"where";
b.isNotEmpty 第一个prepend的值为" "或"and",必须有值。
第二步:引用引用SQL
<!-- 引用通用SQL --> <include refid="TSORGDIAITEM_WHERE"/>
(四)IBATIS + ORACLE
见另外两篇文章
2023年8月22日17:21:22
关于非空判断
<isNotNull property="CONSULT_DATE_AFTER">
<!-- CONSULT_DATE_AFTER = '' -->
<isEmpty prepend="and" property="CONSULT_DATE_AFTER">
T.CONSULT_DATE_AFTER is not null
</isEmpty>
<!-- CONSULT_DATE_AFTER <> '' -->
<isNotEmpty prepend="and" property="CONSULT_DATE">
T.CONSULT_DATE_AFTER = TO_DATE(#CONSULT_DATE_AFTER#,'YYYY-MM-DD HH24:mi')
</isNotEmpty>
</isNotNull>
2023年9月6日14:50:06
isNotNull与isEmpty
在实际开发过程中,往往会存在这种需求:
我们需要将某个字段作为查询条件,根据字段值来执行不同的操作。
示例如下:
当APPLY_NO的字段值为空字符串(APPLY_NO=='')时,执行:APPLY_NO is not null;
当APPLY_NO的字段值不为空(APPLY_NO!='')时,执行:APPLY_NO=#APPLY_NO#;
到底是该用isNotNull还是isEmpty呢?
先来试一下isEmpty(错误用法)
此时,在传参时,没有传字段APPLY_NO
但最终,上面的isEmpty标签却是执行了。
显然,此时使用isEmpty标签是不符合实际需求的。
正确用法1
<!-- APPLY_NO -->
<isNotNull property="APPLY_NO">
<!-- APPLY_NO != null && APPLY_NO != '' -->
<isNotEmpty prepend="and" property="APPLY_NO">
T.APPLY_NO = #APPLY_NO#
</isNotEmpty>
<!-- APPLY_NO != null && APPLY_NO == '' -->
<isEmpty prepend="and" property="APPLY_NO">
T.APPLY_NO is not null
</isEmpty>
</isNotNull>
执行结果:
当没有传APPLY_NO时,执行结果如下:(符合需求)
传空值(APPLY_NO=="")
执行结果如下:(符合需求)
正确用法2
正确用法1存在一个弊端,那就是:
当前端根据字段 APPLY_NO作为查询条件时,就会出现问题,因为当APPLY_NO=""时,执行的是APPLY_NO is not null。
此时,不应该有筛选条件,但用上述方法,相当于:强行添加了一个查询条件,
这样,就会导致:查询的不是所有数据。
为了规避这个问题,我们可以使用isEqual标签。
可以设置字段APPLY_NO在数据库当中根本不会存在的值,作为区分执行不同指令的标识。
如下图所示:
<isEqual prepend="and" property="APPLY_NO" compareValue="-1">
T.APPLY_NO is not null
</isEqual>
<isNotEqual property="APPLY_NO" compareValue="-1">
<!-- APPLY_NO != null && APPLY_NO != '' -->
<isNotEmpty prepend="and" property="APPLY_NO">
T.APPLY_NO = #APPLY_NO#
</isNotEmpty>
</isNotEqual>
当APPLY_NO=-1时,执行:T.APPLY_NO is not null;
当APPLY_NO!=null&&APPLY_NO!=''时,执行:T.APPLY_NO=#APPLY_NO#。
本文来自博客园,作者:Marydon,转载请注明原文链接:https://www.cnblogs.com/Marydon20170307/p/6918057.html