Skip to main content

v6.2.0 (2025-11-22)

<dependency>
<groupId>net.hasor</groupId>
<artifactId>jdbc-redis</artifactId>
<version>6.2.0</version>
</dependency>

Impact

  • JdbcOperations interface and JdbcTemplate class
  • dbvisitor-driver project
  • jdbc-redis driver

Changes

  • Added
    • Adapt jdbc-redis driver for Mapper annotations, Mapper File, and JdbcTemplate APIs.
    • Restore BindTypeHandler annotation from 5.x.
    • Add resultTypeHandler to XmlMapper and @Query for TypeHandler configuration.
    • TypeHandlerColumnRowMapper can be used as a RowMapper.
    • jdbc-redis adds PING, ECHO, SELECT, INFO commands.
    • Support connecting Redis via jdbc-redis in DataGrip/IDEA Database plugin.
    • ResultSetExtractor gains PairsResultSetExtractor to convert result sets to key-value collections.
    • JdbcOperations/JdbcTemplate add three queryForPairs methods to convert each row into a key-value pair.
    • New pairs rule to iterate Map/List/Array and generate query conditions via template.
  • Changed
    • queryForLong return type: Long (was long).
    • queryForInt return type: Integer (was int).
    • AbstractRowMapper.getResultSetTypeHandler(ResultSet, int, Class) moved to TypeHandlerRegistry.
    • jdbc-redis MSET/MSETNX now return number of added keys (previously always 1).
    • For StoreSet-related commands outputting SCORE and ELEMENT, field order becomes ELEMENT, SCORE. Applies to: ZPOPMAX, ZPOPMIN, ZDIFF, ZINTER, ZRANDMEMBER, ZRANGE, ZRANGEBYSCORE, ZREVRANGE, ZREVRANGEBYSCORE, ZUNION, ZMPOP, BZMPOP, BZPOPMAX, BZPOPMIN, ZSCAN.
  • Improved
    • jdbc-redis supports ResultSet.isLast.
    • Some commands now return results via updateCount, including:
      • HKEYS, HDEL, DEL, SET, HSET, HMSET, HSETNX, EXPIRE, EXPIREAT, PEXPIRE, PEXPIREAT, PERSIST, RENAME, RENAMENX, TOUCH, LINSERT, LPUSH, LPUSHX, RPUSH, RPUSHX, LREM, LSET, LTRIM, MOVE, SADD, SDIFFSTORE, SINTERSTORE, SMOVE, SREM, SUNIONSTORE, ZDIFFSTORE, ZINTERSTORE, ZRANGESTORE, ZREM, ZREMRANGEBYLEX, ZREMRANGEBYRANK, ZREMRANGEBYSCORE, ZUNIONSTORE, MSET, MSETNX, PSETEX, SETEX, SETNX, SETRANGE
    • antlr4 dependency is shaded into the jdbc-redis JAR to reduce external deps.
    • Improved jdbc-redis error messages.
    • ConvertUtils in dbvisitor-driver supports Byte[] in toBytes.
  • Fixed
    • jdbc-redis Statement.getLargeUpdateCount / getUpdateCount threw SQLException when no result set; now return -1 per JDBC spec when no more results.
    • jdbc-redis keys command execution failure.

What does queryForPairs do?

使用 JdbcTemplate 查询键值对
// 查询用户表,将用户 ID 和用户名作为 Map 返回
Map<Long, String> userMap = jdbc.queryForPairs("select uid, name from user", Long.class, String.class);

Redis 兼容如何使用?

使用 JdbcTemplate 存取对象
// 1. 使用 BindTypeHandler 注释标记 UserInfo 类,指定使用 JsonTypeHandler 来处理该类的序列化和反序列化
@BindTypeHandler(JsonTypeHandler.class)
public class UserInfo {
...
}

// 2. 获取 Redis 连接,并构建 JdbcTemplate
Connection redisConn = ...; // 参考文档:驱动适配器 > JDBC Redis > 如何使用
JdbcTemplate jdbc = new JdbcTemplate(redisConn);

// 3. 创建 UserInfo 对象,将其插入到 Redis 中,并使用 Json 序列化存储
UserInfo user = new UserInfo();
user.setUid("j1111");
user.setName("username");
user.setLoginName("login_123");
user.setLoginPassword("password");

// 4. 使用 user_ + uid 作为键名,arg0 为 user 对象
int affected = jdbc.executeUpdate("set #{'user_' + arg0.uid} #{arg0}", user);

// 5. 从 Redis 中查询 UserInfo 对象,并进行反序列化
UserInfo info = jdbc.queryForObject("get #{'user_' + arg0}", "j1111", UserInfo.class);

// 6. 删除 Redis 中的 UserInfo 对象
int deleteCount = jdbc.executeUpdate("del #{'user_' + arg0.uid}", user);
使用 Mapper 注解存取对象
// 1. 使用 BindTypeHandler 注释标记 UserInfo 类,指定使用 JsonTypeHandler 来处理该类的序列化和反序列化
@BindTypeHandler(JsonTypeHandler.class)
public class UserInfo {
...
}

@SimpleMapper()
public interface UserInfo1Mapper {
// 1. 生成参数化命令:set ? ?
// 2. 决定键名: #{'user_' + info.uid}
// 3. 键的值: #{info}
@Insert("set #{'user_' + info.uid} #{info}")
int saveUser(@Param("info") UserInfo info);

// 1. 生成参数化命令:get ?
// 2. 决定键名: #{'user_' + uid}
@Query("get #{'user_' + uid}")
UserInfo loadUser(@Param("uid") String uid);

// 1. 生成参数化命令:del ?
// 2. 决定键名: #{'user_' + uid}
@Delete("del #{'user_' + uid}")
int deleteUser(@Param("uid") String uid);
}
使用 Mapper File 管理命令(Mapper)
@RefMapper("dbvisitor_scene/redis/user-mapper.xml")
public interface UserInfoMapper {
int saveUser(@Param("info") UserInfo info);

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

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

int deleteUser(@Param("uid") String uid);
}
使用 Mapper File 管理命令(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.hasor.scene.UserInfoMapper">
<insert id="saveUser">
set #{'user_' + uid} #{info}
</insert>

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

<delete id="deleteUser">
del #{'user_' + uid}
</delete>
</mapper>