《Spring in action 4》(十一)SSM + Redis

SSM + Redis

这里我们先介绍一下如何整合Redis,后面再整合一个SSM+redis的项目,无spring配置文件。

SpringDataRedis

SpringDataRedis提供了两个模板:

  • RedisTemplate
  • StringRedisTemplate

RedisTemplate 的很多功能是以子API的形式提供的,他们区分了单个值和集合值的场景;

方法 子API接口 描述
opsForValue() ValueOperations<K,V> 操作具有简单值得条目
opsForList() ListOperations<K,V> 操作具有list的值的条目
opsForSet() SetOperations<K,V> 操作具有set的值的条目
opsForZSet() ZSetOperations<K,V> 操作具有ZSet值(排序的set)的条目
opsForHash() HashOperations<K,V> 操作具有hash的条目
boundValueOps(K) BoundValueOperations<K,V> 以绑定指定key的方式,操作具有简单值的条目
boundListOps(K) BoundListOperations<K,V> 以绑定指定key的方式,操作具有List值的条目
boundSetOps(K) BoundSetOperations<K,V> 以绑定指定key的方式,操作具有Set值的条目
boundZSetOps(K) BoundZSetOperations<K,V> 以绑定指定key的方式,操作具有ZSet值(排序的Set)的条目
boundHashOps(K) BoundHashOperations<K,V> 以绑定指定key的方式,操作具有Hash值的条目

使用key和value的序列化器

当某个条目保存到Redis key-value存储的时候,key和value都会使用Redis的序列化器(Serializer)进行序列化。SpringDataRedis提供了多个这样的序列化器,包括:

  • GenericToStringSerializer:使用Spring转换服务进行序列化;
  • JacksonJsonRedisSerializer:使用Jackson1,将对象序列化为JSON;
  • Jackson2JsonRedisSerializer:使用Jackson2,将对象序列化为JSON;
  • JdkSerializationRedisSerializer:使用Java序列化;
  • OxmSerializer:使用Spring O/X映射的编排器和解排器(marshaler和unmarshaler)实现序列化,用于XML序列化。
  • StringRedisSerializer:序列化String类型的key和value。

这些序列化器都实现了RedisSerializer接口,如果其中没有符合需求的序列化器,那么可以自行创建。

下面看一个列子:

例如:假设当使用RedisTemplate的时候,我们希望将Product类型的value序列化为json,而key是String类型。RedisTemplate的setKeySerializer()和setValueSerializer()方法就需要如下所示了:

@Bean
public RedisTemplate<String,Product> redisTemplate(RedisConnectionFactory cf){
  RedisTemplate<String,Product> redis = new RedisTemplate<String,Product>();
  redis.setConnectionFactory(cf);
  redis.setKeySerializer(new StringRedisSerializer());
  redis.setValueSerializer(new Jackson2JsonRedisSerializer<Product>(Product.class))
  return redis;
}

在这里,我们设置RedisTemplate在序列化key的时候,使用StringRedisSerializer,并且设置了在序列化Product的时候,使用的是Jackson2JsonRedisSerializer。

项目整合

项目结构

InitWebApplication

public class InitWebApplication extends AbstractAnnotationConfigDispatcherServletInitializer {

    /*加载applicationContext.xml/rootConfig*/
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[]{
                RootConfig.class
        };
    }

    /*加载springmvc.xml/ servletConfig.java*/
    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[]{
                ServletConfig.class
        };
    }

    /*DispatcherServlet 的servletMapping*/
    @Override
    protected String[] getServletMappings() {
        return new String[]{
                "/"
        };
    }

    /*添加编码过滤器*/
    @Override
    protected Filter[] getServletFilters() {
        CharacterEncodingFilter filter = new CharacterEncodingFilter();
        filter.setForceEncoding(true);
        filter.setEncoding("utf-8");
        return new Filter[]{
                filter
        };
    }
}

这个文件的作用主要是替代了原有传统web项目中web.xml文件的角色

RootConfig

RootConfig 则替代了原有的applicationContext.xml文件

package com.ooyhao.spring.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

/**
 * 描述:
 * 类【RootConfig】
 *
 * @author ouYangHao
 * @create 2019-09-12 15:01
 */
@Configuration
@ComponentScan(basePackages = "com.ooyhao.spring") //组件扫描
public class RootConfig {}

ServletCofig.xml

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.ooyhao.spring.controller")
public class ServletConfig implements WebMvcConfigurer {

    /*开启静态文件映射处理*/
    @Override
    public void configureDefaultServletHandling(
      DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }
}

DataSourceConfig

@Configuration
@MapperScan(basePackages = "com.ooyhao.spring.mapper") //扫描Mybatis的Mapper接口
@EnableTransactionManagement //开启事务管理
@PropertySource(value = "classpath:application.properties")
public class DataSourceConfig {

    @Value("${dataSource.maxActive}")
    private Integer dataSourceMaxActive;

    @Value("${dataSource.maxWait}")
    private Integer dataSourceMaxWait;

    @Value("${dataSource.minIdle}")
    private Integer dataSourceMinIdle;

    @Value("${dataSource.initialSize}")
    private Integer dataSourceInitialSize;

    @Value("${dataSource.url}")
    private String dataSourceUrl;

    @Value("${dataSource.username}")
    private String dataSourceUsername;

    @Value("${dataSource.password}")
    private String dataSourcePassword;

    @Value("${dataSource.driverClassName}")
    private String dataSourceDriverClassName;


    @Value("${mybatis.typeAliasesPackage}")
    private String mybatisTypeAliasesPackage;

    @Value("${mybatis.configLocation}")
    private String mybatisConfigLocation;

    @Value("${mybatis.mapperLocations}")
    private String mybatisMapperLocations;


    @Value("${redis.maxTotal}")
    private Integer redisMaxTotal;

    @Value("${redis.maxWaitMillis}")
    private Integer redisMaxWaitMillis;

    @Value("${redis.minIdle}")
    private Integer redisMinIdle;

    @Value("${redis.maxIdle}")
    private Integer redisMaxIdle;

    @Value("${redis.hostName}")
    private String redisUsername;

    @Value("${redis.password}")
    private String redisPassword;

    @Value("${redis.port}")
    private Integer redisPort;

    /*配置Druid数据源*/
    @Bean
    public DataSource dataSource(){
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setMaxActive(dataSourceMaxActive);
        dataSource.setMaxWait(dataSourceMaxWait);
        dataSource.setMinIdle(dataSourceMinIdle);
        dataSource.setInitialSize(dataSourceInitialSize);
        dataSource.setUrl(dataSourceUrl);
        dataSource.setUsername(dataSourceUsername);
        dataSource.setPassword(dataSourcePassword);
        dataSource.setDriverClassName(dataSourceDriverClassName);
        return dataSource;
    }


    /*配置事务*/
    @Bean
    public DataSourceTransactionManager dataSourceTransactionManager(DataSource dataSource){
        DataSourceTransactionManager transactionManager =
                new DataSourceTransactionManager();
        transactionManager.setDataSource(dataSource);
        return transactionManager;
    }

    /*配置Mybatis的SQLSessionFactoryBean*/
    @Bean
    public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource) throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        bean.setTypeAliasesPackage(mybatisTypeAliasesPackage);
        bean.getObject().getConfiguration().setCacheEnabled(true);
        bean.getObject().getConfiguration().setMapUnderscoreToCamelCase(true);//测试无效
        bean.getObject().getConfiguration().setLogImpl(Slf4jImpl.class);
        bean.getObject().getConfiguration().setLogPrefix("###SPRING###MYBATIS###");
        /*读取Mybatis的配置文件*/
        bean.setConfigLocation(new ClassPathResource(mybatisConfigLocation));
        /*适用于通配符情况,读取Mybatis的Mapper文件*/
        PathMatchingResourcePatternResolver resourcePatternResolver =
                new PathMatchingResourcePatternResolver();
        Resource[] resources = resourcePatternResolver.getResources(mybatisMapperLocations);
        bean.setMapperLocations(resources);
        return bean;
    }

    /*配置SpringJDBCTemplate*/
    @Bean
    public JdbcTemplate jdbcTemplate(DataSource dataSource){
        return new JdbcTemplate(dataSource);
    }


    @Bean
    public JedisClientConfiguration poolConfig() {
        JedisPoolConfig config = new JedisPoolConfig();
        config.setMaxTotal(20);
        config.setMaxWaitMillis(3000);
        config.setMinIdle(5);
        config.setMaxIdle(8);
        JedisClientConfiguration.JedisPoolingClientConfigurationBuilder 
          builder= (JedisClientConfiguration.JedisPoolingClientConfigurationBuilder)
          JedisClientConfiguration.builder();
        builder.poolConfig(config);
        return builder.build();
    }

    @Bean
    public RedisStandaloneConfiguration standaloneConfiguration() {
        RedisStandaloneConfiguration configuration = new RedisStandaloneConfiguration();
        configuration.setHostName("120.79.167.88");
        configuration.setPassword("");
        configuration.setPort(6379);
        return configuration;
    }


    @Bean
    public JedisConnectionFactory connectionFactory() {
        return new JedisConnectionFactory(standaloneConfiguration(),poolConfig());
    }


    @Bean
    public RedisTemplate redisTemplate() {
        RedisTemplate redisTemplate = new RedisTemplate();
        redisTemplate.setConnectionFactory(connectionFactory());
        //可以设置序列化的类型
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
        return redisTemplate;
    }
}
  • 开启事务管理 @EnableTransactionManagement
  • 加载配置文件 @PropertySource(value = "classpath:application.properties")
  • 配置了Mybatis的数据源,使用的是alibaba的Druid数据源
  • 配置了事务管理 DataSourceTransactionManager
  • 整合mybatis SqlSessionFactoryBean
  • 将DataSource注入到了JdbcTemplate
  • 整合redis

这里需要配合配置文件application.properties.

# 配置数据源
dataSource.maxActive = 20
dataSource.maxWait = 5
dataSource.minIdle = 5
dataSource.initialSize = 5
dataSource.url = jdbc:mysql://120.79.167.xx:3306/spring_in_action?useUnicode=true&amp;characterEncoding=utf-8
dataSource.username = root
dataSource.password = root
dataSource.driverClassName = com.mysql.jdbc.Driver

# 配置mybatis
mybatis.typeAliasesPackage = com.ooyhao.spring.bean
mybatis.configLocation = mybatis/config/mybatis-config.xml
mybatis.mapperLocations = mybatis/mapper/*.xml

# 配置redis
redis.maxTotal = 20
redis.maxWaitMillis = 3000
redis.minIdle = 5
redis.maxIdle = 8
redis.hostName = 120.79.167.88
redis.password =
redis.port = 6379

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>

    <!--驼峰命名法,即:create_time 与 createTime自动映射-->
    <settings>
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>

    <!-- 类型别名 -->
    <!--已在配置类中配置-->
    <!--
    <typeAliases>
        <package name="com.ooyhao.spring.bean"/>
    </typeAliases>
    -->
</configuration>

mapUnderscoreToCamelCase 驼峰命名法在java配置中没有生效。

剩下的就是简单的Bean,dao,service,controller了。

源码:

https://gitee.com/ooyhao/JavaRepo_Public/tree/master/Spring-in-Action/spring-in-action-13/

最后

如果觉得不错的话,那就关注一下小编哦!一起交流,一起学习

程序yuan
原文地址:https://www.cnblogs.com/ooyhao/p/11561937.html