Mybatis(2)

高级结果映射

数据模型


一对一

association分为:镶嵌查询、镶套结果

镶嵌查询

       <resultMap id="findSaler" type="xx.xx.saler">
                <id column="saler_id" property="salerid"></id>
                <result column="saler_name" property="salername"></result>
                <association column="user_id" property="user" select="findeUser" javaType="xx.xx.user" >//colunm外键列名
                        <id column="user_id" property="userid"></id>
                        <result column="user_name" property="username"></result>
                </association>
        </resultMap>

        <select id="findeUser" resultType="xx.xx.user">
            SELECT  * from user where id = #{id};
        </select>
        <select id="findeSaler" resultMap="findSaler" parameterType="String">
              SELECT  * from saler where id = #{id};
        </select>

这种查询会发生n+1现象,即本来查询一条sql,现在却需要查询1+n条 1指查询saler  n指查询saler相关的user,可以使用延迟加载,但是延迟加载在一些情景下(快速迭代)就会很糟糕,使用镶套查询解决。

镶套查询

        <resultMap id="findSaler" type="xx.xx.saler">
                <id column="saler_id" property="salerid"></id>
                <result column="saler_name" property="salername"></result>
                <association  property="user"  javaType="xx.xx.user" >
                        <id column="user_id" property="userid"></id>
                        <result column="user_name" property="username"></result>
                </association>
        </resultMap>

        
        <select id="findeSaler" resultMap="findSaler" parameterType="String">
              SELECT  * from saler,user  where user.id=saler.id
        </select>

一对多

     <resultMap id="findSaler" type="xx.xx.saler">
                <id column="saler_id" property="salerid"></id>
                <result column="saler_name" property="salername"></result>
                <collection property="customs" javaType="ArrayList" ofType="xx.xx.customs">
                        <id column="cusotom_id" property="cusotomid"></id>
                        <result column="cusotom_name" property="cusotomname"></result>
                </collection>
        </resultMap>


        <select id="findeSaler" resultMap="findSaler" parameterType="String">
              SELECT  * from saler,customs  where cusoms.saler_id=saler.id
        </select>

缓存

一级缓存


a.一级缓存指的就是sqlsession,创建一个新的SqlSession对象,SqlSession对象中会有一个新的Executor对象,Executor对象中持有一个新的PerpetualCache对象; ,Cache最核心的实现其实就是一个Map,将本次查询使用的特征值作为key,将查询结果作为value存储到Map中。,CacheKey由以下条件决定:statementId  + rowBounds  + 传递给JDBC的SQL  + 传递给JDBC的参数值
b. 如果SqlSession调用了close()方法,会释放掉一级缓存PerpetualCache对象,一级缓存将不可用;
c. 如果SqlSession调用了clearCache(),会清空PerpetualCache对象中的数据,但是该对象仍可使用;
d.SqlSession中执行了任何一个update操作(update()、delete()、insert()) ,都会清空PerpetualCache对象的数据,但是该对象可以继续使用;


注意:
1、对于数据变化频率很大,并且需要高时效准确性的数据要求,我们使用SqlSession查询的时候,要控制好SqlSession的生存时间,SqlSession的生存时间越长,它其中缓存的数据有可能就越旧,从而造成和真实数据库的误差;同时对于这种情况,用户也可以手动地适时清空SqlSession中的缓存;


2、对于只执行、并且频繁执行大范围的select操作的SqlSession对象,SqlSession对象的生存时间不应过长。

二级缓存

相关实体类需要实现序列化接口
执行查询后需要close或者commit才会把数据提交到二级缓存中。
执行增删改commit之后会清空二级缓存


MyBatis在为SqlSession对象创建Executor对象时,会对Executor对象加上一个装饰者:
CachingExecutor,这时SqlSession使用CachingExecutor对象来完成操作请求。
CachingExecutor对于查询请求,会先判断该查询请求在Application级别的二级缓存中是
否有缓存结果,如果有查询结果,则直接返回缓存结果;如果缓存中没有,再交给真正的
Executor对象来完成查询操作,之后CachingExecutor会将真正Executor返回的查
询结果放置到缓存中,然后在返回给用户
MyBatis二级缓存的划分
MyBatis并不是简单地对整个Application就只有一个Cache缓存对象,它将缓存划分的更
细,即是Mapper级别的,即每一个Mapper都可以拥有一个Cache对象,具体如下:
a.为每一个Mapper分配一个Cache缓存对象(使用<cache>节点配置);
MyBatis将Application级别的二级缓存细分到Mapper级别,即对于每一个Mapper.xml,如果
在其中使用了<cache> 节点,则MyBatis会为这个Mapper创建一个Cache缓存对象,
b.多个Mapper共用一个Cache缓存对象(使用<cache-ref>节点配置);
如果你想让多个Mapper公用一个Cache的话,你可以使用<cache-ref namespace="">节点,
来指定你的这个Mapper使用到了哪一个Mapper的Cache缓存。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值