Redis在Java中的使用(三)

五、Jedis(Java中使用Redis)

使用Java来操作Redis,Jedis是Redis官方推荐使用的Java连接redis的客户端

1 导入依赖

<!--导入jredis的包-->
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>3.2.0</version>
</dependency>
<!--fastjson-可以使用JSONObject -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.70</version>
</dependency>

2 测试连通

修改配置文件/etc/redis.conf

  • 设置可远程访问,注释掉bind,#bind 127.0.0.1 -::1 ,可远程访问
  • 设置保护模式为no,protected-mode no
  • 防火墙要关闭,systemctl stop firewalld.service
public static void main(String[] args) {
    //创建Jedis对象
    Jedis jedis = new Jedis("192.168.0.106", 6379);
    //测试
    System.out.println(jedis.ping());//输出pong
}

3 API命令使用

//String操作
System.out.println(jedis.set("username","jack"));
System.out.println(jedis.set("password","1234"));
System.out.println(jedis.keys("*"));
//Hash操作
Jedis jedis = new Jedis("192.168.0.106", 6379);
Map<String,String> maps = new HashMap<String,String>();
maps.put("user","jack");
maps.put("pwd","12345");

jedis.hmset("hash",maps); //批量添加
jedis.hset("hash","newpwd","1122"); //添加一条
System.out.println(jedis.hgetAll("hash")); //{pwd=12345, user=jack, newpwd=1122}

4 补充JSONObject()方法

//1.通过原生生成json数据格式。
JSONObject jsonObject = new JSONObject();
jsonObject.put("user","jack");
jsonObject.put("pwd","12345");
System.out.println(jsonObject.toJSONString());//输出:{"pwd":"12345","user":"jack"}

//3.通过实体生成 
Student student = new Student();
student.setId(1); student.setAge("20"); student.setName("张三");
//生成json格式
System.out.println(JSON.toJSON(student));
//对象转成string
String stuString = JSONObject.toJSONString(student);

5 事务(重要)

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

//产生数据
JSONObject jsonObject = new JSONObject();
jsonObject.put("user","jack");
jsonObject.put("pwd","12345");

//开启事务
Transaction multi = jedis.multi();
String str = jsonObject.toJSONString();
//监控
//jedis.watch(str);
try {
    multi.set("user1",str);
    multi.set("user2",str);
    multi.exec(); //可能失败
} catch (Exception e) { //事务失败
    multi.discard(); //放弃事务
    e.printStackTrace();
} finally {
    System.out.println(jedis.get("user1"));
    System.out.println(jedis.get("user2"));
    jedis.close(); //关闭
}

六、SpringBoot整合

简介

springboot 2.x后 ,原来使用的 Jedis 被 lettuce 替换。

jedis:采用的直连,多个线程操作的话,是不安全的。如果要避免不安全,使用jedis pool连接池!更像BIO模式
lettuce:采用netty,实例可以在多个线程中共享,不存在线程不安全的情况!可以减少线程数据了,更像NIO模式

我们在学习SpringBoot自动配置的原理时,整合一个组件并进行配置一定会有一个自动配置类xxxAutoConfiguration,并且在spring.factories中也一定能找到这个类的完全限定名。
Redis也不例外,存在一个RedisProperties类

RedisAutoConfiguration只有两个简单的Bean,分别是RedisTemplate、StringRedisTemplate
通过使用这些Template来间接操作组件。分别用于操作RedisRedis中的String数据类型

在RedisTemplate上也有一个条件注解,说明我们是可以对其进行定制化的

说完这些,我们需要知道如何编写配置文件然后连接Redis,就需要阅读RedisProperties
在这里插入图片描述

1 导入依赖

创建SpringBoot项目时不要乱选默认开发工具,有一个坑

<!--pom中已有-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

2 编写配置文件

# 配置redis
spring.redis.host=192.168.0.106
spring.redis.port=6379
#集群

3 使用RedisTemplate

@SpringBootTest
class Redis02SpringbootApplicationTests {
    @Autowired
    private RedisTemplate redisTemplate;
    @Test
    void contextLoads() {
        // redisTemplate 操作不同的数据类型,api和我们的指令是一样的
        // opsForValue 操作字符串 类似String
        // opsForList 操作List 类似List
        // 除了基本的操作,我们常用的方法都可以直接通过redisTemplate操作,比如事务和基本的CRUD

        // 获取连接对象
        //RedisConnection connection = redisTemplate.getConnectionFactory().getConnection();
        //connection.flushDb();
        //connection.flushAll();

        redisTemplate.opsForValue().set("mykey","jack");
        System.out.println(redisTemplate.opsForValue().get("mykey"));
    }
}

redisTemplate.opsForValue().set("mykey","张三"); //可能乱码

这时候就关系到存储对象的序列化问题,在网络中传输的对象也是一样需要序列化,否者就全是乱码。

默认的RedisTemplate内部有几个关于序列化的参数,默认的序列化器是采用JDK序列化器

4 定制RedisTemplate的模板(开发中常用)

@ConditionalOnMissingBean注解后,就知道如果Spring容器中有了RedisTemplate对象了,这个自动配置的RedisTemplate不会实例化。因此我们可以直接自己写个配置类,配置RedisTemplate。

创建一个Bean加入容器,就会触发RedisTemplate上的条件注解使默认的RedisTemplate失效。

com/yu/config/RedisConfig

@Configuration
public class RedisConfig {
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
        // 将template 泛型设置为 <String, Object>
        RedisTemplate<String, Object> template = new RedisTemplate();
        // 连接工厂,不必修改
        template.setConnectionFactory(redisConnectionFactory);
        /*
         * 序列化设置
         */
        // key、hash的key 采用 String序列化方式
        template.setKeySerializer(RedisSerializer.string());
        template.setHashKeySerializer(RedisSerializer.string());
        ///////////////////
        // value、hash的value 采用 Jackson 序列化方式
        template.setValueSerializer(RedisSerializer.json());
        template.setHashValueSerializer(RedisSerializer.json());
        template.afterPropertiesSet();

        return template;
    }
}

5 使用测试

只要实体类进行了序列化,我们存什么都不会有乱码的担忧了。

//开发中都是序列化
public class User implements Serializable {
    private String name;
    private int age;
}
@Autowired
@Qualifier("redisTemplate")
private RedisTemplate redisTemplate; //使用自定义RedisTemplate

@Test
void contextLoads() {
    User user = new User("小明", 12); //pojo

    redisTemplate.opsForValue().set("key1",user);
    System.out.println(redisTemplate.opsForValue().get("key1"));
}

七、自定义Redis工具类

使用RedisTemplate需要频繁调用.opForxxx然后才能进行对应的操作,这样使用起来代码效率低下,
工作中一般不会这样使用,而是将这些常用的公共API抽取出来封装成为一个工具类,然后直接使用工具类来间接操作Redis,不但效率高并且易用。

redis工具类:

https://www.cnblogs.com/zhzhlong/p/11434284.html

测试:

@Autowired
@Qualifier("redisTemplate")
private RedisTemplate redisTemplate;

@Autowired
private RedisUtil redisUtil;

@Test
void test1(){
    redisUtil.set("name","hellojack");
    System.out.println(redisUtil.get("name"));
}

redis的操作使用在java中非常简单,关键是要理解redis的思想,数据结构以及用途。

posted @ 2022-04-02 08:50  yu10001  阅读(420)  评论(0编辑  收藏  举报