jedis java中操作redis

jedis        java中操作redis的一种工具  

Java中操作redis

1.创建工程

创建maven父工程,例如03-sca-redis,并在此工程下创建两个子工程,一个为sca-jedis,一个为sca-tempate,例如

1.1添加项目依赖

sca-jedis 工程依赖

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

<dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <version>4.12</version>
  <scope>test</scope>
</dependency>

<dependency>
  <groupId>com.google.code.gson</groupId>
  <artifactId>gson</artifactId>
  <version>2.8.6</version>
</dependency>

添加sca-template工程依赖

<dependencyManagement>
      <dependencies>
          <dependency>
              <groupId>org.springframework.boot</groupId>
              <artifactId>spring-boot-dependencies</artifactId>
              <version>2.3.2.RELEASE</version>
              <scope>import</scope>
              <type>pom</type>
          </dependency>
      </dependencies>
  </dependencyManagement>
  <dependencies>
      <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-web</artifactId>
      </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-test</artifactId>
          <scope>test</scope>
      </dependency>
  </dependencies>

2 Jedis的应用

2.1准备工作

第一步:从redis.io官方下载对应版本的redis.conf文件,地址如下(假如下载不下来从code上去取或者从同学那拿):

https://redis.io/topics/config/

将下载的redis.conf拖进第二步的目录下

第二步:停止redis并删除挂载目录下(/usr/local/docker/redis01/conf)的redis.conf配置文件. 第三步:将下载的redis.conf文件拷贝到redis挂载目录(/usr/local/docker/redis01/conf) 第四步:基于vim打开redis.conf文件,然后注释 bind 127.0.0.1这一行,并修改protected-mode的值修改为no. 第五步:重启redis服务,并检查启动日志(docker logs 容器id)

2.2快速入门实现

在Jedis工程中定义单元测试类,在类中定义单元测试方法:

2.3基础类型操作

在项目的src/test/java目录创建单元测类,例如:

public class JedisTests {
   /**阻塞队列应用*/

   public void testListOper02(){
       //1.连接redis
       Jedis jedis=new Jedis("192.168.126.128",6379);
       //2.存储数据(list集合有顺序,允许重复)
       jedis.lpush("list2","A","B","C");
       //3.基于阻塞取数据
       jedis.brpop(50,"list2");
       jedis.brpop(50,"list2");
       List<String> lst1 = jedis.brpop(50,"lst2");//获取lst1列表中所有元素
       System.out.println(lst1);
       jedis.brpop(50,"list2");
       //4.释放资源
       jedis.close();
  }

   @Test
   public  void testListOper01(){
       //1.建立连接
       Jedis jedis = new Jedis("192.168.126.129", 6379);
       //2.存储数据(list集合有顺序,允许重复)
       jedis.lpush("lst1","A","B","C","C");
       //3.修改数据
       Long index=jedis.lpos("lst1","A");//获取A元素的位置
       jedis.lset("lst1",index,"D");//将A元素位置的内容修改为D
       //4.删除数据
       jedis.rpop("lst1",2);//2是移除2个元素
       //5.查询数据
       List<String> lst1 = jedis.lrange("lst1",0,-1);//获取lst1列表中所有元素
       System.out.println(lst1);
       //6.释放资源
       jedis.close();
  }
   @Test
   public void testhashJsonOper02(){
       //1.建立连接
       Jedis jedis = new Jedis("192.168.126.129", 6379);
       //2.存储数据
       Map<String,String> map=new HashMap<>();
       map.put("x","100");
       map.put("y","200");
       jedis.hset("point",map);
       //3.获取博客内容并输出
       map=jedis.hgetAll("point");
       System.out.println(map);
       //4.释放资源
       jedis.close();

  }

   @Test
   public void testHashOper(){
       //1.建立连接
       Jedis jedis = new Jedis("192.168.126.129", 6379);
       //2.存储数据
       jedis.hset("user","id","100");
       jedis.hset("user","name","jack");
       jedis.hset("user","mobile","11111");

       //3.更新
       jedis.hset("user","id","101");
       //4.删除
       jedis.hdel("user","mobile");
       //5.查看
       String id = jedis.hget("user", "id");
       Map<String, String> user = jedis.hgetAll("user");

       System.out.println("user.id="+id);
       System.out.println("user="+user);
       //6.释放
       jedis.close();
  }


   @Test
   public void testStringJsonOper(){

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

       Map<String, Object> map = new HashMap<>();
       map.put("id","101");
       map.put("name","tony");
       Gson gson=new Gson();
       String jsonStr = gson.toJson(map);//将对象转成字符串
       System.out.println("jsonStr="+jsonStr);
       //3.将json数据存储到redis中
       jedis.set("member",jsonStr);
       //4.取出member的数据
       String member =jedis.get("member");
       System.out.println("redis.member="+member);
       //5.将json字符串转换为map
       map=gson.fromJson(member, Map.class);
       map.put("id","201");
       //6.释放
       jedis.close();
  }


   @Test
   public void testStringOper() throws InterruptedException {
       //1.建立连接
       Jedis jedis=new Jedis("192.168.126.129",6379);
       //2.向redis中存储数据
       jedis.set("id","1");
       jedis.set("token","abcd");
       jedis.set("name","Tony");
       jedis.expire("token",2);
       //3.更新redis中指定数据
       jedis.set("id","100");
       jedis.incr("id");
       jedis.incrBy("id",2);
       jedis.decr("id");
       //4.删除
       jedis.del("name");
       //5.查看
       String id = jedis.get("id");
       String token = jedis.get("token");
       Long tokenStrLen =jedis.strlen("token");
       String name =jedis.get("name");

       System.out.println("id="+id);
       System.out.println("name"+name);
       System.out.println("token.length="+tokenStrLen);
       //Thread.sleep(2000);
       TimeUnit.SECONDS.sleep(2);
       System.out.println("token="+token);
       //6.释放资源
       jedis.close();
  }

   @Test
   public void testGetConnection(){
       //假如不能连通,要注释掉redis.conf中 bind 127.0.0.1,
       //并将protected-mode的值修改为no,然后重启redis再试
       Jedis jedis=new Jedis("192.168.126.129",6379);
       //jedis.auth("123456");//假如在redis.conf中设置了密码
       String ping = jedis.ping();
       System.out.println(ping);
  }
}

3.项目工程实践(后台打开redis)

3.1关键代码实现(在Jedis工程中,以下都是启动类)

public class IdGenerator {

   /**
    * 编写一个方法 每次调用此方法
    * 外界都能获取获取一个唯一的递增
    * 整数值。
    * */
   public static Long getId(){
       Jedis jedis = new Jedis("192.168.126.129", 6379);
       //jedis.auth("")//密码
       //incr方法用于对指定的key的值递增 假如key不存在 则创建
       Long id = jedis.incr("incrementId");
       return id;
  }

   public static void main(String[] args) {
       for (int i=0;i<10;i++){
           new Thread(){
               @Override
               public void run(){
                   System.out.println(IdGenerator.getId());
              }
          }.start();
      }
  }
}

 

3.2单点登陆(与启动类并行)

/**
* sso(单点登录) 案例演示
* 1.访问资源(假如没有登陆 要提示先登录 如何判定先登录)
* 2.执行登陆(登陆成功 存储用户登录信息 要将登录用户信息写入到redis)
* 3.访问资源(登录OK 从redis获取token值信息)
*
* 解决方案:
* 1.SpringSecurity+jwt+oauth2(并发比较大)
* 2.SpringSecurity+redis+oauth2(中小型并发)
*
* */
public class SSODemo01 {
   //认证中心的登录设计
   static String doLogin(String username,String password){
   //1.执行用户身份校验
       if ("jack".equals(username)&& password.equals(password))//将来这个数据来自数据库
           throw new IllegalArgumentException("用户不存在");
       //2.用户存在并且密码正确 表示用户是系统的合法用户
       if (!"123456".equals(password))
           throw new IllegalArgumentException("密码错误");
       //3.将合法用户的信息存储到redis中
       Jedis jedis = new Jedis("192.168.126.129", 6379);
       String token = UUID.randomUUID().toString();
       jedis.set(token,username);
       jedis.expire(token,60*60);
       jedis.close();
       return token;//token
  }
   //获取资源服务中的资源
   static String doGetResource(String token){
       //1.检查用户是否登录
       if (token==null||"".equals(token))
           throw new IllegalArgumentException("登录先");
       Jedis jedis = new Jedis("192.168.126.129", 6379);
       Map<String,String> map=jedis.hgetAll(token);
       String username = jedis.get(token);
       jedis.close();
       //2.假如没有登陆提示先登录
       if (map.isEmpty())
           throw new RuntimeException("登录超时 请重新登录");
       //3.已登录则可以访问资源
       System.out.println("继续访问资源");
       //....
       return "the resource of user";
  }

   //客户端
   public static void main(String[] args) {
       String token=null;
       //第一次访问资源
       doGetResource(token);
       //执行登录
       token=doLogin("jack","123456");
       //第二次访问资源
       doGetResource(token);
  }
}

3.3基于某个活动的投票系统的简易设计

/**基于某个活动的投票系统的简易设计
* 需求:
* 1)基于用户Id对活动进行投票
* 2)一个用户id只能参与一次投票
* 3)可以查询投票总数以及参数投票的用户id
* 设计:
* 1)数据存储结构:set结构(不允许重复)*/
public class VoteDemo01 {
   static final String Ip="192.168.126.128";
   static final int PORT=6379;
   /**
    * 检查用户是否参与过此活动的投票
    * @param activityId
    * @param userId
    * @return
    */

   public static Boolean isVote(String activityId, String userId){
       //1.创建jedis对象
       Jedis jedis=new Jedis(Ip, PORT);
       //2.检查是否投票
       Boolean flag = jedis.sismember(activityId, userId);
       //3.释放资源
       jedis.close();
       //4.返回结果
       return flag;
  }

   /**p
    * 处理投票操作
    * @param activityId
    * @param userId
    */
   public static void doVote(String activityId,String userId){
       //1.创建Jedis对象
       Jedis jedis=new Jedis(Ip, PORT);
       //2.执行投票
       jedis.sadd(activityId, userId);
       //3.释放资源
       jedis.close();
  }
   /**
    * 查看活动的总投票数量
    * @param activityId
    * @return
    */
   public static Long doGetVotes(String activityId){
//1.创建Jedis对象
       Jedis jedis=new Jedis(Ip, PORT);
       //2.查看活动的投票数
       Long count = jedis.scard(activityId);
       //3.释放资源
       jedis.close();
       //4.返回投票数量
       return count;
  }
   /**
    * 获取参与投票当前活动的用户
    * @param activityId
    * @return
    */
   public static Set<String> doGetUsers(String activityId){
       //1.创建Jedis对象
       Jedis jedis=new Jedis(Ip, PORT);
       //2.查看活动的投票数
       Set<String> smembers = jedis.smembers(activityId);
       //3.释放资源
       jedis.close();
       //4.返回投票数量
       return smembers;

  }

   public static void main(String[] args) {
       //1.定义活动id
       String activityId="10001";
       String user1="301";
       String user2="302";
       //2.进行投票检查
       Boolean flag=isVote(activityId,user1);
       System.out.println("flag="+flag);
       //3.进行投票
       doVote(activityId, user1);
       doVote(activityId, user2);
       //4.获取投票的总数
       Long aLong = doGetVotes(activityId);
       System.out.println(activityId +"的总投票数为 "+aLong);
       //5.获取参与投票的用户
       Set<String> users = doGetUsers(activityId);
       System.out.println("参与"+activityId+"活动的投票用户为"+users);
  }
}

3.4购物车系统简易实现

/**购物车系统简易实现
* 需求:
* 1)向购物车添加商品
* 2)修改购物车商品数量
* 3)查看购物车商品
* 4)清空购物车商品信息
* 存储设计:
* 1)mysql(优势是持久性,读写速度会差一些)
* 2)redis(优势是性能,持久性相对Mysql会差一下,
* 假如性能要求高于数据的存储安全,可以存储到redis)*/
public class CartDemo01 {
   static final String Ip="192.168.126.128";
   static final int PORT=6379;
   /**
    * * 向购物车添加商品
    *     * @param userId
    *     * @param productId
    *     * @param num*/
   public static void doAddCart(String userId,String productId,int num){
       //1.创建jedis对象
       Jedis jedis=new Jedis(Ip,PORT);
       //2.基于hash结构存储商品信息
       jedis.hincrBy(userId, productId, num);
       //3.释放资源
       jedis.close();
  }
   /**查看购物车商品信息
    * @param userId
    * @return
    */
   public static Map<String, String> doViewCart(String userId){
       //1.创建jedis对象
       Jedis jedis=new Jedis(Ip,PORT);
       //2.查看商品信息
       Map<String, String> cart = jedis.hgetAll("cart:" + userId);
       //3.释放资源
       jedis.close();
       //4.返回购物车商品信息
       return cart;
  }
   /*** 删除购车某个商品
    * @param userId
    * @param productId*/
   public static void doDelCart(String userId,String productId){
       //1.创建jedis对象
       Jedis jedis=new Jedis(Ip,PORT);
       //2.清除指定商品
       jedis.hdel("cart:"+userId, productId);
       //3.释放资源
       jedis.close();
  }
   public static void main(String[] args) {
       String userId="1001";
       //1.购买商品时,将商品信息添加到购物车
       doAddCart(userId, "201", 1);
       doAddCart(userId, "202", 1);
       doAddCart(userId, "203", 1);
       //2.修改购物车商品的数量
       doAddCart(userId, "202", 1);
       doAddCart(userId, "203", 2);
       //3.查看购物车商品
       Map<String,String>cart=doViewCart(userId);
       System.out.println(cart);

       //4.清空购物车
       doDelCart(userId, "203");
       //再次查看
     cart=doViewCart(userId);
       System.out.println(cart);
  }


}

3.5 抢购活动中的秒杀队列

/**演示抢购活动中的秒杀队列
* 数据逻辑结构:list
* 算法:fifo(公平特性)
* 数据存储结构:redis中的list类型进行存储
*
*
* 在抢购活动中会执行这样的操作
* 1)生产者(购买商品的用户):创建请求并将请求存储到队列
* 2)消费者(处理购买请求的底层对象):从队列取请求,然后处理请求*/
public class secondskillDemo01 {
/**
* 入队操作
*/
public static void enque(String request){
Jedis jedis=new Jedis("192.168.126.129", 6379);
jedis.lpush("queue-1",request);
jedis.close();
}
/**
* 出队操作
*/
public static String deque(){
Jedis jedis=new Jedis("192.168.126.129", 6379);
//非阻塞式取数据
//return jedis.rpop("queue-1");
//阻塞式取数据
//List<String> list = jedis.brpop(3, "queue-1");
List<String> list = jedis.brpop(60, "queue-1");
jedis.close();
return list!=null?list.get(1):null;//0为key
}

public static void main(String[] args) {
//1.构建生产对象(购买商品的用户)
Thread t1=new Thread(){
@Override
public void run() {
// for(int i=1;i<=10;i++){
// enque("request-"+i);
int i=1;
for(;;){
enque("request-"+i++);
try { Thread.sleep(1000);
}catch (Exception e){}
}
}
};
//2.构建消费者对象(处理请求的对象)
Thread t2=new Thread(){
@Override
public void run() {
for(;;){
String request=deque();
if(request==null)continue;
System.out.println("process "+request);
}
}
};
//3.开启抢购活动
t1.start();
t2.start();
}
}

3.6测试jedis连接池(在测试类中创建)

/**测试jedis连接池的一个基本应用*/
public class JedisPoolTests {
@Test
public void testJedisPool(){
//1.构建jedis连接池(JedisPool对象)
//1.1定义连接池配置
JedisPoolConfig config=new JedisPoolConfig();
config.setMaxTotal(16);//最大连接数,默认为8
config.setMaxIdle(60);//最大空闲时间(连接后续不用了,超出一定空闲时间要释放)
//config.setxxxx
//1.2定义连接的url和端口
String host="192.168.126.128";
int port=6379;
//1.3创建连接池
JedisPool jedisPool=new JedisPool(config,host,port);
//2.从池中获取连接(jedis对象)
Jedis resource = jedisPool.getResource();
//3.执行redis操作
resource.set("pool", "JedisPool");
String pool = resource.get("pool");
System.out.println(pool);
//4.释放资源(不是关,而是将连接还回池中)
resource.close();
//5.关闭池(一般服务停止时关)
//jedisPool.close();
}
}

获取连接池,并操作(与启动类并行)

/**
* 构建一个Jedis数据源,基于此数据源可以从一个Jedis池中
* 获取连接(Jedis),进而操作redis数据库。
*/
public class JedisDataSource {
private static final JedisPool jedisPool;
private static final String HOST="192.168.126.129";
private static final int PORT=6379;
static{
JedisPoolConfig config=new JedisPoolConfig();
config.setMaxTotal(16);//最大连接数,默认为8
config.setMaxIdle(60);
jedisPool=new JedisPool(config,HOST,PORT);
}
/**
* 获取一个连接对象
* @return
*/
public static Jedis getConnection(){
return jedisPool.getResource();
}
public static JedisPool getJedisPool() {
return jedisPool;
}

}

4 RedisTemplate应用

4.1简介

RedisTemplate为SpringBoot工程中操作redis数据库的一个Java对象,此对象封装了对redis的一些基本操作。

4.2准备工作 (先启动redis)

在RedisTemplate的pom中添加

  <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>

第一步:创建工程配置文件application.yml,其内容如下:

spring:
redis:
host: 192.168.64.129 #写自己的ip
port: 6379

第二步:创建工程启动类,例如:


@SpringBootApplication
public class RedisApplication {
public static void main(String[] args) {
SpringApplication.run(RedisApplication.class,args);
}
}

4.3 快速入门实现

StringRedisTemplate 应用(测试类)

StringRedisTemplate 是一个专门用于操作redis字符串类型数据的一个对象,其应用方式如下:

@SpringBootTest
public class StringRedisTemplateTests {
/**
* 此对象为操作redis的一个客户端对象,这个对象
* 对key/value采用了字符串的序列化(StringRedisSerializer)
* 方式进行,redis数据的读写操作.
*/
@Autowired
private StringRedisTemplate stringRedisTemplate;

@Test
void testHashOper01(){
//1.获取hash操作的对象
HashOperations<String, Object, Object> vo =
stringRedisTemplate.opsForHash();
//2.读写redis数据
//2.1存储一个对象
vo.put("user", "id", "100");
vo.put("user", "username", "tony");
vo.put("user", "status", "1");
//2.2获取一个对象
//2.2.1获取对象某个属性值
Object status =vo.get("user","status");
System.out.println(status);
//2.2.2获取对象某个key对应的所有值
List<Object> user = vo.values("user");
System.out.println(user);
}
@Test
void testStringOper02() throws JsonProcessingException {
//1.获取字符串操作对象(ValueOperations)
ValueOperations<String, String> vo =
stringRedisTemplate.opsForValue();
//2.读写redis中的数据
Map<String,String> map=new HashMap<>();
map.put("id","100");
map.put("title","StringRedisTemplate");

//将map对象转换为json字符串写到redis数据库
String jsonStr=//jackson (spring-boot-starter-web依赖中自带)
new ObjectMapper().writeValueAsString(map);
vo.set("blog", jsonStr);
jsonStr=vo.get("blog");
System.out.println(jsonStr);
//将json字符串转换为map对象
map=
new ObjectMapper().readValue(jsonStr, Map.class);
System.out.println(map);
}
@Test
void testStringOper01(){
//1.获取字符串操作对象(ValueOperations)
ValueOperations<String, String> vo =
stringRedisTemplate.opsForValue();
//2.读写redis中的数据
vo.set("x", "100");
vo.increment("x");
// 1, TimeUnit.SECONDS 设置失效
vo.set("y", "200", 1, TimeUnit.SECONDS);
String x = vo.get("x");
String y = vo.get("y");
System.out.println("x="+x+",y="+y);
}

@Test
void testGetConnection(){
RedisConnection connection =
stringRedisTemplate.getConnectionFactory()
.getConnection();
String ping = connection.ping();
System.out.println(ping);
}

 

posted @ 2021-10-16 16:24  身在江湖  阅读(65)  评论(0编辑  收藏  举报