SpringBoot2教程(四)整合缓存Redis

源码地址:https://github.com/q200737056/Spring-Course/tree/master/springboot2Redis

一、项目环境

Java8+Maven3.3.9+SpringBoot2.0.4+Mybatis3+Redis+H2+Eclipse


二、Redis简介

Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库。

Redis具有以下优势

  • 性能极高 – Redis能读的速度是110000次/s,写的速度是81000次/s 。
  • 丰富的数据类型 – Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。
  • 原子性 – Redis的所有操作都是原子性的,要么成功执行要么失败不执行。单个操作是原子性的。多个操作也支持事务,即原子性,通过MULTI和EXEC指令包起来。
  • 丰富的特性 – Redis还支持 publish/subscribe, 通知, key 过期,master-slave模式的数据备份等特性。
    下载windows版Redis地址:
    https://github.com/MicrosoftArchive/redis/releases
    开启Redis服务

三、H2数据库简介

H2数据库一般适合作为嵌入式数据库使用,而其它的数据库大部分都需要安装独立的客户端和服务器端,如mysql等。

H2的优势

  • H2采用纯Java编写,因此不受平台的限制。
  • H2只有一个jar文件,十分适合作为嵌入式数据库使用。
  • H2提供了一个十分方便的web控制台用于操作和管理数据库内容。

H2数据库下载地址:http://www.h2database.com/html/download.html
运行H2 bin目录下的 h2.bat 或h2w.bat 启动H2数据库。输入http://localhost:8082访问H2数据库的Web Console。如图:


本教程实例中已内嵌H2数据库,不需要单独启用。

四、SpringBoot整合Redis

jar包依赖

<!--省略sringboot等其它依赖-->
<!-- h2嵌入式数据库 -->
         <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
         </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <!-- 使用redis连接池 必须有pool依赖-->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
     </dependency>

application.yml

spring:
  redis:
    host: 127.0.0.1
    port: 6379
    timeout: 60s
    lettuce:
      pool:
        max-active: 20
        max-wait: 10000ms
        max-idle: 10
        min-idle: 2

springboot2.x默认使用lettuce,如果想要使用jedis,可引入其jar包,修改配置为jedis。Redis默认密码为空,所以不用配置。如果想设置密码,打开Redis根目录下的xx.conf的文件,比如使用了redis.conf配置文件。找到requirepass添加自己想要设置的密码。之后重启Redis服务使之生效。

JavaConfig配置Redis

@Bean
    public RedisTemplate<Object, Object> redisTemplate
(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);
 
        //使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值
        Jackson2JsonRedisSerializer serializer = new 
     Jackson2JsonRedisSerializer(Object.class);
 
        ObjectMapper mapper = new ObjectMapper();
        mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        serializer.setObjectMapper(mapper);
 
        template.setValueSerializer(serializer);
        //使用StringRedisSerializer来序列化和反序列化redis的key值
        template.setKeySerializer(new StringRedisSerializer());
        template.afterPropertiesSet();
        return template;
    }
    @Bean
    public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
 
      // 生成一个默认配置,通过config对象即可对缓存进行自定义配置
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
        //  设置缓存的默认过期时间3分,使用Duration设置
        config = config.entryTtl(Duration.ofMinutes(3))  
        // 不缓存空值  
                .disableCachingNullValues();     
 
        // 设置一个初始化的缓存空间set集合
        Set<String> cacheNames =  new HashSet<>();
        cacheNames.add("default");
        cacheNames.add("user");
 
        // 对每个缓存空间应用不同的配置
        Map<String, RedisCacheConfiguration> configMap = new HashMap<>();
        configMap.put("default", config);
        configMap.put("user", config.entryTtl(Duration.ofSeconds(120)));
       // 使用自定义的缓存配置初始化一个cacheManager
        RedisCacheManager cacheManager = 
RedisCacheManager.builder(redisConnectionFactory)
        // 注意这两句的调用顺序,一定要先调用该方法设置初始化的缓存名,再初始化相关的配置
                .initialCacheNames(cacheNames)  
                .withInitialCacheConfigurations(configMap)
                .build();
        return cacheManager;
    }

启动H2数据库内存模式并初始化表数据

spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: org.h2.Driver
    #使用TCP/IP的服务器模式
    url: jdbc:h2:tcp://localhost/mem:demo
    username: test
    password: test
@Component
@Order(1)
public class H2dbStart implements ApplicationRunner  {
    @Override
    public void run(ApplicationArguments args) throws Exception {
    try {  
            System.out.println("正在启动h2数据库...");
            Server.createTcpServer().start(); 
            System.out.println("h2数据库启动成功...");
        } catch (SQLException e) {  
            System.out.println("启动h2数据库出错:" + e.toString());  
            e.printStackTrace();  
           throw new RuntimeException(e);  
        }  
    }
}
@Component
public class H2DataInit implements ApplicationRunner {
    @Autowired
    DruidDataSource druidDataSource;
    //初始化h2 数据库表和数据
    @Override
    public void run(ApplicationArguments args) throws Exception {
    
         String sql1 = "CREATE TABLE TEST_USER(id INT NOT NULL AUTO_INCREMENT, "
                + "name VARCHAR(30),password VARCHAR(30), email VARCHAR(100),"
                + "PRIMARY KEY (id))";
         String sql2="INSERT INTO test_user (id, name, password, email) "
                + "VALUES (1, 'admin', 'admin', '1111@qq.com')";
         String sql3="INSERT INTO test_user (id, name, password, email) "
                + "VALUES (2, 'hehe', 'hehe', '119@qq.com')";
         Connection connection = null;
         Statement stmt = null;
         
         try {
            connection = druidDataSource.getConnection();
            stmt = connection.createStatement();
            stmt.addBatch(sql1);
            stmt.addBatch(sql2);
            stmt.addBatch(sql3);
            stmt.executeBatch();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            try {
                 stmt.close();
                 connection.close();
             } catch (Exception e2) {
                 e2.printStackTrace();
             }
            System.out.println("初始化表数据完成。。。");
        }
    }
}

内存模式的数据库,只在服务运行时存在,一旦停止服务,数据库也随之而去。配置servletnew ServletRegistrationBean<>(new WebServlet(),"/h2/*"),启动服务后,可通过http://localhost:8080/h2/访问h2数据库。

启动类@EnableCaching开启缓存

@SpringBootApplication
@MapperScan("com.springboot2.test4.dao")
@EnableCaching
public class App {
    public static void main( String[] args ){
        SpringApplication.run(App.class, args);
        System.out.println("启动成功。。。。。。。。。。。");
    }
}

业务层@Cacheable,@CachePut,@CacheEvict

@Cacheable(value="user",key="'user'+#id",unless = "#result eq null")
@Override
    public User queryUserById(String id){
        System.out.println("去查询数据库。。。");
        return this.indexDao.queryUserById(Integer.valueOf(id));
    }
@CachePut(value="user",key="'user'+#user.id")
    @Override
    public User updateUser(User user){
         this.indexDao.updateUser(user);
         return user;
    }
@CacheEvict(value="user",key="'user'+#id")
    @Override
    public int deleteUser(String id){
        return this.indexDao.deleteUser(id);
    }

缓存注解的说明可参考本人的上一篇文章SpringBoot2教程(三)整合缓存Ehcache

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,284评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,115评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,614评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,671评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,699评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,562评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,309评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,223评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,668评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,859评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,981评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,705评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,310评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,904评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,023评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,146评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,933评论 2 355

推荐阅读更多精彩内容