ehcache使用_Mybatis整合(Redis、Ehcache)实现二级缓存,恕我直言,你不会

目的:

  1. Mybatis整合Ehcache实现二级缓存
  2. Mybatis整合Redis实现二级缓存

Mybatis整合ehcache实现二级缓存

  • ssm中整合ehcache

  在POM中导入相关依赖

e91e0885a87192e4539e0de940ae26a4.gif
org.springframework    spring-context-support    ${spring.version}org.mybatis.caches    mybatis-ehcache    1.1.0net.sf.ehcache    ehcache    2.10.0
e91e0885a87192e4539e0de940ae26a4.gif
  • 修改日志配置,因为ehcache使用了Slf4j作为日志输出

  日志我们使用slf4j,并用log4j来实现。SLF4J不同于其他日志类库,与其它有很大的不同。

SLF4J(Simple logging Facade for Java)不是一个真正的日志实现,而是一个抽象层( abstraction layer),

它允许你在后台使用任意一个日志类库。

  Pom.xml

e91e0885a87192e4539e0de940ae26a4.gif
    2.9.13.2.01.7.13org.slf4j      slf4j-api      ${slf4j.version}org.slf4j      jcl-over-slf4j      ${slf4j.version}runtimeorg.apache.logging.log4j      log4j-api      ${log4j2.version}org.apache.logging.log4j      log4j-core      ${log4j2.version}org.apache.logging.log4j      log4j-slf4j-impl      ${log4j2.version}org.apache.logging.log4j      log4j-web      ${log4j2.version}runtimecom.lmax      disruptor      ${log4j2.disruptor.version}
e91e0885a87192e4539e0de940ae26a4.gif

  在Resource中添加一个ehcache.xml的配置文件

cc98afe1ec08828abe8c39da265c68f5.png

  ehcache.xml

e91e0885a87192e4539e0de940ae26a4.gif
<?xml version="1.0" encoding="UTF-8"?>
e91e0885a87192e4539e0de940ae26a4.gif

  在applicationContext-mybatis.xml中给mybatis设置支持

a59fb89d4d8d84bccca22dd9253172a6.png
e91e0885a87192e4539e0de940ae26a4.gif
      truefalsetrue
e91e0885a87192e4539e0de940ae26a4.gif

现在我们来测试一下它访问是否使用了二级缓存

e91e0885a87192e4539e0de940ae26a4.gif
@Test    public void cacheSingle() {        Book book= this.bookService.selectByPrimaryKey(5);        System.out.println(book);        Book book2= this.bookService.selectByPrimaryKey(5);        System.out.println(book2);    }
e91e0885a87192e4539e0de940ae26a4.gif

  效果:

2b943691cc52e03e0f14ccee621748be.png

很明显查询了两次数据库,没有成功,继续往下看如何解决这个问题

  我们需要在BookMapper.xml中加入chache配置

00de47bd7391709973fa59d16f261c3b.png

  我们在运行之前的测试方法测试一下

f559c8b297fb029e212454784d60b404.png

  很明显,第一次从数据库中查询数据第二次就从缓存中拿数据了

  现在我们来测试查询多条数据的效果

e91e0885a87192e4539e0de940ae26a4.gif
@Test    public void cacheMany() {        Map map = new HashMap();        map.put("bname", StringUtils.toLikeStr("圣墟"));        List hhhh = this.bookService.listPager(map,pageBean);        for (Map m : hhhh) {            System.out.println(m);        }        List hhhh2 = this.bookService.listPager(map,pageBean);        for (Map m : hhhh2) {            System.out.println(m);        }    }
e91e0885a87192e4539e0de940ae26a4.gif

  效果:

2ca2e3de0b6241dc6aaa9a1a4ef0a37a.png
  •   关闭缓存

既然开启了那就会有关闭缓存的时候,对吧

我们可以通过select标签的useCache属性打开或关闭二级缓存即可

  

注意:

1、mybatis默认使用的二级缓存框架就是ehcache(org.mybatis.caches.ehcache.EhcacheCache),无缝结合

2、Mybatis缓存开关一旦开启,可缓存单条记录,也可缓存多条,hibernate不能缓存多条。

3、Mapper接口上的所有方法上另外提供关闭缓存的属性


Mybatis整合redis实现二级缓存

   1. redis常用类

1.1 Jedis

jedis就是集成了redis的一些命令操作,封装了redis的java客户端

1.2 JedisPoolConfig

Redis连接池

1.3 ShardedJedis

基于一致性哈希算法实现的分布式Redis集群客户端

实现 mybatis 的二级缓存,一般来说有如下两种方式:

1) 采用 mybatis 内置的 cache 机制。

2) 采用三方 cache 框架, 比如ehcache, oscache 等等.

  2. 添加jar依赖

    添加redis相关依赖

e91e0885a87192e4539e0de940ae26a4.gif
    2.9.01.7.1.RELEASEredis.clients      jedis      ${redis.version}org.springframework.data      spring-data-redis      ${redis.spring.version}
e91e0885a87192e4539e0de940ae26a4.gif

  log4j2配置

jackson依赖

e91e0885a87192e4539e0de940ae26a4.gif
    2.9.3com.fasterxml.jackson.core      jackson-databind      ${jackson.version}com.fasterxml.jackson.core      jackson-core      ${jackson.version}com.fasterxml.jackson.core      jackson-annotations      ${jackson.version}
e91e0885a87192e4539e0de940ae26a4.gif
  • spring + redis 集成实现缓存功能(与mybatis无关)

添加两个redis的配置文件,并将redis.properties和applicationContext-redis.xml配置到applicationContext.xml文件中

  redis.properties

e91e0885a87192e4539e0de940ae26a4.gif
redis.hostName=192.168.80.128redis.password=613613redis.timeout=10000redis.maxIdle=300redis.maxTotal=1000redis.maxWaitMillis=1000redis.minEvictableIdleTimeMillis=300000redis.numTestsPerEvictionRun=1024redis.timeBetweenEvictionRunsMillis=30000redis.testOnBorrow=trueredis.testWhileIdle=true
e91e0885a87192e4539e0de940ae26a4.gif

applicationContext-redis.xml

e91e0885a87192e4539e0de940ae26a4.gif
<?xml version="1.0" encoding="UTF-8"?>
e91e0885a87192e4539e0de940ae26a4.gif

  将redis.properties导入到applicationContext.xml文件中

applicationContext.xml

  <?xml version="1.0" encoding="UTF-8"?>

e91e0885a87192e4539e0de940ae26a4.gif
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"       xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"       xmlns:aop="http://www.springframework.org/schema/aop"       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">     
e91e0885a87192e4539e0de940ae26a4.gif

  将redis缓存引入到mybatis中

e91e0885a87192e4539e0de940ae26a4.gif
package com.ht.Util;import org.apache.ibatis.cache.Cache;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.dao.DataAccessException;import org.springframework.data.redis.connection.RedisConnection;import org.springframework.data.redis.core.RedisCallback;import org.springframework.data.redis.core.RedisTemplate;import java.util.concurrent.TimeUnit;import java.util.concurrent.locks.ReadWriteLock;import java.util.concurrent.locks.ReentrantReadWriteLock;public class RedisCache implements Cache //实现类{    private static final Logger logger = LoggerFactory.getLogger(RedisCache.class);    private static RedisTemplate redisTemplate;    private final String id;    /**     * The {@code ReadWriteLock}.     */    private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();    @Override    public ReadWriteLock getReadWriteLock()    {        return this.readWriteLock;    }    public static void setRedisTemplate(RedisTemplate redisTemplate) {        RedisCache.redisTemplate = redisTemplate;    }    public RedisCache(final String id) {        if (id == null) {            throw new IllegalArgumentException("Cache instances require an ID");        }        logger.debug("MybatisRedisCache:id=" + id);        this.id = id;    }    @Override    public String getId() {        return this.id;    }    @Override    public void putObject(Object key, Object value) {        try{            logger.info(">>>>>>>>>>>>>>>>>>>>>>>>putObject: key="+key+",value="+value);            if(null!=value)                redisTemplate.opsForValue().set(key.toString(),value,60, TimeUnit.SECONDS);        }catch (Exception e){            e.printStackTrace();            logger.error("redis保存数据异常!");        }    }    @Override    public Object getObject(Object key) {        try{            logger.info(">>>>>>>>>>>>>>>>>>>>>>>>getObject: key="+key);            if(null!=key)                return redisTemplate.opsForValue().get(key.toString());        }catch (Exception e){            e.printStackTrace();            logger.error("redis获取数据异常!");        }        return null;    }    @Override    public Object removeObject(Object key) {        try{            if(null!=key)                return redisTemplate.expire(key.toString(),1,TimeUnit.DAYS);        }catch (Exception e){            e.printStackTrace();            logger.error("redis获取数据异常!");        }        return null;    }    @Override    public void clear() {        Long size=redisTemplate.execute(new RedisCallback() {            @Override            public Long doInRedis(RedisConnection redisConnection) throws DataAccessException {                Long size = redisConnection.dbSize();                //连接清除数据                redisConnection.flushDb();                redisConnection.flushAll();                return size;            }        });        logger.info(">>>>>>>>>>>>>>>>>>>>>>>>clear: 清除了" + size + "个对象");    }    @Override    public int getSize() {        Long size = redisTemplate.execute(new RedisCallback() {            @Override            public Long doInRedis(RedisConnection connection)                    throws DataAccessException {                return connection.dbSize();            }        });        return size.intValue();    }}
e91e0885a87192e4539e0de940ae26a4.gif

  RedisCacheTransfer

e91e0885a87192e4539e0de940ae26a4.gif
package com.ht.Util;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.data.redis.core.RedisTemplate;public class RedisCacheTransfer {    @Autowired    public void setRedisTemplate(RedisTemplate redisTemplate) {        RedisCache.setRedisTemplate(redisTemplate);    }}
e91e0885a87192e4539e0de940ae26a4.gif

  接下来,我们在BookMapper.xml中配置RedisCache缓存

f1d5c13541013fb6b18d61604e86715a.png

  测试:

e91e0885a87192e4539e0de940ae26a4.gif
 @Test    public void cacheSingle() {        Book book= this.bookService.selectByPrimaryKey(5);        System.out.println(book);        Book book2= this.bookService.selectByPrimaryKey(5);        System.out.println(book2);    }
e91e0885a87192e4539e0de940ae26a4.gif
8bad6dcfd0ebad9ee73fe27513062a3f.png
e63f5a90c894940ff02cb32e39cbade8.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/506308.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

取证 c语言实现日志导出_日志与日志不一样:五种不能忽略的日志源

给日志源分出主次大有利于开展有效事件响应。就像分诊护士一样&#xff0c;安全人员也必须给数据分出个优先主次&#xff0c;以帮助他们更好地识别问题&#xff0c;使公司企业及其数据和设备能够避免入侵者和网络攻击的伤害。但是&#xff0c;记录和监视IT环境中的所有相关事件…

codesoft指定打印机打印_巧用win32print来控制windows系统打印机并推送打印任务

小爬最近接到的一个需求是&#xff1a;将windows系统下的打印任务批量有序传输给网络打印机&#xff0c;实现批量有序打印。用户先从公司的OA(B/S模式)系统下 打印指定内容的表单以及表单中的附件内容。这个问题可以这样分解&#xff1a;1、抓包&#xff0c;得到OA对应的任务接…

crmeb pc端模板下载_PC端人人影视下载速度如何提高

首先下载最新版本的人人影视我的是这个&#xff0c;右下角版本号1022然后在下载设置那里把连接数调高一点大致就这样我的就是调了一下然后下载速度高了许多&#xff0c;刚开始只有1M左右的速度&#xff0c;现在4&#xff0c;5M每秒

android 编辑自定义可编辑表格,smart 框架 列表 可编辑表格

可编辑表格常用属性colModel: [{label: "主键ID", name: "hellop1",hidden:true},{label: "列明", name: "hellop2",align: "center", editable: true, edittype: text, editrules: { required: true } }editable&#xff1…

dos虚拟机如何全屏显示_实用工具 | 虚拟机软件VirtualBox详细使用介绍

前言&#xff1a;搞自动化控制的工程师&#xff0c;要擅于利用工具和软件&#xff0c;其中&#xff0c;虚拟机就是很好的工具&#xff0c;安装操作系统以后&#xff0c;就相当于多了一台电脑&#xff0c;可以用来测试网络&#xff0c;测试软件&#xff0c;或者直接用来调试设备…

axure原型案例_Axure RP9原型案例:制作一个可以滑动的菜单

摘要&#xff1a;在PC端的产品中我们会常常见到滑动式菜单&#xff0c;当鼠标移入菜单上方&#xff0c;向下或向右自动滑动弹出子菜单&#xff0c;当页面信息层级较多或功能较多时&#xff0c;在产品设计时经常会用到这种滑动式菜单。今天就和大家分享如下制作滑动式菜单的交互…

一会404一会500_没网络就是404?这锅可不能乱背!

在那个房价未突破天际&#xff0c;一台计算机还可以占着几间房的年代。数据库被存放在一个神秘的房间中。如果无法找到请求者所需要的文件&#xff0c;用户将会得到file not found的信息。而这件房间的门牌就是404。404https://www.zhihu.com/video/1168484640850579456当然以上…

android8 呼吸灯,红米note8pro呼吸灯颜色如何设置?

红米note8pro支持呼吸灯功能&#xff0c;当有未读通知的时候&#xff0c;指示灯就会闪烁提醒。此外&#xff0c;我们还可以根据自己的喜好设置呼吸灯的颜色&#xff0c;下面为大家带来详细的设置教程。红米note8pro怎么设置呼吸灯颜色1、首先&#xff0c;进入手机桌面&#xff…

java string 返回匹配正则的字符串的起始位置_【Python】正则表达式

概述正则表达式是一个特殊的字符序列&#xff0c;它能帮助你方便的检查一个字符串是否与某种模式匹配。 Python 自1.5版本起增加了re 模块&#xff0c;它提供 Perl 风格的正则表达式模式。re 模块使 Python 语言拥有全部的正则表达式功能。 compile 函数根据一个模式字符串和可…

html九图拼图游戏代码,HTML5拼图游戏

拼图游戏介绍 拼图游戏将一幅图片分割成若干拼块并将它们随机打乱顺序。当将所有拼块都放回原位置时&#xff0c;就完成了拼图(游戏结束)。 在“游戏”中&#xff0c;单击滑块选择游戏难易&#xff0c;“容易”为3行3列拼图游戏&#xff0c;中间为一个4行4列拼图游戏&#xff0…

access驱动程序_Linux驱动程序学习二 (续) scull 源码在内核5.4.0上的编译调试

《LINUX设备驱动程序》第三章提供了源码scull,但是由于我用的是5.4.0内核,书中的是2.6.10内核,内核发生了很大的变化,因此编译scull源码花费了不少时间,下面是编译调试记录。&#xff08;这个编译调试记录应该是目前网络上适应内核版本最高的&#xff0c;所以也希望给近期加入《…

android评论嵌套,android 嵌套的listview示例(可参照实现朋友圈评论)

android 嵌套的listview示例(可参考实现朋友圈评论) 最近在项目中用到listview中再嵌套一个listview&#xff0c;两层也有监听&#xff0c;都没有问题。其实&#xff0c;主要解决里面那一层的listview的高度计算就可以&#xff0c;外面那一层listview自动计算。加上里面那层展开…

捷达vs7测试_捷达VS5话题:防撞钢梁,溃缩梁。第200311期

//封面图&#xff0c;捷达VS5&#xff0c;自中&#xff0c;最近看到网上有些观点有点儿带偏&#xff0c;然后咱们技术群今天也讨论了一下&#xff0c;大家也来听听咱们爱折腾的车主们是怎么看防撞梁的事情的。事情起因是因为大家看到一些网上的拆车视频&#xff0c;说捷达VS5前…

html5 原生拖拽,原生JS实现拖拽效果

这篇文章主要为大家详细介绍了原生JS实现拖拽效果&#xff0c;文中示例代码介绍的非常详细&#xff0c;具有一定的参考价值&#xff0c;感兴趣的小伙伴们可以参考一下本文实例为大家分享了JS实现拖拽效果的具体代码&#xff0c;供大家参考&#xff0c;具体内容如下想要让整个元…

ov5640帧率配置_逃离塔科夫怎么提升帧率 帧率优化建议_单机游戏_游戏攻略

逃离塔科夫有着非常真实的游玩与画面表现&#xff0c;所以这类的多人游戏比较吃配置&#xff0c;那么帧率上不去会十分影响游戏体验&#xff0c;下面请看由“SIIYAM”带来的逃离塔科夫帧率优化建议&#xff0c;一起来看看吧。帧率优化建议&#xff1a;这游戏对于cpu资源分配和内…

js 带笔锋 签字版_年轻人的第一支签字笔? ——米家签字笔评测

emm感觉笔者能咕到自己都怀疑人生惹QAQ…对于小米而言&#xff0c;可能他家中性笔做的还真没手机那么好。但对于劝退这件事&#xff0c;理由其实是很复杂的。但既然决定了要来写这样一点东西&#xff0c;那我也自然要把我知道的和能想到的&#xff0c;略述一二。我们先来看看小…

itools 不支持缩略图下载_PS插件缩略图3.8.0.96安装教程

插件下载[名称]&#xff1a;PS插件『缩略图补丁3.8.0.96』[大小]&#xff1a;1.4 MB [语言]&#xff1a;简体中文 [安装环境]&#xff1a;Win7/Win8/Win10[支持版本]&#xff1a;PS CS6—CC2019[32/64位下载链接]&#xff1a;https://pan.baidu.com/s/1AlOlWzMZfYgdJSlZpbQsmw…

z370支持pcie信号拆分吗_定了!AMD B550主板确认将支持PCIE4.0,多项能力接近X570

近日&#xff0c;华擎B550AM Gaming主板照片和文档泄露&#xff0c;Micro-ATX板型、具备4内存插槽&#xff0c;支持PCIE4.0显卡/固态硬盘。B550芯片组本身无法拆分PCIE4.0信道&#xff0c;所以华擎的这张B550主板在搭配第三代锐龙时只有第一条PCIE插槽(通常安装独立显卡)和M.2固…

mac 修改conda镜像 condarc_win10 修改anaconda源

通过 conda config 命令生成配置文件&#xff0c;这里&#xff0c;我们使用清华的镜像&#xff1a;https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/&#xff0c;首先&#xff0c;打开CMD&#xff0c;执行命令&#xff1a;conda config --add channels https://mirro…

倒计时css和js html代码,手把手教你利用CSS和JS创建一个倒数计时器

倒计时功能&#xff0c;在很多地方都会用到&#xff0c;我们平时都习惯去用一些插件来应用&#xff0c;会减少不少的工作量&#xff0c;并且效果也能达到预期。我今天并不是想分享什么倒计时插件&#xff0c;而是自己写一个简单的倒数计时器&#xff0c;有兴趣的同学可以往下看…