spring boot + mysql +mybatis +redis(二级缓存)实例

来源:互联网 发布:江国香织 知乎 编辑:程序博客网 时间:2024/06/06 10:05

配置了好几天才算配置好

个人感觉spring boot版本间兼容不好

一、创建maven项目并添加 pom 依赖

<?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>1</groupId>    <artifactId>1</artifactId>    <version>1.0-SNAPSHOT</version>    <!-- Inherit defaults from Spring Boot -->    <parent>        <groupId>org.springframework.boot</groupId>        <artifactId>spring-boot-starter-parent</artifactId>        <version>1.5.3.RELEASE</version>        <relativePath/> <!-- lookup parent from repository -->    </parent>    <!--项目编码格式以及JDK版本指定-->    <properties>        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>        <java.version>1.8</java.version>    </properties>    <!-- Add typical dependencies for a web application -->    <dependencies>        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-data-redis</artifactId>        </dependency>        <dependency>            <groupId>org.mybatis.spring.boot</groupId>            <artifactId>mybatis-spring-boot-starter</artifactId>            <version>1.3.0</version>        </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>        <!--alibaba.fastjson-->        <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->        <dependency>            <groupId>com.alibaba</groupId>            <artifactId>fastjson</artifactId>            <version>1.2.41</version>        </dependency>        <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->        //spring 包 很容易与spring boot 版本冲突 注意        <dependency>            <groupId>org.springframework</groupId>            <artifactId>spring-context</artifactId>            <version>4.3.12.RELEASE</version>        </dependency>    </dependencies>    <build>        <plugins>            <plugin>                <groupId>org.springframework.boot</groupId>                <artifactId>spring-boot-maven-plugin</artifactId>            </plugin>        </plugins>    </build></project>

二、yml 配置文件

######################################                     ###########     应用通用配置     ###########                     #####################################spring:# 应用名称  application:    name: MavenDemoProject# 多环境配置  profiles:    active: dev# http请求编码配置  http:    encoding:      charset: UTF-8      force: true      enabled: true# mysql数据库配置  datasource:#    type: com.alibaba.druid.pool.DruidDataSource    driver-class-name: com.mysql.jdbc.Driver    #url,username,password动态配置    url: jdbc:mysql://localhost:3306/test?useUnicode:true&characterEncoding:utf-8    username: root    password: ****    dbcp2:       #最大空闲连接       max-idle: 100       #最小空闲连接       min-idle: 10       #最大连接数       max-total: 200       #最大等待时间       max-wait-millis: 5000       #检测周期 单位毫秒       time-between-eviction-runs-millis: 30000       #连接池足校生存时间       min-evictable-idle-time-millis: 1800000#       test-on-borrow: true#       validation-query: SELECT 1#       test-while-idle: true#       num-tests-per-eviction-run: 100# redis缓存配置  redis:     #host,password,port,database动态配置    host: *******    password: *****    port: 6379    database: 0    timeout: 2000    pool:        # 连接池中的最大空闲连接        max-idle: 80        # 连接池中的最小空闲连接        min-idle: 1        # 连接池最大连接数(使用负值表示没有限制)        max-active: 80        # 连接池最大阻塞等待时间(使用负值表示没有限制)        max-wait: 10# mybatis配置mybatis:  #config-location: classpath:/mybatis-config.xml  type-aliases-package: com.frank.dao.*  mapper-locations: classpath:/mapper/*.xml#  configuration:#    #延时加载#    lazy-loading-enabled: true#    map-underscore-to-camel-case: true#    use-column-label: true

需要在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.weixin.dao.student.StudentMapper">    <!--开启二级缓存--><cache type="com.weixin.config.RedisConfig"/>    <select id="get" resultType="com.weixin.model.Student">        SELECT * FROM student        WHERE id = #{id}    </select>    <update id="update" parameterType="com.weixin.model.Student">        UPDATE student SET        name = #{name},        age = #{age}        WHERE id = #{id}    </update></mapper>

bean类型 需要实现Serializable接口

package com.weixin.model;import java.io.Serializable;public class Student implements Serializable {    private int id;    private String name;    private int age;    public int getId() {        return id;    }    public void setId(int id) {        this.id = id;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public void setAge(int age) {        this.age = age;    }    public int getAge() {        return age;    }}

三、Redis 配置类

package com.weixin.config;import org.apache.ibatis.cache.Cache;import org.slf4j.Logger;import org.springframework.data.redis.core.RedisCallback;import org.springframework.data.redis.core.RedisTemplate;import org.springframework.data.redis.core.ValueOperations;import org.springframework.data.redis.serializer.RedisSerializer;import org.springframework.data.redis.serializer.StringRedisSerializer;import java.util.concurrent.TimeUnit;import java.util.concurrent.locks.ReadWriteLock;import java.util.concurrent.locks.ReentrantReadWriteLock;public class RedisConfig implements Cache {    private static final Logger logger = org.slf4j.LoggerFactory.getLogger(RedisConfig.class);    private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();    private  String id; // cache instance id    private RedisTemplate redisTemplate;    private static final long EXPIRE_TIME_IN_MINUTES = 30; // redis过期时间    private static final String DEFAULT_ID = "default_id";    public RedisConfig(String id) {        if (id == null) {            id = DEFAULT_ID;        }        this.id = id;    }    public void setId(String 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) {        try {            RedisTemplate redisTemplate = getRedisTemplate();            ValueOperations opsForValue = redisTemplate.opsForValue();            opsForValue.set(key, value, EXPIRE_TIME_IN_MINUTES, TimeUnit.MINUTES);            logger.debug("Put query result to redis");        } catch (Throwable t) {            logger.error("Redis put failed", t);        }    }    /**     * Get cached query result from redis     *     * @param key     * @return     */    @Override    public Object getObject(Object key) {        try {            RedisTemplate redisTemplate = getRedisTemplate();            ValueOperations opsForValue = redisTemplate.opsForValue();            logger.debug("Get cached query result from redis");            return opsForValue.get(key);        } catch (Throwable t) {            logger.error("Redis get failed, fail over to db", t);            return null;        }    }    /**     * Remove cached query result from redis     *     * @param key     * @return     */    @Override    @SuppressWarnings("unchecked")    public Object removeObject(Object key) {        try {            RedisTemplate redisTemplate = getRedisTemplate();            redisTemplate.delete(key);            logger.debug("Remove cached query result from redis");        } catch (Throwable t) {            logger.error("Redis remove failed", t);        }        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");    }    /**     * This method is not used     *     * @return     */    @Override    public int getSize() {        return 0;    }    @Override    public ReadWriteLock getReadWriteLock() {        return readWriteLock;    }    private RedisTemplate getRedisTemplate() {        if (redisTemplate == null) {            redisTemplate = ApplicationContextHolder.getBean("redisTemplate");        }        //spring-data-redis的RedisTemplate<K, V>模板类在操作redis时默认使用JdkSerializationRedisSerializer来进行序列化        //一下修改为String类型序列化 解决redis库中 K V 出现 xAC\xED\x00\x05t\x00\x04 问题        RedisSerializer stringSerializer = new StringRedisSerializer();        redisTemplate.setKeySerializer(stringSerializer);//        redisTemplate.setValueSerializer(stringSerializer);        redisTemplate.setHashKeySerializer(stringSerializer);//        redisTemplate.setHashValueSerializer(stringSerializer);        return redisTemplate;    }}

ApplicationContextHolder 类

package com.weixin.config;import org.springframework.beans.BeansException;import org.springframework.context.ApplicationContext;import org.springframework.context.ApplicationContextAware;import org.springframework.stereotype.Component;@Componentpublic class ApplicationContextHolder implements ApplicationContextAware {    private static ApplicationContext applicationContext;    @Override    public void setApplicationContext(ApplicationContext ctx) throws BeansException {        applicationContext = ctx;    }    /**     * Get application context from everywhere     *     * @return     */    public static ApplicationContext getApplicationContext() {        return applicationContext;    }    /**     * Get bean by class     *     * @param clazz     * @param <T>     * @return     */    public static <T> T getBean(Class<T> clazz) {        return applicationContext.getBean(clazz);    }    /**     * Get bean by class name     *     * @param name     * @param <T>     * @return     */    @SuppressWarnings("unchecked")    public static <T> T getBean(String name) {        return (T) applicationContext.getBean(name);    }}

上面需要用到spring-context jar 包,需要注意版本,版本不同可能冲突

注意:

 RedisSerializer stringSerializer = new StringRedisSerializer();        redisTemplate.setKeySerializer(stringSerializer);//        redisTemplate.setValueSerializer(stringSerializer);        redisTemplate.setHashKeySerializer(stringSerializer);//        redisTemplate.setHashValueSerializer(stringSerializer);

上面表示redis中的key值设置为String类型,这样能更清楚的找到key值,但是如果开启二级缓存的话,执行sql语句时查找的对象不会进行redis存储,因为查找到对象key为Object值,控制台会报错,如图

这里写图片描述

可以改成 key.toString() 进行存储,但是出现文件分级,如图:

这里写图片描述

所以说还要按照实际情况进行设置

四、controller层进行使用

package com.weixin.controller;import com.alibaba.fastjson.JSONObject;import com.weixin.config.RedisConfig;import com.weixin.model.Student;import com.weixin.service.student.StudentService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.data.redis.core.RedisTemplate;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.PathVariable;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;@RestController@RequestMapping("/test")public class SpringBootTest {    @Autowired    private StudentService studentService;    @RequestMapping("/one")    public JSONObject test() {        JSONObject jsonObject = new JSONObject();        jsonObject.put("code", "success");        //id 没有实际价值 只是为了更好确认        RedisConfig redisConfig = new RedisConfig("100");        redisConfig.putObject("1000","hello i m frank!");        return jsonObject;    }    /**     * 根据id获取对象     *     * @param id     * @return     */    @GetMapping("/{id}")    public JSONObject get(@PathVariable("id") int id) {        Student student = studentService.get(id);        JSONObject jsonObject = new JSONObject();        jsonObject.put("id", student.getId());        jsonObject.put("age", student.getAge());        jsonObject.put("name", student.getName());        RedisConfig redisConfig = new RedisConfig("100");        redisConfig.putObject("frank",jsonObject);        return jsonObject;    }    /**     * 更新对象     *     * @return     */    @RequestMapping("/update")    public String put() {        Student student = new Student();        student.setId(1);        student.setAge(22);        student.setName("new frank");        studentService.update(student);        return "success";    }    @RequestMapping("/getRedis")    public JSONObject get() {        RedisConfig redisConfig = new RedisConfig("100");        return  (JSONObject) redisConfig.getObject("frank");    }}

五、运行查看

这里写图片描述

查看redis

这里写图片描述

添加JSON value 值

这里写图片描述

显示情况

这里写图片描述

如果想显示String的话 可以在RedisConfig中 setValueSerializer 进行设置

获取value值

这里写图片描述

五、项目总体结构

这里写图片描述

项目下载

http://download.csdn.net/download/jasonhector/10158450

阅读全文
1 0
原创粉丝点击