脚本宝典收集整理的这篇文章主要介绍了Mybatis一级缓存的锅,脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。
项目开发中有一个树形数据结构,不像经典组织结构树、菜单级别树,我们这个树形结构是用户后期手动建立起来的关系。因此数据库表结构为两张表:数据记录表、记录关系表,通过业务规则限制,形成的树形结构像下面这样:
特殊之处就是树结构节点是有重复的
不复制重复节点
复制重复节点
项目要求前端展示、导出时使用复制重复节点的方式。开搞吧
树结构查询,在MySQL下当然是使用Mybatis框架提供的递归查询了。
<resultMap tyPE="(...).OKRAlignTreeNode" id="TreeNodeResult">
<result PRoperty="id" column="objective_id" />
<result property="content" column="content" />
<result property="theOrder" column="the_order" />
<collection property="children" select="getChildren" column="objective_id" ofType="(...).OKRAlignTreeNode"/>
</resultMap>
<select id="getTree" parameterType="Map" resultMap="TreeNodeResult">
select
objective_id,content,the_order
From okr_objective oo
where oo.objective_id = #{id}
order by the_order
</select>
<select id="getChildren" resultMap="TreeNodeResult">
select objective_id,content,the_order
from
(select objective_id from okr_aline where parent_ids = #{objective_id} ) a
left join okr_objective oo on a.objective_id = oo.objective_id
order by b.the_order
</select>
public interface OKRAlignexportMapper {
TreeNode getTree(Long objectiveid);
}
关于树形结构数据导出,我参考这篇博客,并针对OKR的特点做了修改。
Java 树形结构数据生成导出excel文件
OKR对齐视图数据结构的特点是:
关于OKR对齐视图这种数据结构的导出,我们下篇博客会把完整的代码放上来,并分析一下。这里说一下导出这种树形结构数据的主要步骤:
首先我们来了解一下Mybatis一级缓存:
Mybatis对缓存提供支持,但是在没有配置的默认情况下,它只开启一级缓存,一级缓存只是相对于同一个SQLSession而言。所以在参数和SQL完全一样的情况下,我们使用同一个SqlSession对象调用一个Mapper方法,往往只执行一次SQL,因为使用SelSession第一次查询后,MyBatis会将其放在缓存中,以后再查询的时候,如果没有声明需要刷新,并且缓存没有超时的情况下,SqlSession都会取出当前缓存的数据,而不会再次发送SQL到数据库。
mybatis一级缓存二级缓存
由于Mybatis的缓存机制,导致在出现重复的叶子节点时,虽然树结构正常构建,但是指向的是同一个java对象。因为是使用的Mybatis的递归查询,因此确认整个查询在一个SqlSession中执行完成,肯定是一级缓存导致的。这样会造成的后果,就是无法设置重复叶子节点的正确位置,因为指向同一个java对象,后遍历到的节点设置会覆盖前面的节点设置。
既然确定是一级缓存导致的,那关闭或者清除一级缓存就行了吧。因为是框架的递归查询,因此无法
调用SqlSession的修改、添加、删除、commIT(),close等
清空一级缓存。那怎么办呢,笨办法了:
既然树的结构关系时正确的,只是重复节点指向了同一个java对象,那就遍历重建对象吧
/**
* 深度拷贝树结构
* @param node
* @return
*/
private static OKRAlignTreeNode deepCopyTree(OKRAlignTreeNode node){
OKRAlignTreeNode newNode = node.clone();
List<OKRAlignTreeNode> children = node.getChildren();
if(children!=null&&children.size()>0){
List<OKRAlignTreeNode> newChildren = new LinkedList<>();
for (OKRAlignTreeNode child:children){
if(child!=null){
OKRAlignTreeNode newChild = deepCopyTree(child);
newChildren.add(newChild);
}
}
newNode.setChildren(newChildren);
}
return newNode;
}
以上是脚本宝典为你收集整理的Mybatis一级缓存的锅全部内容,希望文章能够帮你解决Mybatis一级缓存的锅所遇到的问题。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。