2020-11-20-SSM使用Redis做二级缓存

目的:使用Redis做MyBatis的二级缓存提高查询速度

参考文献:

https://blog.csdn.net/xushiyu1996818/article/details/89215428

https://blog.51cto.com/zhengqidaxia/1960256

步骤小结

  1. 导入依赖
  2. mybatis-config.xml中开启缓存
  3. 在Mapper.xml中设置二级缓存
  4. 其他(其他文件的编写)
  5. 测试
1、创建一个空的Maven项目

目录结构如下

2、导入依赖
<properties>
    <spring.version>5.2.7.RELEASE</spring.version>
</properties>

<dependencies>
     <!-- mybatis-redis cache实现 -->
        <dependency>
            <groupId>org.mybatis.caches</groupId>
            <artifactId>mybatis-redis</artifactId>
            <version>1.0.0-beta2</version>
        </dependency>

        <!-- redis -->
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-redis</artifactId>
            <version>2.3.4.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>3.1.0</version>
        </dependency>

        <!-- mybatis -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.5</version>
        </dependency>
        <!-- mybatis整合spring -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>2.0.5</version>
        </dependency>

        <!-- 连接池 druid -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.23</version>
        </dependency>
        <!-- mysql-connector -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
            <scope>runtime</scope>
        </dependency>
    
    <!-- springmvc -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <!-- spring-jdbc -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <!-- lombok 需要安装插件 -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.16</version>
    </dependency>
    <!-- test -->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.13</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-test</artifactId>
        <version>${spring.version}</version>
    </dependency>

    <!-- jackson -->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-core</artifactId>
        <version>2.11.2</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.11.2</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-annotations</artifactId>
        <version>2.11.2</version>
    </dependency>
</dependencies>
3、几个配置文件内容

mybatis-config.xml

在该文件中开启缓存

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <!-- 全局配置 -->
    <settings>
        <!-- 开启日志 -->
<!--        <setting name="logImpl" value="LOG4J"/>-->
        <setting name="logImpl" value="STDOUT_LOGGING"/>
        <!-- 开启驼峰和下滑线的命名转换 -->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
        <!-- 开启缓存 必须 同时 在 mapper.xml 使用缓存 -->
        <setting name="cacheEnabled" value="true"/>
    </settings>
</configuration>

spring-mybatis.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">
    <!-- 1.关联数据库配置文件 配置文件名为 db.properties -->
<!--    <context:property-placeholder location="classpath:db.properties"/>-->

    <!-- 2.配置数据源 -->
    <!-- druid -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
        <!-- 基本属性 url、user、password-->
        <property name="driverClassName" value="${jdbc.driver}" />
        <property name="url" value="${jdbc.url}" />
        <property name="username" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />


        <!-- 配置初始化大小、最小、最大-->
        <property name="maxActive" value="20" />
        <property name="initialSize" value="1" />
        <property name="minIdle" value="1" />

        <!-- 配置获取连接等待超时的时间-->
        <property name="maxWait" value="60000" />

        <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒-->
        <property name="timeBetweenEvictionRunsMillis" value="60000" />

        <!-- 配置一个连接在池中最小生存的时间,单位是毫秒-->
        <property name="minEvictableIdleTimeMillis" value="300000" />

        <property name="testWhileIdle" value="true" />
        <property name="testOnBorrow" value="false" />
        <property name="testOnReturn" value="false" />

        <!-- 打开PSCache,并且指定每个连接上、PSCache的大小-->
        <property name="poolPreparedStatements" value="true" />
        <property name="maxOpenPreparedStatements" value="20" />

         <!-- 配置监控统计拦截的filters,去掉后监控界面sql无法统计-->
        <property name="filters" value="stat" />
    </bean>

    <!-- 3.sqlSessionFactory -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!--    <bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">-->
        <property name="dataSource" ref="dataSource"/>
        <!-- 绑定mybatis-config.xml 文件 -->
        <property name="configLocation" value="classpath:mybatis/mybatis-config.xml"/>
        <!-- 绑定 com.liuyou.blog.***Mapper.xml 取代mybatis-config.xml中的<mapper>标签作用 -->
        <property name="mapperLocations" value="classpath:mapper/*.xml"/>
        <!-- 指定别名 -->
        <property name="typeAliasesPackage" value="pojo"/>
    </bean>

    <!-- 4.配置dao(mapper)接口扫描,即Mapper扫描器,动态的实现了Dao接口可以注入到spring容器中 == 代替了实现类 -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <!--注入 sqlSessionFactory-->
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
        <!-- 要扫描的dao包 -->
        <property name="basePackage" value="mapper"/>
    </bean>
</beans>

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">

    <!-- 加载配置文件 -->
<!--    <context:property-placeholder location="classpath:*.properties"/>-->
    <!-- 加载配置文件 -->
    <context:property-placeholder location="classpath:db.properties,redis.properties"/>

    <!-- 导入spring配置文件 -->
    <import resource="classpath:spring/spring-mybatis.xml"/>

</beans>

db.properties

# 驱动
jdbc.driver=com.mysql.jdbc.Driver
# url 数据库 为 liuyou_blog 可自行修改
jdbc.url=jdbc:mysql://localhost:3306/ssmbuild?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8
# 用户名
jdbc.username=root
# 密码
jdbc.password=mysql

redis.properties

必须保证 配置文件名是 redis.properties,以及其内容中key满足 org.mybatis.caches.redis.RedisConfig属性名对应(包含其父类的属性名)

#redis的服务器地址 ip地址
host=...
#redis的服务端口
port=6379
#链接数据库
database=0
#redis验证密码 没有就不用配置
password=
#客户端超时时间单位是毫秒
connectionTimeout=10000
#最大连接数
maxTotal=100
#最大空闲数
maxIdle=20
#最小空闲数
minIdle=1
#最大建立连接等待时间
maxWaitMills=2000
#指明是否在从池中取出连接前进行检验,如果检验失败,则从池中去除连接并尝试取出另一个
testOnBorrow=true
#当调用return Object方法时,进行有效性检查
testOnReturn=true
4、实体类、Mapper接口及Mapper.xml

Books

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Books implements Serializable {
    private static final long serialVersionUID = -4420834025097707421L;

    private Integer bookID;
    private String bookName;
    private Integer bookCounts;
    private String detail;
}

BooksMapper

public interface BooksMapper {
    //add a book
    int addBook(Books books);

    //delete a book
    int deleteBookById(int id);

    //update a book
    int updateBook(Books books);

    //queryAll
    List<Books> queryAll();
}

BooksMapper.xml

在该文件中设置缓存

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="mapper.BooksMapper">
    <!--在当前Mapper.xml中使用二级缓存-->
    <!--
        eviction LRU(默认) 缓存淘汰策略
            LRU – 最近最少使用的:移除最长时间不被使用的对象。
            FIFO – 先进先出:按对象进入缓存的顺序来移除它们。
            SOFT – 软引用:移除基于垃圾回收器状态和软引用规则的对象。
            WEAK – 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。
        flushInterval 缓存时间,以毫秒为单位,默认情况是不设置,也就是没有刷新间隔,缓存仅仅调用语句时刷新。
        size 缓存大小,每个缓存可以存储 1024(默认) 个列表或对象的引用
        readOnly 是否是只读的,只读的缓存会给所有调用者返回缓存对象的相同实例。因此这些对象不能被修改。这提供了很重要的性能优势。可读写的缓存会返回缓存对象的拷贝(通过序列化) 。这会慢一些,但是安全,因此默认是false。
	-->
    <cache eviction="LRU"
           type="org.mybatis.caches.redis.RedisCache"
           flushInterval="120000"
           size="1024"
           readOnly="true"/>

    <!-- 
		useCache表示是否需要使用缓存
        flushCache表示插入后是否需要刷新缓存
		以下是默认情况:
            <select ... flushCache="false" useCache="true"/>
            <insert ... flushCache="true"/>
            <update ... flushCache="true"/>
            <delete ... flushCache="true"/>
	-->
    <insert id="addBook" parameterType="Books">
        insert into ssmbuild.books(bookName, bookCounts, detail)
            value(#{bookName},#{bookCounts},#{detail});
    </insert>
    <delete id="deleteBookById" parameterType="int">
        delete from ssmbuild.books where bookID = #{bookID};
    </delete>
    <update id="updateBook" parameterType="Books">
        update ssmbuild.books
        set bookName = #{bookName},
            bookCounts = #{bookCounts},
            detail = #{detail}
        where bookID=#{bookID};
    </update>

    <select id="queryAll" resultType="books">
        select *
        from books;
    </select>
</mapper>
5、测试及结果

测试

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class TestMyBatis {

    @Autowired
    BooksMapper booksMapper;

    @Test
    public void test(){

        System.out.println("=======================start===========================");
        System.out.println("查询所有的书籍: ");
        System.out.println("first"+booksMapper.queryAll());
        System.out.println("再次查询所有的书籍: Redis做二级缓存");
        System.out.println("second"+booksMapper.queryAll());
        System.out.println("========================end==========================");
    }
}

结果

第一次查询,缓存命中率:0,没命中缓存,从数据库中拿数据

第二次查询,缓存命中率:0.5,命中缓存,从缓存中拿数据

=======================start===========================
查询所有的书籍: 
Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@1722011b] was not registered for synchronization because synchronization is not active

Cache Hit Ratio [mapper.BooksMapper]: 0.0  // 第一次,缓存命中率 0

JDBC Connection [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@352c1b98] will not be managed by Spring
==>  Preparing: select * from books; // 执行sql语句
==> Parameters: 
<==    Columns: bookID, bookName, bookCounts, detail
<==        Row: 74, test-spring-mybatis, 10, spring整合mybatis
<==      Total: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@1722011b]

first[Books(bookID=74, bookName=test-spring-mybatis, bookCounts=10, detail=spring整合mybatis)] // 查询结果(从数据库中获取)

再次查询所有的书籍: Redis做二级缓存
Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@ae3540e] was not registered for synchronization because synchronization is not active

Cache Hit Ratio [mapper.BooksMapper]: 0.5 // 第二次,缓存命中率 0.5(以命中)

Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@ae3540e]
    
second[Books(bookID=74, bookName=test-spring-mybatis, bookCounts=10, detail=spring整合mybatis)] // 查询结果(从缓存中获取)
========================end==========================
扩展
RedisConfig所有属性(含父类)
host = ""
port = 6379
connectionTimeout = 10000
soTimeout = 2000
password = ""
database = 0
clientName = null
maxTotal = 100
maxIdle = 20
minIdle = 1
lifo = true
fairness = false
maxWaitMillis = -1
minEvictableIdleTimeMillis = 60000
evictorShutdownTimeoutMillis = 10000
softMinEvictableIdleTimeMillis = -1
numTestsPerEvictionRun = -1
evictionPolicy = null
evictionPolicyClassName = "org.apache.commons.pool2.impl.DefaultEvictionPolicy"
testOnCreate = false
testOnBorrow = true
testOnReturn = true
testWhileIdle = true
timeBetweenEvictionRunsMillis = 30000
blockWhenExhausted = true
jmxEnabled = true
jmxNamePrefix = "pool"
jmxNameBase = null
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值