问题原因:字段不识别(多个表不同字段)
我现在有两张表,两张表中有不同的字段。
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会在每次查询的时候内省查询结果来设置元数据,来保证返回恰当的结果。这个属性会造成一定的性能损失,所以要谨慎使用