Redis data types and commands and Java usage

Posted by Rushyo on Mon, 10 Jan 2022 23:01:27 +0100

Basic data type

Specific details can be accessed directly Redis official website , here is only the command summary

  • String binary safe string
  • Lists: a collection of string elements sorted by insertion order. They are basically linked lists.
  • Sets: a collection of non repeating and unordered string elements.
  • Sorted sets (ZSets), similar to Sets, but each string element is associated with a floating number value called score. The elements inside are always sorted by score, so the difference is that it is a series of elements that can be retrieved. (for example, you might ask: give me the first 10 or the last 10 elements).
  • Hashes, a map consisting of a field and an associated value. Both field and value are strings. This is very similar to hashes in Ruby and Python.
  • Bit arrays (or simply bitmaps): through special commands, you can treat String values as a series of bits: you can set and clear individual bits, count the number of bits set to 1, find the first bit set to 1 or 0, and so on.
  • Hyperlogs: This is a probabilistic data structure used to estimate the number of elements in a set.

Redis keys operation

Full command:

DEL key [key ...] # Delete the specified key (one or more)
DUMP key # Serialize the value of the exported key
EXISTS key [key ...] # Query whether a key exists
EXPIRE key seconds # Set the number of seconds a key expires
EXPIREAT key timestamp # Set the expiration time of a UNIX timestamp
KEYS pattern # Finds all keys that match a given pattern
MIGRATE host port key destination-db timeout [COPY] [REPLACE] # Atomically move the key from one instance of redis to another
MOVE key db # Move a key to another database
OBJECT subcommand [arguments [arguments ...]] # Check internal reallocation objects
PERSIST key # Remove the expiration time of the key
PEXPIRE key milliseconds # Set the effective time of the key in milliseconds
PEXPIREAT key milliseconds-timestamp # Set the expiration timestamp of the key in milliseconds
PTTL key # Gets the number of valid milliseconds for the key
RANDOMKEY # Returns a random key
RENAME key newkey # Rename a key
RENAMENX key newkey # Rename a key. The new key must be a nonexistent key
RESTORE key ttl serialized-value [REPLACE] # Deserialization generates a key corresponding to DUMP
SORT key [BY pattern] [LIMIT offset count] [GET pattern [GET pattern ...]] [ASC|DESC] [ALPHA] [STORE destination] # Sort queues, sets, ordered sets
TTL key # Valid time to get key (unit: seconds)
TYPE key # Gets the storage type of the key
WAIT numslaves timeout # Block the current client until all previous write commands are successfully transmitted and the specified slaves are confirmed. timeout=0 will permanently block until numslaves are inserted
SCAN cursor [MATCH pattern] [COUNT count] # Incremental iteration key  
# The SCAN command is used to iterate over the key set in the current database.
# The SSCAN command is used to iterate over the elements in the SET.
# The HSCAN command is used to iterate over key value pairs in a Hash type.
# The ZSCAN command is used to iterate the elements in the SortSet set and the corresponding scores of the elements. Each execution will return only a small number of elements, so these commands can be used in the production environment without the problems that may block the server caused by the KEYS or SMEMBERS commands.
# Cursor must be 0 when starting a new iteration. The cursor returned by the incremental iteration command after execution, which is used to continue the iteration process. 
# MATCH is used to MATCH the key. The pattern matching of elements by the MATCH function is carried out after the command takes out the elements from the dataset and before returning the elements to the client. Therefore, if only a few elements in the iterated dataset MATCH the pattern, the iterative command may not return any elements in multiple executions. 
# The default value of the COUNT parameter is 10. When the dataset is relatively large, if the MATCH option is not used, the number of elements returned by the command is usually the same as or slightly more than that specified by the COUNT option. When iterating over an integer set (intset, a small set consisting only of integer values) or a compressed list (ziplost, a small hash composed of different values or a small ordered set), the incremental iteration command usually ignores the value specified by the COUNT option and returns all elements contained in the dataset to the user in the first iteration.

String type

Full command:

APPEND key value # Append a value to the key
BITCOUNT key [start end] # Counts the number of bytes at the specified starting position of the string
BITFIELD key [GET type offset] [SET type offset value] [INCRBY type offset increment] [OVERFLOW WRAP|SAT|FAIL] # Performs an arbitrary bit field integer operation on a string
BITOP operation destkey key [key ...] # Performs bitwise operations between strings
BITPOS key bit [start] [end] # Finds the first bit set or cleared in the string
DECR key # Integer atom minus 1
DECRBY key decrement # Atomic minus the specified integer
GET key # Returns the value of the key
GETRANGE key start end # Gets a substring of the value stored on the key
GETSET key value # Set the value of a key and get the value before setting
INCR key # Perform atomic plus one operation
INCRBY key increment # The execution atom is incremented by an integer
INCRBYFLOAT key increment # The execution atom adds a floating point number
MGET key [key ...] # Get the values of all key s
MSET key value [key value ...] # Set multiple key value s
MSETNX key value [key value ...] # Set multiple key value s, only when the key exists
PSETEX key milliseconds value # Sets the value and expiration time of the key in milliseconds
SET key value [EX seconds] [PX milliseconds] [NX|XX] # Set the value of a key
SETEX key seconds value # Set key value and expiration time (unit: seconds)
SETNX key value # Set a key value only if the key does not exist
SETRANGE key offset value # Replace specified return substring
STRLEN key # Gets the length of the specified key value

String operation:

127.0.0.1:6379> set hello world  # Set value key = hello value = world
OK
127.0.0.1:6379> get hello # Get the value of hello
"world"
127.0.0.1:6379> set fristKey "hello word"
OK
127.0.0.1:6379> get fristKey
"hello word"
127.0.0.1:6379> keys *  # Query all keys
1) "fristKey"
2) "hello"
127.0.0.1:6379> setex hello 10 redis # Set the valid time of hello to 10s and the value to redis
OK
127.0.0.1:6379> ttl hello #Query remaining time
(integer) 4
127.0.0.1:6379> get hello  # hello has expired
(nil)                       
127.0.0.1:6379> get fristKey
"hello word"
127.0.0.1:6379> set fristKey "hello redis" # Modify the value of fristKey
OK
127.0.0.1:6379> setnx fristKey "is exists" # If fristKey does not exist, set or modify the value
(integer) 0
127.0.0.1:6379> get fristKey
"hello redis"
127.0.0.1:6379> mset k1 v1 k2 v2 k3 v3   # Batch set key (atomic operation, success or failure together)
OK
127.0.0.1:6379> mget k1 k2 k3 fristKey # Batch acquisition 
1) "v1"
2) "v2"
3) "v3"
4) "hello redis"
127.0.0.1:6379> msetnx k5 c2 k1 c1  k6 c3 # After k1 fails, subsequent settings also fail
(integer) 0
127.0.0.1:6379> keys *
1) "fristKey"
2) "k2"
3) "k3"
4) "k1"
127.0.0.1:6379> mget k5 k1 k2 k3
1) (nil)
2) "v1"
3) "v2"
4) "v3"

########################################################################################

127.0.0.1:6379> incr num  # Set num to increment by 1,
(integer) 1
127.0.0.1:6379> decr num # Set num minus 1,
(integer) 0
127.0.0.1:6379> incrby num 2 # Set num += 2,
(integer) 2
127.0.0.1:6379> incrby num 10  # Set num += 10,
(integer) 12
127.0.0.1:6379> decrby num 5  # Set num -= 5,
(integer) 7

########################################################################################
127.0.0.1:6379> strlen fristKey # Get string length
(integer) 11
127.0.0.1:6379> get fristKey
"hello redis"
127.0.0.1:6379> getrange fristKey 1 4 # Intercept string index [1,4]
"ello"
127.0.0.1:6379> getrange fristKey 1 -1 # Intercept string index [1,len-1]
"ello redis"
127.0.0.1:6379> getrange fristKey 0 -1 # Intercepted string index [0,len-1] is equivalent to get
"hello redis"
127.0.0.1:6379> setrange fristKey 2 "la"  # Replace substring from index 2
(integer) 11
127.0.0.1:6379> getrange fristKey 0 -1  
"helao redis"
127.0.0.1:6379> append fristKey " this " # Append append substring after string
(integer) 17
127.0.0.1:6379> getrange fristKey 0 -1
"helao redis this "
127.0.0.1:6379> getset fristKey "hello worl"  # Get the original value and set the new value
"helao redis this "
127.0.0.1:6379> getrange fristKey 0 -1
"hello worl"

Summary of string usage

  1. Ordinary get and set operations, basic key value pair operations, effective time setting (setex), only new operations (setnx), batch operations mget and Mset
  2. Statistics, incr (incrby) and decr (decrby) are available
  3. String operations: get length (strlen), intercept range (getrange), replace (setrange), append substring (append)

Lists type

The basic prefix L is the operation command of list, and the bottom layer of list is the linked list structure

Full command:

BLPOP key [key ...] timeout # Delete and get the first element in the list, or block until one is available
BRPOP key [key ...] timeout # Delete and get the last element in the list, or block until one is available
BRPOPLPUSH source destination timeout # Pop up the value of a list, push it to another list, and return it; Or block until one is available
LINDEX key index # Gets an element through its index list
LINSERT key BEFORE|AFTER pivot value # Inserts an element before or after another element in the list
LLEN key # Gets the length of the queue (List)
LPOP key # Queue an element from the left side of the queue
LPUSH key value [value ...] # Queue one or more elements from the left side of the queue
LPUSHX key value # When the queue exists, an element is queued from the queue to the left
LRANGE key start stop # Gets the specified returned element from the list
LREM key count value # Remove element from list
LSET key index value # Set the value of an element in the queue
LTRIM key start stop # Trim the list to the specified range
RPOP key # One yuan from the right side of the queue
RPOPLPUSH source destination # Deletes the last element in the list and appends it to another list
RPUSH key value [value ...] # Queue an element from the right side of the queue
RPUSHX key value # Queue an element from the right side of the queue, which is valid only when the queue exists

Practical application:

127.0.0.1:6379> lpush list 0 1 2 3  # Insert data from the left into the key=list
(integer) 4
127.0.0.1:6379> rpush list 4 5 6  # Insert data from the right into the list
(integer) 7
127.0.0.1:6379> lrange list 0 -1  # Get the data of list [0,len-1]
1) "3"
2) "2"
3) "1"
4) "0"
5) "4"
6) "5"
7) "6"
127.0.0.1:6379> llen list # Gets the length of the list
(integer) 7
127.0.0.1:6379> lpop list 2 # Take out two pieces of data from the left
1) "3"
2) "2"
127.0.0.1:6379> rpop list  # Take a piece of data from the right
1) "6"
127.0.0.1:6379> lrange list 0 -1 
1) "1"
2) "0"
3) "4"
4) "5"
127.0.0.1:6379> lindex list 2 # Gets the element with index 2
"4"
127.0.0.1:6379> linsert list before 0 2 # Insert '2' before element '0' and after
(integer) 5
127.0.0.1:6379> lrange list 0 -1
1) "1"
2) "2"
3) "0"
4) "4"
5) "5"
127.0.0.1:6379> lrem list 2 0 # Delete 2 elements "0". Here, only 1 element is deleted because there is only one 0 in the list
(integer) 1

#########################################################################################

127.0.0.1:6379> lrange list 0 -1 
1) "1"
2) "2"
3) "4"
4) "5"
127.0.0.1:6379> ltrim list 1 2 # Truncate the list, leaving only [1,2]
OK
127.0.0.1:6379> lrange list 0 -1
1) "2"
2) "4"
127.0.0.1:6379> rpush list 3 5 6 7 8 9
(integer) 8
127.0.0.1:6379> lrange list 0 -1
1) "2"
2) "4"
3) "3"
4) "5"
5) "6"
6) "7"
7) "8"
8) "9"

######################################################################################
127.0.0.1:6379> brpoplpush newlist list 10  # Block operation, take out an element from the right side of the newlist and insert it into the list. When the newlist is empty, wait for 10s at most
(nil)
(10.07s)
127.0.0.1:6379> rpoplpush list newlist # Take an element from the right side of the list and insert it into the newlist
"9"
127.0.0.1:6379> lrange newlist 0 -1
1) "9"
127.0.0.1:6379> brpoplpush newlist list 10  # Blocking operation: take an element from the right side of the newlist and insert it into the list. When the newlist is not empty, operate directly
"9"
127.0.0.1:6379> lrange list 0 -1
1) "9"
2) "2"
3) "4"
4) "3"
5) "5"
6) "6"
7) "7"
8) "8"

list usage summary

  1. Use of two-way linked list: push (lpush left rpush right insert value, operate lpushx,rpushx only when the set exists), pop (l left r right extract value), obtain length (len), obtain index element (lindex), delete corresponding element (lrem), insert value in corresponding element (linsert),

  2. Range acquisition: range (lrange acquisition of specified return elements), truncation (ltrim)

  3. Queue operation: rpoplpush (take it out from the right side of the source set and insert it to the left side of the target set. The source set = = target set becomes a circular list)

    Blocking operation (starting with b, brpoplpush, blpop, brpop. When the source set is empty, the operation will block the waiting time. The maximum waiting time is the set waiting time. Non empty direct operation)

Sets type

Unordered non repeating collection

Full command (beginning with s):

SADD key member [member ...] # Add one or more elements to the set
SCARD key # Gets the number of elements in the collection
SDIFF key [key ...] # Get elements that do not exist in the queue
SDIFFSTORE destination key [key ...] # Get the elements that do not exist in the queue and store them in a key result set
SINTER key [key ...] # Gets the intersection of two sets
SINTERSTORE destination key [key ...] # The intersection of two sets is obtained and stored in a key result set
SISMEMBER key member # Determines that a given value is a member of a collection
SMEMBERS key # Get all elements in the collection
SMOVE source destination member # Move an element in a collection to another collection
SPOP key [count] # (randomly) delete and get the elements in (1 or count) sets
SRANDMEMBER key [count] # Get (1 or count) elements randomly from the collection
SREM key member [member ...] # Deletes one or more elements from the collection
SUNION key [key ...] # Gets the union of multiple set s
SUNIONSTORE destination key [key ...] # Merge the set elements and store the results in a new set
SSCAN key cursor [MATCH pattern] [COUNT count] # Iterate over the elements in the set

Practical application:

127.0.0.1:6379> sadd set1 1 2 3 4 5 6 6 7  # Add the set element, and 6 repeat without adding it
(integer) 7
127.0.0.1:6379> smembers set1 # Get all set elements
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"
6) "6"
7) "7"
127.0.0.1:6379> scard set1 # Gets the number of elements in the set
(integer) 7
127.0.0.1:6379> SRANDMEMBER set1 2
1) "5"
2) "6"
127.0.0.1:6379> SRANDMEMBER set1 # Get an element at random
"5"
127.0.0.1:6379> SRANDMEMBER set1 
"6"
127.0.0.1:6379> SRANDMEMBER set1 
"7"
127.0.0.1:6379> SRANDMEMBER set1 
"2"
127.0.0.1:6379> SRANDMEMBER set1 
"6"
127.0.0.1:6379> SRANDMEMBER set1 
"1"
127.0.0.1:6379> SRANDMEMBER set1 
"2"
127.0.0.1:6379> SRANDMEMBER set1 
"7"
127.0.0.1:6379> SRANDMEMBER set1 
"5"
127.0.0.1:6379> SPOP set1 # Randomly delete and get an element
"7"
127.0.0.1:6379> SPOP set1
"1"
127.0.0.1:6379> SPOP set1
"6"
127.0.0.1:6379> smembers set1
1) "2"
2) "3"
3) "4"
4) "5"
127.0.0.1:6379> srem set1 0 1 2 3 # Delete existing elements
(integer) 2
127.0.0.1:6379> smembers set1
1) "4"
2) "5"
127.0.0.1:6379> sismember set1 4  # See if 4 is set1 Medium price in java in Set#contains
(integer) 1
127.0.0.1:6379> sismember set1 0
(integer) 0

##########################################################################################
127.0.0.1:6379> sadd set2 0 1 2 3 4 
(integer) 5
127.0.0.1:6379> sdiff set1 set2  # Find the difference set between set1 and set2 (set1 - set2)
1) "5"
127.0.0.1:6379> sdiff set2 set1
1) "0"
2) "1"
3) "2"
127.0.0.1:6379> sadd set3 5 6 7 8
(integer) 4
127.0.0.1:6379> sdiff set1 set2 set3 # Find the difference set between set1, set2 and set3 (set1 - set2 - set3)
(empty array)
127.0.0.1:6379> sunion set1 set2 set3 # Find the union of set1, set2 and set3 (set1 ∪ set2 ∪ set3)
1) "0"
2) "1"
3) "2"
4) "3"
5) "4"
6) "5"
7) "6"
8) "7"
9) "8"
127.0.0.1:6379> sunionstore setall set1 set2 set3 # Put the union of set1, set2 and set3 (set1 ∪ set2 ∪ set3) into setall
(integer) 9
127.0.0.1:6379> smembers setall
1) "0"
2) "1"
3) "2"
4) "3"
5) "4"
6) "5"
7) "6"
8) "7"
9) "8"
127.0.0.1:6379> sinter set1 set2 setall   # Find the intersection of set1, set2 and setall (set1 ∩ set2 ∩ set3)
1) "4"

127.0.0.1:6379> smove set2 setall 0 # Move element 0 from set2 to setall
(integer) 1
127.0.0.1:6379> smembers set2
1) "1"
2) "2"
3) "3"
4) "4"
127.0.0.1:6379> smembers setall
1) "0"
2) "1"
3) "2"
4) "3"
5) "4"
6) "5"
7) "6"
8) "7"
9) "8"


Usage Summary:

  1. Ensure no duplication of data
  2. Processing of random values SRANDMEMBER, SPOP
  3. Processing of intersection, union and difference sets of sets SINTER, SUNION and SDIFF

Hashes type

The hash type has a k-v structure under each key. It is similar to the String type (only one more layer of k-v is nested), which is more suitable for storing objects

Full command (beginning with h)

HMSET key field value [field value ...] # Set hash field value
HSET key field value # Set the value of one field in the hash (you can also set multiple fields, equivalent to hmset)
HGET key field # Get the value of field in hash
HGETALL key # Read all fields and values from the hash
HMGET key field [field ...] # Get the value of the specified field in the hash
HLEN key # Get the number of all fields in the hash
HSTRLEN key field # Gets the length of the specified field in the hash
HEXISTS key field # Determine whether the field exists in the hash
HSETNX key field value # Set a field of hash, which is valid only when this field does not exist
HKEYS key # Get all fields of hash
HVALS key # Get all the values of the hash
HDEL key field [field ...] # Delete one or more Hash field s
HINCRBY key field increment # Increases the value of the specified field in the hash by a given number
HINCRBYFLOAT key field increment # Increases the value of the specified field in the hash by a given floating-point number
HSCAN key cursor [MATCH pattern] [COUNT count] # Iterate over the elements in the hash

Practical application:

127.0.0.1:6379> hset user:1 name zhangsan age 18 sex 1  # Set the attribute value of user: 1 object name=zhangsan age=18 sex=1
(integer) 3
127.0.0.1:6379> hget user:1 name # Get user: 1 Name attribute value
"zhangsan"
127.0.0.1:6379> hgetall user:1 # Get all attribute fields and values of user:1
1) "name"
2) "zhangsan"
3) "age"
4) "18"
5) "sex"
6) "1"
127.0.0.1:6379> hlen user:1  # Get the number of user:1 key value pairs
(integer) 3
127.0.0.1:6379> hstrlen user:1 name # Get user: 1 Length of name
(integer) 8
127.0.0.1:6379> HEXISTS user:1 weight  # See if the weight field exists for user:1
(integer) 0
127.0.0.1:6379> hset user:1 weight 120 # Set user: 1 weight=120
(integer) 1
127.0.0.1:6379> hsetnx user:1 weight 100 # user:1.weight does not exist. Setting user: 1 weight=100
(integer) 0
127.0.0.1:6379> hmget user:1 name sex weight
1) "zhangsan"
2) "1"
3) "120"
127.0.0.1:6379> hkeys user:1 # Get all attribute fields of user:1
1) "name"
2) "age"
3) "sex"
4) "weight"
127.0.0.1:6379> hvals user:1 # Get all attribute values of user:1
1) "zhangsan"
2) "18"
3) "1"
4) "120"
127.0.0.1:6379> hincrby user:1 age 1 # Add age field + 1
(integer) 19
127.0.0.1:6379> hincrby user:1 age -10 # Set the age field to - 1
(integer) 9
127.0.0.1:6379> hincrbyfloat user:1 age 0.5 # Add age field + 0.5
"9.5"
127.0.0.1:6379> hincrbyfloat user:1 age -2.556  # Change the age field to -2.556
"6.944"
127.0.0.1:6379> hincrby user:1 age 1  # Only integers can be used, and decimals will report errors
(error) ERR hash value is not an integer

Usage Summary:

  1. It is mainly used to store objects. You can directly operate on field values. The operation is basically the same as that of String

ZSet type

The ordered set and set items have an additional dimension of score score, which is convenient for sorting

Full command (zset at the beginning of z):

ZADD key [NX|XX] [CH] [INCR] score member [score member ...] #Add one or more members to an ordered set, or update the score if it already exists
# 20: Only existing members are updated without adding new members.
# NX: do not update existing members. Add only new members.
# Ch: modify the return value to the total number of changed members. The original value is to return the total number of newly added members (CH means changed). The changed element is a newly added member, and the existing member updates the score. Therefore, members specified in the command with the same score will not be counted. Note: under normal circumstances, the ZADD return value only calculates the number of newly added members.
# INCR: when ZADD specifies this option, the member's operation is the same as the ZINCRBY command, which increments the member's score.
ZCARD key #Gets the number of members in a sorted collection
ZCOUNT key min max #Returns the number of members in the score range
ZINCRBY key increment member #Increment the score of a member in the sort setting
ZINTERSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX] # Intersecting multiple sort sets and sorting settings are stored in a new zset
ZLEXCOUNT key min max # Returns the number of members between members
ZPOPMAX key [count] # Delete the element with the smallest score
ZPOPMIN key [count] # Delete the element with the largest score
ZRANGE key start stop [WITHSCORES] # Returns the member list of sorted set according to the specified index. WITHSCORES is whether to carry score
ZRANGEBYLEX key min max [LIMIT offset count] # Returns the members in the specified member range, arranged in positive order by score, and the scores must be the same.
ZREVRANGEBYLEX key max min [LIMIT offset count] # Returns the members in the specified member range in reverse order of score. The scores must be the same
ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count] # Returns the members within the specified score range in an ordered set, and the scores are sorted from low to high.
ZRANK key member # Determines the index of the members of the sorted collection
ZREM key member [member ...] # Removes one or more members from the sorted collection
ZREMRANGEBYLEX key min max # Delete all members between members whose names are sorted by dictionary from low to high.
ZREMRANGEBYRANK key start stop # All members set in the sort are deleted in the given index
ZREMRANGEBYSCORE key min max # Delete a sorted setting in a given score for all members
ZREVRANGE key start stop [WITHSCORES] # In the sorting setting, the returned member range is ordered from high to low by index
ZREVRANGEBYSCORE key max min [WITHSCORES] [LIMIT offset count] # Returns the members within the specified score range in an ordered set, and the scores are sorted from high to low.
ZREVRANK key member # Determine the members of the index in the sorting set and order from high to low
ZSCORE key member # Gets the score related to the member's sorting settings
ZUNIONSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX] # The settings for merging multiple sort sets and sorting are stored in a new zset
ZSCAN key cursor [MATCH pattern] [COUNT count] # Iterate over the elements in sorted sets

Practical application:

127.0.0.1:6379> zadd zset1 1 a1 2 a2 3 a3 4 a4 # Set zset value
(integer) 4
127.0.0.1:6379> zadd zset1 incr 1 a1 # Set the score of a1 to increase by 1
"2" 
127.0.0.1:6379> zadd zset1 incr 3 a1 # Set the score of a1 to increase by 3
"5"
127.0.0.1:6379> zrange zset1 0 -1  withscores # Get the elements in zset1 according to the index, and WithCores displays the score value
1) "a2"
2) "2"
3) "a3"
4) "3"
5) "a4"
6) "4"
7) "a1"
8) "5"
127.0.0.1:6379> zrangebyscore zset1 -inf inf withscores # Get the elements in zset1 according to the score range. WithCores displays the score value, - inf inf negative infinity to positive infinity
1) "a2"
2) "2"
3) "a3"
4) "3"
5) "a4"
6) "4"
7) "a1"
8) "5"
127.0.0.1:6379> zrangebyscore zset1 4 5 withscores
1) "a4"
2) "4"
3) "a1"
4) "5"
127.0.0.1:6379> zcard zset1  # Get the number of zset1 elements
(integer) 4
127.0.0.1:6379> zcount zset1 0 4 # Count the quantity within the score range
(integer) 3
127.0.0.1:6379> zincrby zset1 -3 a1 # Set a1 score auto increment - 3
"2"
127.0.0.1:6379> zcount zset1 0 4 
(integer) 4
127.0.0.1:6379> zrangebylex zset1 - +  # Get the element according to the interval, - min + Max [including (excluding
1) "a0"
2) "a2"
3) "a3"
127.0.0.1:6379> zrangebylex zset1 (a0 [a3  # Obtain the elements within the range (a0, a3] according to the interval 
1) "a2"
2) "a3"
127.0.0.1:6379> zrank zset1 a0  # Get element index
(integer) 0
127.0.0.1:6379> zrank zset1 a2
(integer) 1

Usage Summary:

  1. It is applicable to automatic de duplication and sorting of elements
  2. Intersection and union sets need to be stored and there is no difference set

Special data type

Geo type (geographic location)

It is used for longitude and latitude of existing geographical cities, and provides the operation of longitude and latitude calculation

Full command:

GEOADD key longitude latitude member [longitude latitude member ...] # Add one or more geospatial locations to the sorted set (which is a sorted set)
GEOHASH key member [member ...] # Returns a standard geospatial Geohash string
GEOPOS key member [member ...] # Returns the latitude and longitude of a geospatial
GEODIST key member1 member2 [unit] # Returns the distance between two geospatials
GEORADIUS key longitude latitude radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] # Queries a collection of all geospatial elements within a specified radius.
GEORADIUSBYMEMBER key member radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] # Queries a geospatial element that matches the maximum distance within a specified radius.

Practical use:

redis-master:0>geoadd loc 103.30 30.2837 c1 # Add a c1 geographical element, longitude and latitude
"1"
redis-master:0>geoadd loc 103.98 31.38137 c2
"1"
redis-master:0>geohash loc c1 c2  # Convert c1 and c2 to hash values
 1)  "wm3kq8uz260"
 2)  "wm9fw0gctx0"
redis-master:0>geopos loc c1 c2 # Obtain the longitude and dimension of c1 and c2
 1)    1)   "103.299998939037323"
  2)   "30.28369891573603212"

 2)    1)   "103.97999793291091919"
  2)   "31.38137005267240198"

redis-master:0>geodist loc c1 c2 m # The distance between C1 and C2 is m
"138287.5103"
redis-master:0>geodist loc c1 c2 km # The distance between C1 and C2 is km
"138.2875"
redis-master:0>georadius loc 104.01928 30.7328 200 km withdist # Query the elements within 200 km of coordinates (104.01928,30.7328) and return the straight-line distance
 1)    1)   "c1"
  2)   "85.1238"

 2)    1)   "c2"
  2)   "72.2351"


redis-master:0>GEORADIUSBYMEMBER loc c2 200 km WITHDIST # Find C2 nodes within 200km
 1)    1)   "c1"
  2)   "138.2875"

 2)    1)   "c2"
  2)   "0.0000"

Usage Summary

  1. It can store geographical location, compare the straight-line distance between two points, and punch in with nearby people and locations

Hyperlogs type (cardinality Statistics)

Like sets, elements are not repeated, but only counted. Use a constant amount of memory! 12kb in the worst case,

Full command: (beginning with pf)

PFADD key element [element ...]  # Adds the specified element to the hyperlog
PFCOUNT key [key ...] # Count the number of all key elements (de duplication)
PFMERGE destkey sourcekey [sourcekey ...] # Merge all sourcekeys into destkey

Practical application:

127.0.0.1:6379> PFADD blog:1 1 3 4 6 5 7 8  # blog1 add statistics element
(integer) 1
127.0.0.1:6379> pfadd blog:1 3 23 5 45 6 45 
(integer) 1
127.0.0.1:6379> pfcount blog:1  # Statistics blog1 element
(integer) 9
127.0.0.1:6379> pfadd blog:2 1 2 3 4 5 6 7 8 9 # blog2 add statistical elements
(integer) 1
127.0.0.1:6379> pfmerge blog:count blog:1 blog:2 # Merge the elements of blog1 and blog2 into blogcount
OK
127.0.0.1:6379> PFCOUNT blog:count
(integer) 11

Usage Summary:

  1. Applications where statistics such as user visits only increase the number (de duplication by value)

Bitmap (bit storage)

Treat the value of a key as a string and operate on bits

Full command: (BIT related)

GETBIT key offset # The value of the return bit is stored at the offset (index) of the key string value.
SETBIT key offset value # Set the value of offset (index) to 0 or 1
BITCOUNT key [start end] # Counts the number of bytes at the specified starting position of the string
BITFIELD key [GET type offset] [SET type offset value] [INCRBY type offset increment] [OVERFLOW WRAP|SAT|FAIL] # Performs an arbitrary bit field integer operation on a string
# Get < type > < offset > – returns the specified bit field
# Set < type > < offset > < value > – sets the value of the specified bit field and returns its original value
# Incrby < type > < offset > < increment > – increment or decrement (if increment is negative) specifies the value of the bit field and returns its new value
# OVERFLOW [WRAP|SAT|FAIL] changes the subsequent operation of calling the INCRBY instruction by setting the overflow behavior
# WRAP: loop back algorithm, applicable to signed and unsigned integer types. For unsigned integers, loop counting will modulo the maximum integer value (the standard behavior of C language). For signed integers, overflow starts from the most negative number, and underflow starts from the largest positive number. For example, if the value of i8 integer is set to 127, the value after adding 1 becomes - 128.
# SAT: saturation algorithm, set the minimum integer value after underflow and the maximum integer value after overflow. For example, if the value of the i8 integer starts from 120 and increases by 10, the result will be 127. If it continues to increase, the result will remain 127. The same is true for underflow, but the result value will remain at the most negative value.
# FAIL: failed algorithm. In this mode, no operation is performed when overflow or underflow is detected. The corresponding return value is set to NULL and returned to the caller.
# type: when an integer is required, the signed integer must be preceded by I, and the unsigned integer must be preceded by u. For example, u8 is an 8-bit unsigned integer and i16 is a 16 bit signed integer. Signed integers support up to 64 bits, while unsigned integers support up to 63 bits. The limitation on unsigned integers is that the current Redis protocol cannot return 64 bit unsigned integers in the response message.
BITOP operation destkey key [key ...] # Performs bitwise operations between strings
BITPOS key bit [start] [end] # Finds the first bit set or cleared in the string

Usage Summary

Mode: use bitmap to count the number of times users go online

Bitmap is very effective for some specific types of calculations.

Suppose we want to record the online frequency of users on our website, for example, calculate how many days user A has been online, how many days user B has been online, and so on, as data, so as to decide which users to participate in beta testing and other activities - this mode can be used SETBIT And BITCOUNT.

For example, whenever a user goes online on a certain day, we use SETBIT, take the user name as the key, take the online date of the website represented on that day as the offset parameter, and set the value on this offset to 1.

For example, if today is the 100th day when the website goes online, and user peter has read the website today, execute the command SETBIT peter 100 1; If peter continues to read the website tomorrow, execute the command SETBIT peter 101 1, and so on.

When you want to calculate the total number of times peter has been online, you can use the count command: execute count peter, and the result is the total number of days peter has been online.

performance

In the previous statistical example of online times, even if it runs for 10 years, the occupied space is only 10 * 365 bits (bits) per user, that is, 456 bytes per user. For data of this size, the processing speed of BITCOUNT is like GET and INCR This O(1) complexity operates just as fast.

If your bitmap data is very large, you can consider using the following two methods:

  • Disperse a large bitmap into different key s and treat it as a small bitmap. This can be done easily using Lua scripts.
  • Using the start and end parameters of BITCOUNT, only part of the required bits are calculated each time, the bit accumulating work is put on the client, and the results are cached.

affair

command

multi # Start transaction
exec # Execute transaction
discard # Abandon transaction
WATCH key [key ...] # Lock the key until the MULTI/EXEC command is executed
UNWATCH #Cancel lock command

Chinese related

By default, redis will escape Chinese. Most of the get codes in the client will be garbled. If the client tests, it can be added when linking

redis-cli --raw

In java, the operation generally needs to use the serialization mode to avoid garbled code

Jedis

jedis is a redis link customer service terminal in Java version. It is very simple to use and is basically consistent with the above commands

Introduce dependency

<dependencies>
    <dependency>
        <groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
        <version>3.1.0</version>
    </dependency>
</dependencies>

Code test

public class JedisTest {

    public static void main(String[] args) {
        // Open client link
        Jedis jedis = new Jedis(host,port);
        // If you have a password, you need to enter it
        jedis.auth(password);

        // Basic link test
        System.out.println(jedis.ping());
        jedis.flushDB();
        System.out.println(jedis.set("k1", "v1"));
        System.out.println(jedis.get("k1"));

        // Set optimistic lock
        jedis.watch("k1");
        Transaction multi = jedis.multi();
        try {
            // After the transaction starts, the command is invoked using the transaction object
            multi.mset("k1","d2","k2","v2","k3","v3");
            //Manufacturing exception view transaction
//            int i = 1/0;
            multi.lpush("list","a","b","c","d");

            // Execute transaction
            multi.exec();
        }catch (Exception e){
            e.printStackTrace();
            // Abandon transaction
            multi.discard();
            jedis.unwatch();
        }finally {
            System.out.println(jedis.mget("k1","k2","k3"));
            System.out.println(jedis.lrange("list",0,-1));
        }
        // Close link
        jedis.close();

    }
}

Advantages and disadvantages of Jedis:

advantage:

  1. Use direct connection: simple and convenient, suitable for a small number of long-term connection scenarios

  2. Using connection pool: there is no need to generate Jedis objects every connection to reduce the overhead

  3. Protect and control the use of resources in the form of connection pools

Disadvantages:

  1. Use direct connection: there is overhead for each new / closed TCP connection
  2. Use direct connection: resources cannot be controlled, and connection leakage occurs in extreme cases
  3. Using connection pool: Jedis object is thread unsafe (Lettuce object is thread safe)
  4. Using connection pool: compared with direct connection, it is more troublesome to use. In particular, many parameters are required to ensure resource management. Once the planning is unreasonable, problems will occur

Springboot

Introducing redis starter

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

The redis client used in springboot is provided by spring data, which mainly encapsulates jedis and Lettuce

redisTemplate is used for external operations (serializable objects need to be passed in every operation)

redisTemplate. keys or general operation commands

redisTemplate.opsForValue() String (bitmap is also classified as String)
redisTemplate.opsForList() List
redisTemplate.opsForHash() hash
redisTemplate.opsForSet() set
redisTemplate.opsForZSet() zset
redisTemplate.opsForGeo() geo
redisTemplate.opsForHyperLogLog() HyperLogLog

to configure

application.yml:

spring:
  redis:
    # The password is blank by default
    password: 123456  
    # The ip address defaults to localhost
    host: localhost
    # The default port number is 6379
    port: 6379
    # Connection timeout (MS)
    connect-timeout: 1000
    jedis:
      pool:
        # Maximum number of connections in the connection pool (negative value indicates no limit)
        max-active: 200
        # Maximum blocking wait time of connection pool (negative value indicates no limit)
        max-wait: 1000ms
        # Maximum free connections in the connection pool
        max-idle: 10
        # Minimum free connections in connection pool
        min-idle: 0

Configure RedisTemplate,

RedisConf.java:

@Component
public class RedisConf {

    /**
     * Configure redistemplate key value serialization
     * @param factory
     * @return
     */
    @Bean
    @SuppressWarnings("all")
    public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory factory){
        RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
        template.setConnectionFactory(factory);
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        // The key is serialized by String
        template.setKeySerializer(stringRedisSerializer);
        // The key of hash is also serialized by String
        template.setHashKeySerializer(stringRedisSerializer);
        // value is serialized by jackson
        template.setValueSerializer(jackson2JsonRedisSerializer);
        // The value serialization method of hash is jackson
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        template.afterPropertiesSet();
        return template;
    }
}

Encapsulating common simple operations

(e.printStackTrace() replace the project requirements with log error())

RedisUtil.java:

@Component
public final class RedisUtil {
    
    @Resource(name = "redisTemplate")
    private RedisTemplate<String, Object> redisTemplate;

    // =============================common============================
    /**
     * Specify cache expiration time
     *
     * @param key  key
     * @param time Time (seconds)
     * @return
     */
    public boolean expire(String key, long time) {
        try {
            if (time > 0) {
                redisTemplate.expire(key, time, TimeUnit.SECONDS);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * Get expiration time according to key
     *
     * @param key Key cannot be null
     * @return Time (seconds) returns 0, which means it is permanently valid
     */
    public long getExpire(String key) {
        return redisTemplate.getExpire(key, TimeUnit.SECONDS);
    }

    /**
     * Determine whether the key exists
     *
     * @param key key
     * @return true Exists false does not exist
     */
    public boolean hasKey(String key) {
        try {
            return redisTemplate.hasKey(key);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * Delete cache
     *
     * @param key One or more values can be passed
     */
    public void del(String... key) {
        if (key != null && key.length > 0) {
            if (key.length == 1) {
                redisTemplate.delete(key[0]);
            } else {
                redisTemplate.delete((Collection<String>) CollectionUtils.arrayToList(key));
            }
        }
    }

    // ============================String=============================

    /**
     * Normal cache fetch
     *
     * @param key key
     * @return value
     */
    public Object get(String key) {
        return key == null ? null : redisTemplate.opsForValue().get(key);
    }

    /**
     * Normal cache put
     *
     * @param key   key
     * @param value value
     * @return true Success false failure
     */
    public boolean set(String key, Object value) {
        try {
            redisTemplate.opsForValue().set(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }

    }

    /**
     * Normal cache put and set time
     *
     * @param key   key
     * @param value value
     * @param time  Time (seconds) time must be greater than 0. If time is less than or equal to 0, the infinite period will be set
     * @return true Success false failure
     */
    public boolean set(String key, Object value, long time) {
        try {
            if (time > 0) {
                redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
            } else {
                set(key, value);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * Increasing
     *
     * @param key   key
     * @param delta How many to add (greater than 0)
     * @return
     */
    public long incr(String key, long delta) {
        if (delta < 0) {
            throw new RuntimeException("The increment factor must be greater than 0");
        }
        return redisTemplate.opsForValue().increment(key, delta);
    }

    /**
     * Diminishing
     *
     * @param key   key
     * @param delta How many to reduce (less than 0)
     * @return
     */
    public long decr(String key, long delta) {
        if (delta < 0) {
            throw new RuntimeException("Decrement factor must be greater than 0");
        }
        return redisTemplate.opsForValue().increment(key, -delta);
    }

    // ================================Map=================================

    /**
     * HashGet
     *
     * @param key  Key cannot be null
     * @param item Item cannot be null
     * @return value
     */
    public Object hget(String key, String item) {
        return redisTemplate.opsForHash().get(key, item);
    }

    /**
     * Get all key values corresponding to hashKey
     *
     * @param key key
     * @return Corresponding multiple key values
     */
    public Map<Object, Object> hmget(String key) {
        return redisTemplate.opsForHash().entries(key);
    }

    /**
     * HashSet
     *
     * @param key key
     * @param map Corresponding to multiple key values
     * @return true Success false failure
     */
    public boolean hmset(String key, Map<String, Object> map) {
        try {
            redisTemplate.opsForHash().putAll(key, map);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * HashSet And set the time
     *
     * @param key  key
     * @param map  Corresponding to multiple key values
     * @param time Time (seconds)
     * @return true Success false failure
     */
    public boolean hmset(String key, Map<String, Object> map, long time) {
        try {
            redisTemplate.opsForHash().putAll(key, map);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * Put data into a hash table. If it does not exist, it will be created
     *
     * @param key   key
     * @param item  term
     * @param value value
     * @return true Success false failure
     */
    public boolean hset(String key, String item, Object value) {
        try {
            redisTemplate.opsForHash().put(key, item, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * Put data into a hash table. If it does not exist, it will be created
     *
     * @param key   key
     * @param item  term
     * @param value value
     * @param time  Time (seconds): Note: if the existing hash table has time, the original time will be replaced here
     * @return true Success false failure
     */
    public boolean hset(String key, String item, Object value, long time) {
        try {
            redisTemplate.opsForHash().put(key, item, value);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * Delete values from hash table
     *
     * @param key  Key cannot be null
     * @param item Item can make multiple non null able
     */
    public void hdel(String key, Object... item) {
        redisTemplate.opsForHash().delete(key, item);
    }

    /**
     * Judge whether there is a value of this item in the hash table
     *
     * @param key  Key cannot be null
     * @param item Item cannot be null
     * @return true Exists false does not exist
     */
    public boolean hHasKey(String key, String item) {
        return redisTemplate.opsForHash().hasKey(key, item);
    }

    /**
     * hash If increment does not exist, it will create one and return the added value
     *
     * @param key  key
     * @param item term
     * @param by   How many to add (greater than 0)
     * @return
     */
    public double hincr(String key, String item, double by) {
        return redisTemplate.opsForHash().increment(key, item, by);
    }

    /**
     * hash Diminishing
     *
     * @param key  key
     * @param item term
     * @param by   To reduce (less than 0)
     * @return
     */
    public double hdecr(String key, String item, double by) {
        return redisTemplate.opsForHash().increment(key, item, -by);
    }

    // ============================set=============================

    /**
     * Get all the values in the Set according to the key
     *
     * @param key key
     * @return
     */
    public Set<Object> sGet(String key) {
        try {
            return redisTemplate.opsForSet().members(key);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * Query from a set according to value whether it exists
     *
     * @param key   key
     * @param value value
     * @return true Exists false does not exist
     */
    public boolean sHasKey(String key, Object value) {
        try {
            return redisTemplate.opsForSet().isMember(key, value);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * Put data into set cache
     *
     * @param key    key
     * @param values Values can be multiple
     * @return Number of successful
     */
    public long sSet(String key, Object... values) {
        try {
            return redisTemplate.opsForSet().add(key, values);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

    /**
     * Put set data into cache
     *
     * @param key    key
     * @param time   Time (seconds)
     * @param values Values can be multiple
     * @return Number of successful
     */
    public long sSetAndTime(String key, long time, Object... values) {
        try {
            Long count = redisTemplate.opsForSet().add(key, values);
            if (time > 0) {
                expire(key, time);
            }
            return count;
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

    /**
     * Gets the length of the set cache
     *
     * @param key key
     * @return
     */
    public long sGetSetSize(String key) {
        try {
            return redisTemplate.opsForSet().size(key);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

    /**
     * Remove with value
     *
     * @param key    key
     * @param values Values can be multiple
     * @return Number of removed
     */
    public long setRemove(String key, Object... values) {
        try {
            Long count = redisTemplate.opsForSet().remove(key, values);
            return count;
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
    // ===============================list=================================

    /**
     * Get the contents of the list cache
     *
     * @param key   key
     * @param start start
     * @param end   End 0 to - 1 represent all values
     * @return
     */
    public List<Object> lGet(String key, long start, long end) {
        try {
            return redisTemplate.opsForList().range(key, start, end);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * Gets the length of the list cache
     *
     * @param key key
     * @return
     */
    public long lGetListSize(String key) {
        try {
            return redisTemplate.opsForList().size(key);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

    /**
     * Get the value in the list through the index
     *
     * @param key   key
     * @param index When index index > = 0, 0 header, 1 second element, and so on; When index < 0, - 1, footer, - 2, the penultimate element, and so on
     * @return
     */
    public Object lGetIndex(String key, long index) {
        try {
            return redisTemplate.opsForList().index(key, index);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * Put list into cache
     *
     * @param key   key
     * @param value value
     * @return
     */
    public boolean lSet(String key, Object value) {
        try {
            redisTemplate.opsForList().rightPush(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * Put list into cache
     *
     * @param key   key
     * @param value value
     * @param time  Time (seconds)
     * @return
     */
    public boolean lSet(String key, Object value, long time) {
        try {
            redisTemplate.opsForList().rightPush(key, value);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * Put list into cache
     *
     * @param key   key
     * @param value value
     * @return
     */
    public boolean lSet(String key, List<Object> value) {
        try {
            redisTemplate.opsForList().rightPushAll(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * Put list into cache
     *
     * @param key   key
     * @param value value
     * @param time  Time (seconds)
     * @return
     */
    public boolean lSet(String key, List<Object> value, long time) {
        try {
            redisTemplate.opsForList().rightPushAll(key, value);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * Modify a piece of data in the list according to the index
     *
     * @param key   key
     * @param index Indexes
     * @param value value
     * @return
     */
    public boolean lUpdateIndex(String key, long index, Object value) {
        try {
            redisTemplate.opsForList().set(key, index, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * Remove N values as value
     *
     * @param key   key
     * @param count How many are removed
     * @param value value
     * @return Number of removed
     */
    public long lRemove(String key, long count, Object value) {
        try {
            Long remove = redisTemplate.opsForList().remove(key, count, value);
            return remove;
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
}

test

@SpringBootTest
class NosqlBootApplicationTests {

    @Test
    void contextLoads() {
    }

    @Autowired
    RedisTemplate<String,Object> redisTemplate;
    @Autowired
    RedisUtil redisUtil;

    @Test
    void restTest(){
        // Normal operation
        redisUtil.set("k1","s1");
        long num1 = redisUtil.incr("num1", 2);
        System.out.println(num1);

        // Transaction operation
        List<Object> execute = redisTemplate.execute(new SessionCallback<List<Object>>() {
            @Override
            public List<Object> execute(RedisOperations redisOperations) throws DataAccessException {
                redisOperations.watch(Arrays.asList("k1","k2"));
                redisOperations.multi();
                redisOperations.opsForValue().multiSet(Map.of("k1", "v1", "k2", "v2")); // Map.of refers to the occurrence of JAVA9, and the self put below 8
                redisOperations.opsForValue().multiGet(Arrays.asList("k1", "k2"));
                return redisOperations.exec();
            }
        });
        System.out.println(execute);
    }
}
2
[true, [v1, v2]]

Topics: Java Redis data structure map