准备工作

1.Linux系统

2.安装redis(也可以安装docker,然后再docker中装redis,本文章就直接用Linux安装redis做演示)

  redis下载地址:http://download.redis.io/releases/redis-4.0.14.tar.gz

修改redis,开启远程访问

找到redis中的redis.conf文件并编辑(在安装路径中找到)

vim ./redis.conf

1、找到bind 127.0.0.1并注释掉

  默认127.0.0.1只能本地访问,注释掉即可ip访问

2、修改 protected-mode 属性值为no

  注释掉并把保护模式禁用以后可以IP访问

3、修改daemonize属性将no 改为yes

  将daemonize设置为yes即启动后台运行

4、开放6379端口

/sbin/iptables -I INPUT -p tcp --dport 6379 -j ACCEPT

  默认不对外开放6379

5、启动redis

redis-server /myconf/redis.conf

  redis-server默认在/usr/local/bin路径下,redis.conf在redis的安装路径下

6、测试连接

redis-cli -h 192.168.126.129 -p 6379

  redis-cli -h redis服务器IP -p 6379 -a 密码(没有设置redis密码不要写空,否则报错)

Java代码编写

目录结构

项目源码结构

一个user表

代码

pom.xml文件(可以根据自己的需要来添加或修改)

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency> <!-- mybatis 与 spring boot 2.x的整合包 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency> <!--mysql JDBC驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.39</version>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
</dependencies>

 下面是springboot的配置文件application.yml,配置redis(里面都有注释解释)

server:
port: 8081 #数据库连接
spring:
datasource:
url: jdbc:mysql://localhost:3306/mytest_springboot_cache?useUnicode=true
driver-class-name: com.mysql.jdbc.Driver
username: root
password: lzh ## Redis 配置
redis:
## Redis数据库索引(默认为0)
database: 0
## Redis服务器地址
host: 192.168.126.129
## Redis服务器连接端口
port: 6379
## Redis服务器连接密码(默认为空)
password:
jedis:
pool:
## 连接池最大连接数(使用负值表示没有限制)
#spring.redis.pool.max-active=8
max-active: 8
## 连接池最大阻塞等待时间(使用负值表示没有限制)
#spring.redis.pool.max-wait=-1
max-wait: -1
## 连接池中的最大空闲连接
#spring.redis.pool.max-idle=8
max-idle: 8
## 连接池中的最小空闲连接
#spring.redis.pool.min-idle=0
min-idle: 0
## 连接超时时间(毫秒)
timeout: 1200 #将themilef的默认缓存禁用,热加载生效
thymeleaf:
cache: false #mybatis的下划线转驼峰配置
configuration:
map-underscore-to-camel-case: true #另外一种打印语句的方式
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #打印sql时的语句
logging:
level:
com:
acong:
dao: debug
file: d:/logs/bsbdj.log

 接着是实体类,这个比较简单就不多说了

package com.lzh.springbootstudytest.bean;

import java.io.Serializable;

/**
* @author lzh
* create 2019-09-18-22:32
*/
public class User implements Serializable { private static final long serialVersionUID = 1L;
private int uid;
private String userName;
private String passWord;
private int salary;
public int getUid() {
return uid;
}
public void setUid(int uid) {
this.uid = uid;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassWord() {
return passWord;
}
public void setPassWord(String passWord) {
this.passWord = passWord;
}
public int getSalary() {
return salary;
}
public void setSalary(int salary) {
this.salary = salary;
}
public User(int uid, String userName, String passWord, int salary) {
super();
this.uid = uid;
this.userName = userName;
this.passWord = passWord;
this.salary = salary;
}
public User() {
super();
}
} 

这是controller类,用于暴露接口访问

package com.lzh.springbootstudytest.controller;

import com.lzh.springbootstudytest.bean.User;
import com.lzh.springbootstudytest.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController; import java.util.HashMap;
import java.util.List;
import java.util.Map; /**
* @author lzh
* create 2019-09-18-22:36
*/
@RestController
public class TestController { @Autowired
private UserService userService; @RequestMapping("/queryAll")
public List<User> queryAll(){
List<User> lists = userService.queryAll();
return lists;
} @RequestMapping("/findUserById")
public Map<String, Object> findUserById(@RequestParam int id){
User user = userService.findUserById(id);
Map<String, Object> result = new HashMap<>();
result.put("uid", user.getUid());
result.put("uname", user.getUserName());
result.put("pass", user.getPassWord());
result.put("salary", user.getSalary());
return result;
} @RequestMapping("/updateUser")
public String updateUser(){
User user = new User();
user.setUid(1);
user.setUserName("cat");
user.setPassWord("miaomiao");
user.setSalary(4000); int result = userService.updateUser(user); if(result != 0){
return "update user success";
} return "fail";
} @RequestMapping("/deleteUserById")
public String deleteUserById(@RequestParam int id){
int result = userService.deleteUserById(id);
if(result != 0){
return "delete success";
}
return "delete fail";
}
}

配置redistemplate序列化 

package com.lzh.springbootstudytest.config;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
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.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.*;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer; import java.time.Duration; /**
* @author lzh
* create 2019-09-24-15:07
*/
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport { /**
* 选择redis作为默认缓存工具
* @param redisConnectionFactory
* @return
*/
/*@Bean
//springboot 1.xx
public CacheManager cacheManager(RedisTemplate redisTemplate) {
RedisCacheManager rcm = new RedisCacheManager(redisTemplate);
return rcm;
}*/
@Bean
public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofHours(1)); // 设置缓存有效期一小时
return RedisCacheManager
.builder(RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory))
.cacheDefaults(redisCacheConfiguration).build();
} /**
* retemplate相关配置
* @param factory
* @return
*/
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) { RedisTemplate<String, Object> template = new RedisTemplate<>();
// 配置连接工厂
template.setConnectionFactory(factory); //使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值(默认使用JDK的序列化方式)
Jackson2JsonRedisSerializer jacksonSeial = new Jackson2JsonRedisSerializer(Object.class); ObjectMapper om = new ObjectMapper();
// 指定要序列化的域,field,get和set,以及修饰符范围,ANY是都有包括private和public
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
// 指定序列化输入的类型,类必须是非final修饰的,final修饰的类,比如String,Integer等会跑出异常
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jacksonSeial.setObjectMapper(om); // 值采用json序列化
template.setValueSerializer(jacksonSeial);
//使用StringRedisSerializer来序列化和反序列化redis的key值
template.setKeySerializer(new StringRedisSerializer()); // 设置hash key 和value序列化模式
template.setHashKeySerializer(new StringRedisSerializer());
template.setHashValueSerializer(jacksonSeial);
template.afterPropertiesSet(); return template;
} /**
* 对hash类型的数据操作
*
* @param redisTemplate
* @return
*/
@Bean
public HashOperations<String, String, Object> hashOperations(RedisTemplate<String, Object> redisTemplate) {
return redisTemplate.opsForHash();
} /**
* 对redis字符串类型数据操作
*
* @param redisTemplate
* @return
*/
@Bean
public ValueOperations<String, Object> valueOperations(RedisTemplate<String, Object> redisTemplate) {
return redisTemplate.opsForValue();
} /**
* 对链表类型的数据操作
*
* @param redisTemplate
* @return
*/
@Bean
public ListOperations<String, Object> listOperations(RedisTemplate<String, Object> redisTemplate) {
return redisTemplate.opsForList();
} /**
* 对无序集合类型的数据操作
*
* @param redisTemplate
* @return
*/
@Bean
public SetOperations<String, Object> setOperations(RedisTemplate<String, Object> redisTemplate) {
return redisTemplate.opsForSet();
} /**
* 对有序集合类型的数据操作
*
* @param redisTemplate
* @return
*/
@Bean
public ZSetOperations<String, Object> zSetOperations(RedisTemplate<String, Object> redisTemplate) {
return redisTemplate.opsForZSet();
}
}

接着是Mapper持久层Dao,这里主要用注解写比较方便,也可以使用mybatis的xml配置文件写sql语句

package com.lzh.springbootstudytest.mapper;

import com.lzh.springbootstudytest.bean.User;
import org.apache.ibatis.annotations.*; import java.util.List; /**
* @author lzh
* create 2019-09-18-22:32
*/
@Mapper
public interface UserDao { @Select("select * from user")
List<User> queryAll(); @Select("select * from user where uid = #{id}")
User findUserById(int id); @Update("UPDATE USER SET username = CASE WHEN (#{userName} != NULL) AND (#{userName} != '') THEN #{userName},PASSWORD = CASE WHEN (#{passWord} != NULL) AND (#{passWord} != '') THEN #{passWord},salary = CASE WHEN (#{salary} != 0) THEN #{salary} WHERE uid = #{uid}")
int updateUser(@Param("user") User user); @Delete("delete from user where uid = #{id}")
int deleteUserById(int id); }

 service层,这里主要是使用redis模板来写

package com.lzh.springbootstudytest.service;

import com.lzh.springbootstudytest.bean.User;
import com.lzh.springbootstudytest.mapper.UserDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service; import java.util.List;
import java.util.concurrent.TimeUnit; /**
* @author lzh
* create 2019-09-18-22:33
*/
@Service
public class UserService { @Autowired
private UserDao userDao; @Autowired
private RedisTemplate redisTemplate; public List<User> queryAll() {
return userDao.queryAll();
} /**
* 获取用户策略:先从缓存中获取用户,没有则取数据表中 数据,再将数据写入缓存
*/
public User findUserById(int id) {
String key = "user_" + id; ValueOperations<String, User> operations = redisTemplate.opsForValue(); //判断redis中是否有键为key的缓存
boolean hasKey = redisTemplate.hasKey(key); if (hasKey) {
User user = operations.get(key);
System.out.println("从缓存中获得数据:"+user.getUserName());
System.out.println("------------------------------------");
return user;
} else {
User user = userDao.findUserById(id);
System.out.println("查询数据库获得数据:"+user.getUserName());
System.out.println("------------------------------------"); // 写入缓存
operations.set(key, user, 5, TimeUnit.HOURS);
return user;
}
} /**
* 更新用户策略:先更新数据表,成功之后,删除原来的缓存,再更新缓存
*/
public int updateUser(User user) {
ValueOperations<String, User> operations = redisTemplate.opsForValue();
int result = userDao.updateUser(user);
if (result != 0) {
String key = "user_" + user.getUid();
boolean haskey = redisTemplate.hasKey(key);
if (haskey) {
redisTemplate.delete(key);
System.out.println("删除缓存中的key-----------> " + key);
}
// 再将更新后的数据加入缓存
User userNew = userDao.findUserById(user.getUid());
if (userNew != null) {
operations.set(key, userNew, 3, TimeUnit.HOURS);
}
}
return result;
} /**
* 删除用户策略:删除数据表中数据,然后删除缓存
*/
public int deleteUserById(int id) {
int result = userDao.deleteUserById(id);
String key = "user_" + id;
if (result != 0) {
boolean hasKey = redisTemplate.hasKey(key);
if (hasKey) {
redisTemplate.delete(key);
System.out.println("删除了缓存中的key:" + key);
}
}
return result;
} } 

  

  这里主要是使用RedisTemplate来对远程redis操作,每次访问controller暴露的接口,首先判断redis缓存中是否存在该数据,若不存在就从数据库中读取数据,然后保存到redis缓存中,当下次访问的时候,就直接从缓存中取出来。这样就不用每次都执行sql语句,能够提高访问速度。 但是在保存数据到缓存中,通过设置键和值和超时删除,注意设置超时删除缓存时间不要太长,否则会给服务器带来压力。

执行spring boot的启动类,访问http://localhost:8081/findUserById?id=1

再次访问http://localhost:8081/findUserById?id=1就是从缓存中获取保存的数据

SpringBoot整合redis缓存(一)的更多相关文章

  1. SpringBoot 整合 Redis缓存

    在我们的日常项目开发过程中缓存是无处不在的,因为它可以极大的提高系统的访问速度,关于缓存的框架也种类繁多,今天主要介绍的是使用现在非常流行的NoSQL数据库(Redis)来实现我们的缓存需求. Spr ...

  2. springboot整合redis缓存

    使用springBoot添加redis缓存需要在POM文件里引入 org.springframework.bootspring-boot-starter-cacheorg.springframewor ...

  3. springboot整合redis缓存一些知识点

    前言 最近在做智能家居平台,考虑到家居的控制需要快速的响应于是打算使用redis缓存.一方面减少数据库压力另一方面又能提高响应速度.项目中使用的技术栈基本上都是大家熟悉的springboot全家桶,在 ...

  4. SpringBoot缓存管理(二) 整合Redis缓存实现

    SpringBoot支持的缓存组件 在SpringBoot中,数据的缓存管理存储依赖于Spring框架中cache相关的org.springframework.cache.Cache和org.spri ...

  5. SpringBoot入门系列(七)Spring Boot整合Redis缓存

    前面介绍了Spring Boot 中的整合Mybatis并实现增删改查,.不清楚的朋友可以看看之前的文章:https://www.cnblogs.com/zhangweizhong/category/ ...

  6. springBoot整合redis(作缓存)

    springBoot整合Redis 1,配置Redis配置类 package org.redislearn.configuration; import java.lang.reflect.Method ...

  7. SpringBoot整合Redis、mybatis实战,封装RedisUtils工具类,redis缓存mybatis数据 附源码

    创建SpringBoot项目 在线创建方式 网址:https://start.spring.io/ 然后创建Controller.Mapper.Service包 SpringBoot整合Redis 引 ...

  8. Redis-基本概念、java操作redis、springboot整合redis,分布式缓存,分布式session管理等

    NoSQL的引言 Redis数据库相关指令 Redis持久化相关机制 SpringBoot操作Redis Redis分布式缓存实现 Resis中主从复制架构和哨兵机制 Redis集群搭建 Redis实 ...

  9. SpringBoot整合Redis、ApachSolr和SpringSession

    SpringBoot整合Redis.ApachSolr和SpringSession 一.简介 SpringBoot自从问世以来,以其方便的配置受到了广大开发者的青睐.它提供了各种starter简化很多 ...

随机推荐

  1. 解决Mac下VSCode打开zsh乱码

    1.乱码问题 iTerm2终端使用Zsh,并且配置Zsh主题,该主题主题需要安装字体来支持箭头效果,在iTerm2中设置这个字体,但是VSCode里这个箭头还是显示乱码. iTerm2展示如下: VS ...

  2. net core Webapi基础工程搭建(六)——数据库操作_Part 2

    目录 前言 开始 使用 小结 前言 昨天是写着写着发现,时间不早了,已经养成了晚上下班抽时间看看能写点儿啥的习惯(貌似),今天实在是不想让昨天没做完的事情影响,所以又坐下,沉下心(周末了),开始把数据 ...

  3. Selenium + python 测试环境搭建扩展-HTMLUNIT的使用

    尝试给公司的网站写每日例行检查的脚本时,不需要去打开浏览器,这是就用到HTMLUNIT的使用 HTMLUNIT是基于Selenium服务端的,所以需要selenium-server-standalon ...

  4. import 和from…import

    import 和from-import 一.import模块名 import time print(time.time()) import首次导入模块发生了3件事: 使用import time导入的时 ...

  5. 利用ShardingSphere-JDBC实现分库分表

    利用ShardingSphere-JDBC实现分库分表 1. ShardingSphere概述 1.1 概述 业务发展到一定程度,分库分表是一种必然的要求,分库可以实现资源隔离,分表则可以降低单表数据 ...

  6. 2019牛客暑期多校训练营(第十场)J - Wood Processing (斜率优化DP)

    >传送门< 题意 $n$个宽度为$w_{i}$,高为$h_{i}$ 的 木块,要求分成$k$组,对于每组内的所有木块,高度都变为组内最低木块的高度,宽度保持不变,求变化的最小面积. 分析 ...

  7. Java中访问修饰符public、private、protecte、default

    Java中访问修饰符public.private.protecte.default的意义讲解:public: Java语言中访问限制最宽的修饰符,一般称之为“公共的”.被其修饰的类.属性以及方法不 仅 ...

  8. springBoot框架分布式部署定时任务重复执行之解决方案

    问题描述: 在集群模式部署服务端时,会出现所有的定时任务在各自的节点处均会执行一遍,这显然不符合实际的开发场景,针对这种问题,本文给出一种springboot集成shedlock的解决方案 第一步:引 ...

  9. python实例:利用jieba库,分析统计金庸名著《倚天屠龙记》中人物名出现次数并排序

    本实例主要用到python的jieba库 首先当然是安装pip install jieba 这里比较关键的是如下几个步骤: 加载文本,分析文本 txt=open("C:\\Users\\Be ...

  10. RANSAC简史

    前言 在进行泡泡机器人[图灵智库]栏目的翻译的过程中,我发现在2018-2019的顶会中,依然有很多文章(我看到的不少于6篇)对RANSAC进行各种改进,这令我感到很吃惊.毕竟该方法在1981年就被提 ...