Redis数据结构为字符串String的实践 之 分别存储字符串和存储对象(下)

一.项目用redis-learn参考文章,存储字符串可以看上文

本文我们实际操作下 数据结构字符串String 分别存储字符串和存储对象

二. 存储对象:

一般情况下,我们做redis会和数据库合起来使用,如果在redis中查不到,就到数据库中查,有查到再保存到redis中。
2.1 配置数据库,用的是mysql和mybatis-plus,添加依赖,代码如下:

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus</artifactId>
            <version>2.3</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
            <version>1.5.6.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.39</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>0.2.16</version>
        </dependency>

2.2 配置文件中配置数据库和mybatis-plus的信息,代码如下:


server:
  port: 8782

spring:
  #配置程序名为redis-learn
  application:
    name: redis-learn
    
  #数据库配置
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/spring_cloud?characterEncoding=utf8
    driver-class-name: com.mysql.jdbc.Driver
    username: root
    password: 123456
    #最大活跃数
    maxActive: 20
    #初始化数量
    initialSize: 1
    #最大连接等待超时时间
    maxWait: 60000
    #打开PSCache,并且指定每个连接PSCache的大小
    poolPreparedStatements: true
    maxPoolPreparedStatementPerConnectionSize: 20
    #通过connectionProperties属性来打开mergeSql功能;慢SQL记录
    connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
    minIdle: 1
    timeBetweenEvictionRunsMillis: 60000
    minEvictableIdleTimeMillis: 300000
    validationQuery: select 1 from dual
    testWhileIdle: true
    testOnBorrow: false
    testOnReturn: false
    #配置监控统计拦截的filters,去掉后监控界面sql将无法统计,'wall'用于防火墙
    #filters: stat, wall, log4j

  #redis 单机配置
  redis:
    #Redis数据库索引(默认为0)
    database: 0
    #Redis服务器地址
    host: 127.0.0.1
    #Redis服务器连接端口
    port: 6379
    #Redis服务器连接密码
    password: 123456
    #客户端超时时间单位是毫秒 默认是2000
    timeout: 1000
    pool:
      #连接池的最大数据库连接数。设为0表示无限制,如果是jedis 2.4以后用redis.maxTotal
      max-active: 200
      #最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制。
      max-wait: -1
      #连接池中的最大空闲连接
      max-idle: 8
      #连接池中的最小空闲连接
      min-idle: 0
#集群配置
#spring.redis.cluster.nodes=127.0.0.1:6379,127.0.0.1:6380,127.0.0.1:6381,127.0.0.1:6382


mybatis-plus:
  mapper-locations: classpath:/mapper/*Mapper.xml
  #实体扫描,多个package用逗号或者分号分隔
  typeAliasesPackage: com.example.redislearn.entity
  global-config:
    #主键类型  0:"数据库ID自增", 1:"用户输入ID",2:"全局唯一ID (数字类型唯一ID)", 3:"全局唯一ID UUID";
    id-type: 0
    #字段策略 0:"忽略判断",1:"非 NULL 判断"),2:"非空判断"
    field-strategy: 2
    #驼峰下划线转换
    db-column-underline: true
    #刷新mapper 调试神器
    refresh-mapper: true
    #数据库大写下划线转换
    capital-mode: true
    #序列接口实现类配置
    #key-generator: com.baomidou.springboot.xxx
    #逻辑删除配置
    logic-delete-value: 0
    logic-not-delete-value: 1
    #自定义填充策略接口实现
    #meta-object-handler: com.baomidou.springboot.MyMetaObjectHandler
    #自定义SQL注入器
    #sql-injector: com.baomidou.springboot.xxx
  configuration:
    map-underscore-to-camel-case: true
    cache-enabled: false
    #不加这个查询数据为空时,字段将被隐藏
    call-setters-on-nulls: true

2.3 新建数据库连接的配置类DruidDBConfig 和 mybatis-plus的配置类MybatisPlusConfig ,工具类BlankUtil,代码分别如下:

DruidDBConfig :

package com.example.redislearn.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;

/**
 * 为什么要增加呢?

 因为SpringBoot本身提供的配置只是部分的数据库连接配置,很多Druid需要的属性配置是没有的,如:
 spring.datasource.initialSize

 这个属性,SpringBoot是没有的,只有Druid才有,所以需要增加相应的配置类,自动注入。

 */
@Configuration
public class DruidDBConfig {
    private Logger logger = LoggerFactory.getLogger(DruidDBConfig.class);

    @Value("${spring.datasource.url}")
    private String dbUrl;

    @Value("${spring.datasource.username}")
    private String username;

    @Value("${spring.datasource.password}")
    private String password;

    @Value("${spring.datasource.driver-class-name}")
    private String driverClassName;

    @Value("${spring.datasource.initialSize}")
    private int initialSize;

    @Value("${spring.datasource.minIdle}")
    private int minIdle;

    @Value("${spring.datasource.maxActive}")
    private int maxActive;

    @Value("${spring.datasource.maxWait}")
    private int maxWait;

    @Value("${spring.datasource.timeBetweenEvictionRunsMillis}")
    private int timeBetweenEvictionRunsMillis;

    @Value("${spring.datasource.minEvictableIdleTimeMillis}")
    private int minEvictableIdleTimeMillis;

    @Value("${spring.datasource.validationQuery}")
    private String validationQuery;

    @Value("${spring.datasource.testWhileIdle}")
    private boolean testWhileIdle;

    @Value("${spring.datasource.testOnBorrow}")
    private boolean testOnBorrow;

    @Value("${spring.datasource.testOnReturn}")
    private boolean testOnReturn;

    @Value("${spring.datasource.poolPreparedStatements}")
    private boolean poolPreparedStatements;

    @Value("${spring.datasource.maxPoolPreparedStatementPerConnectionSize}")
    private int maxPoolPreparedStatementPerConnectionSize;

   /* @Value("${spring.datasource.filters}")
    private String filters;*/

    @Value("{spring.datasource.connectionProperties}")
    private String connectionProperties;

    @Bean    //声明其为Bean实例
    @Primary  //在同样的DataSource中,首先使用被标注的DataSource
    public DataSource dataSource(){
        System.out.println("=========================开始=========================");
        DruidDataSource datasource = new DruidDataSource();
        datasource.setUrl(this.dbUrl);
        datasource.setUsername(username);
        datasource.setPassword(password);
        datasource.setDriverClassName(driverClassName);
        //configuration
        datasource.setInitialSize(initialSize);
        datasource.setMinIdle(minIdle);
        datasource.setMaxActive(maxActive);
        datasource.setMaxWait(maxWait);
        datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
        datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
        datasource.setValidationQuery(validationQuery);
        datasource.setTestWhileIdle(testWhileIdle);
        datasource.setTestOnBorrow(testOnBorrow);
        datasource.setTestOnReturn(testOnReturn);
        datasource.setPoolPreparedStatements(poolPreparedStatements);
        datasource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);
      /*  try {
            datasource.setFilters(filters);
        } catch (SQLException e) {
            logger.error("druid configuration initialization filter", e);
        }*/
        datasource.setConnectionProperties(connectionProperties);
        System.out.println("=========================结束=========================");
        return datasource;
    }

    /**
     * 事务:配置DataSourceTransactionManager
     * @param dataSource
     * @return
     */
    @Bean
    public DataSourceTransactionManager dataSourceTransactionManager(DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);

    }
}

MybatisPlusConfig:

package com.example.redislearn.config;

import com.baomidou.mybatisplus.entity.GlobalConfiguration;
import com.baomidou.mybatisplus.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.plugins.PerformanceInterceptor;
import com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean;
import com.example.redislearn.util.BlankUtil;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.annotation.MapperScan;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.sql.DataSource;

//@EnableTransactionManagement //开启事务支持后

@EnableTransactionManagement(proxyTargetClass = true)//解决 because it is a JDK dynamic proxy that implement
@Configuration
//扫描dao或者是Mapper接口
@MapperScan("com.example.redislearn.dao")
public class MybatisPlusConfig {

    private Logger log = LoggerFactory.getLogger(MybatisPlusConfig.class);

    //主键类型  0:"数据库ID自增", 1:"用户输入ID",2:"全局唯一ID (数字类型唯一ID)", 3:"全局唯一ID UUID";
    @Value("${mybatis-plus.global-config.id-type}")
    private Integer idType;

    //字段策略 0:"忽略判断",1:"非 NULL 判断"),2:"非空判断"
    @Value("${mybatis-plus.global-config.field-strategy}")
    private Integer fieldStrategy;

    //驼峰下划线转换
    @Value("${mybatis-plus.global-config.db-column-underline}")
    private Boolean dbColumnUnderline;

    //刷新mapper 调试神器
    @Value("${mybatis-plus.global-config.refresh-mapper}")
    private Boolean isRefresh;

    //数据库大写下划线转换
    @Value("${mybatis-plus.global-config.capital-mode}")
    private Boolean isCapitalMode;

    //逻辑删除配置
    @Value("${mybatis-plus.global-config.logic-delete-value}")
    private String logicDeleteValue;

    //逻辑删除配置
    @Value("${mybatis-plus.global-config.logic-not-delete-value}")
    private String logicNotDeleteValue;

    /**
     * mybatisPlus全局配置
     * @return
     */
    @Bean(name = "globalConfig")
    public GlobalConfiguration globalConfig(
    ) {
        log.info("初始化GlobalConfiguration");
        GlobalConfiguration globalConfig = new GlobalConfiguration();
        if ( !BlankUtil.isBlank(idType)) {
            globalConfig.setIdType(idType);  //主键类型
        }
        if ( !BlankUtil.isBlank(fieldStrategy)) {
            //        globalConfig.setFieldStrategy(fieldStrategy); //字段策略
        }
        if ( !BlankUtil.isBlank(dbColumnUnderline)) {
            globalConfig.setDbColumnUnderline(dbColumnUnderline);  //驼峰下划线转换
        }
        if ( !BlankUtil.isBlank(isRefresh)) {
             globalConfig.setRefresh(isRefresh); //刷新mapper 调试神器
        }
        if ( !BlankUtil.isBlank(isCapitalMode)) {
            globalConfig.setCapitalMode(isCapitalMode); //数据库大写下划线转换
        }
        if ( !BlankUtil.isBlank(logicDeleteValue)) {
            //        globalConfig.setLogicDeleteValue(logicDeleteValue);  //逻辑删除配置
        }
        if ( !BlankUtil.isBlank(logicNotDeleteValue)) {
            //        globalConfig.setLogicNotDeleteValue(logicNotDeleteValue);  //逻辑删除配置
        }
        return globalConfig;
    }

    /**
     * @Description : mybatis-plus分页插件
     * 文档:http://mp.baomidou.com
     */
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
        //paginationInterceptor.setLocalPage(true);// 开启 PageHelper 的支持
        paginationInterceptor.setDialectType("mysql");
        return new PaginationInterceptor();
    }


    /**
     * mybatis-plus SQL执行效率插件【生产环境可以关闭】
     */
    @Bean
    @Profile({"dev","test"})// 设置 dev test 环境开启
    public PerformanceInterceptor performanceInterceptor() {
        PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
        //SQL 执行性能分析,开发环境使用,线上不推荐。 maxTime 指的是 sql 最大执行时长
        //performanceInterceptor.setMaxTime(1000);
        //SQL是否格式化 默认false
        performanceInterceptor.setFormat(true);
        return performanceInterceptor;
    }

    @Bean("sqlSessionFactory")
    public SqlSessionFactory sqlSessionFactory(@Qualifier(value = "globalConfig")GlobalConfiguration globalConfig, @Qualifier(value = "dataSource") DataSource dataSource) throws Exception {
        log.info("初始化SqlSessionFactory");
        String mapperLocations = "classpath*:/mapper/*.xml";
        String typeAliasesPackage = "com.example.redislearn.entity";
        MybatisSqlSessionFactoryBean sqlSessionFactory = new MybatisSqlSessionFactoryBean();
        sqlSessionFactory.setDataSource(dataSource); //数据源
        sqlSessionFactory.setGlobalConfig(globalConfig); //全局配置
        Interceptor[] interceptor = {new PaginationInterceptor()};
        sqlSessionFactory.setPlugins(interceptor); //分页插件
        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        try {
            //自动扫描Mapping.xml文件
            sqlSessionFactory.setMapperLocations(resolver.getResources(mapperLocations));
            sqlSessionFactory.setTypeAliasesPackage(typeAliasesPackage);
            return sqlSessionFactory.getObject();
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }
    }


}

工具类BlankUtil:

package com.example.redislearn.util;

import java.io.Serializable;
import java.util.Collection;
import java.util.Map;
import java.util.Set;

/**
 * 逻辑、功能相关描述:验证对象空值,字符串零长,集合无元素
 */
public class BlankUtil {
    /**
     * Function:判断字符串是否为空或零长
     * @param str 待检查的字符串变量
     * @return true  字符串为空或零长
     *         false 字符串不为空且不是零长字符串
     */
    public static boolean isBlank(final String str) {
        return (str == null) || (str.trim().length() <= 0);
    }

    /**
     * Function:判断字符是否为空或空格
     * @param cha 待检查的字符变量
     * @return true  字符为空或空格
     *         false 字符不为空且不是空格
     */
    public static boolean isBlank(final Character cha) {
        return (cha == null) || cha.equals(' ');
    }

    /**
     * Function:判断对象是否为空
     * @param obj 待检查的对象变量
     * @return true  对象为空
     *         false 对象不为空
     */
    public static boolean isBlank(final Object obj) {
        return (obj == null);
    }

    /**
     * Function:判断对象数组是否为空或无元素
     * @param objs 待检查的对象数组变量
     * @return true  对象数组为空或无元素
     *         false 对象数组不为空且有元素
     */
    public static boolean isBlank(final Object[] objs) {
        return (objs == null) || (objs.length <= 0);
    }

    /**
     * Function:判断集合对象是否为空或无元素
     * @param obj 待检查的集合对象变量
     * @return true  集合对象为空或无元素
     *         false 集合对象不为空且有元素
     */
    public static boolean isBlank(final Collection<?> obj) {
        return (obj == null) || (obj.size() <= 0);
    }

    /**
     * Function:判断Set对象是否为空或无元素
     * @param obj 待检查的Set对象变量
     * @return true  Set对象为空或无元素
     *         false Set对象不为空且有元素
     */
    public static boolean isBlank(final Set<?> obj) {
        return (obj == null) || (obj.size() <= 0);
    }

    /**
     * Function:判断Serializable对象是否为空
     * @param obj 待检查的Serializable对象变量
     * @return true  Serializable对象为空
     *         false Serializable对象不为空
     */
    public static boolean isBlank(final Serializable obj) {
        return obj == null;
    }

    /**
     * Function:判断Map对象是否为空或无元素
     * @param obj 待检查的Map对象变量
     * @return true  Map对象为空或无元素
     *         false Map对象不为空且有元素
     */
    public static boolean isBlank(final Map<?, ?> obj) {
        return (obj == null) || (obj.size() <= 0);
    }
}

2.4 创建一个商品goods的数据库表:

CREATE TABLE `goods` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键id',
  `code` varchar(255) DEFAULT NULL COMMENT '商品编码',
  `name` varchar(255) DEFAULT NULL COMMENT '商品名称',
  `create_time` timestamp NULL DEFAULT NULL COMMENT '创建时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

2.5 在控制类 RedisStringController 添加对象的存储和对象的获取的功能,代码如下:

package com.example.redislearn.controller;

import com.example.redislearn.entity.Goods;
import com.example.redislearn.response.BaseResponse;
import com.example.redislearn.response.StatusCode;
import com.example.redislearn.service.RedisStringService;
import com.example.redislearn.util.RedisUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

/**
 * 数据结构为字符串String
 * 分别存储字符串和存储对象
 */
@RestController
@RequestMapping("RedisStringController")
public class RedisStringController {

    private static final Logger log= LoggerFactory.getLogger(RedisStringController.class);

    private static final String RedisStringdKey = "Redis:String";

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private RedisStringService redisStringService;

    /**
     * 字符串的存储
     * @param helloName
     * @return
     */
    @RequestMapping(value = "/stringSet", method = RequestMethod.POST)
    public BaseResponse stringSet(@RequestParam String helloName) {
        BaseResponse response = new BaseResponse(StatusCode.Success);
        try {
            //stringRedisTemplate.opsForValue().set(RedisHelloWorldKey,helloName);
            redisUtil.set(RedisStringdKey, helloName);
            response.setData("String set success!");
        } catch (Exception e) {
            log.info("--String set异常信息: ", e.fillInStackTrace());
            response = new BaseResponse(StatusCode.Fail.getCode(), e.getMessage());
        }
        return response;
    }


    /**
     * 字符串的获取
     * @return
     */
    @RequestMapping(value = "stringGet", method = RequestMethod.GET)
    public BaseResponse stringGet() {
        BaseResponse response = new BaseResponse(StatusCode.Success);
        try {
            //String result = stringRedisTemplate.opsForValue().get(RedisHelloWorldKey);
            String result = redisUtil.get(RedisStringdKey).toString();
            response.setData(result);
        } catch (Exception e) {
            log.info("--String gett异常信息: ", e.fillInStackTrace());
            response = new BaseResponse(StatusCode.Fail.getCode(), e.getMessage());
        }
        return response;
    }


    /**
     * 对象的存储
     * @param goods
     * @param result
     * @return
     */
    @RequestMapping(value = "/objectSet",method = RequestMethod.POST,consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public BaseResponse objectSet(@RequestBody @Validated Goods goods, BindingResult result){
        if (result.hasErrors()){
            return new BaseResponse(StatusCode.InvalidParams);
        }
        BaseResponse response=new BaseResponse(StatusCode.Success);
        try {
            log.info("--商品信息:{}",goods);
            redisStringService.addGoods(goods);
        }catch (Exception e){
            log.error("--对象的存储-发生异常:",e.fillInStackTrace());
            response=new BaseResponse(StatusCode.Fail.getCode(),e.getMessage());
        }
        return response;
    }


    /**
     * 对象的获取
     * @param id
     * @return
     */
    @RequestMapping(value = "/objectGet",method = RequestMethod.GET)
    public BaseResponse objectGet(@RequestParam Integer id){
        BaseResponse response=new BaseResponse(StatusCode.Success);
        try {
            response.setData(redisStringService.getGoods(id));
        }catch (Exception e){
            log.error("--对象的获取-发生异常:",e.fillInStackTrace());
            response=new BaseResponse(StatusCode.Fail.getCode(),e.getMessage());
        }
        return response;
    }

}

2.6 新建实体类 Goods ,业务逻辑类RedisStringService,数据库相关类GoodsMapper,和GoodsMapper.xml。代码分别如下:

Goods :

package com.example.redislearn.entity;

import org.hibernate.validator.constraints.NotBlank;
import java.io.Serializable;
import java.util.Date;

/**
 * 商品实体类
 */
public class Goods implements Serializable {
    private static final long serialVersionUID = 1L;
    private Integer id;

    @NotBlank(message = "商品编码不能为空!")
    private String code;

    @NotBlank(message = "商品名称不能为空!")
    private String name;

    private Date createTime;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }
}

RedisStringService:

package com.example.redislearn.service;

import com.example.redislearn.entity.Goods;
import com.example.redislearn.dao.GoodsMapper;
import com.example.redislearn.util.RedisUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.util.Date;

@Service
public class RedisStringService {

    private static final Logger log = LoggerFactory.getLogger(RedisStringService.class);

    private static final String RedisObjectKey = "Redis:Object";

    @Autowired
    private ObjectMapper objectMapper;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private GoodsMapper goodsMapper;

    /**
     * 添加商品
     *
     * @param goods
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public Integer addGoods(Goods goods) throws JsonProcessingException {
        goods.setCreateTime(new Date());
        goods.setId(null);
        goodsMapper.insertSelective(goods);
        Integer id = goods.getId();

        //保证缓存-数据库双写的一致性
        if (id > 0) {
            //"商品信息"是一个实体对象,为了能将该实体对象信息塞入Redis的String类型中,
            // 我们需要将其“序列化”,采用的Jackson的序列化机制,将该实体对象序列化为“Json格式的字符串”!
            redisUtil.set(RedisObjectKey + id.toString(), objectMapper.writeValueAsString(goods));
        }
        return id;
    }


    /**
     * 获取商品信息
     *
     * @param id
     * @return
     */
    public Goods getGoods(Integer id) throws IOException {
        Goods goods = null;
        String key = RedisObjectKey + id;
        if (id != null) {
            if (redisUtil.hasKey(key)) {
                String result = redisUtil.get(key).toString();
                log.info("---String数据类型,从缓存中取出来的value:{}", result);
                if (StringUtils.isNotBlank(result)) {
                    //根据Key直接进行获取,但由于其结果是String类型的Json格式字符串常量值,故而我们需要将其“反序列化”,
                    // 即同样也是采用Jackson的反序列化机制,将其映射到一个Item实体对象中即可
                    goods = objectMapper.readValue(result, Goods.class);
                }
            } else {
                log.info("---String数据类型,从数据库查询:id={}", id);
                goods = goodsMapper.selectByPrimaryKey(id);
                if (goods != null) {
                    redisUtil.set(key, objectMapper.writeValueAsString(goods));
                }
            }
        }
        return goods;
    }
}

注:

  1. "商品信息"是一个实体对象,为了能将该实体对象信息塞入Redis的String类型中,我们需要将其“序列化”,采用的Jackson的序列化机制,将该实体对象序列化为“Json格式的字符串”!
  2. 在获取商品详情时根据Key直接进行获取,但由于其结果是String类型的Json格式字符串常量值,故而我们需要将其“反序列化”,即同样也是采用Jackson的反序列化机制,将其映射到一个Item实体对象中即可。

GoodsMapper:

package com.example.redislearn.dao;


import com.example.redislearn.entity.Goods;

public interface GoodsMapper {
    int deleteByPrimaryKey(Integer id);

    int insert(Goods goods);

    int insertSelective(Goods goods);

    Goods selectByPrimaryKey(Integer id);

    int updateByPrimaryKeySelective(Goods goods);

    int updateByPrimaryKey(Goods goods);
}

GoodsMapper.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.example.redislearn.dao.GoodsMapper">

    <resultMap id="BaseResultMap" type="com.example.redislearn.entity.Goods">
        <id column="id" property="id" jdbcType="INTEGER"/>
        <result column="code" property="code" jdbcType="VARCHAR"/>
        <result column="name" property="name" jdbcType="VARCHAR"/>
        <result column="create_time" property="createTime" jdbcType="TIMESTAMP"/>
    </resultMap>

    <sql id="Base_Column_List">
    id, code, name, create_time
    </sql>

    <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer">
        select
        <include refid="Base_Column_List"/>
        from goods
        where id = #{id,jdbcType=INTEGER}
    </select>

    <delete id="deleteByPrimaryKey" parameterType="java.lang.Integer">
    delete from goods
    where id = #{id,jdbcType=INTEGER}
    </delete>

    <insert id="insert" parameterType="com.example.redislearn.entity.Goods">
    insert into
    goods (id, code, name,create_time)
    values
    (#{id,jdbcType=INTEGER}, #{code,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR},
      #{createTime,jdbcType=TIMESTAMP})
    </insert>

    <insert id="insertSelective" keyProperty="id" useGeneratedKeys="true"
            parameterType="com.example.redislearn.entity.Goods">
        insert into goods
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="id != null">
                id,
            </if>
            <if test="code != null">
                code,
            </if>
            <if test="name != null">
                name,
            </if>
            <if test="createTime != null">
                create_time,
            </if>
        </trim>
        <trim prefix="values (" suffix=")" suffixOverrides=",">
            <if test="id != null">
                #{id,jdbcType=INTEGER},
            </if>
            <if test="code != null">
                #{code,jdbcType=VARCHAR},
            </if>
            <if test="name != null">
                #{name,jdbcType=VARCHAR},
            </if>
            <if test="createTime != null">
                #{createTime,jdbcType=TIMESTAMP},
            </if>
        </trim>
    </insert>

    <update id="updateByPrimaryKeySelective" parameterType="com.example.redislearn.entity.Goods">
        update goods
        <set>
            <if test="code != null">
                code = #{code,jdbcType=VARCHAR},
            </if>
            <if test="name != null">
                name = #{name,jdbcType=VARCHAR},
            </if>
            <if test="createTime != null">
                create_time = #{createTime,jdbcType=TIMESTAMP},
            </if>
        </set>
        where id = #{id,jdbcType=INTEGER}
    </update>

    <update id="updateByPrimaryKey" parameterType="com.example.redislearn.entity.Goods">
    update goods
    set
      code = #{code,jdbcType=VARCHAR},
      name = #{name,jdbcType=VARCHAR},
      create_time = #{createTime,jdbcType=TIMESTAMP}
    where
    id = #{id,jdbcType=INTEGER}
  </update>

</mapper>

三.测试

运行项目,测试对象的存储。

在浏览器或postman输出地址和参数:
http://127.0.0.1:8782/RedisStringController/objectSet,结果如下:
在这里插入图片描述
在这里插入图片描述
因为我一开始没在goods 表中设置数据,所以运行完之后会在goods表插入一条数据,redis中也会插入一条数据。
在这里插入图片描述

接着测试,获取对象。
在浏览器或postman输出地址和参数:
http://127.0.0.1:8782/RedisStringController/objectGet?id=1,结果如下:
在这里插入图片描述

发布了56 篇原创文章 · 获赞 85 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_40991408/article/details/104346364