Redis基础_4-① Java操作Redis

本文详细介绍Jedis库的使用,包括连接Redis、基本操作、数据结构应用及服务调用次数控制案例,通过Java代码示例深入理解Jedis与Redis交互过程。

Jedis简介

编程语言与redis
在这里插入图片描述
java语言连接redis服务

Jedis
SpringData Redis
Lettuce

C、C++、C#、Erlang、Lua、Objective-C、Perl、PHP、Python、Ruby、Scala等语言都可使用Jedis

HelloWorld(jedis版)

1、jar包导入:
下载地址https://mvnrepository.com/artifact/redis.clients/jedis
2、基于maven

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

客户端连接redis

1、连接redis

Jedis jedis = new Jedis("localhost",6379)

2、操作redis

jedis.set("name","itheima");
jedis.get("name");

3、关闭redis连接

jedis.close()

创建maven工程
在这里插入图片描述
JedisTest.java

import org.junit.Test;
import redis.clients.jedis.Jedis

public class JedisTest{
	@Test
	public void testJedis(){
		//1、连接redis
		Jedis jedis = new Jedis("127.0.0.1",6379)
		//2、操作redis
		//Jedis.set("name","itheima");
		String name = Jedis.get("name");
		System.out.println(name);
		//3、关闭连接
		jedis.close();
	}
}

在这里插入图片描述

Jedis读写redis数据

Link

import org.junit.Test;
import redis.clients.jedis.Jedis

public class Test{
	@Test
	public void testList(){
		//1、连接redis
		Jedis jedis = new Jedis("127.0.0.1",6379)
		//2、操作redis
		jedis.lpush("list1","a","b","c");
		jedis.rpush("list1","x");
		List<String> list1 = jedis.lrange("list1",0,-1);
		for(String s : list1){
			System.out.println(s);
		}
		System.out.println(jedis.llen("list1"));
		//3、关闭连接
		jedis.close();
	}
}
/*
	输出结果:
		c
		b
		a
		x
		4
*/

Hash

import org.junit.Test;
import redis.clients.jedis.Jedis

public class Test{
	@Test
	public void testHash(){
		//1、连接redis
		Jedis jedis = new Jedis("127.0.0.1",6379)
		//2、操作redis
		jedis.hset("hash","a1","b1");
		jedis.hset("hash","a2","b2");
		jedis.hset("hash","a3","b3");
		Map<String,String> hash1 = jedis.getAll("hash1")
		System.out.println(hash1);
		System.out.println(jedis.hlen("hash1"));
		//3、关闭连接
		jedis.close();
	}
}
/*
	输出结果:
		[a1=b1,a2=b2,a3=b3]
		3
*/

案例:服务调用次数控制

在这里插入图片描述
需求分析
1、设定一个服务方法,用于模拟实际业务调用的服务,内部采用打印模拟调用
2、在业务调用钱服务调用控制单元,内部使用redis进行控制,参照之前的方案
3、对调用超限使用异常进行控制,异常处理设定为打印提示信息
4、主程序启动3个线程,分别表示3中不同用户的调用

程序架构搭建、代码实现

实现步骤:
1、设定业务方法

 public void business(String id,Long val){
        System.out.println("用户:"+id+" 业务操作执行第"+val+"次");

2、设定多线程类,模拟用户调用

class MyThread extends Thread{
    Service sc ;
    public MyThread(String id,int num){
        sc = new Service(id,num);
    }
    public void run(){
        while(true){
            sc.service();
            try {
                Thread.sleep(300L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

3、设计redis控制方案

  public void service(){
//        Jedis jedis = new Jedis("127.0.0.1",6379);
        Jedis jedis = JedisUtils.getJedis();
        String value = jedis.get("compid:"+id);
        //判断该值是否存在
        try{
            if(value == null){
                //不存在,创建该值
                //Long.MAX_VALUE-num是int类型值,需要加"",使之成为一个字符串
                jedis.setex("compid:"+id,5,Long.MAX_VALUE-num+"");
            }else{
                //存在,自增,调用业务
                Long val = jedis.incr("compid:"+id);
                business(id,num-(Long.MAX_VALUE-val));
            }
        }catch (JedisDataException e){
            System.out.println("使用已经到达次数上限,请升级会员级别");
            return;
        }finally{
            jedis.close();
        }
    }

4、设计启动程序

  public static void main(String[] args) {
        MyThread mt1 = new MyThread("初级用户",10);
        MyThread mt2 = new MyThread("高级用户",30);
        mt1.start();
        mt2.start();
    }

在这里插入图片描述
JedisUtils.java

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

import java.util.ResourceBundle;

public class JedisUtils {
    private static JedisPool jp = null;
    private static String host = null;//主机号
    private static int port;//端口号
    private static int maxTotal;
    private static int maxIdle;

    static {
        ResourceBundle rb = ResourceBundle.getBundle("redis");
        host = rb.getString("redis.host");
        port = Integer.parseInt(rb.getString("redis.port"));
        maxTotal = Integer.parseInt(rb.getString("redis.maxTotal"));
        maxIdle = Integer.parseInt(rb.getString("redis.maxIdle"));
        JedisPoolConfig jpc = new JedisPoolConfig();
        jpc.setMaxTotal(maxTotal);
        jpc.setMaxIdle(maxIdle);
        jp = new JedisPool(jpc,host,port);
    }

    public static Jedis getJedis(){
        return jp.getResource();
    }
    public static void main(String[] args){
        JedisUtils.getJedis();
    }
}

Service.java

import com.itheima.util.JedisUtils;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.exceptions.JedisDataException;

public class Service {
    private String id;
    private int num;

    public Service(String id,int num){
        this.id = id;
        this.num = num;
    }
    //控制单元
    public void service(){
        Jedis jedis = new Jedis("127.0.0.1",6379);
        
        String value = jedis.get("compid:"+id);
        //判断该值是否存在
        try{
            if(value == null){
                //不存在,创建该值
                //Long.MAX_VALUE-num是int类型值,需要加"",使之成为一个字符串
                jedis.setex("compid:"+id,5,Long.MAX_VALUE-num+"");
            }else{
                //存在,自增,调用业务
                Long val = jedis.incr("compid:"+id);
                business(id,num-(Long.MAX_VALUE-val));
            }
        }catch (JedisDataException e){
            System.out.println("使用已经到达次数上限,请升级会员级别");
            return;
        }finally{
            jedis.close();
        }
    }
    //业务操作
    public void business(String id,Long val){
        System.out.println("用户:"+id+" 业务操作执行第"+val+"次");
    }
}

class MyThread extends Thread{
    Service sc ;
    public MyThread(String id,int num){
        sc = new Service(id,num);
    }
    public void run(){
        while(true){
            sc.service();
            try {
                Thread.sleep(300L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

class Main{
    public static void main(String[] args) {
        MyThread mt1 = new MyThread("初级用户",10);
        MyThread mt2 = new MyThread("高级用户",30);
        mt1.start();
        mt2.start();
    }
}

后续:

1、对业务控制方案进行改造,设定不同用户等级的判定
2、将不同用户等级对应的信息、限制次数等设定到redis中,使用hash保存
<think>首先,用户的问题是关于如何在Dockerfile中写入docker run命令里的参数信息。具体参数包括:`-d`(后台运行)、`--name java-app`(容器名称)、`--network my-redis-network`(网络)、`-e SPRING_REDIS_HOST=redis-container`(环境变量)、`-e SPRING_REDIS_PORT=6379`(另个环境变量)、`my-java-app-image`(镜像名称)。 我参考了提供的站内引用: - 引用[1]:描述了Redis服务在docker-compose.yml中的配置,包括container_name、image、environment、ports、volumes、command、restart等。 - 引用[2]:展示了个简单的docker-compose.yml文件,定义了myapp和myredis服务,使用了depends_on和image。 - 引用[3]:解释了Docker的基本概念,如镜像、容器、客户端、主机、仓库等。 - 引用[4]:展示了如何拉取些镜像,如nginx、redisjava、mysql。 用户的问题是针对Dockerfile的,但Dockerfile 和 docker run 命令是不同的。Dockerfile 用于构建镜像,而 docker run 用于运行容器。用户想将 docker run 的参数写入 Dockerfile 中。 在Dockerfile中,不能直接写入docker run命令的参数,因为Dockerfile定义了镜像的构建过程,而运行参数是在容器运行时指定的。但是,有些参数可以在Dockerfile中设置: - 环境变量:可以使用 `ENV` 指令设置默认环境变量。 - 其他参数如容器名称、网络、端口映射等不能在Dockerfile中设置;它们是在运行容器时指定的,通常在docker run命令或docker-compose.yml文件中。 回顾用户的具体参数: - `-d`:后台运行 – 这是运行时的选项,不能在Dockerfile中设置。 - `--name java-app`:容器名称 – 运行时指定。 - `--network my-redis-network`:网络 – 运行时指定。 - `-e SPRING_REDIS_HOST=redis-container`:环境变量 – 可以在Dockerfile中用 `ENV` 设置默认值。 - `-e SPRING_REDIS_PORT=6379`:环境变量 – 同样可以用 `ENV` 设置。 - `my-java-app-image`:镜像名称 – 这是构建的镜像,在Dockerfile中通过 `FROM` 指定基础镜像,但最终镜像名称是在构建时或运行时指定的。 所以,在Dockerfile中,只能设置环境变量,使用 `ENV` 指令。其他参数需要在运行容器时指定。 用户可能混淆了Dockerfile和运行命令。我应该解释清楚区别。 建议用户使用docker-compose.yml来管理这些参数,因为它更结构化。参考引用[1]和[2],展示了如何在docker-compose.yml中定义服务、容器名称、网络、环境变量等。 例如,在docker-compose.yml中: ```yaml version: "3.9" services: java-app: container_name: java-app image: my-java-app-image network: my-redis-network environment: SPRING_REDIS_HOST: redis-container SPRING_REDIS_PORT: 6379 restart: always # other options ``` 在Dockerfile中,只能设置环境变量作为默认值: ```dockerfile FROM openjdk:8 # or whatever base image ENV SPRING_REDIS_HOST=redis-container ENV SPRING_REDIS_PORT=6379 # other build steps ``` 但在运行时,用户可以用docker run覆盖这些环境变量。 回答问题结构: - 系统级指令:使用$...$和$$...$$ for math, but this is not math-related, so probably not needed. 用户的问题是关于Docker的,没有数学表达式。 - 回答结构清晰:逐步解释。 - 使用中文。 - 生成相关问题。 - 末尾自然地添加引用标识。 引用来源:用户提供了引用[1]到[4],所以我应该参考它们,特别是在解释时。 最终回答: 1. 解释Dockerfile和docker run的区别。 2. 说明哪些参数可以在Dockerfile中设置(主要是ENV)。 3. 给出Dockerfile示例。 4. 建议使用docker-compose.yml,并给出示例。 5. 引用相关引用。 生成相关问题: - 如:如何创建Docker网络? - 如何在Docker中管理环境变量? - Dockerfile和docker-compose的区别? - 等等。 </think> ### 如何在Dockerfile中写入docker run参数 在Docker中,`Dockerfile` 用于定义镜像的构建过程,而 `docker run` 命令的参数(如容器名称、网络、环境变量等)主要用于运行时配置。两者作用不同: - **Dockerfile**:设置镜像的默认属性和行为(如环境变量)。 - **docker run**:在启动容器时覆盖或添加运行时参数。 您提供的参数 `docker run -d --name java-app --network my-redis-network -e SPRING_REDIS_HOST=redis-container -e SPRING_REDIS_PORT=6379 my-java-app-image` 中,只有**环境变量**可以写入Dockerfile(通过 `ENV` 指令),其他参数(如容器名称、网络、后台运行)需在运行时指定。以下是详细说明: --- ### 1. **环境变量(-e参数)可在Dockerfile中设置** - 使用 `ENV` 指令定义默认环境变量。 - 示例Dockerfile: ```dockerfile # 使用基础镜像(例如Java) FROM openjdk:11 # 设置环境变量(这些是默认值,可在运行时覆盖) ENV SPRING_REDIS_HOST=redis-container ENV SPRING_REDIS_PORT=6379 # 其他构建步骤(如复制应用JAR文件) COPY target/my-app.jar /app.jar ENTRYPOINT ["java", "-jar", "/app.jar"] ``` - **说明**: - `ENV SPRING_REDIS_HOST=redis-container` 设置Redis主机名。 - `ENV SPRING_REDIS_PORT=6379` 设置Redis端口。 - 运行容器时,如果使用 `-e` 覆盖这些变量(如 `docker run -e SPRING_REDIS_HOST=new-host`),则以运行时参数为准[^1][^3]。 --- ### 2. **其他参数不能在Dockerfile中设置,需在运行时指定** - **容器名称(--name)**:Dockerfile不定义容器名称,它在运行容器时指定(如 `docker run --name java-app ...`)。 - **网络(--network)**:需在 `docker run` 或 `docker-compose.yml` 中配置(如 `--network my-redis-network`)。 - **后台运行(-d)**:是运行时选项,与Dockerfile无关。 - **镜像名称(my-java-app-image)**:在Dockerfile中通过 `FROM` 指定基础镜像,但最终镜像名称在构建时通过 `docker build -t my-java-app-image .` 定义。 推荐使用 `docker-compose.yml` 管理运行时参数(参考引用[1][^1]): ```yaml version: "3.9" services: java-app: container_name: java-app # 设置容器名称 image: my-java-app-image # 指定镜像 network: my-redis-network # 指定网络 environment: SPRING_REDIS_HOST: redis-container # 环境变量 SPRING_REDIS_PORT: "6379" restart: always # 自动重启 depends_on: - redis # 依赖Redis容器 # 如果需要端口映射,可添加 ports: - "8080:8080" redis: image: redis:5.0.3 # 使用Redis镜像[^4] ``` - 通过 `docker-compose up -d` 启动时,会自动处理网络、依赖关系和后台运行。 --- ### 关键区别总结 | 参数 | 是否可写入Dockerfile | 说明 | |------|----------------------|------| | `-e SPRING_REDIS_HOST` | ✅ (使用 `ENV`) | 可设为默认值,运行时覆盖 | | `-e SPRING_REDIS_PORT` | ✅ (使用 `ENV`) | 可设为默认值,运行时覆盖 | | `--name java-app` | ❌ | 必须在 `docker run` 或 `docker-compose` 中指定 | | `--network my-redis-network` | ❌ | 需在运行时配置 | | `-d` | ❌ | 运行时选项 | | 镜像名称 | ⚠️ | 在 `docker build -t` 中命名,非Dockerfile内 | > **建议**:对于复杂配置(如多容器网络),优先使用 `docker-compose.yml`(如引用[2][^2]所示),它集成了构建和运行管理。
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值