• Redis的使用


    相关链接
    redis-lua
    redis-lua

    单独使用

    • maven配置
    <!-- jedis依赖 -->
    <dependency>
       <groupId>redis.clients</groupId>
       <artifactId>jedis</artifactId>
       <version>2.7.1</version>
    </dependency>
    <dependency>
       <groupId>org.springframework.data</groupId>
       <artifactId>spring-data-redis</artifactId>
       <version>1.6.2.RELEASE</version>
    </dependency>
    
    • 配置文件 redis.properties
    redis.host=127.0.0.1
    redis.port=6379
    redis.sentinel.port=26879
    redis.pwd=
    redis.database=0
    #逐出扫描的时间间隔(毫秒) 如果为负数,则不运行逐出线程, 默认-1
    redis.pool.timeBetweenEvictionRunsMillis=30000
    redis.pool.testOnBorrow=true
    # 连接超时时间
    redis.timeout=1000
    redis.userPool=true
    #最大空闲数
    redis.pool.maxIdle=100
    redis.pool.minIdle=10
    #控制一个pool可分配多少个jedis实例,用来替换上面的redis.maxActive,如果是jedis 2.4以后用该属性
    redis.pool.maxTotal=200
    #最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制。
    redis.pool.maxWaitMillis=10000
    #连接的最小空闲时间 默认1800000毫秒(30分钟)
    redis.pool.minEvictableIdleTimeMillis=300000
    #每次释放连接的最大数目,默认3
    redis.pool.numTestsPerEvictionRun=10
    redis.pool.testOnReturn=true
    redis.pool.testWhileIdle=true
    
    • 配置文件 spring-redis.xml
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:context="http://www.springframework.org/schema/context"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">
    
        <context:property-placeholder location="classpath:redis.properties" ignore-unresolvable="true"/>
       
        <!-- 连接池参数 -->
        <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
            <property name="maxIdle" value="${redis.pool.maxIdle}" />
            <property name="minIdle" value="${redis.pool.minIdle}" />
            <property name="maxTotal" value="${redis.pool.maxTotal}" />
            <property name="maxWaitMillis" value="${redis.pool.maxWaitMillis}" />
            <property name="minEvictableIdleTimeMillis" value="${redis.pool.minEvictableIdleTimeMillis}"></property>
            <property name="numTestsPerEvictionRun" value="${redis.pool.numTestsPerEvictionRun}"></property>
            <property name="timeBetweenEvictionRunsMillis" value="${redis.pool.timeBetweenEvictionRunsMillis}"></property>
            <property name="testOnBorrow" value="${redis.pool.testOnBorrow}" />
            <property name="testOnReturn" value="${redis.pool.testOnReturn}" />
            <property name="testWhileIdle" value="${redis.pool.testWhileIdle}"></property>
        </bean>
    
        <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
            <property name="poolConfig" ref="jedisPoolConfig" />
            <property name="hostName" value="${redis.host}" />
            <property name="port" value="${redis.port}" />
            <property name="password" value="${redis.pwd}" />
            <property name="usePool" value="${redis.userPool}" />
            <property name="database" value="${redis.database}" />
            <property name="timeout" value="${redis.timeout}" />
        </bean>
    
        <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
            <property name="connectionFactory" ref="jedisConnectionFactory" />
            <!-- 序列化方式 建议key/hashKey采用StringRedisSerializer -->
            <property name="keySerializer">
                <bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />
            </property>
            <property name="valueSerializer">
                <bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer" />
            </property>
            <property name="hashKeySerializer">
                <bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />
            </property>
            <property name="hashValueSerializer">
                <bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer" />
            </property>
            <!-- 开启REIDS事务支持 -->
            <property name="enableTransactionSupport" value="false" />
        </bean>
    </beans>
    
    • 在spring.xml里添加
    <!--引入rabbit配置文件-->
    <import resource="spring-redis.xml"/>
    
    • 使用
    public class TestHash {
        @Autowired
        private RedisTemplate redisTemplate;
     
        // 存值
        public void testSetValue() {
            redisTemplate.boundHashOps("namehash").put("a", "唐僧");
            redisTemplate.boundHashOps("namehash").put("b", "悟空");
            redisTemplate.boundHashOps("namehash").put("c", "八戒");
            redisTemplate.boundHashOps("namehash").put("d", "沙僧");
        }
     
        // 获取所有的key
        public void testGetKeys() {
            Set s = redisTemplate.boundHashOps("namehash").keys();
            System.out.println(s);
        }
     
        // 获取所有的value
        public void testGetValues() {
            List values = redisTemplate.boundHashOps("namehash").values();
            System.out.println(values);
        }
     
        // 根据key获取值
        public void testGetValueByKey() {
            Object object = redisTemplate.boundHashOps("namehash").get("b");
            System.out.println(object);
        }
     
        // 根据key移除值
        public void testRemoveValueByKey() {
            redisTemplate.boundHashOps("namehash").delete("c");
        }
    }
    

    可以封装一个Dao

    @Component
    public class RedisDao {
    
        @Autowired
        private RedisTemplate redisTemplate;
    
        //redisTemplate.opsForList();//操作list
        //redisTemplate.opsForValue();//操作字符串
        //redisTemplate.opsForCluster();//集群时使用
        //redisTemplate.opsForGeo();//地理位置时使用
        //redisTemplate.opsForHash();//操作hash
        //redisTemplate.opsForSet();//操作set
        //redisTemplate.opsForZSet();//操作有序set
    
        public void setKey(String key, String value) {
            ValueOperations<String, String> ops = redisTemplate.opsForValue();
            ops.set(key, value);
        }
        
        public String getValue(String key) {
            ValueOperations<String, String> ops = redisTemplate.opsForValue();
            return ops.get(key);
        }
    
        // 还有isHas,setExTime,getExTime,递增,递减等等
    }
    
    @RestController
    public class HelloRedis {
     
        @Autowired
        RedisDao redisDao;
    	
        @RequestMapping("/helloredis")
        @ResponseBody
        public String hello(String name, String age) {
    	redisDao.setKey("name", name);
    	redisDao.setKey("age", age);
    	System.out.println("name=" + name + " * " + "age=" + age);
    	String retName = redisDao.getValue("name");
    	String retAge = redisDao.getValue("age");
    	return retName + " * " + retAge;
        }
    }
    

    redis分布式锁
    redis秒杀业务使用锁,可以查看笔记【各种锁】

    结合Mybatis
    查看【Mybatis-Redis-Cache】笔记

    redis-lua,为什么要使用lua查看【工具/redis】

    • 例子一
    --- 获取key
    local key = KEYS[1]
    --- 获取value
    local val = KEYS[2]
    --- 获取一个参数
    local expire = ARGV[1]
    --- 如果redis找不到这个key就去插入
    if redis.call("get", key) == false then
        --- 如果插入成功,就去设置过期值
        if redis.call("set", key, val) then
            --- 由于lua脚本接收到参数都会转为String,所以要转成数字类型才能比较
            if tonumber(expire) > 0 then
                --- 设置过期时间
                redis.call("expire", key, expire)
            end
            return true
        end
        return false
    else
        return false
    end
    
    // 配置类
    @Configuration
    public class LuaConfiguration {
        @Bean
        public DefaultRedisScript<Boolean> redisScript() {
            DefaultRedisScript<Boolean> redisScript = new DefaultRedisScript<>();
            // 添加lua脚本的文件地址
            redisScript.setScriptSource(new ResourceScriptSource(new ClassPathResource("script/Test.lua")));
            // 设置好这个脚本返回的结果类型
            redisScript.setResultType(Boolean.class);
            return redisScript;
        }
    }
    
    @RestController
    public class test{
        @Resource
        private DefaultRedisScript<Boolean> redisScript;
        @Resource
        private StringRedisTemplate stringRedisTemplate;
    
        @GetMapping("/lua")
        public ResponseEntity lua() {
            List<String> keys = Arrays.asList("testLua", "hello lua");
            Boolean execute = stringRedisTemplate.execute(redisScript, keys, "100");
            assert execute != null;
            return ResponseEntity.ok(execute);
        }
    }
    
    • 例子二
    --获取KEY
    local key1 = KEYS[1]
    local key2 = KEYS[2]
     
    -- 获取ARGV[1],这里对应到应用端是一个List<Map>.
    --  注意,这里接收到是的字符串,所以需要用csjon库解码成table类型
    local receive_arg_json =  cjson.decode(ARGV[1])
     
    --返回的变量
    local result = {}
     
    --打印日志到reids
    --注意,这里的打印日志级别,需要和redis.conf配置文件中的日志设置级别一致才行
    redis.log(redis.LOG_DEBUG,key1)
    redis.log(redis.LOG_DEBUG,key2)
    redis.log(redis.LOG_DEBUG, ARGV[1],#ARGV[1])
     
    --获取ARGV内的参数并打印
    local expire = receive_arg_json.expire
    local times = receive_arg_json.times
    redis.log(redis.LOG_DEBUG,tostring(times))
    redis.log(redis.LOG_DEBUG,tostring(expire))
     
    --往redis设置值
    redis.call("set",key1,times)
    redis.call("incr",key2)
    redis.call("expire",key2,expire)
     
    --用一个临时变量来存放json,json是要放入要返回的数组中的
    local jsonRedisTemp={}
    jsonRedisTemp[key1] = redis.call("get",key1)
    jsonRedisTemp[key2] = redis.call("get", key2)
    jsonRedisTemp["ttl"] = redis.call("ttl",key2)
    redis.log(redis.LOG_DEBUG, cjson.encode(jsonRedisTemp))
    
    --springboot redistemplate接收的是List,如果返回的数组内容是json对象,需要将json对象转成字符串,客户端才能接收
    result[1] = cjson.encode(jsonRedisTemp) 
    --将源参数内容一起返回
    result[2] = ARGV[1] 
    --打印返回的数组结果,这里返回需要以字符返回
    redis.log(redis.LOG_DEBUG,cjson.encode(result)) 
    
    return result
    
    // 配置类
    @Configuration
    public class LuaConfiguration {
        @Bean
        public DefaultRedisScript<Boolean> redisScript() {
            DefaultRedisScript<Boolean> redisScript = new DefaultRedisScript<>();
            // 添加lua脚本的文件地址
            redisScript.setScriptSource(new ResourceScriptSource(new ClassPathResource("script/Test.lua")));
            // 设置好这个脚本返回的结果类型
            redisScript.setResultType(List.class);
            return redisScript;
        }
    }
    
    @RestController
    public class test{
        @Resource
        private DefaultRedisScript<Boolean> redisScript;
        @Resource
        private StringRedisTemplate stringRedisTemplate;
    
        @GetMapping("/lua")
        public ResponseEntity lua() {
            List<String> keyList = new ArrayList();
            keyList.add("count");
            keyList.add("rate.limiting:127.0.0.1");
    
            /**
             * 用Mpa设置Lua的ARGV[1]
             */
            Map<String,Object> argvMap = new HashMap<String,Object>();
            argvMap.put("expire",10000);
            argvMap.put("times",10);
     
            /**
             * 调用脚本并执行
             */
            List result = redisTemplate1.execute(getRedisScript,keyList, argvMap);
            System.out.println(result);
        }
    }
    

    主从连接
    查看【Redis多数据源】笔记

    哨兵连接
    查看【Redis多数据源】笔记

    集群连接
    查看【Redis多数据源】笔记

  • 相关阅读:
    java定时读取文件
    Java面试:投行的15个多线程和并发面试题(转)
    读取一个文件,给定一个字符串,判断这个字符串在文件中出现的次数
    随机产生10个数,并每个数给定一个序号,然后将这10个数按照从小到大的顺序输出来,并带上序号输出
    找出给定字符串中出现最多的字符和次数
    公司开发部门GIT与SVN 之争
    浅谈Hibernate中的三种数据状态
    MyBatis框架的XML数据访问Dao层接口的组合使用
    浅谈WebLogic和Tomcat
    为什么我们不要 .NET 程序员
  • 原文地址:https://www.cnblogs.com/pengdt/p/13523288.html
Copyright © 2020-2023  润新知