>  기사  >  Java  >  Java SpringBoot 프로젝트에 Redis를 통합하는 방법은 무엇입니까?

Java SpringBoot 프로젝트에 Redis를 통합하는 방법은 무엇입니까?

王林
王林앞으로
2023-05-12 13:52:131479검색

Redis는 완전한 오픈 소스이며 BSD 프로토콜을 준수하며 고성능 키-값 데이터베이스입니다.

Redis는 다른 키-값 캐시 제품과 비교하여 다음 세 가지 특징을 갖습니다.

  • Redis는 데이터 지속성을 지원합니다. , 메모리에 있는 데이터는 디스크에 저장했다가 다시 로드하여 재시작 시 사용할 수 있습니다.

  • Redis는 단순한 키-값 유형의 데이터를 지원할 뿐만 아니라 list, set, zset, hash와 같은 데이터 구조의 저장도 제공합니다.

  • Redis는 데이터 백업, 즉 마스터-슬레이브 모드에서의 데이터 백업을 지원합니다.

Redis의 장점

  • 매우 높은 성능– Redis는 110000회/초의 속도로 읽고 81000회/s의 속도로 쓸 수 있습니다.

  • 다양한 데이터 유형&ndash는 바이너리 케이스를 지원합니다. zset 데이터 유형 작업.

  • Atomic – Redis의 모든 작업은 원자적입니다. 즉, 성공적으로 실행되거나 전혀 실행되지 않습니다. 개별 작업은 원자적입니다. 다중 작업은 MULTI 및 EXEC 명령어로 래핑된 트랜잭션, 즉 원자성도 지원합니다.

  • 다양한 기능 – Redis는 게시/구독, 알림, 키 만료 및 기타 기능도 지원합니다.

  • Redis는 단일 스레드이며 버전 6.0은 다중 스레딩 활성화를 지원합니다.

Redis 설치

java SpringBoot项目整合Redis的方法是什么

다운로드한 압축 파일의 압축을 해제하세요. 압축을 푼 후 파일 목록은 다음과 같습니다.

java SpringBoot项目整合Redis的方法是什么

cmd 창을 사용하여 Redis를 엽니다

redis-server.exe   redis.windows.conf   #加载配置文件启动

java SpringBoot项目整合Redis的方法是什么

注:启动之后,不要关闭窗口,关闭窗口服务停止!

Redis 설치 데이터베이스 클라이언트

java SpringBoot项目整合Redis的方法是什么

라이브러리 관련 지침:

flushdb  清空当前库

flushall  清空所有库

select   1    切换库

주요 관련 지침

명령 함수 구문
del 하나 이상의 키 삭제 del keyname
exists 하나 이상의 키가 존재하는지 확인합니다. 키가 여러 개 있으면 1 exists keyname
expire 을 반환합니다. 키의 생존 시간 단위: 초 expire keyname 초
keys 패턴과 일치하는 모든 키를 쿼리하시겠습니까? 문자 일치 * 0-n 문자 일치 [] 키 * 키 h?llo
move 키를 지정된 라이브러리로 이동 move 키 이름 db
pexpire 키의 생존 시간 단위를 설정합니다: 밀리초. 설정이 성공하면 1을 반환하고, 그렇지 않으면 0을 반환합니다. pexpire 키 이름 밀리초
ttl 키의 남은 생존 시간을 초 단위로 반환하고 - 1은 영구 저장소, -2는 키가 존재하지 않음을 의미합니다. ttl keyname
randomkey 현재 데이터베이스에서 키를 무작위로 반환 randomkey
rename 키 이름을 바꾸고 ok를 성공적으로 반환합니다. 그렇지 않으면 오류 메시지가 반환됩니다. rename key newkey
type key에 저장된 값의 유형을 반환 type keyname

Redis 데이터 유형

1.String(string)

  • string은 Redis의 가장 기본적인 유형이며 Memcached와 완전히 동일한 유형으로 이해하면 됩니다.

  • 문자열 유형은 바이너리 안전합니다. 이는 redis 문자열에 모든 데이터가 포함될 수 있음을 의미합니다. 예를 들어 jpg 이미지 또는 직렬화된 개체입니다.

  • 문자열 유형은 Redis의 가장 기본적인 데이터 유형이며 문자열 유형 값은 최대 512MB까지 저장할 수 있습니다.

작업 지침:

Command Description
SET 지정된 키의 값 설정
GET 지정된 키의 값을 가져옵니다. .
GETRANGE 키에 있는 문자열 값의 하위 문자를 반환합니다.
GETSET 주어진 키의 값을 value로 설정하고 키의 이전 값을 반환합니다.
SETEX 값 값을 키에 연결하고 키의 만료 시간을 초(초)로 설정합니다.
SETNX 키가 존재하지 않는 경우에만 키 값을 설정합니다.
STRLEN 키에 저장된 문자열 값의 길이를 반환합니다.
MSET 하나 이상의 키-값 쌍을 동시에 설정합니다.
MSETNX 주어진 키가 모두 존재하지 않는 경우에만 하나 이상의 키-값 쌍을 동시에 설정합니다.
INCR 키에 저장된 숫자 값을 다음과 같이 증가시킵니다. one
INCRBY 키에 저장된 값을 주어진 증분만큼 추가
INCRBYFLOAT 키에 저장된 값을 주어진 부동 소수점 증분(증분)만큼 추가
DECR 키에 저장된 숫자 값을 1씩 감소시킵니다.
DECRBY 키에 저장된 값에서 주어진 감소분을 뺀 값입니다.
APPEND 키가 이미 존재하고 문자열인 경우 APPEND 명령은 원본 끝에 Append 값을 지정합니다. 키의 값

2. 해시(Hash)

  • Redis 해시는 키-값(key=>value) 쌍의 집합입니다.

  • Redis 해시는 문자열 형식의 필드와 값을 매핑하는 테이블입니다. 특히 객체를 저장하는 데 적합합니다.

작업 지침:

Command Description
hset 키/값 쌍 설정
hget Get
hgetall 키에 해당하는 값 모든 키/값 쌍 가져오기
hdel 키/값 쌍 삭제
hexists 키 존재 여부 확인
hkeys 모든 키 가져오기
hvals 모든 값 가져오기
hmset 여러 키/값 설정
hmget 여러 키 값 가져오기
hsetnx 존재하지 않는 키 값 설정
힝크비 value 값에 대한 덧셈 연산을 수행합니다
hincrbyfloat value 값에 대한 부동 소수점 유형 값의 덧셈 연산을 수행합니다

3.List(List)

  • Redis 목록은 삽입 순서대로 정렬된 간단한 문자열 목록입니다. 목록의 머리 부분(왼쪽)이나 끝 부분(오른쪽)에 요소를 추가할 수 있습니다.

Operation command

Command Description
LINDEX 목록의 요소 가져오기 0
LINSERT 키 이전| AFTER 목록 요소 앞이나 뒤에 요소 삽입
LLEN 목록 길이 가져오기
LPOP 목록의 첫 번째 요소 제거 및 가져오기
LPUSH 목록의 머리 부분에 하나 이상의 값을 삽입합니다
LPUSHX 목록의 머리 부분에 값을 삽입합니다existinglist
LRANG 이자 받기 목록의 지정된 범위(0 -1) 내의 요소
LREM 목록에서 중복된 요소 제거
LSET 목록 요소의 값을 인덱스를 통해 설정하지만, 색인이 존재해야 하며, 핵심은 색인에 따라 값을 수정하는 것입니다
LTRIM 목록 자르기, 즉 목록이 지정된 범위 내의 요소만 유지하고 지정된 범위 내에 없는 요소만 유지하도록 합니다. 삭제됩니다
RPOP Remove 목록의 마지막 요소, 반환 값은 제거된 요소입니다.
RPOPLPUSH 목록의 마지막 요소를 제거하고 해당 요소를 다른 목록에 추가합니다. 그리고
RPUSH 을 반환합니다. 목록에 하나 이상의 값을 추가합니다
RPUSHX 기존 목록에 값 추가

4.Set(세트)

  • Redis' Set은 문자열 형식의 정렬되지 않은 모음입니다.

  • 세트는 해시 테이블을 통해 구현되므로 추가, 삭제, 검색의 복잡성은 O(1)입니다.

작업 지침:

Command Description
sadd 컬렉션에 요소 추가
smembers 모두 표시 컬렉션의 요소(없음) 서문)
scard 세트의 요소 수를 반환합니다.
spop 요소를 무작위로 반환하고 이 요소를 삭제합니다.
smove 한 세트에서 다른 세트로 요소 이동
srem 집합에서 요소 제거
sismember 집합에 이 요소가 포함되어 있는지 확인
srandmember 임의로 요소 반환
sinter 교점 찾기
sunion 합계 세트 ”
차이점은 각 요소가

double

유형 점수와 연관되어 있다는 것입니다.
    Redis
  • 는 점수를 사용하여 세트의 구성원을 작은 것부터 큰 것까지 정렬합니다.

    ZSet의 멤버는 고유하지만 점수가 반복될 수 있습니다.

  • 작업 명령:

    Command

  • Description
  • zadd

주문한 세트 요소 추가

zcard반환 세트의 요소 수 zrange 오름차순 zrevrange 내림차순 범위의 요소 반환 zrangebyscore 점수별로 범위의 요소 찾기zrankReturn 순위zrevrank플래시백 순위zscore디스플레이 요소 점수zrem요소 제거zincrby특정 요소에 포인트 부여

SpringBoot 操作 Redis

  spring boot data redis中提供了RedisTemplate和StringRedisTemplate,其中StringRedisTemplate是Redistemplate的子类,两个方法基本一致,不同之处主要体现在操作的数据类型不同,RedisTemplate中的两个泛型都是Object,意味着存储的key和value都可以是一个对象,而StringRedisTemplate的两个泛型都是String,意味着StringRedisTemplate的key和value都只能是字符串。

引入依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

SpringBoot 配置 Redis

spring:
  redis:
    # Redis数据库索引(默认为0)
    database: 0
    # Redis服务器地址
    host: 127.0.0.1
    # Redis服务器连接端口
    port: 6379
    # Redis服务器连接密码(默认为空)
    password:
    # 连接池最大连接数(使用负值表示没有限制)
    jedis.pool.max-active: 20
    # 连接池最大阻塞等待时间(使用负值表示没有限制)
    jedis.pool.max-wait: -1
    # 连接池中的最大空闲连接
    jedis.pool.max-idle: 10
    # 连接池中的最小空闲连接
    jedis.pool.min-idle: 0
    # 连接超时时间(毫秒)
    timeout: 1000

RedisTemplate 及其相关方法

1.RedisTemplate 介绍

  Spring封装了RedisTemplate对象来进行对Redis的各种操作,它支持所有的Redis原生的api。RedisTemplate位于spring-data-redis包下。RedisTemplate提供了redis各种操作、异常处理及序列化,支持发布订阅。

2.Redis 5种数据结构操作

  • redisTemplate.opsForValue(); //操作字符串

  • redisTemplate.opsForHash(); //操作hash

  • redisTemplate.opsForList(); //操作list

  • redisTemplate.opsForSet(); //操作set

  • redisTemplate.opsForZSet(); //操作有序set

或者:

  • redistempalate.boundValueOps

  • redistempalate.boundSetOps

  • redistempalate.boundListOps

  • redistempalate.boundHashOps

  • redistempalate.boundZSetOps

 opsForXXX和boundXXXOps的区别:XXX为value的类型,前者获取一个operator,但是没有指定操作的对象(key),可以在一个连接(事务)内操作多个key以及对应的value;后者获取了一个指定操作对象(key)的operator,在一个连接(事务)内只能操作这个key对应的value。

 SpringBootTest 实现Redis数据库增删改查

/**
 * 使用RedisTemplate 操作Redis数据的不同数据类型
 */
@SpringBootTest
public class Springbootday03ApplicationTests {
    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    /**
     * String 类型数据操作
     */
    @Test
    public void operateString() {

        //添加值
        redisTemplate.opsForValue().set("str", "strValue1");

        //添加值  判定是否存在 存在则不添加
        Boolean aBoolean = redisTemplate.opsForValue().setIfAbsent("str", "strAbsent");
        System.out.println("str设置成功:" + aBoolean);

        //获取值
        String str = redisTemplate.opsForValue().get("str");
        System.out.println("str = " + str);

        //更新值
        redisTemplate.opsForValue().set("str", "strValue2");
        str = redisTemplate.opsForValue().get("str");
        System.out.println("newStr = " + str);

        //删除值
        Boolean b = redisTemplate.delete("str");
        System.out.println("str删除成功:" + b);

    }

    /**
     * 操作string类型数据  设置过期时间
     */
    @Test
    public void operateString2() {
        redisTemplate.opsForValue().set("str", "strTimeout", 10, TimeUnit.SECONDS);
        //判定值是否存在 不存在则设置值 同时设置过期时间
        Boolean aBoolean = redisTemplate.opsForValue().setIfAbsent("str2", "strTimeoutAbsent", 20, TimeUnit.SECONDS);
        System.out.println("setIfAbsent:" + aBoolean);
    }

    /**
     * 操作hash类型数据
     */
    @Test
    public void operateHash() {
        //添加hash类型数据  key - value
        redisTemplate.opsForHash().put("hash", "username", "admin");
        //修改hash类型数据
        redisTemplate.opsForHash().put("hash", "username", "tom");
        redisTemplate.opsForHash().put("hash", "password", "123456");

        //添加hash类型数据  key - map
        HashMap<String, String> map = new HashMap<>();
        map.put("driverName", "com.mysql.jdbc.Driver");
        map.put("url", "jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC");
        redisTemplate.opsForHash().putAll("hash", map);

        //获取hash类型数据  entries
        Map<Object, Object> hash = redisTemplate.opsForHash().entries("hash");
        hash.forEach((key, value) -> {
            System.out.println(key + "::" + value);
        });

        //获取所有的key
        Set<Object> keys = redisTemplate.opsForHash().keys("hash");
        for (Object key : keys) {
            System.out.println("key:" + key);
        }
        //获取所有value
        List<Object> values = redisTemplate.opsForHash().values("hash");
        values.forEach(value -> System.out.println("value:" + value));

        //删除hash类型数据  删除一个  返回删除的个数
        Long delete = redisTemplate.opsForHash().delete("hash", "username");
        System.out.println("delete = " + delete);

        //删除hash类型数据  删除多个  返回删除的个数
        delete = redisTemplate.opsForHash().delete("hash", "username", "password", "driverName");
        System.out.println("delete = " + delete);

        //删除hash类型数据  删除所有
        Boolean delHash = redisTemplate.delete("hash");
        System.out.println("delHah:" + delHash);

    }

    /**
     * 操作List类型  有序 可重复
     */
    @Test
    public void operateList() {

        //左压栈
        // redisTemplate.opsForList().leftPush("list", "listValue1");
        // redisTemplate.opsForList().leftPush("list", "listValue1");
        // redisTemplate.opsForList().leftPush("list", "listValue2");
        // redisTemplate.opsForList().leftPush("list", "listValue3");

        //右压栈
        redisTemplate.opsForList().rightPush("list", "listValue0");
        redisTemplate.opsForList().rightPush("list", "listValue2");
        redisTemplate.opsForList().rightPush("list", "listValue0");

        //左出栈
        String list1 = redisTemplate.opsForList().leftPop("list");
        System.out.println("leftPop list1 = " + list1);
        //右出栈
        String list2 = redisTemplate.opsForList().rightPop("list");
        System.out.println("rightPop list2 = " + list2);

        //获取所有数据
        List<String> lists = redisTemplate.opsForList().range("list", 0, 		        redisTemplate.opsForList().size("list") - 1);
        lists.forEach(list -> System.out.println(list));


        //设置指定位置的数据
        redisTemplate.opsForList().set("list", 0, "listValue0");
        /**
         * 从存储在键中的列表中删除等于值的元素的第一个计数事件。
         * count> 0:删除等于从左到右移动的值的第一个元素;
         * count< 0:删除等于从右到左移动的值的第一个元素;
         * count = 0:删除等于value的所有元素。
         */
        Long remove = redisTemplate.opsForList().remove("list", -1, "listValue0");
        System.out.println("remove:" + remove);

        //删除指定key的list数据
        Boolean list = redisTemplate.delete("list");
        System.out.println("list集合删除成功:" + list);
    }

    /**
     * 操作Set类型  无序 不可重复
     */
    @Test
    public void operateSet() {

        //设置set值
        redisTemplate.opsForSet().add("set", "setValue0");
        redisTemplate.opsForSet().add("set", "setValue0");
        redisTemplate.opsForSet().add("set", "setValue1");

        //判定是否包含
        Boolean member = redisTemplate.opsForSet().isMember("set", "setValue0");
        System.out.println("isMember:" + member);

        //删除set中的值
        Long remove = redisTemplate.opsForSet().remove("set", "setValue0");
        System.out.println("remove = " + remove);

        //获取set类型值
        Set<String> set = redisTemplate.opsForSet().members("set");
        set.forEach(str -> {
            System.out.println("str = " + str);
        });
    }

    /**
     * 操作 ZSet  有序 不可重复
     */
    @Test
    public void operateZSet() {
        //存储值
        Boolean add = redisTemplate.opsForZSet().add("zset", "zsetValue0", 10);
        System.out.println("add = " + add);
        System.out.println("add = " + add);
        add = redisTemplate.opsForZSet().add("zset", "zsetValue2", 2);
        System.out.println("add = " + add);
        //获取值
        // Boolean zset = redisTemplate.delete("zset");
        // System.out.println("delete zset = " + zset);
    }
}

Redis工具类的封装

/**
 * Redis 工具类
 * @author mosin
 * date 2021/11/30
 * @version 1.0
 */
@Component
public final class RedisUtil {

    private RedisUtil(){};
    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    //设置值
    public void  setValue(String key,String value){
        redisTemplate.opsForValue().set(key, value);
    }
    // 设置值 同时设置有效时间
    public void setValue(String key, String value, Long timeOut, TimeUnit timeUnit){
        redisTemplate.opsForValue().setIfAbsent(key, value, timeOut, timeUnit);
    }

    //设置值 没有则设置 有则不设置
    public void  setNx(String key,String value){
        redisTemplate.opsForValue().setIfAbsent(key, value);
    }

    //设置值 没有则设置 同时设置有效时间 有则不设置
    public void  setNx(String key,String value,long timeOut,TimeUnit timeUnit){
        redisTemplate.opsForValue().setIfAbsent(key, value,timeOut,timeUnit);
    }

    //删除值
    public boolean del(String key){
        return redisTemplate.delete(key);
    }
    
     //获取值
    public String getValue(String key){
        return  redisTemplate.opsForValue().get(key);
    }
}

Redis 业务实践

redis 存储 token,实现非法请求拦截

1.编写拦截器

@Component
public class AdminInterceptor implements HandlerInterceptor {
    @Autowired
    private RedisUtil redisUtil;
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("拦截器以拦截请求");
        //从请求头中获取token  验证用户是否登录
        String token = request.getHeader("token");
        System.out.println(token);
        String tokenValue = redisUtil.getValue(token);
        System.out.println("tokenValue = " + tokenValue);
        if(tokenValue!=null){ //用户已登录 放行请求
            return  true;
        }else{//重定向到登录页面
            response.sendRedirect(request.getContextPath()+"/login.jsp");
            return false;
        }
    }
}

2.配置拦截器

@Configuration
public class LoginConfig implements WebMvcConfigurer {
    @Autowired
    private AdminInterceptor adminInterceptor;
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        InterceptorRegistration registration = registry.addInterceptor(adminInterceptor);
        registration.addPathPatterns("/**");
        registration.excludePathPatterns("/user/login","/user/register","/login.jsp");
    }
}

3.编写统一返回数据格式类

@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class JsonResult<T> {
    private Integer code;
    private String msg;
    private Long count;
    private T data;
}

4.编写控制器

@Controller
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserService userService;
    @Autowired
    private RedisUtil redisUtil;
    @ResponseBody
    @RequestMapping("/login")
    public Object login(User user) throws JsonProcessingException {
        User usr = User.builder().id(1).name("admin").password("123456").build();
        //获取token  放入redis
        String token = UUID.randomUUID().toString().replace("-", "");
        //将user 转为json格式放入 redis
        ObjectMapper objectMapper = new ObjectMapper();
        String s1 = objectMapper.writeValueAsString(usr);
        //将 token 和用户信息存入 redis
        redisUtil.setValue(token, s1, 2L, TimeUnit.MINUTES);
        //将token 存入map集合返回
        HashMap<String, String> map = new HashMap<>();
        map.put("token", token);
        return map;
    }

    @ResponseBody
    @RequestMapping("/register")
    public Object register(User user){
        HashMap<String, String> map = new HashMap<>();
        map.put("msg", "ok");
        return map;
    }

    @ResponseBody
    @RequestMapping("/add")
    public Object add(User user){
        HashMap<String, String> map = new HashMap<>();
        map.put("msg", "ok");
        return map;
    }
}

5.编写业务类和Mapper接口

6.使用postman接口测试工具测试接口

위 내용은 Java SpringBoot 프로젝트에 Redis를 통합하는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 yisu.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제