• springboot+mybatis 用redis作二级缓存


    1.加入相关依赖包:

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>springBootD</groupId>
        <artifactId>demo</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <packaging>jar</packaging>
    
        <name>demo</name>
        <description>Demo project for Spring Boot</description>
    
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.0.3.RELEASE</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
            <java.version>1.8</java.version>
        </properties>
    
        <dependencies>
          <!--mybatis依赖--> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.2</version> </dependency>
          <!--redis依赖--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency>
        <!--swagger2自动文档依赖--> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.6.1</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>2.6.1</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin>
           <!--生成实体类、mapper映射接口、mapperXML映射文件 插件--> <plugin> <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator-maven-plugin</artifactId> <version>1.3.2</version> <configuration> <!--配置文件的位置--> <configurationFile>src/main/resources/generatorConfig.xml</configurationFile> <verbose>true</verbose> <overwrite>true</overwrite> </configuration> <executions> <execution> <id>Generate MyBatis Artifacts</id> <goals> <goal>generate</goal> </goals> </execution> </executions> <dependencies> <dependency> <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator-core</artifactId> <version>1.3.2</version> </dependency> </dependencies> </plugin> </plugins> </build> </project>

    2.springboot配置文件:

    #数据库配置
    spring.datasource.data-username=com.mysql..jdbc.Driver
    spring.datasource.url=jdbc:mysql://localhost:3306/springboot?seUnicode=true&characterEncoding=utf8&characterSetResults=utf8
    spring.datasource.username=root
    spring.datasource.password=root
    
    #redis配置
    spring.redis.host=localhost
    spring.redis.port=6379
    spring.redis.database=1
    spring.redis.jedis.pool.max-active=8
    spring.redis.jedis.pool.max-wait= -1ms
    spring.redis.jedis.pool.max-idle=500
    
    #mybatis
    mybatis.mapper-locations=classpath*:mybatis/mapper/**/*.xml
    #开启MyBatis的二级缓存
    mybatis.configuration.cache-enabled=true
    
    #日志配置
    logging.level.springbootd.demo=debug
    logging.level.org.springframework.web=debug
    logging.level.org.springframework.transaction=debug
    logging.level.org.mybatis=debug

    3.建立获取spring容器获取bean工具类,通过Spring Aware(容器感知)来获取到ApplicationContext,然后根据ApplicationContext获取容器中的Bean,因为RedisTemplate的bean不能用@Autowired注解注入

    package springbootd.demo.util;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.ApplicationContextAware;
    import org.springframework.stereotype.Component;
    
    @Component
    public class ApplicationContextHolder implements ApplicationContextAware{
    
        private static ApplicationContext applicationContext;
    
        /**
         * 实现ApplicationContextAware接口的context注入函数, 将其存入静态变量.
         */
        public void setApplicationContext(ApplicationContext applicationContext) {
            ApplicationContextHolder.applicationContext = applicationContext; // NOSONAR
        }
    
        /**
         * 取得存储在静态变量中的ApplicationContext.
         */
        public static ApplicationContext getApplicationContext() {
            checkApplicationContext();
            return applicationContext;
        }
    
        /**
         * 从静态变量ApplicationContext中取得Bean, 自动转型为所赋值对象的类型.
         */
        @SuppressWarnings("unchecked")
        public static <T> T getBean(String name) {
            checkApplicationContext();
            return (T) applicationContext.getBean(name);
        }
    
        /**
         * 从静态变量ApplicationContext中取得Bean, 自动转型为所赋值对象的类型.
         */
        @SuppressWarnings("unchecked")
        public static <T> T getBean(Class<T> clazz) {
            checkApplicationContext();
            return (T) applicationContext.getBeansOfType(clazz);
        }
    
        /**
         * 清除applicationContext静态变量.
         */
        public static void cleanApplicationContext() {
            applicationContext = null;
        }
    
        private static void checkApplicationContext() {
            if (applicationContext == null) {
                throw new IllegalStateException("applicaitonContext未注入,请在applicationContext.xml中定义SpringContextHolder");
            }
        }
    
    
    }

    4.实现mybatis缓存接口:

    package springbootd.demo.util;
    import org.apache.ibatis.cache.Cache;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.data.redis.core.RedisCallback;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.data.redis.core.ValueOperations;
    import java.util.concurrent.TimeUnit;
    import java.util.concurrent.locks.ReadWriteLock;
    import java.util.concurrent.locks.ReentrantReadWriteLock;
    
    public class MybatisRedisCache implements Cache {
    
        private static final Logger logger = LoggerFactory.getLogger(MybatisRedisCache.class);
        private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
        private final String id; // cache instance id
        private RedisTemplate redisTemplate;
        private static final long EXPIRE_TIME_IN_MINUTES = 30; // redis过期时间
        public MybatisRedisCache(String id) {
            if (id == null) {
                throw new IllegalArgumentException("Cache instances require an ID");
            }
            this.id = id;
        }
        @Override
        public String getId() {
            return id;
        }
        /**
         * Put query result to redis
         *
         * @param key
         * @param value
         */
        @Override
        @SuppressWarnings("unchecked")
        public void putObject(Object key, Object value) {
            RedisTemplate redisTemplate = getRedisTemplate();
            ValueOperations opsForValue = redisTemplate.opsForValue();
            opsForValue.set(key, value, EXPIRE_TIME_IN_MINUTES, TimeUnit.MINUTES);
            logger.debug("Put query result to redis");
        }
        /**
         * Get cached query result from redis
         *
         * @param key
         * @return
         */
        @Override
        public Object getObject(Object key) {
            RedisTemplate redisTemplate = getRedisTemplate();
            ValueOperations opsForValue = redisTemplate.opsForValue();
            logger.debug("Get cached query result from redis");
            return opsForValue.get(key);
        }
        /**
         * Remove cached query result from redis
         *
         * @param key
         * @return
         */
        @Override
        @SuppressWarnings("unchecked")
        public Object removeObject(Object key) {
            RedisTemplate redisTemplate = getRedisTemplate();
            redisTemplate.delete(key);
            logger.debug("Remove cached query result from redis");
            return null;
        }
        /**
         * Clears this cache instance
         */
        @Override
        public void clear() {
            RedisTemplate redisTemplate = getRedisTemplate();
            redisTemplate.execute((RedisCallback) connection -> {
                connection.flushDb();
                return null;
            });
            logger.debug("Clear all the cached query result from redis");
        }
        @Override
        public int getSize() {
            return 0;
        }
        @Override
        public ReadWriteLock getReadWriteLock() {
            return readWriteLock;
        }
        private RedisTemplate getRedisTemplate() {
            if (redisTemplate == null) {
                redisTemplate = ApplicationContextHolder.getBean("redisTemplate");
            }
            return redisTemplate;
        }
    }

    5.在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="springbootd.demo.mybatisDao.UserMapper" >
      <cache type="springbootd.demo.util.MybatisRedisCache"/>
      <resultMap id="BaseResultMap" type="springbootd.demo.mybatisEntity.User" >
        <id column="id" property="id" jdbcType="BIGINT" />
        <result column="pass_word" property="passWord" jdbcType="VARCHAR" />
        <result column="user_name" property="userName" jdbcType="VARCHAR" />
      </resultMap>
      <sql id="Base_Column_List" >
        id, pass_word, user_name
      </sql>
      <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Long" >
        select 
        <include refid="Base_Column_List" />
        from user
        where id = #{id,jdbcType=BIGINT}
      </select>
    </mapper>

    细节提示:

    1.mapper映射接口类要加上@mapper注解,将其添加入ioc容器:

    import org.apache.ibatis.annotations.Mapper;
    import springbootd.demo.mybatisEntity.User;
    @Mapper
    public interface UserMapper {

    User selectByPrimaryKey(Long id); }

    或者在springboot入口类加上@MapperScan(basePackages ="包路径")

    @SpringBootApplication
    @MapperScan(basePackages ="springbootd.demo.mybatisDao")
    public class DemoApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(DemoApplication.class, args);
        }
    }
  • 相关阅读:
    MySQL中IS NULL、IS NOT NULL、!=不能用索引?胡扯!
    市值TOP10,人类进化及中美坐标
    倒序切片
    对list进行切片
    Python之定义可变参数
    Python之递归函数
    Python之“可变”的tuple
    Python之创建单元素tuple
    Python中Unicode字符串
    Pycharm配置autopep8让Python代码更符合pep8规范
  • 原文地址:https://www.cnblogs.com/chenziyu/p/9229748.html
Copyright © 2020-2023  润新知