關於mybatis增加緩存引入的坑

mapper.xml的配置文件裏面開啓了緩存,代碼如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.pp.dao.mapper.ProductMapper">
	
	<cache eviction="LRU" flushInterval="3000" size="1024" readOnly="true" />
	
	<resultMap id="queryProductListMap" type="java.util.HashMap">
		<result column="id" property="id" />
		<result column="name" property="name" />
		<result column="price" property="price" />
		<result column="create_time" property="createTime" javaType="java.util.Date"/>
	</resultMap>
	
	<select id="queryProductList" resultMap="queryProductListMap">
		select id,name,price,create_time 
		from tb_product 
		where is_del=0 
		order by create_time desc
	</select>
	
</mapper>

緩存時間是3s,注意返回的結果,createTime類型是java.util.Date


java代碼如下:

package com.pp.controller;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.pp.dao.ProductMapper;

@RestController
public class HomeController {
	@Autowired
	private ProductMapper productMapper;
	
	@RequestMapping(value = "/list")
	public Object list() {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		List<Map<String, Object>> list = productMapper.queryProductList();
		Date now = new Date();
		for (Map<String, Object> map : list) {
			Date date = (Date)map.get("createTime");
			int days = (int)((now.getTime() - date.getTime())/1000/60/60/24);
			if (days > 3) {
				map.put("exitable", 1);
			} else {
				map.put("exitable", 0);
			}
			map.put("createTime", sdf.format(date));
		}
		return list;
	}
}

運行代碼之後,如果在3s(緩存時間)之內,多次訪問,就會報錯。

原因就在於 Date date = (Date)map.get("createTime"); 這一行把map裏面的對象轉換成Date(第一次這裏面的對象的確是Date),

map.put("createTime", sdf.format(date)); 這一行,又把map裏面的對象轉換成字符串了。

在緩存時間之內訪問,每次返回的是緩存的list<Map>,第一次把數據改掉之後,第二次那個對象就不是Date類型的對象了,強轉自然就報錯了。


問題定位到之後,解決方法就有很多了

最主要的是,不要改productMapper.queryProductList();返回的數據,可以把productMapper.queryProductList();返回的數據clone一份,去修改clone之後的數據

需要注意的是,要深度clone



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章