1.情况
SpringBoot在使用@Cacheable缓存对象为空
具体就是在实体类的时候,List<Integer>为空
1.1 实体类
@Schema( description = "赠送礼物id")
private List<Integer> itemId;
@Schema( description = "赠送礼物数量")
private List<Integer> itemNum;1.2 数据库
item_id varchar(255)
item_num varchar(255)
1.3 Service
@Cacheable(cacheNames = "Task", sync = true, key = "#root.methodName+ '_'+ #root.args[1] + #page + '_' + #size")1.4 具体情况
在mybatisplus的日志中
Row: 5, 1333, 333, [3037], [1], 1, 2025-11-05 16:10:45, null, 2025-11-05 16:10:45, 0
也就是在mybatisplus读取数据的时候是正常的,但是
List<Task> taskList = iPage.getRecords();
for (Task task1 : taskList) {
System.out.println(task1);
System.out.println(task1.getItemId() + "---" + task1.getItemNum());
}在输出taskList的时候
Task(id=9, name=555, content=555, itemId=null, itemNum=null, onlineCount=1, createTime=Wed Nov 05 16:54:30 CST 2025, endTime=Thu Nov 06 00:00:00 CST 2025, updateTime=Wed Nov 05 16:54:30 CST 2025, deleted=0)
null---null
可以看到itemId itemNum均为null
redisTemplate配置了FastJsonRedisSerializer
就是在转为 List<Integer>的时候出了问题
2.解决方案
我的Fastjson2
2.1 maven导入Fastjson2
<!-- fastJson -->
<!-- https://mvnrepository.com/artifact/com.alibaba.fastjson2/fastjson2 -->
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>2.0.59</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba.fastjson2/fastjson2-extension-spring6 -->
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2-extension-spring6</artifactId>
<version>2.0.59</version>2.2 附上我的RedisConfig.java
import com.alibaba.fastjson2.support.spring6.data.redis.FastJsonRedisSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.time.Duration;
import java.util.HashMap;
import java.util.Map;
@Configuration
//@EnableCaching开启对SpringCache的支持(提供基于方法级别的缓存)
@EnableCaching
public class RedisConfig {
/**
* 默认缓存到期时间
*/
private static final Integer DEFAULT_EXPIRE_TIME = 3600;
@Bean
@SuppressWarnings("all")
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory, ObjectMapper objectMapper) {
//便于开发自己编写redis
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
//序列化配置
// GenericJackson2JsonRedisSerializer serializer = new GenericJackson2JsonRedisSerializer();
FastJsonRedisSerializer<Object> serializer = new FastJsonRedisSerializer<>(Object.class);
// FastJson2JsonRedisSerializer<Object> serializer = new FastJson2JsonRedisSerializer<>(Object.class);
//string序列化
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
//key 采用string的序列化
template.setKeySerializer(stringRedisSerializer);
template.setValueSerializer(serializer);
//hansh的key也采用string的序列化方式
template.setHashKeySerializer(stringRedisSerializer);
//hansh的value也采用string的序列化方式
template.setHashValueSerializer(serializer);
//设置默认
template.setDefaultSerializer(serializer);
template.afterPropertiesSet();
return template;
}
/**
* 配置SpringCache基于方法级别的缓存的过期时间、key-value的序列化方式
*
* @param connectionFactory
* @return
*/
@Bean
public RedisCacheManager cacheManager(RedisConnectionFactory connectionFactory) {
//设置特有的Redis配置
Map<String, RedisCacheConfiguration> speCacheConfigurations = new HashMap<>();
//定制化的Cache为300s\400s\500s
speCacheConfigurations.put("cacheName1",redisCacheConfiguration(300));
speCacheConfigurations.put("cacheName2",redisCacheConfiguration(400));
speCacheConfigurations.put("cacheName3",redisCacheConfiguration(500));
//根据redis缓存配置和redis连接工厂生成redis缓存管理器
RedisCacheManager redisCacheManager = RedisCacheManager.builder(connectionFactory)
.cacheDefaults(redisCacheConfiguration(DEFAULT_EXPIRE_TIME)) // 默认缓存配置
.withInitialCacheConfigurations(speCacheConfigurations) // 定制化的缓存配置
.build();
return redisCacheManager;
}
/**
* RedisCacheConfiguration redis缓存配置
*
* @param ttl 缓存过期时间
* @return
*/
public RedisCacheConfiguration redisCacheConfiguration(Integer ttl) {
//redis缓存配置
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
//缓存生存时间60秒
.entryTtl(Duration.ofSeconds(ttl))
// 配置Key序列化(解决乱码的问题)
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
// 配置Value序列化
.serializeValuesWith(RedisSerializationContext.SerializationPair
.fromSerializer(new FastJsonRedisSerializer<Object>(Object.class)))
// 不缓存空值
.disableCachingNullValues();
return config;
}2.3 创建JsonListIntegerTypeHandler.java
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.TypeReference;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
public class JsonListIntegerTypeHandler extends BaseTypeHandler<List<Integer>> {
// 插入/更新时:将List<Integer>转为JSON字符串存入数据库
@Override
public void setNonNullParameter(PreparedStatement ps, int i, List<Integer> parameter, JdbcType jdbcType) throws SQLException {
String jsonStr = JSON.toJSONString(parameter); // 例如:[3037, 3038]
ps.setString(i, jsonStr);
}
// 查询时:从数据库读取字符串并解析为List<Integer>
@Override
public List<Integer> getNullableResult(ResultSet rs, String columnName) throws SQLException {
String jsonStr = rs.getString(columnName);
return parseJsonToList(jsonStr);
}
@Override
public List<Integer> getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
String jsonStr = rs.getString(columnIndex);
return parseJsonToList(jsonStr);
}
@Override
public List<Integer> getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
String jsonStr = cs.getString(columnIndex);
return parseJsonToList(jsonStr);
}
// 解析JSON字符串为List<Integer>
private List<Integer> parseJsonToList(String jsonStr) {
if (jsonStr == null || jsonStr.trim().isEmpty()) {
return null;
}
// 使用FastJSON解析为List<Integer>
return JSON.parseObject(jsonStr, new TypeReference<List<Integer>>() {});
}
}2.4 在实体类上注解@TableField
@Schema( description = "赠送礼物id")
@TableField(value = "item_id", typeHandler = JsonListIntegerTypeHandler.class)
private List<Integer> itemId;
@Schema( description = "赠送礼物数量")
@TableField(value = "item_Num", typeHandler = JsonListIntegerTypeHandler.class)
private List<Integer> itemNum;2.5 最重要的在properties或者yaml中启动Handler
下面的xxx换成你自己包的目录
2.5.1 yaml
mybatis-plus:
typehandlers-package: com.xxx.handler2.5.2 properties
mybaits-plus.typehandlers-package=com.xxx.handler3 结果展示
Task(id=9, name=555, content=555, itemId=[3037], itemNum=[1], onlineCount=1, createTime=Wed Nov 05 16:54:30 CST 2025, endTime=Thu Nov 06 00:00:00 CST 2025, updateTime=Wed Nov 05 16:54:30 CST 2025, deleted=0)
[3037]---[1]
本文共 375 个字数,平均阅读时长 ≈ 1分钟
评论 (0)