您好,欢迎访问代理记账网站
移动应用 微信公众号 联系我们

咨询热线 -

电话 15988168888

联系客服
  • 价格透明
  • 信息保密
  • 进度掌控
  • 售后无忧

java操作redis

一:使用普通Maven项目整合redis

在使用maven整合jedis之前,首先要保证redis部署的虚拟机的防火墙是关闭的状态,否则会连接不上redis。

1.加入jedis依赖

<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>3.6.0</version>
</dependency>

2.创建jedis对象

创建jedis对象的时候,需要传入两个参数,分别是redis部署的IP地址和redis的端口号。

Jedis jedis = new Jedis("192.168.116.29",6379);

 3.使用jedis进行写入和读取操作

使用jedis执行的方法跟我们直接使用redis命令是一样的

jedis.set("jedis01","1");
jedis.set("jedis02","2");
/**
 * 获取所有的key
 */
Set<String> keys = jedis.keys("*");
for (String key : keys) {
    System.out.println(key);
}

HashMap map = new HashMap();
map.put("name","zs");
map.put("age","20");
map.put("sex","nan");
jedis.hset("user",map);
Map<String, String> user = jedis.hgetAll("user");
System.out.println(user);

二:springboot整合redis

1.创建springboot项目

在创建springboot项目的时候,选择引入两个依赖,一个是spring web,一个是spring date redis,这样我们就不需要手动去添加依赖

2.修改配置文件

在springboot的配置文件中,指定连接的redis的ip地址和端口号

# 配置redis
spring.redis.host=192.168.116.29
spring.redis.port=6379

3.使用StringRedisTemplate模板执行对redis的操作 

springboot提供了一个StringRedisTemplate类,这个类可以用来执行对redis的读写操作,通过StringRedisTemplate 对象获取到 ValueOperations 对象,再通过 ValueOperations 对象执行对redis的读写,使用的方法与原本redis命令不相同。

①执行对Sting类型的数据操作

// 获取操作String类型的对象
ValueOperations<String, String> opsForValue = stringRedisTemplate.opsForValue();
opsForValue.set("opsForValue","1");
String value = opsForValue.get("opsForValue");
System.out.println(value);
Set<String> keys = stringRedisTemplate.keys("*");
for (String key : keys) {
    System.out.println(key);
}
// ValueOperations对象没有setnx方法,但是有 setIfAbsent 方法,
// 相当于setnx,会返回一个boolean类型数据,true就是写入成功,false就是写入失败
Boolean ifAbsent = opsForValue.setIfAbsent("opsForValue", "2");
System.out.println(ifAbsent);
// 一次写入多个key value,在redis命令中是mset,ValueOperations 对象是使用multiSet方法
Map map = new HashMap();
map.put("name","lisi");
map.put("age","20");
opsForValue.multiSet(map);

②执行对Hash类型数据的操作

HashOperations<String, Object, Object> opsForHash = stringRedisTemplate.opsForHash();
// 执行redis命令中的hset
opsForHash.put("hash1","name","zs");
opsForHash.put("hash1","age","20");
// 执行hget key filed 获取某个key中的每一列值
Object o = opsForHash.get("hash1", "name");
System.out.println(0);
// 获取key中的所有列
System.out.println(opsForHash.keys("hash1"));
// 获取key中的所有value
System.out.println(opsForHash.values("hash1"));
// 获取key中的所有列何其对应的value
System.out.println(opsForHash.entries("hash1"));

4.使用RedisTemplate模板执行对redis的操作

springboot提供了一个RedisTemplate类,这个类可以用来执行对redis的读写操作,通过StringRedisTemplate 对象获取到 ValueOperations 对象,再通过 ValueOperations 对象执行对redis的读写,使用的方法与原本redis命令不相同。 

RedisTemplate类和StringRedisTemplate类不同的是,使用RedisTemplate类执行的操作需要对数据进行序列化,如果不指定则是默认使用jdk序列化。

①执行对Sting类型的数据操作

/**
 * RedisTemplate默认会使用JDK序列化方式对我们set的key和value进行序列化
 * 将序列化后的值存入redis中,所以当我们不手动指定序列化的方式的时候
 * 如果想要将对象存入到redis中,需要将实体类实现 Serializable 接口。
 * 并且经过jdk序列化的数据可能会产生乱码,能存入redis,但是无法进行读取。
 * 所以通常情况下,我们一般都要手动指定RedisTemplate序列化的方式。
 * 这样实体类不用实现接口,并且存入redis的数据更小
 */
// 设置String类型数据key的序列化方式
redisTemplate.setKeySerializer(new StringRedisSerializer());
// 设置String类型数据value的序列化方式
redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
ValueOperations opsForValue = redisTemplate.opsForValue();
User user = new User();
user.setName("张三");
user.setPhone("152515151");
user.setAge(20);
opsForValue.set("redistemplate",user);
System.out.println(opsForValue.get("redistemplate"));

②执行对hash类型数据的操作

// 设置Hash类型数据key的序列化方式
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
// 设置Hash类型数据value的序列化方式
redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
HashOperations opsForHash = redisTemplate.opsForHash();
// 执行hset操作
opsForHash.put("hash2","name","李思");
opsForHash.put("hash2","age","80");
// 获取key中的所有列和对应的value
System.out.println(opsForHash.entries("hash2"));

三:使用springboot连接redis集群

因为redis在虚拟机上部署的有哨兵模式和集群模式,所以使用springboot连接redis集群可以连接哨兵的集群也可以连接redis主节点的集群。连接的不一样,配置文件的形式也不相同。

哨兵模式:

# 哨兵模式
# 第一个是在redis的哨兵配置文件中,给哨兵声明的名称
# spring.redis.sentinel.master=mymaster
# 第二个是哨兵部署的ip地址以及哨兵的端口号
# spring.redis.sentinel.nodes=192.168.116.29:26379

注意:在配置哨兵模式的时候,修改的哨兵配置文件中,会指定哨兵要监听的主节点的ip地址以及端口号,这里主节点的ip地址,就算监听的redis在本地也不能写成127.0.0.1,应该写具体的ip地址

集群模式:

# 这里写的是redis集群的所有主节点以及从节点的ip地址和端口号,主节点写前,从节点写后
spring.redis.cluster.nodes=192.168.116.29:6370,192.168.116.29:6380,192.168.116.29:6390,192.168.116.29:6371,192.168.116.29:6381,192.168.116.29:6391

在虚拟机上开启redis集群的所有服务,登录客户端,set key value 测试集群是否可用

编写代码测试能否进行读写

@Autowired
private RedisTemplate redisTemplate;
@RequestMapping("/test")
private Object doTest() {
    redisTemplate.setKeySerializer(new StringRedisSerializer());
    redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
    ValueOperations opsForValue = redisTemplate.opsForValue();
    opsForValue.set("集群测试","测试插入");
    Set<String> keys = redisTemplate.keys("*");
    for (String key : keys) {
        System.out.println(key);
    }
    return "成功";
}

四:使用redis当缓存

缓存是为了减少程序与数据库之间的访问而产生的,因为如果程序对数据进行访问的操作是需要大量资源和时间的,如果每次查询都去数据库中查找数据,这样对于程序的性能是一种很大的影响。所以我们一般将查询频率较高的数据存放在缓存中,当我们需要进行查询的时候,先去缓存中查找,如果查询到,就直接取出,无需在进行与数据库的交互。如果未查询导数据,再去数据库中进行查找,并且将结果取出,放入换存中,这样如果有第二次查询同样的数据时,就可以直接从缓存中取出。

程序执行流程:

①用户发出请求=====》后端业务层先去redis中查询是否有数据,有数据=====》直接返回用户。

①用户发出请求=====》后端业务层先去redis中查询是否有数据,五数据=====》去mysql数据库中进行查找=====》将查询出的数据存入redis中=====》将结果返回给用户

controller层

package com.hyn.springbootredis.controller;

import com.hyn.springbootredis.entity.User;
import com.hyn.springbootredis.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


@RestController
public class UserController {

    @Autowired
    private UserService userService;

    @RequestMapping("/login")
    private String doLogin(User user) {

        User queryUser = userService.doLogin(user);
        if (queryUser!=null) {
            return "成功";
        } else {
            return "失败";
        }
    }
}

service层

package com.hyn.springbootredis.service.impl;

import com.hyn.springbootredis.dao.UserDao;
import com.hyn.springbootredis.entity.User;
import com.hyn.springbootredis.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserDao userDao;
    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public User doLogin(User user) {

        // 设置key的序列化
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        // 设置value的序列化
        redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());

        ValueOperations opsForValue = redisTemplate.opsForValue();
        // 先判断redis中是否有数据
        User redisUser = (User) opsForValue.get("user::findById::" + user.getId());
        if (redisUser!=null) {
            System.out.println("redis中有数据");
            return redisUser;
        } else {
            // 如果没有数据,从mysql中查询,并存入redis
            User mysqlUser = userDao.selectById(user.getId());
            System.out.println("redis中无数据,从mysql中查询");
            // 存入redis
            if (mysqlUser!=null) {
                opsForValue.set("user::findById::"+mysqlUser.getId(),mysqlUser);
                System.out.println("将数据写入redis");
                // 将user返回
                return mysqlUser;
            }
        }
        return null;
    }
}

结果:

再次查询redis中已经有的数据,没有从数据库中进行查找


分享:

低价透明

统一报价,无隐形消费

金牌服务

一对一专属顾问7*24小时金牌服务

信息保密

个人信息安全有保障

售后无忧

服务出问题客服经理全程跟进