zoukankan      html  css  js  c++  java
  • [二十三]SpringBoot 之 redis

    本文章牵涉到的技术点比较多:spring Data JPA、Redis、Spring MVC,Spirng Cache,所以在看这篇文章的时候,需要对以上这些技术点有一定的了解或者也可以先看看这篇文章,针对文章中实际的技术点在进一步了解(注意,您需要自己下载Redis Server到您的本地,所以确保您本地的Redis可用,这里还使用了MySQL数据库,当然你也可以内存数据库进行测试)。这篇文章会提供对应的Eclipse代码示例,具体大体的分如下几个步骤:

    (1)新建Java MavenProject;

    (2)在pom.xml中添加相应的依赖包;

    (3)编写Spring Boot启动类;

    (4)配置application.properties;

    (5)编写RedisCacheConfig配置类;

    (6)编写DemoInfo测试实体类;

    (7)编写DemoInfoRepository持久化类;

    (8)编写DemoInfoService类;

    (9)编写DemoInfoController类;

    (10)测试代码是否正常运行了

    (11)自定义缓存key;

    (1)新建Java Maven Project;

    (2)在pom.xml中添加相应的依赖包;

    <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>me.shijunjie</groupId>
        <artifactId>testspringbootredis</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <packaging>jar</packaging>
    
        <name>testspringbootredis</name>
        <url>http://maven.apache.org</url>
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        </properties>
    
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>1.3.3.RELEASE</version>
        </parent>
    
        <dependencies>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <scope>test</scope>
            </dependency>
            <!-- springboot web支持:mvc,aop... -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context-support</artifactId>
            </dependency>
    
            <!-- 添加redis支持 -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-redis</artifactId>
            </dependency>
    
            <!-- JPA操作数据库. -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-jpa</artifactId>
            </dependency>
    
            <!-- mysql数据库驱动. -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
            </dependency>
    
            <!-- https://mvnrepository.com/artifact/commons-pool/commons-pool -->
            <!-- <dependency>
                <groupId>commons-pool</groupId>
                <artifactId>commons-pool</artifactId>
            </dependency> -->
    
            <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-pool2 -->
            <dependency>
                <groupId>org.apache.commons</groupId>
                <artifactId>commons-pool2</artifactId>
            </dependency>
    
            <!-- 单元测试. -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin </artifactId>
                </plugin>
    
                <!-- <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin 
                    </artifactId> <dependencies> springloaded hotdeploy <dependency> <groupId>org.springframework</groupId> 
                    <artifactId>springloaded</artifactId> <version>1.2.4.RELEASE</version> </dependency> 
                    </dependencies> <executions> <execution> <goals> <goal>repackage</goal> </goals> 
                    <configuration> <classifier>exec</classifier> </configuration> </execution> 
                    </executions> </plugin> -->
    
                <!-- java编译插件 -->
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <configuration>
                        <source>1.8</source>
                        <target>1.8</target>
                        <encoding>UTF-8</encoding>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    </project>

    (3)编写Spring Boot启动类(com.kfit.App);

    package me.shijunjie.testspringbootredis;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.boot.orm.jpa.EntityScan;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
    
    @SpringBootApplication
    @ComponentScan("me.shijunjie")
    @EnableJpaRepositories("me.shijunjie.repository")
    @EntityScan("me.shijunjie.bean")
    public class App 
    {
        public static void main( String[] args )
        {
            SpringApplication.run(App.class, args);
        }
    }

    (4)配置application.properties;

    ########################################################

    ###datasource u914Du7F6EMySQLu6570u636Eu6E90uFF1B

    ########################################################

    spring.datasource.url =jdbc:mysql://123.206.228.200:3306/test

    spring.datasource.username = shijunjie

    spring.datasource.password = ******

    spring.datasource.driverClassName =com.mysql.jdbc.Driver

    spring.datasource.max-active=20

    spring.datasource.max-idle=8

    spring.datasource.min-idle=8

    spring.datasource.initial-size=10

    ########################################################

    ###REDIS (RedisProperties) redisu57FAu672Cu914Du7F6EuFF1B

    ########################################################

    # database name

    spring.redis.database=0

    # server host1

    spring.redis.host=123.206.228.200

    # server password

    spring.redis.password=******

    #connection port

    spring.redis.port=6379

    # pool settings ...

    spring.redis.pool.max-idle=8

    spring.redis.pool.min-idle=0

    spring.redis.pool.max-active=8

    spring.redis.pool.max-wait=-1

    # name of Redis server

    #spring.redis.sentinel.master=

    # comma-separated list of host:portpairs

    #spring.redis.sentinel.nodes=


    ########################################################

    ### Java Persistence Api u81EAu52A8u8FDBu884Cu5EFAu8868

    ########################################################

    # Specify the DBMS

    spring.jpa.database = MYSQL

    # Show or not log for each sqlquery

    spring.jpa.show-sql = true

    # hibernate ddl auto (create,create-drop, update)

    spring.jpa.hibernate.ddl-auto = update

    # Naming strategy

    spring.jpa.hibernate.naming-strategy =org.hibernate.cfg.ImprovedNamingStrategy

    # stripped before adding them tothe entity manager)

    spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect

    (5)编写RedisCacheConfig配置类;

    缓存主要有几个要实现的类:其一就是CacheManager缓存管理器;其二就是具体操作实现类;其三就是CacheManager工厂类(这个可以使用配置文件配置的进行注入,也可以通过编码的方式进行实现);其四就是缓存key生产策略(当然Spring自带生成策略,但是在Redis客户端进行查看的话是系列化的key,对于我们肉眼来说就是感觉是乱码了,这里我们先使用自带的缓存策略)。

    package me.shijunjie.config;
    
    import org.springframework.cache.CacheManager;
    import org.springframework.cache.annotation.CachingConfigurerSupport;
    import org.springframework.cache.annotation.EnableCaching;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.data.redis.cache.RedisCacheManager;
    import org.springframework.data.redis.connection.RedisConnectionFactory;
    import org.springframework.data.redis.core.RedisTemplate;
    
    @Configuration
    @EnableCaching //启用缓存,这个注解很重要;
    public class RedisCacheConfig extends CachingConfigurerSupport {
         /**
         * 缓存管理器.
         * @param redisTemplate
         * @return
         */
        @Bean
        public CacheManager cacheManager(RedisTemplate<?,?> redisTemplate) {
               CacheManager cacheManager = new RedisCacheManager(redisTemplate);
               return cacheManager;
        }
        
        /**
         * redis模板操作类,类似于jdbcTemplate的一个类;
         * 虽然CacheManager也能获取到Cache对象,但是操作起来没有那么灵活;
         * 这里在扩展下:RedisTemplate这个类不见得很好操作,我们可以在进行扩展一个我们
         * 自己的缓存类,比如:RedisStorage类;
         * @param factory : 通过Spring进行注入,参数在application.properties进行配置;
         * @return
         */
        @Bean
        public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {
               RedisTemplate<String,String> redisTemplate = new RedisTemplate<String, String>();
               redisTemplate.setConnectionFactory(factory);
               //key序列化方式;(不然会出现乱码;),但是如果方法上有Long等非String类型的话,会报类型转换错误;
               //所以在没有自己定义key生成策略的时候,以下这个代码建议不要这么写,可以不配置或者自己实现ObjectRedisSerializer
               //或者JdkSerializationRedisSerializer序列化方式;
    //        RedisSerializer<String>redisSerializer = new StringRedisSerializer();//Long类型不可以会出现异常信息;
    //        redisTemplate.setKeySerializer(redisSerializer);
    //        redisTemplate.setHashKeySerializer(redisSerializer);
               return redisTemplate;
        }
    }

    (6)编写DemoInfo测试实体类;

    package me.shijunjie.bean;
    
    import java.io.Serializable;
    
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.Id;
    
    @Entity
    public class DemoInfo  implements Serializable{
        private static final long serialVersionUID = 1L;
    
        @Id @GeneratedValue
        private long id;
        private String name;
        private String pwd;
        public long getId() {
            return id;
        }
        public void setId(long id) {
            this.id = id;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public String getPwd() {
            return pwd;
        }
        public void setPwd(String pwd) {
            this.pwd = pwd;
        }
        @Override
        public String toString() {
            return "DemoInfo [id=" + id + ", name=" + name + ", pwd=" + pwd + "]";
        }
    
    }

    (7)编写DemoInfoRepository持久化类;

    package me.shijunjie.repository;
    
    import java.io.Serializable;
    
    import org.springframework.data.repository.CrudRepository;
    import org.springframework.stereotype.Repository;
    
    import me.shijunjie.bean.DemoInfo;
    
    @Repository
    public interface DemoInfoRepository extends CrudRepository<DemoInfo, Serializable> {
    
    }

    (8)编写DemoInfoService类;

           编写DemoInfoService,这里有两个技术方面,第一就是使用Spring @Cacheable注解方式和RedisTemplate对象进行操作,具体代码如下:

    package me.shijunjie.service;
    
    import me.shijunjie.bean.DemoInfo;
    
    public interface DemoInfoService {
         public DemoInfo findById(long id);
         public void deleteFromCache(long id);
         void test();
         void save(DemoInfo demoInfo);
    }
    package me.shijunjie.service.impl;
    
    import javax.annotation.Resource;
    
    import org.springframework.cache.annotation.CacheEvict;
    import org.springframework.cache.annotation.Cacheable;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.data.redis.core.ValueOperations;
    import org.springframework.stereotype.Service;
    
    import me.shijunjie.bean.DemoInfo;
    import me.shijunjie.repository.DemoInfoRepository;
    import me.shijunjie.service.DemoInfoService;
    
    @Service
    public class DemoInfoServiceImpl implements DemoInfoService {
        
        @Resource
        private DemoInfoRepository demoInfoDao;
        
        @Resource
        private RedisTemplate<String,String> redisTemplate;
    
        @Cacheable(value="demoInfo") //缓存,这里没有指定key.
        @Override
        public DemoInfo findById(long id) {
            System.err.println("DemoInfoServiceImpl.findById()=========从数据库中进行获取的....id="+id);
            DemoInfo demoInfo = demoInfoDao.findOne(id);
            return demoInfo;
        }
    
        @CacheEvict(value="demoInfo")
        @Override
        public void deleteFromCache(long id) {
            System.out.println("DemoInfoServiceImpl.delete().从缓存中删除.");
        }
    
        @Override
        public void test() {
             ValueOperations<String,String> valueOperations = redisTemplate.opsForValue();
             valueOperations.set("mykey4", "random1="+Math.random());
             System.out.println(valueOperations.get("mykey4"));
        }
    
        @Override
        public void save(DemoInfo demoInfo) {
            demoInfoDao.save(demoInfo);
        }
    
    }

    (9)编写DemoInfoController类;

    package me.shijunjie.controller;
    
    import javax.annotation.Resource;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    import me.shijunjie.bean.DemoInfo;
    import me.shijunjie.service.DemoInfoService;
    
    @Controller
    public class DemoInfoController {
        @Resource
        DemoInfoService demoInfoService;
    
        @RequestMapping("/save")
        public @ResponseBody String save(){
            DemoInfo demoInfo = new DemoInfo();
            demoInfo.setName("aaa");
            demoInfo.setPwd("aaab");
            demoInfoService.save(demoInfo);
            return "ok";
        }
        
        @RequestMapping("/test")
        public @ResponseBody String test(){
            DemoInfo loaded = demoInfoService.findById(1);
            System.out.println("loaded="+loaded);
            DemoInfo cached = demoInfoService.findById(1);
            System.out.println("cached="+cached);
            loaded = demoInfoService.findById(2);
            System.out.println("loaded2="+loaded);
            return "ok";
        }
    
        @RequestMapping("/delete")
        public @ResponseBody String delete(long id){
            demoInfoService.deleteFromCache(id);
            return "ok";
        }
    
        @RequestMapping("/test1")
        public @ResponseBody String test1(){
            demoInfoService.test();
            System.out.println("DemoInfoController.test1()");
            return "ok";
        }
    }

    (10)测试代码是否正常运行了

    启动应用程序,访问地址:http://127.0.0.1:8080/test

    查看控制台可以查看:

    (11)自定义缓存key;

    在me.shijunjie.config.RedisCacheConfig类中重写CachingConfigurerSupport中的keyGenerator ,具体实现代码如下:

    /**
         * 自定义key.
         * 此方法将会根据类名+方法名+所有参数的值生成唯一的一个key,即使@Cacheable中的value属性一样,key也会不一样。
         */
        @Override
        public KeyGenerator keyGenerator() {
            System.out.println("RedisCacheConfig.keyGenerator()");
            return new KeyGenerator() {
                
                @Override
                public Object generate(Object o, Method method, Object... args) {
                     StringBuilder sb = new StringBuilder();
                     sb.append(o.getClass().getName());
                     sb.append(method.getName());
                     for (Object obj : args) {
                            sb.append(obj.toString());
                     }
                     System.out.println("keyGenerator=" + sb.toString());
                     return sb.toString();
                }
            };
        }

    具体参照http://blog.csdn.net/linxingliang/article/details/52263763

  • 相关阅读:
    fail to start File System Check
    qemu:///system 没有连接驱动器可用;读取数据时进入文件终点: 输入/输出错误
    [转载]libvirt(virsh命令总结)
    【转载】CentOS 7自动以root身份登录gnome桌面 操作系统开机后自动登录到桌面 跳过GDM
    Linux查看PCIe版本及速率# lspci -vvv |grep Width -i
    JAVA的线程能够在多个CPU上执行么?
    给定字典做分词
    POJ 3130 &amp; ZOJ 2820 How I Mathematician Wonder What You Are!(半平面相交 多边形是否有核)
    高仿一元云购IOS应用源代码项目
    增加收藏兼容主流浏览器代码
  • 原文地址:https://www.cnblogs.com/s648667069/p/6516005.html
Copyright © 2011-2022 走看看