问题原因:字段不识别(多个表不同字段)
我现在有两张表,两张表中有不同的字段。
T_POLICY_BASE 字段(POLICY_NO 有)(ENDORSE_NO 无)
T_ENDORSE_BASE 字段(POLICY_NO 有)(ENDORSE_NO 有)
<select id="PolicyOrEndorse.search" parameterClass="java.util.Map" resultClass="com.tpaic.nonmotor.domain.PolicyBase">
SELECT
e.POLICY_NO policyNo,
<isEqual property="noType" compareValue="0">
e.total_net_premium totalNetPremium
FROM T_POLICY_BASE e
WHERE UNDERWRITE_MARK = '2'
</isEqual>
<isEqual property="noType" compareValue="1">
e.ENDORSE_NO endorseNo,
TEI.CALCULATE_ENDORSE_PREMIUM totalNetPremium
FROM T_ENDORSE_BASE e, T_ENDORSE_INFO TEI
WHERE e.UNDERWRITE_MARK = '2' AND e.ENDORSE_NO = TEI.ENDORSE_NO
</isEqual>
<isEqual property="noType" compareValue="2">
e.ENDORSE_NO endorseNo,
TEI.CALCULATE_ENDORSE_PREMIUM totalNetPremium
FROM T_ENDORSE_BASE e, T_ENDORSE_INFO TEI
WHERE e.UNDERWRITE_MARK = '2' AND e.ENDORSE_NO = TEI.ENDORSE_NO
<isEmpty property="policyNo" prepend="AND">
TRUNC(e.CREATED_DATE) = TRUNC(SYSDATE - 1)
</isEmpty>
</isEqual>
<isNotEmpty property="policyNo" prepend="AND">
e.POLICY_NO = #policyNo#
</isNotEmpty>
<isNotEmpty property="endorseNo" prepend="AND">
e.ENDORSE_NO = #endorseNo#
</isNotEmpty>
</select>
通过三个条件分支(noType 的值为 0、1、2)对应不同的表。
第一步noType=1查询,sql正常执行
第二步noType=0查询提示endorseNo字段不识别
因为T_POLICY_BASE 表中是没有ENDORSE_NO这个字段的。但是明明noType=0为什么还会走第一个1的时候的sql呢,是因为当第一次调用这个select语句时,会将字段查询出来,放入缓存中。select e.POLICY_NO policyNo,e.ENDORSE_NO endorseNo 这个时候 这两个字段都被缓存起来了。
IBATIS源码缓存
com.ibatis.sqlmap.engine.mapping.result.AutoResultMap
public synchronized Object[] getResults(StatementScope statementScope, ResultSet rs)
throws SQLException {
if (allowRemapping || getResultMappings() == null) {
initialize(rs);
}
return super.getResults(statementScope, rs);
}
第二次查询时候, T_ENDORSE_BASE 表中没有ENDORSE_NO所以提示改字段不存在了。
解決方法:
第一种:(修改别名)这里要着重记录下,不然容易混淆
也就是说两张表中用一个同样的别名字段
APPLY_POLICY_NO这个字段,两张表中都有别名对应两张不同表字段即可。
<select id="PolicyOrEndorse.search" parameterClass="java.util.Map" resultClass="com.tpaic.nonmotor.domain.PolicyBase">
SELECT
e.POLICY_NO policyNo,
<isEqual property="noType" compareValue="0">
e.APPLY_POLICY_NO applyPolicyNo
e.total_net_premium totalNetPremium
FROM T_POLICY_BASE e
WHERE UNDERWRITE_MARK = '2'
</isEqual>
<isEqual property="noType" compareValue="1">
e.ENDORSE_NO applyPolicyNo,
TEI.CALCULATE_ENDORSE_PREMIUM totalNetPremium
FROM T_ENDORSE_BASE e, T_ENDORSE_INFO TEI
WHERE e.UNDERWRITE_MARK = '2' AND e.ENDORSE_NO = TEI.ENDORSE_NO
</isEqual>
<isEqual property="noType" compareValue="2">
e.ENDORSE_NO applyPolicyNo,
TEI.CALCULATE_ENDORSE_PREMIUM totalNetPremium
FROM T_ENDORSE_BASE e, T_ENDORSE_INFO TEI
WHERE e.UNDERWRITE_MARK = '2' AND e.ENDORSE_NO = TEI.ENDORSE_NO
<isEmpty property="policyNo" prepend="AND">
TRUNC(e.CREATED_DATE) = TRUNC(SYSDATE - 1)
</isEmpty>
</isEqual>
<isNotEmpty property="policyNo" prepend="AND">
e.POLICY_NO = #policyNo#
</isNotEmpty>
<isNotEmpty property="endorseNo" prepend="AND">
e.ENDORSE_NO = #endorseNo#
</isNotEmpty>
</select>
第二种:最简单 添加标签属性remapResults="true"(效率,性能要考虑下)
ibatis的select标签有个属性remapResults,该属性默认值为false;为保证查询结果的正确就需要设置remapResults="true"
<select remapResults=”true”></select>,这样iBATIS会在每次查询的时候内省查询结果来设置元数据,来保证返回恰当的结果。这个属性会造成一定的性能损失,所以要谨慎使用