IBATIS别名SELECT(缓存字段)引起的问题(动态sql)

简介: IBATIS别名SELECT(缓存字段)引起的问题(动态sql)

问题原因:字段不识别(多个表不同字段)

我现在有两张表,两张表中有不同的字段。

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会在每次查询的时候内省查询结果来设置元数据,来保证返回恰当的结果。这个属性会造成一定的性能损失,所以要谨慎使用


相关文章
|
SQL 关系型数据库 数据库
03_MyBatis基本查询,mapper文件的定义,测试代码的编写,resultMap配置返回值,sql片段配置,select标签标签中的内容介绍,配置使用二级缓存,使用别名的数据类型,条件查询ma
 1 PersonTestMapper.xml中的内容如下: &lt;?xmlversion="1.0"encoding="UTF-8"?&gt; &lt;!DOCTYPEmapper PUBLIC"-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapp
1041 0
|
2月前
|
缓存 NoSQL 安全
【Redis】缓存穿透
【Redis】缓存穿透
30 0
|
2月前
|
缓存 监控 NoSQL
解析Redis缓存雪崩及应对策略
解析Redis缓存雪崩及应对策略
|
2月前
|
存储 缓存 NoSQL
Redis高效缓存:加速应用性能的利器
Redis高效缓存:加速应用性能的利器
|
2月前
|
存储 缓存 Java
【Spring原理高级进阶】有Redis为啥不用?深入剖析 Spring Cache:缓存的工作原理、缓存注解的使用方法与最佳实践
【Spring原理高级进阶】有Redis为啥不用?深入剖析 Spring Cache:缓存的工作原理、缓存注解的使用方法与最佳实践
|
5天前
|
缓存 NoSQL Redis
深度解析Redis的缓存双写一致性
【4月更文挑战第20天】
30 1
|
5天前
|
存储 缓存 NoSQL
Redis入门到通关之Redis缓存数据实战
Redis入门到通关之Redis缓存数据实战
14 0
|
7天前
|
存储 缓存 运维
软件体系结构 - 缓存技术(5)Redis Cluster
【4月更文挑战第20天】软件体系结构 - 缓存技术(5)Redis Cluster
137 10
|
15天前
|
缓存 NoSQL Java
使用Redis进行Java缓存策略设计
【4月更文挑战第16天】在高并发Java应用中,Redis作为缓存中间件提升性能。本文探讨如何使用Redis设计缓存策略。Redis是开源内存数据结构存储系统,支持多种数据结构。Java中常用Redis客户端有Jedis和Lettuce。缓存设计遵循一致性、失效、雪崩、穿透和预热原则。常见缓存模式包括Cache-Aside、Read-Through、Write-Through和Write-Behind。示例展示了使用Jedis实现Cache-Aside模式。优化策略包括分布式锁、缓存预热、随机过期时间、限流和降级,以应对缓存挑战。
|
22天前
|
存储 缓存 NoSQL
使用redis进行缓存加速
使用redis进行缓存加速
29 0