精华内容
下载资源
问答
  • redis项目实例
    2022-04-07 15:27:38

    Redis Java String(字符串) 实例

    //连接Redis 服务
    Jedis jedis = new Jedis("116.63.178.139");
    System.out.println("连接成功");
    //设置 redis 字符串数据
    jedis.set("runoobkey", "www.runoob.com");
    // 获取存储的数据并输出
    System.out.println("redis 存储的字符串为: "+ jedis.get("runoobkey"));
    //关闭Redis服务
     jedis.close();

    Redis Java List(列表) 实例

     //连接Redis 服务
     Jedis jedis = new Jedis("116.63.178.139");
     System.out.println("连接成功");
     //存储数据到列表中
     jedis.lpush("site-list", "Runoob2");
     jedis.lpush("site-list", "Google");
     jedis.lpush("site-list", "Taobao");
     System.out.println("保存或者更新成功");
     // 获取存储的数据并输出
     List<String> list = jedis.lrange("site-list", 0 ,2);
     for(int i=0; i<list.size(); i++) {
     System.out.println("列表项为: "+list.get(i));
     }
     //关闭Redis服务
     jedis.close();

    Redis Java Keys 实例(获取缓存中的所有的key)

    //连接Redis 服务
    Jedis jedis = new Jedis("116.63.178.139");
    System.out.println("连接成功");
    
    // 获取数据并输出
    Set<String> keys = jedis.keys("*"); 
    Iterator<String> it=keys.iterator() ;   
    while(it.hasNext()){   
    String key = it.next();   
    System.out.println(key);   
    }
    //关闭Redis服务
    jedis.close();

    Redis详细安装与连接请参考我发布的之前博客

    更多相关内容
  • SSM+Shiro+redis项目实例

    2018-04-28 13:44:22
    SSM+Shiro+redis项目实例,所有的配置文件加注释,也许有设计不好的地方,请见谅!
  • Redis项目应用场景与实例汇总

    千次阅读 2021-01-25 16:10:29
    文章目录一、背景1.1 开发环境1.2 项目配置二、字符串的应用场景:封锁一个IP地址三、Hash的应用场景:存储用户信息四、List的应用场景:队列实现五、Set的应用场景:自动去重 一、背景 本篇文章是将以前Redis实战...

    一、背景

    • 本篇文章是将以前Redis实战的系列文章进行汇总,针对Redis中常用的一些数据结构,进行实战模拟。
    stringshasheslistssetssorted sets
    封锁一个IP地址存储用户信息模拟消息队列自动排重以某一个条件为权重,进行排序

    1.1 开发环境

    1. JDK 1.8
    2. SpringBoot 2.2.5
    3. JPA
    4. Spring Security
    5. Mysql 8.0
    6. Redis Server 3.2.1
    7. Redis Desktop Manager
    8. Swagger2

    1.2 项目配置

    • SpringBoot集成Redis, 添加依赖
    <!--pom.xl-->
    	   <!--Redis-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-redis</artifactId>
            </dependency>
    
    • 项目配置文件 添加redis连接配置
    <!-- application.yml-->
    server:
      port: 8000
    
    spring:
        freemarker:
          check-template-location: false
        profiles:
          active: dev
        jackson:
          time-zone: GMT+8
        data:
          redis:
            repositories:
              enabled: false
    
        #配置 Jpa
        jpa:
          properties:
            hibernate:
              dialect: org.hibernate.dialect.MySQL5InnoDBDialect
          open-in-view: true
    
        redis:
          database: 0
          host: 127.0.0.1
          port: 6379
          password:
    
    
    • 增加RedisConfig配置类
      在这里插入图片描述
    /**
     * Redis配置类
     *
     * @author zhuhuix
     */
    @Configuration
    @EnableCaching
    @ConditionalOnClass(RedisOperations.class)
    @EnableConfigurationProperties(RedisProperties.class)
    public class RedisConfig extends CachingConfigurerSupport {
    
        /**
         *设置 redis 数据默认过期时间
         */
        @Bean
        public RedisCacheConfiguration redisCacheConfiguration(){
            FastJsonRedisSerializer<Object> fastJsonRedisSerializer = new FastJsonRedisSerializer<>(Object.class);
            RedisCacheConfiguration configuration = RedisCacheConfiguration.defaultCacheConfig();
            configuration = configuration.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(fastJsonRedisSerializer)).entryTtl(Duration.ofHours(Constant.CACHE_TIMEOUT_HOUR));
            return configuration;
        }
    
    
        @Bean
        public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
            RedisTemplate<Object, Object> template = new RedisTemplate<>();
            template.setConnectionFactory(redisConnectionFactory);
    
            FastJsonRedisSerializer fastJsonRedisSerializer = new FastJsonRedisSerializer(Object.class);
            template.setValueSerializer(fastJsonRedisSerializer);
            template.setHashValueSerializer(fastJsonRedisSerializer);
    
            ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
    
            template.setKeySerializer(new StringRedisSerializer());
            template.setHashKeySerializer(new StringRedisSerializer());
    
            template.afterPropertiesSet();
            return template;
        }
    
        /**
         * 参考:https://blog.csdn.net/qq_15071263/article/details/84335632
         * 自定义缓存key生成策略,默认将使用该策略
         */
        @Bean
        @Override
        public KeyGenerator keyGenerator() {
            return (target, method, params) -> {
                Map<String,Object> container = new HashMap<>(3);
                Class<?> targetClassClass = target.getClass();
                // 类地址
                container.put("class",targetClassClass.toGenericString());
                // 方法名称
                container.put("methodName",method.getName());
                // 包名称
                container.put("package",targetClassClass.getPackage());
                // 参数列表
                for (int i = 0; i < params.length; i++) {
                    container.put(String.valueOf(i),params[i]);
                }
                // 转为JSON字符串
                String jsonString = JSON.toJSONString(container);
                // 做SHA256 Hash计算,得到一个SHA256摘要作为Key
                return DigestUtils.sha256Hex(jsonString);
            };
        }
    
    
    • 增加RedisUtils工具类:实现对各种数据结构的封装
    /**
     * Redis工具类
     *
     * @author zhuhuix
     */
    @Component
    @AllArgsConstructor
    public class RedisUtils {
        private RedisTemplate<Object, Object> redisTemplate;
    
        /**
         * HashGet根据键值得到对象
         *
         * @param key  键值 @NotNull
         * @param item 项目 @NotNull
         * @return 对象
         */
        public Object hashGet(String key, String item) {
            return redisTemplate.opsForHash().get(key, item);
        }
    
        /**
         * 根据键值向hash表中写入对象
         *
         * @param key   键值 @NotNull
         * @param item  项目 @NotNull
         * @param value 对象 @NotNull
         * @return true 成功 false失败
         */
        public boolean hashSet(String key, String item, Object value) {
            try {
                redisTemplate.opsForHash().put(key, item, value);
                return true;
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
    
        }
    
        /**
         * 根据键值向hash表中写入对象,并设置过期时间
         *
         * @param key   键值 @NotNull
         * @param item  项目 @NotNull
         * @param value 对象 @NotNull
         * @param time  过期时间(秒) @NotNull
         * @return true 成功 false失败
         */
        public boolean hashSet(String key, String item, Object value, long time) {
            try {
                redisTemplate.opsForHash().put(key, item, value);
                if (time > 0) {
                    expire(key, time);
                }
                return true;
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        }
    
        /**
         * 根据键值对某一项目的进行累加计数
         *
         * @param key 键值
         * @param l   累加数
         */
        public long increment(String key, long l) {
            return redisTemplate.opsForValue().increment(key, l);
        }
    
        /**
         * 根据键值对某一项目的进行累加计数,并设置过期时间
         *
         * @param key  键值
         * @param l    累加数
         * @param time 过期时间(秒)
         */
        public long increment(String key, long l, long time) {
            long count = redisTemplate.opsForValue().increment(key, l);
            if (time > 0) {
                expire(key, time);
            }
            return count;
        }
    
        /**
         * 入队
         *
         * @param key   队列键值
         * @param value 元素
         * @return 添加数量
         */
        public long leftPush(String key, Object value) {
            return redisTemplate.opsForList().leftPush(key, value);
        }
    
        /**
         * 向队列头部添加全部集合元素
         *
         * @param key  队列键值
         * @param list 集合
         * @return 返回添加的数量
         */
        public long leftPushAll(String key, List<Object> list) {
            return redisTemplate.opsForList().leftPushAll(key, list);
        }
    
        /**
         * 统计队列中所有元素数量
         *
         * @param key 队列键值
         * @return 队列中元素数量
         */
        public long size(String key) {
            return redisTemplate.opsForList().size(key);
        }
    
        /**
         * 返回队列中从起始位置到结束位置的集合元素
         *
         * @param key   队列键值
         * @param start 起始位置
         * @param end   结束位置
         * @return 返回集合
         */
        public List<Object> range(String key, long start, long end) {
            return redisTemplate.opsForList().range(key, start, end);
        }
    
        /**
         * 出队
         *
         * @param key 队列键值
         * @return 元素
         */
        public Object rightPop(String key) {
            return redisTemplate.opsForList().rightPop(key);
        }
    
        /**
         * 弹出队列最新元素
         *
         * @param key 队列键值
         * @return 元素
         */
        public Object leftPop(String key) {
            return redisTemplate.opsForList().leftPop(key);
        }
    
        /**
         * 删除队列所有元素
         *
         * @param key 队列键值
         */
        public void deleteAll(String key) {
            redisTemplate.opsForList().trim(key, 0, 0);
            redisTemplate.opsForList().leftPop(key);
        }
    
        /**
         * 向集合中增加元素
         *
         * @param key   集合键值
         * @param value 元素
         * @return 添加数量
         */
        public long setAdd(String key, Object value) {
            return redisTemplate.opsForSet().add(key,value);
        }
    
        /**
         * 向集合中批量增加元素
         *
         * @param key  集合键值
         * @param list 元素列表
         * @return 添加数量
         */
        public long setAdd(String key, List<Object> list) {
            return redisTemplate.opsForSet().add(key,list);
        }
    
        /**
         * 集合删除指定元素
         *
         * @param key   集合键值
         * @param value 指定元素
         * @return 删除数量
         */
        public long setRemove(String key, Object value) {
            return redisTemplate.opsForSet().remove(key, value);
        }
    
        /**
         * 集合批量删除指定元素
         *
         * @param key  集合键值
         * @param list 指定元素列表
         * @return 删除数量
         */
        public long setRemove(String key, List<Object> list) {
            return redisTemplate.opsForSet().remove(key, list);
        }
    
        /**
         * 取出两信集合的交集
         *
         * @param key1 集合1键值
         * @param key2 集合2键值
         * @return 交集
         */
        public Set<Object> setInter(String key1, String key2) {
            return redisTemplate.opsForSet().intersect(key1, key2);
        }
    
        /**
         * 取出多个集合的交集
         *
         * @param keys 键值列表
         * @return 交集
         */
        public Set<Object> setInter(List<Object> keys) {
            return redisTemplate.opsForSet().intersect(keys);
        }
    
        /**
         * 取出两个集合的差集
         *
         * @param key1 集合1键值
         * @param key2 集合2键值
         * @return 差集
         */
        public Set<Object> setDifference(String key1,String key2){
            return redisTemplate.opsForSet().difference(key1,key2);
        }
    
        /**
         * 指定缓存的失效时间
         *
         * @param key  键值 @NotNull
         * @param time 时间(秒) @NotNull
         */
        public boolean expire(String key, long time) {
            try {
                if (time > 0) {
                    redisTemplate.expire(key, time, TimeUnit.SECONDS);
                }
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
            return true;
        }
    
    }
    
    

    二、字符串的应用场景:封锁一个IP地址

    • 创建SpringBoot后台服务程序,实现用户登录及JWT认证;
    • 通过Redis缓存限制在1分钟内同一IP请求登录不能超过5次。

    在这里插入图片描述

    • 登录实现类增加Redis计数判断
    /**
     * 授权登录接口实现类
     *
     * @author zhuhuix
     */
    @Slf4j
    @Service
    @Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
    public class AuthServiceImpl implements AuthService {
    
        @Value("${wxMini.appId}")
        private String appId;
        @Value("${wxMini.secret}")
        private String secret;
    
        private final JwtTokenUtils jwtTokenUtils;
        private final WxMiniApi wxMiniApi;
        private final UserService userService;
        private final JwtSecurityProperties properties;
        private final RedisUtils redisUtils;
    
        public AuthServiceImpl(JwtTokenUtils jwtTokenUtils, WxMiniApi wxMiniApi, UserService userService, JwtSecurityProperties properties, RedisUtils redisUtils) {
            this.jwtTokenUtils = jwtTokenUtils;
            this.wxMiniApi = wxMiniApi;
            this.userService = userService;
            this.properties = properties;
            this.redisUtils = redisUtils;
        }
    
        @Override
        @Transactional(rollbackFor = Exception.class)
        public Result<AuthUserDto> login(AuthUserDto authUserDto, HttpServletRequest request) {
            // 通过缓存判断同一IP某一时间段内的登录次数是否超出限定次数
            String ip = NetworkUtils.getIp(request);
            String requestLoginIp = "request_login_".concat(ip);
            long loginCount = redisUtils.increment(requestLoginIp, 1L);
            if (loginCount == 1) {
                redisUtils.expire(requestLoginIp, Constant.REQUEST_LOGIN_LIMIT_TIME);
            }
            if (loginCount > Constant.REQUEST_LOGIN_LIMIT_COUNT) {
                log.warn("IP:[".concat(ip).concat("]已超出限定次数"));
                throw new RuntimeException("时间段内已超出限定次数,请不要频繁登录!");
            }
    
           ...
           ...
        }
    }
    
    
    • 测试与验证
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述

    三、Hash的应用场景:存储用户信息

    创建SpringBoot后台服务程序,实现微信小程序登录及JWT认证;
    通过Redis缓存记录该用户最后一次登录时间及登录累计次数。

    /**
     * 授权登录接口实现类--增加redis缓存哈希表应用
     *
     * @author zhuhuix
     */
    @Slf4j
    @Service
    @Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
    public class AuthServiceImpl implements AuthService {
    		....
    		....
    		
     		// 将当前用户信息与登录时间写入Redis缓存的哈希表
     		// 以微信登录用户的openId作为哈希键值
            String key = authUserDto.getUserInfo().getOpenId();
            
            redisUtils.hashSet(key, "id", authUserDto.getUserInfo().getId());
            redisUtils.hashSet(key, "nickName", authUserDto.getUserInfo().getNickName());
            redisUtils.hashSet(key, "getAvatarUrl", authUserDto.getUserInfo().getAvatarUrl());
            redisUtils.hashSet(key, "lastLoginTime", Timestamp.valueOf(LocalDateTime.now()));
            
            // 读取缓存中当前哈希值对应的用户的登录次数
            Long loginCount = 1L;
            Object obj = redisUtils.hashGet(key, "loginCount");
            if (obj != null) {
                loginCount += Long.valueOf(String.valueOf(obj));
            }
            // 累加后回写到哈希表中
            redisUtils.hashSet(key, "loginCount", loginCount);
            ...
      }
    
    • 测试与验证
      在这里插入图片描述
      在这里插入图片描述

    四、List的应用场景:队列实现

    • 创建SpringBoot上传文件WebApi服务接口;
    • 通过Redis缓存队列记录最新10笔用户上传文件的信息。

    缓存队列时序图

    • 图片上传服务源码中增加Redis队列
    /**
     * 微信小程序CRM实现类:实现Redis队列
     *
     * @author zhuhuix
     */
    @Slf4j
    @AllArgsConstructor
    @Service
    @Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
    public class WxMiniCrmImpl implements WxMiniCrm {
    
        ...
    
        @Override
        @Transactional(rollbackFor = Exception.class)
        public Result<CrmIndex> uploadCrmIndex(String json, String openId, String realName, MultipartFile multipartFile) {
            try {
                JSONObject jsonObject = JSONObject.parseObject(json);
    
                String createTime = jsonObject.getString("create");
                String employeeCode = jsonObject.getString("employeeCode");
                String customerCode = jsonObject.getString("customerCode");
                String customerName = jsonObject.getString("customerName");
                String type = jsonObject.getString("type");
    
                if (StringUtils.isEmpty(createTime) || StringUtils.isEmpty(employeeCode) || StringUtils.isEmpty(customerCode)
                        || StringUtils.isEmpty(customerName) || StringUtils.isEmpty(type)) {
                    throw new RuntimeException("上传信息中缺少关键资料");
                }
    
                UploadFile uploadFile = uploadFileTool.upload(openId, realName, multipartFile);
                if (uploadFile == null) {
                    throw new RuntimeException("上传文件失败!");
                }
                CrmIndex crmIndex = new CrmIndex();
                DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm");
                crmIndex.setCreateTime(Timestamp.valueOf(LocalDateTime.parse(createTime, dateTimeFormatter)));
                crmIndex.setEmployeeCode(employeeCode);
                crmIndex.setCustomerCode(customerCode);
                crmIndex.setCustomerName(customerName);
                crmIndex.setType(type);
                crmIndex.setJson(json);
                crmIndex.setOpenId(openId);
                crmIndex.setPath(uploadFile.getPath());
    
                // 将最新10条上传的信息放入redis缓存
                if (redisUtils.size(Constant.REDIS_UPLOAD_QUEUE_NAME) >= Constant.REDIS_UPLOAD_QUEUE_COUNT) {
                    log.warn(Constant.REDIS_UPLOAD_QUEUE_NAME.concat("队列已满,移除最旧上传信息:") + redisUtils.rightPop(Constant.REDIS_UPLOAD_QUEUE_NAME));
                }
                log.info(Constant.REDIS_UPLOAD_QUEUE_NAME.concat("队列增加上传信息:").concat(crmIndex.toString()));
                redisUtils.leftPush(Constant.REDIS_UPLOAD_QUEUE_NAME, crmIndex);
    
                return new Result<CrmIndex>().ok(crmIndexRepository.save(crmIndex));
    
            } catch (JSONException ex) {
                throw new RuntimeException("json转换失败:" + ex.getMessage());
            }
    
        }
    	...
    }
    
    

    文件上传的原理与实现可参考该文章《SpringBoot实现微信小程序文件上传的完整案例》

    • 测试与验证

    • 微信小程序端
      – 前端将识别信息与图片上传至服务器
      在这里插入图片描述
      在这里插入图片描述

    • Redis缓存队列
      – 队列中只保存最新10条(数量可自行调整)信息.:

    在这里插入图片描述

    五、Set的应用场景:自动去重

    • 创建SpringBoot添加客户信息服务接口;
    • 通过Redis集合缓存客户信息,要求自动去重,不得重复记录。

    在这里插入图片描述

    • 客户实体类
    /**
     * CRM客户信息
     *
     * @author zhuhuix
     */
    @Entity
    @Getter
    @Setter
    @Table(name = "customer")
    public class Customer implements Serializable {
    
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        @NotNull(groups = Update.class)
        private Long id;
    
        @Column(name = "open_id")
        private String openId;
    
        /**
         * 客户代码
         */
        @Column(name = "customer_code")
        private String customerCode;
    
        /**
         * 客户名称
         */
        @Column(name = "customer_name")
        private String customerName;
    
        /**
         * 首字母
         */
        @Column(name = "first_letter")
        private String firstLetter;
    
        /**
         * 创建时间
         */
        @Column(name = "create_time")
        @CreationTimestamp
        private Timestamp createTime;
    
        /**
         * 更新时间
         */
        @Column(name = "update_time")
        @UpdateTimestamp
        private Timestamp updateTime;
    
        @Override
        public String toString() {
            return "Customer{" +
                    "customerCode='" + customerCode + '\'' +
                    ", customerName='" + customerName + '\'' +
                    '}';
        }
    }
    
    
    • 客户信息WebApi
    	@ApiOperation(value = "通过扫一扫功能上传客户信息")
        @PostMapping(value = "/crmScan/{openId}")
        public ResponseEntity crmScan(@RequestBody WxScanDto wxScanDto, @PathVariable String openId) {
    
            return ResponseEntity.ok(wxMiniCrm.wxScan(wxScanDto, openId));
    
        }
    
    • 记录并缓存客户信息实现类
    /**
     * 微信小程序CRM实现类
     *
     * @author zhuhuix
     */
    @Slf4j
    @AllArgsConstructor
    @Service
    @Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
    public class WxMiniCrmImpl implements WxMiniCrm {
    
        private final UploadFileTool uploadFileTool;
        private final CrmIndexRepository crmIndexRepository;
        private final CustomerRepository customerRepository;
        private final UserService userService;
        private final RedisUtils redisUtils;
    
    	...
    	
        @Override
        @Transactional(rollbackFor = Exception.class)
        public Result<WxScanDto> wxScan(WxScanDto wxScanDto, String openId) {
    
            //微信扫一扫保存客户信息
            if (Constant.SAVE_CUSTOMER_INFO.equals(wxScanDto.getScanType()) && wxScanDto.getJsonObject() != null) {
                try {
                    Customer customer = JSONObject.parseObject(wxScanDto.getJsonObject().toJSONString(), Customer.class);
                    Customer target = customerRepository.findByCustomerCodeAndOpenId(customer.getCustomerCode(), openId);
                    if (target != null) {
                        BeanUtils.copyProperties(customer, target, RepositoryUtil.getNullPropertyNames(customer));
                    } else {
                        target = customer;
                        target.setOpenId(openId);
                    }
                    wxScanDto.setReturnObject(customerRepository.save(target));
                    // 将用户增加的客户信息添加到redis集合中
                    redisUtils.setAdd(openId.concat("_customer"),customer.toString());
    
                    return new Result<WxScanDto>().ok(wxScanDto);
                } catch (JSONException ex) {
                    throw new RuntimeException("json转换失败:" + ex.getMessage());
                }
    
            }
            return new Result<WxScanDto>().error("无法处理扫一扫功能");
        }
    
    
    }
    
    
    • 测试与验证
    1. 相同信息自动去重:通过swagger2进行接口测试,多次提交相同的客户信息
      在这里插入图片描述
    • Redis Desktop Manager验证数据
      – 查看集合中的数据,实现自动去重
      在这里插入图片描述
    1. 不同集合之间的交集与差集:用户1通过接口添加4个客户
      在这里插入图片描述
      –用户2通过接口添加3个客户
      在这里插入图片描述
      – 获取用户1与用户2相同及不同的客户信息
    /**
     * Redis测试
     * 
     * @author zhuhuix
     */
    @SpringBootTest
    @Slf4j
    public class TestSet {
        @Test
        void test() {
            RedisUtils redisUtils = SpringContextHolder.getBean(RedisUtils.class);
            //获取交集:相同客户
            Set<Object> setInter=redisUtils.setInter("openId1_customer","openId2_customer");
            Iterator iterator = setInter.iterator();
            log.info("openId1_customer与openId2_customer相同的客户为:");
            while(iterator.hasNext()){
                log.info(iterator.next().toString());
            }
            //获取差集:不同客户
            Set<Object> setDiff=redisUtils.setDifference("openId1_customer","openId2_customer");
            iterator = setDiff.iterator();
            log.info("openId1_customer与openId2_customer不同的客户为:");
            while(iterator.hasNext()){
                log.warn(iterator.next().toString());
            }
            
     		//获取差集:不同客户
            Set<Object> setDiff1=redisUtils.setDifference("openId2_customer","openId1_customer");
            iterator = setDiff1.iterator();
            log.info("openId2_customer与openId1_customer不同的客户为:");
            while(iterator.hasNext()){
                log.warn(iterator.next().toString());
            }
        }
    }
    
    
    • 测试结果
      在这里插入图片描述
    展开全文
  • springboot与redis结合的实战、实例项目,有助于帮助你了解springboot中怎么使用redis
  • Redis项目案例

    千次阅读 多人点赞 2019-07-26 17:17:06
    实战案例 基于redis缓存实现用户增删改查的项目分析需求项目运行环境项目搭建1、父工程2、子工程运行效果 基于redis缓存实现用户增删改查的项目分析 需求 redis的作用是实现数据的缓存,以此来提升系统性能。 在本...

    基于redis缓存实现用户增删改查的项目分析

    需求

    redis的作用是实现数据的缓存,以此来提升系统性能。
    在本案例中,基本功能是实现用户的增删改查,主要在用户的查询和修改时用到了redis的缓存。

    • 业务逻辑 -查询:首先对接收到的userid在redis缓存中查询,如果没有在查询mysql数据库,查询到以后将查询结果封装成json类型发送给redis进行缓存,方便下次读取
    • 业务逻辑 -更新:执行更新操作后,需要将redis中原来的缓存也一并删除,并将更新过的数据重新插入redis缓存

    项目运行环境

    1、在运行项目时,需要打开单机版redis,以及redis图形化工具RedisDesktopManager(方便查看数据变更信息)
    2、需要关闭防火墙
    3、需要有mysql或者oracle数据库

    项目搭建

    在这里插入图片描述

    1、父工程

    采取maven来构建项目,父工程为pom工程,并且添加以下坐标,并对其版本进行控制

    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>com.bjsxt</groupId>
      <artifactId>parent</artifactId>
      <version>0.0.1-SNAPSHOT</version>
      <packaging>pom</packaging>
     
     	<!-- 对依赖的jar包的版本统一进行定义 -->
    	<properties>
    		<jedis.version>2.9.0</jedis.version>
    		<jedis.version>2.9.0</jedis.version>
    		<junit.version>4.12</junit.version>
    		<spring.version>4.1.3.RELEASE</spring.version>
    		<mybatis.version>3.2.8</mybatis.version>
    		<mybatis.spring.version>1.2.2</mybatis.spring.version>
    		<mysql.version>5.1.32</mysql.version>
    		<slf4j.version>1.6.4</slf4j.version>
    		<druid.version>1.0.9</druid.version>
    		<jstl.version>1.2</jstl.version>
    		<servlet-api.version>2.5</servlet-api.version>
    		<tomcat.version>2.2</tomcat.version>
    		<jsp-api.version>2.0</jsp-api.version>
    		<jackson.version>2.4.2</jackson.version>
    		
    	</properties>
    
    
    	<!-- jar包的依赖注入 ,由于该工程是一个父工程,所以jar包在该pom文件中只是声明 -->
    	<dependencyManagement>
    		
    		<dependencies>
    		
    		<!-- Jedis,实现java操作redis数据库 -->
    		<dependency>
    			<groupId>redis.clients</groupId>
    			<artifactId>jedis</artifactId>
    			<version>${jedis.version}</version>
    		</dependency>
    		
    			<!-- 单元测试 -->
    			<dependency>
    				<groupId>junit</groupId>
    				<artifactId>junit</artifactId>
    				<version>${junit.version}</version>
    			</dependency>
    			<!-- 日志处理 -->
    			<dependency>
    				<groupId>org.slf4j</groupId>
    				<artifactId>slf4j-log4j12</artifactId>
    				<version>${slf4j.version}</version>
    			</dependency>
    			<!-- Mybatis -->
    			<dependency>
    				<groupId>org.mybatis</groupId>
    				<artifactId>mybatis</artifactId>
    				<version>${mybatis.version}</version>
    			</dependency>
    			<dependency>
    				<groupId>org.mybatis</groupId>
    				<artifactId>mybatis-spring</artifactId>
    				<version>${mybatis.spring.version}</version>
    			</dependency>
    			<!-- MySql -->
    			<dependency>
    				<groupId>mysql</groupId>
    				<artifactId>mysql-connector-java</artifactId>
    				<version>${mysql.version}</version>
    			</dependency>
    			<!-- 连接池 -->
    			<dependency>
    				<groupId>com.alibaba</groupId>
    				<artifactId>druid</artifactId>
    				<version>${druid.version}</version>
    			</dependency>
    			<!-- Spring -->
    			<dependency>
    				<groupId>org.springframework</groupId>
    				<artifactId>spring-context</artifactId>
    				<version>${spring.version}</version>
    			</dependency>
    			<dependency>
    				<groupId>org.springframework</groupId>
    				<artifactId>spring-beans</artifactId>
    				<version>${spring.version}</version>
    			</dependency>
    			<dependency>
    				<groupId>org.springframework</groupId>
    				<artifactId>spring-webmvc</artifactId>
    				<version>${spring.version}</version>
    			</dependency>
    			<dependency>
    				<groupId>org.springframework</groupId>
    				<artifactId>spring-jdbc</artifactId>
    				<version>${spring.version}</version>
    			</dependency>
    			<dependency>
    				<groupId>org.springframework</groupId>
    				<artifactId>spring-aspects</artifactId>
    				<version>${spring.version}</version>
    			</dependency>
    			<!-- JSP相关 -->
    			<dependency>
    				<groupId>jstl</groupId>
    				<artifactId>jstl</artifactId>
    				<version>${jstl.version}</version>
    			</dependency>
    			<dependency>
    				<groupId>javax.servlet</groupId>
    				<artifactId>servlet-api</artifactId>
    				<version>${servlet-api.version}</version>
    				<scope>provided</scope>
    			</dependency>
    			<dependency>
    				<groupId>javax.servlet</groupId>
    				<artifactId>jsp-api</artifactId>
    				<version>${jsp-api.version}</version>
    				<scope>provided</scope>
    			</dependency>
    			
    			<!-- Jackson Json处理工具包 -->
    			<dependency>
    				<groupId>com.fasterxml.jackson.core</groupId>
    				<artifactId>jackson-databind</artifactId>
    				<version>${jackson.version}</version>
    			</dependency>
    		</dependencies>
    	</dependencyManagement>
    	
    <build>
    		<resources>
    			<resource>
    				<directory>src/main/java</directory>
    				<includes>
    					<include>**/*.xml</include>
    				</includes>
    			</resource>
    			<resource>
    				<directory>src/main/resources</directory>
    				<includes>
    					<include>**/*.xml</include>
    					<include>**/*.properties</include>
    				</includes>
    			</resource>
    		</resources>
    		<!-- tomcat插件,由于子项目不一定每个都是web项目,所以该插件只是声明,并未开启 -->
    		<pluginManagement>
    			<plugins>
    				<!-- 配置Tomcat插件 -->
    				<plugin>
    					<groupId>org.apache.tomcat.maven</groupId>
    					<artifactId>tomcat7-maven-plugin</artifactId>
    					<version>${tomcat.version}</version>
    				</plugin>
    			</plugins>
    		</pluginManagement>
    	</build>
    </project>
    

    2、子工程

    jar工程,进行业务功能的具体实现,下面将主要粘贴一些重要代码

    • JedisDao 与其实现类
    package com.bjsxt.jedisdao;
    
    public interface JedisDao {
    	
    	 String set(String key,String value);
    	 String get(String key);
    	 
    	 Long hset(String key,String field,String value);
    	 String hget(String key,String field);
    	 
    	 /**
    	  * 用于设置失效时间
    	  * @param key
    	  * @param sec
    	  * @return
    	  */
    	 Long expire(String key,int sec);
    	 /**
    	  * 删除jedis缓存
    	  * @param key
    	  * @return
    	  */
    	 Long del(String key);
    }
    
    
    
    package com.bjsxt.jedisdao.impl;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    import com.bjsxt.jedisdao.JedisDao;
    
    import redis.clients.jedis.Jedis;
    import redis.clients.jedis.JedisPool;
    @Service
    public class JedisDaoSingleImpl implements JedisDao{
    	//使用@Autowired要开启组件扫描,不使用的话要通过pagebean的propertie注入进来
    	@Autowired
    	private JedisPool jedispool;
    	
    	@Override
    	public String set(String key, String value) {
    		Jedis resource=jedispool.getResource();
    		return resource.set(key, value);
    	}
    
    	@Override
    	public String get(String key) {
    		Jedis resource=jedispool.getResource();
    		return resource.get(key);
    	}
    
    	@Override
    	public Long hset(String key, String field, String value) {
    		Jedis resource=jedispool.getResource();
    		return resource.hset(key, field, value);
    	}
    
    	@Override
    	public String hget(String key, String field) {
    		Jedis resource=jedispool.getResource();
    		return resource.hget(key, field);
    	}
    
    	@Override
    	public Long expire(String key, int sec) {
    		Jedis resource = jedispool.getResource();
    		
    		return resource.expire(key, sec);
    	}
    
    	@Override
    	public Long del(String key) {
    		Jedis resource = jedispool.getResource();
    		
    		return resource.del(key);
    	}
    
    }
    
    
    • 业务实现类(核心代码),实现用户的增删改查并使用redis缓存对系统进行优化
    package com.bjsxt.service.impl;
    
    import org.springframework.beans.factory.annotation.Autowired;
    
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.stereotype.Service;
    
    import com.bjsxt.commons.JsonUtils;
    import com.bjsxt.jedisdao.JedisDao;
    import com.bjsxt.mapper.UsersMapper;
    import com.bjsxt.pojo.Users;
    import com.bjsxt.service.UserService;
    
    import redis.clients.jedis.JedisPool;
    /**
     * 业务逻辑 -查询:首先对接受到的userid在redis数据库中查询,如果没有在查询mysql数据库,查询以后将拆线呢结果封装成json类型发送给redis缓存
     *  业务逻辑 -更新:执行更新操作后,需要将redis中的缓存也一并删除,并将更新过的数据重新插入redis缓存
     */
    @Service
    public class UserServiceImpl implements UserService {
    	@Autowired
    	private UsersMapper userMapper;	
    	@Autowired
    	private JedisDao jedisDao;
    	//@Autowired
    	//private JedisPool jedisPool;
    	
    	@Override
    	public void addUser(Users users) {
    		this.userMapper.insertUsers(users);
    	}
    	@Override
    	public void updateUser(Users users) {
    		this.userMapper.updateUser(users);
    		int userid = users.getUserid();
    		
    		try {
    			//删除原来的redis缓存
    			this.jedisDao.del(this.REDIS_USERS_PRIFX+":"+userid);
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    		
    		try {
    			//删除后将更新过后的信息放入redis
    			String objectToJson = JsonUtils.objectToJson(users);
    			//String redis_Key = this.REDIS_USERS_PRIFX+":"+userid;
    			jedisDao.set(this.REDIS_USERS_PRIFX+":"+userid, objectToJson);
    			jedisDao.expire(this.REDIS_USERS_PRIFX+":"+userid,100);//如果设置失败,最好clean一下
    			//jedisPool.getResource().expire(redis_Key, 20);
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    	}
    	//添加了一个配置文件内容为:REDIS_USERS_PRIFX=REDIS_USERS_PRIFX
    	//@Value,获取配置文件中相关参数的值
    	@Value("${REDIS_USERS_PRIFX}")
    	private String REDIS_USERS_PRIFX;
    	
    	@Override
    	public Users findByUserid(int userid) {
    		
    		try {
    			//查看缓存
    			String json=this.jedisDao.get(this.REDIS_USERS_PRIFX+":"+userid );//p拼接成json类型字符串key:value
    			//在缓存中是否命中
    			if (json != null && json.length()>0) {//命中
    				System.out.println("-----------------调用查看redis缓存操作--------------------");
    				Users users=JsonUtils.jsonToPojo(json, Users.class);
    				return users;
    			}
    		} catch (Exception e) {//保证不影响功能正常实现,需要用try。。。catch
    			e.printStackTrace();
    		}
    		
    		
    		//查询数据库
    		Users users=this.userMapper.selByUserId(userid);
    		System.out.println(users);
    		System.out.println("==================查询mysql并放入redis缓存=========================");
    		try {
    			//放入redis中
    			String objectToJson = JsonUtils.objectToJson(users);
    			//String redis_Key = this.REDIS_USERS_PRIFX+":"+userid;
    			jedisDao.set(this.REDIS_USERS_PRIFX+":"+userid, objectToJson);
    			jedisDao.expire(this.REDIS_USERS_PRIFX+":"+userid,60);//如果设置失败,最好clean一下
    			//jedisPool.getResource().expire(redis_Key, 1000);
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    
    		return users;
    		
    		
    	}
    	
    }
    
    
    • 扫描配置文件,在application-dao.xml配置文件中添加如下代码
    <!-- 配置解析properties文件的工具类 -->
      <!--   <context:property-placeholder location="classpath:db.properties"/> -->
          <context:property-placeholder location="classpath:resource/*.properties"/> 
    
    • 令redis生效的applicationContext-jedis.xml配置文件
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
    	xmlns:context="http://www.springframework.org/schema/context"
    	xmlns:mvc="http://www.springframework.org/schema/mvc"
    	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
    	<!-- 1、首先配置组件扫描,在这里秩序依赖spring来扫描 -->
    	<!--  <context:component-scan base-package="com.bjsxt.jedisdao.JedisDao"/>  -->
    	
    	<!-- jedisPool的配置 -->
    	<bean id="poolconfig" class="redis.clients.jedis.JedisPoolConfig">
    	        <!-- 最大连接数 -->
    		<property name="maxTotal" value="30" />
    		<!-- 最大空闲连接数 -->
    		<property name="maxIdle" value="10" />
    		<!-- 每次释放连接的最大数目 -->
    		<property name="numTestsPerEvictionRun" value="1024" />
    		<!-- 释放连接的扫描间隔(毫秒) -->
    		<property name="timeBetweenEvictionRunsMillis" value="30000" />
    		<!-- 连接最小空闲时间 -->
    		<property name="minEvictableIdleTimeMillis" value="1800000" />
    		<!-- 连接空闲多久后释放, 当空闲时间>该值 且 空闲连接>最大空闲连接数 时直接释放 -->
    		<property name="softMinEvictableIdleTimeMillis" value="10000" />
    		<!-- 获取连接时的最大等待毫秒数,小于零:阻塞不确定的时间,默认-1 -->
    		<property name="maxWaitMillis" value="1500" />
    		<!-- 在获取连接的时候检查有效性, 默认false -->
    		<property name="testOnBorrow" value="true" />
    		<!-- 在空闲时检查有效性, 默认false -->
    		<property name="testWhileIdle" value="true" />
    		<!-- 连接耗尽时是否阻塞, false报异常,ture阻塞直到超时, 默认true -->
    		<property name="blockWhenExhausted" value="false" />
    		
    	</bean>
    	
    	<!-- 3、配置JedisPool -->
    	<bean id="jedisPool" class="redis.clients.jedis.JedisPool">
    		<constructor-arg name="poolConfig">
    			<ref bean="poolconfig"></ref>
    		</constructor-arg>
    		<constructor-arg name="host">
    			<value>192.168.179.131</value>
    		</constructor-arg>
    		<constructor-arg name="port">
    			<value>6379</value>
    		</constructor-arg>
    	</bean>
    	<!-- 2、springJedisDaoSingleImpl -->
    	 <bean id="jedisDaoSingleImpl" class="com.bjsxt.jedisdao.impl.JedisDaoSingleImpl"></bean> 
    	
    	<!-- a、配置JedisCluster -->
    	<bean id="jedisCluster" class="redis.clients.jedis.JedisCluster">
    		<constructor-arg name="nodes">
    			<set>
    				<bean name="hostAndPort" class="redis.clients.jedis.HostAndPort">
    					<constructor-arg name="host">
    						<value>192.168.179.131</value>
    					</constructor-arg>
    					<constructor-arg name="port">
    						<value>8001</value>
    					</constructor-arg>
    				</bean>
    				<bean name="hostAndPort" class="redis.clients.jedis.HostAndPort">
    					<constructor-arg name="host">
    						<value>192.168.179.131</value>
    					</constructor-arg>
    					<constructor-arg name="port">
    						<value>8002</value>
    					</constructor-arg>
    				</bean>
    				<bean name="hostAndPort" class="redis.clients.jedis.HostAndPort">
    					<constructor-arg name="host">
    						<value>192.168.179.131</value>
    					</constructor-arg>
    					<constructor-arg name="port">
    						<value>8003</value>
    					</constructor-arg>
    				</bean>
    				<bean name="hostAndPort" class="redis.clients.jedis.HostAndPort">
    					<constructor-arg name="host">
    						<value>192.168.179.131</value>
    					</constructor-arg>
    					<constructor-arg name="port">
    						<value>8004</value>
    					</constructor-arg>
    				</bean>
    				<bean name="hostAndPort" class="redis.clients.jedis.HostAndPort">
    					<constructor-arg name="host">
    						<value>192.168.179.131</value>
    					</constructor-arg>
    					<constructor-arg name="port">
    						<value>8005</value>
    					</constructor-arg>
    				</bean>
    				<bean name="hostAndPort" class="redis.clients.jedis.HostAndPort">
    					<constructor-arg name="host">
    						<value>192.168.179.131</value>
    					</constructor-arg>
    					<constructor-arg name="port">
    						<value>8006</value>
    					</constructor-arg>
    				</bean>
    				
    			</set>
    			
    		</constructor-arg>
    		<constructor-arg name="poolConfig">
    			<ref bean="poolconfig"></ref>
    		</constructor-arg>
    	</bean>
    	<!-- 配置JedisDaoClusterImpl -->
    	<!-- 	<bean id="jedisDaoClusterImpl" class="com.bjsxt.jedisdao.impl.JedisDaoClusterImpl"></bean> -->
    </beans>
    

    运行效果

    第一次查询id为1的用户
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    第二次查询id为1的用户(相当于刷新页面)
    在这里插入图片描述
    修改数据:

    在这里插入图片描述
    redis客户端显示的结果
    在这里插入图片描述

    项目源码~~~
    链接:https://pan.baidu.com/s/1Bat7QS6akuSF4k6MprIFiw
    提取码:z23d
    复制这段内容后打开百度网盘手机App,操作更方便哦

    展开全文
  • redis.hostname=Redis所在服务器ip redis.port=6379 redis.database=0 redis.pool.maxActive=100 redis.pool.maxIdle=20 redis.pool.maxWait=3000 redis.pool.testOnBorrow=true
  • springboot中使用redis的案例

    千次阅读 2022-03-27 15:22:54
    springboot调用redis的步骤

    1. application.properties中配置redis

    #设置Redis配置
    spring.redis.host=******
    spring.redis.port=6379
    spring.redis.password=******
    

    2. pom.xml中

    <!--        springboot集成Redis的依赖-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-redis</artifactId>
                <version>2.6.4</version>
            </dependency>
    

    3. StudentServiceImpl.java中

    public class StudentServiceImpl implements StudentService {
        @Autowired
        private RedisTemplate<Object,Object> redisTemplate;
        @Autowired
        private StudentMapper studentMapper;
    	@Override
        public Integer queryAllStudentCount() {
    
            //为提升系统性能和用户体验
            //首先在Redis缓存中查询,如果有,直接使用;如果没有,去数据库查询并放入redis缓存
            Integer allStudentCount = (Integer) redisTemplate.opsForValue().get("allStudentCount");
    
            if (null == allStudentCount) {
                //去数据库查询
                allStudentCount = studentMapper.selectAllStudentCount();
                //并放入redis缓存
                redisTemplate.opsForValue().set("allStudentCount", allStudentCount, 30, TimeUnit.SECONDS);
            }
    
            return allStudentCount;
        }
    

    其他

    其他部分该怎么写还怎么写!!!

    展开全文
  • 一个普通java工程, springboot、dubbo、zookeeper、redis、MQ、mybatis、druid、swagger 项目实例
  • Redis使用实例

    2015-09-22 11:12:47
    代码都是我自己测试过的,已经放在我的项目中了,解压之后可以使用。
  • Spring Boot中除了对常用的关系型数据库提供了优秀的自动化支持之外,对于很多NoSQL数据库一样提供了自动化配置的支持。本篇文章主要介绍了Spring Boot中Redis的使用实例代码,有兴趣的开业了解一下。
  • Redis 实战案例总结

    千次阅读 2018-12-05 11:22:28
    Redis 基础 Redis的n种妙用,不仅仅是缓存 ...多线程实现项目初始化完成大规模数据写入redis缓存 redis 集群配置实现 16个Redis常见使用场景总结 Redis 实战篇:巧用数据类型实现亿级数据统计 ...
  • java 对redis各类型的操作,maven管理项目
  • Redis单机多实例集群部署

    千次阅读 2020-03-11 23:25:27
    一、安装redis单节点 官网下载二进制源码包安装,包里面为预编译过的,解压后可以直接二进制安装: [root@localhost ~]# tar -zxf redis [root@localhost ~]# cd redis [root@localhost ~]# make && make ...
  • 本篇文章主要介绍了Spring Boot项目利用Redis实现session管理实例,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
  • 主要给大家介绍了关于Redis在Laravel项目中应用的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用laravel具有一定的参考学习价值,需要的朋友们下面跟着小编来一起学习学习吧。
  • 一个redis实例默认有16个数据库,但一般来说不同的项目用不同的redis实例会比较好,以免有的操作影响到其它的项目。 拷贝一份新的配置文件 cp redis.conf redis6379.conf vim修改对应的配置项 vim redis6378.conf ...
  • php之redis的应用实例

    2021-04-13 11:44:27
    本文主要和大家分享php之redis的应用实例,主要以代码的形式和大家分享,希望能帮助到大家。
  • redis项目中的应用 ps:PHP 会自动 关redis连接 不需要手动关 对于临时的数据 可以不经过数据库直接redis上操作 /*消息队列实例 */ public function insertinfo(){ //连接本地的 Redis 服务 $redis = new \...
  • redis的详细安装说明以及javaweb项目集成实例
  • 在实际的项目中,可能一个项目需要操作多个redis的数据,那么我们就需要做相应的配置 首先在我们项目的 application.proterties中添加如下配置。有几个就写几个。 注意这里的命名: spring.redis开头是springboot ...
  • 本篇文章主要介绍了Spring Boot项目利用Redis实现集中式缓存实例,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
  • redis由于其高并发和高性能常被用于缓存 配置时常常会遇到一些问题。 正常情况下,访问应该如下展示: 第一次访问页面 再次刷新上次访问页面,会出现如下页面 mysql 变为redis 但在配置过程中常常出现,...
  • 以下主要讲解单机多实例的部署方法,所谓单机多实例也就是你也不用麻麻烦烦部署多次来实现一台服务器上多个redis。 一、前置条件 首先需要一套已经部署好了的redis,参考上边的单节点redis部署方法。 二、...
  • (1)停掉项目,停止对redis实例的数据写入。 (2)登录单实例redis客户端通过命令keys *查看当前单实例缓存的所有数据条数,记录下来。 (3)假如单实例redis同时开启了RDB和AOF,只要AOF文件就可以了,因为当...
  • Spring boot+redis+rabbitMq实例整合的简单例子,可用来参考学习
  • redis实例

    千次阅读 2019-11-16 16:32:11
    文章目录启动连接redis导入依赖java连接redisjava 操作 redis使用redis优化简答的mvc项目1.需要导入夹包(jedis 和 fastjosn)2.查询和修改思路图解 启动连接redis 通过此命令启动redis服务直到出现pong ./src/redis-...
  • redis应用场景及实例

    2020-12-08 14:39:30
    redis应用场景及实例 前言 Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。在这篇文章中,我们将阐述 Redis 最常用的使用场景,以及那些...
  • Redis在java中的使用示例,里面写了对4种类型的具体使用:string、list、set、hash

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 75,336
精华内容 30,134
关键字:

redis项目实例