Skip to main content
Hint

This article is generated by AI translation.

Redis Datasource Specifics

dbVisitor accesses Redis data sources via the JDBC-Redis driver, based on the JDBC protocol.

Supported capabilities:

Not supported: Fluent API, BaseMapper, Object Mapping, ResultSet Mapping, executeBatch, stored procedures

Concept Analogy

Different Redis commands produce three types of results:

  • Update count — analogous to INSERT/UPDATE/DELETE, retrieved via executeUpdate
  • Single/multiple row results — analogous to SELECT result sets

Command Mode (JdbcTemplate)

Use JdbcTemplate to execute Redis commands directly. Ensure you have properly configured the Redis data source first — see Redis Driver Usage Guide.

Tip

For more usage patterns, see JdbcTemplate. The following features are not supported due to driver limitations:

  • Batch operations
  • Stored procedures
Create JdbcTemplate
JdbcTemplate jdbc = new JdbcTemplate(dataSource);
// or
JdbcTemplate jdbc = new JdbcTemplate(connection);

Key Read/Write/Delete

Read Key
// Direct command
String result1 = jdbc.queryForString("GET myKey");
// Parameterized command
String result2 = jdbc.queryForString("GET ?", "myKey");
Write Key
// Direct command
int result1 = jdbc.executeUpdate("SET myKey myValue");
// Parameterized command
int result2 = jdbc.executeUpdate("SET ? ?", new Object[] { "myKey", "myValue" });
Delete Key
// Direct command
int result1 = jdbc.executeUpdate("DEL myKey");
// Parameterized command
int result2 = jdbc.executeUpdate("DEL ?", "myKey");

Key Read/Write/Delete (Multiple Keys)

Read multiple Keys
Map<String, Integer> result = jdbc.queryForPairs("MGET ? ? ?", String.class, Integer.class,
new Object[] { "key1", "key2", "key3" });
Write multiple Keys
int result = jdbc.executeUpdate("MSET ? ? ? ? ? ?",
new Object[] { "key1", "value1", "key2", "value2", "key3", "value3" });
Delete multiple Keys
int result = jdbc.executeUpdate("DEL ? ? ?", new Object[] { "key1", "key2", "key3" });

Object Read/Write

Bind JSON serialization with @BindTypeHandler
@BindTypeHandler(JsonTypeHandler.class)
public class MyObject {
...
}
Read/write objects
// Read object
MyObject obj = jdbc.queryForObject("GET ?", MyObject.class, "myObjectKey");
// Write object
jdbc.executeUpdate("SET ? ?", new Object[] { "myObjectKey", (MyObject) myObject });

Annotations

Tip

All annotations provided by the core API work on Redis data sources, except for the @Call annotation.

1. Define object with JSON serialization
@BindTypeHandler(JsonTypeHandler.class)
public class UserInfo {
private String uid;
private String name;
... // getters/setters omitted
}
2. Define Mapper interface
// Key name uses prefix "user_" combined with UID for storing/retrieving user info
@SimpleMapper()
public interface UserInfoMapper {
@Insert("set #{'user_' + info.uid} #{info}")
int saveUser(@Param("info") UserInfo info);

@Query("get #{'user_' + uid}")
UserInfo loadUser(@Param("uid") String uid);

@Delete("del #{'user_' + uid}")
int deleteUser(@Param("uid") String uid);
}
3. Create and use Mapper
Configuration config = new Configuration();
Session session = config.newSession(dataSource);

UserInfoMapper mapper = session.createMapper(UserInfoMapper.class);

File Mode (Mapper File)

Tip

In XML Mapper files, when configuring object serialization mapping via the select tag, the resultType attribute must be specified to correctly discover the BindTypeHandler annotation on the object.

1. Define object with JSON serialization
@BindTypeHandler(JsonTypeHandler.class)
public class UserInfo {
private String uid;
private String name;

... // getters/setters omitted
}
2. Define Mapper file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//dbvisitor.net//DTD Mapper 1.0//EN"
"https://www.dbvisitor.net/schema/dbvisitor-mapper.dtd">
<mapper namespace="net.test.dto.UserInfoMapper">
<insert id="saveUser">
set #{'user_' + uid} #{info}
</insert>

<select id="loadUser" resultType="net.test.dto.UserInfo">
get #{'user_' + uid}
</select>

<delete id="deleteUser">
del #{'user_' + uid}
</delete>
</mapper>
3. Define Mapper interface
@RefMapper("dbvisitor/mapper/UserInfoMapper.xml")
public interface UserInfoMapper {
int saveUser(@Param("info") UserInfo info);

UserInfo loadUser(@Param("uid") String uid);

int deleteUser(@Param("uid") String uid);
}
4. Create and use Mapper
Configuration config = new Configuration();
Session session = config.newSession(dataSource);

UserInfoMapper mapper = session.createMapper(UserInfoMapper.class);

Redis Data Type Operations

Redis has 5 main data types. Below is how to use dbVisitor for read/write operations on each type.

Tip

Redis main data type command reference: String, Hash, List, Set, SortedSet

String

Read/write strings via GET/SET commands
jdbc.executeUpdate("SET ? ?", new Object[] { "myKey", "myValue" });
String value = jdbc.queryForString("GET ?", "myKey");
Set expiration time when writing
jdbc.executeUpdate("SETEX ? ? ?", new Object[] { "myKey", 60, "myValue" });
jdbc.executeUpdate("SET ? ? EX ?", new Object[] { "myKey", "myValue", 60 });
Increment/decrement numeric values via INCR/DECR commands
jdbc.executeUpdate("SET myKey 0");                      // Initial value 0
String result = jdbc.queryForString("INCR ?", "myKey"); // Value after increment: 1
String result = jdbc.queryForString("DECR ?", "myKey"); // Value after decrement: 0
Append/substring via APPEND/GETRANGE commands
jdbc.executeUpdate("SET myKey myValue");                                              // Initial value: myValue
String result = jdbc.queryForString("APPEND ? ?", new Object[] { "myKey", "123" }); // After append: myValue123
String result = jdbc.queryForString("GETRANGE ? ? ?", new Object[] { "myKey", 0, 5 });// After substring: myVal
Read/write objects using JSON serialization
// MyObject type needs to be annotated with @BindTypeHandler(JsonTypeHandler.class)
jdbc.queryForObject("GET myObjectKey", MyObject.class);
jdbc.executeUpdate("SET myObjectKey ?", (MyObject) myObject);

Hash

Read/write hash fields via HSET/HGET commands
jdbc.executeUpdate("HSET myHashKey field1 value1");
jdbc.queryForString("HGET ? ?", new Object[] { "myHashKey", "field1" });
Read all fields under a hash key via HKEYS command
List<String> keys = jdbc.queryForList("HKEYS myHashKey", String.class);
Read all fields and values under a hash key via HGETALL command
Map<String, String> hashFields = jdbc.queryForPairs("HGETALL myHashKey", String.class, String.class);
Persist a Map to a hash key using the @{pairs} rule
Map<String,String> hashData = new HashMap<>();
hashData.put("field1", "value1");
hashData.put("field2", "value2");
jdbc.executeUpdate("HSET myKey1 @{pairs, :arg0, :k :v}", SqlArg.valueOf(hashData));

List

Read/write list elements
jdbc.executeUpdate("LPUSH myListKey value1 value2 value3");
String result = jdbc.queryForString("LPOP myListKey"); // value3
String result = jdbc.queryForString("RPOP myListKey"); // value1
Implement message queue via LPUSH/BLPOP
// Left-in right-out blocking queue
jdbc.executeUpdate("LPUSH myListKey value1");
String result = jdbc.queryForString("BRPOP myListKey");
// Right-in left-out blocking queue
jdbc.executeUpdate("RPUSH myListKey value1");
String result = jdbc.queryForString("BLPOP myListKey");
Persist a List to a list key using the @{pairs} rule
List<String> listData = new ArrayList<>();
listData.add("value1");
listData.add("value2");
jdbc.executeUpdate("LPUSH myListKey @{pairs, :arg0, :v}", SqlArg.valueOf(listData));

Set

Read/write set elements via SADD/SMEMBERS commands
jdbc.executeUpdate("SADD mySetKey value1 value2 value3");
jdbc.queryForList("SMEMBERS mySetKey", String.class);
Tag articles by leveraging the uniqueness of SET keys
jdbc.executeUpdate("SADD article_1 tag1 tag2");
jdbc.executeUpdate("SADD article_1 tag1 tag3");
jdbc.queryForList("SMEMBERS article_1", String.class); // Result: [tag1, tag2, tag3]
Persist Map keys to a Set using the @{pairs} rule
Map<String,String> hashData = new HashMap<>();
hashData.put("field1", "value1");
hashData.put("field2", "value2");
jdbc.executeUpdate("SADD myKey1 @{pairs, :arg0, :k}", SqlArg.valueOf(hashData));
jdbc.queryForList("SMEMBERS myKey1", String.class); // Result: [field1, field2]

Sorted Set

Sorted Set is similar to Set, but each element has a score, allowing elements to be sorted by score.

Read/write elements via ZADD/ZRANGEBYSCORE commands
jdbc.execute("ZADD mySetKey 3 value3 2 value2 1 value1");
jdbc.queryForList("ZRANGEBYSCORE mySetKey -inf +inf ", String.class); // [value1, value2, value3]
Store elements with scores in a Map and persist to ZSet
Map<String,Double> hashData = new HashMap<>();
hashData.put("field1", 3.0);
hashData.put("field2", 2.0);
hashData.put("field3", 1.0);
jdbc.executeUpdate("ZADD myKey1 @{pairs, :arg0, :v :k}", SqlArg.valueOf(hashData));
jdbc.queryForList("ZRANGEBYSCORE myKey1 -inf +inf ", String.class); // [field3, field2, field1]
Persist scored data to ZSet using Tuple type and @{pairs} rule
List<Tuple> data = new ArrayList<>();
data.add(Tuple.of("field1", 3.0));
data.add(Tuple.of("field2", 2.0));
data.add(Tuple.of("field3", 1.0));
jdbc.queryForString("ZADD myKey1 @{pairs, :arg0, :v.arg1 :v.arg0 }", SqlArg.valueOf(data));
jdbc.queryForList("ZRANGEBYSCORE myKey1 -inf +inf ", String.class); // [field3, field2, field1]
  • Reference: ZADD command, PAIRS Rule
  • In addition to Tuple type, you can also use Map type or custom types to store elements and scores