Welcome to MLink Developer Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
70 views
in Technique[技术] by (71.8m points)

redisTemplate.delete()不能删除元素

最近在学习redis,使用spring-data-redis的RedisTemplate.delete()方法删除时,添加是成功的,但是不能删除。

代码如下

public abstract class AbstractBaseRedisDao<K, V> {
    @Autowired
    protected RedisTemplate<K, V> redisTemplate;

//    public void setRedisTemplate(RedisTemplate<K, V> redisTemplate) {
//        this.redisTemplate = redisTemplate;
//    }

    public RedisSerializer<String> getRedisSerializer() {
        return redisTemplate.getStringSerializer();
    }
}

public interface IUserDao {
    boolean add(User user);

    void delete(String key);

    void delete(List<String> keys);

    User get(String keyId);
}

@Service
public class UserDao extends AbstractBaseRedisDao<String, User> implements IUserDao {
    public boolean add(final User user) {
        boolean result = redisTemplate.execute(new RedisCallback<Boolean>() {
            public Boolean doInRedis(RedisConnection redisConnection) throws DataAccessException {
                RedisSerializer<String> serializer = getRedisSerializer();
                byte[] key = serializer.serialize(user.getId());
                byte[] name = serializer.serialize(user.getName());
                return redisConnection.setNX(key, name);
            }
        });
        return result;
    }

    public void delete(String key) {
        List<String> list = new ArrayList<String>();
        list.add(key);
        delete(list);
    }

    public void delete(List<String> keys) {
        redisTemplate.delete(keys);
    }

    public User get(final String keyId) {
        User result = redisTemplate.execute(new RedisCallback<User>() {
            public User doInRedis(RedisConnection redisConnection) throws DataAccessException {
                RedisSerializer<String> serializer = getRedisSerializer();
                byte[] key = serializer.serialize(keyId);
                byte[] value = redisConnection.get(key);
                if (value == null) {
                    return null;
                }
                String name = serializer.deserialize(value);
                return new User(keyId, name, null);
            }
        });
        return result;
    }
}

配置如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd">

    <context:annotation-config />
    <context:component-scan base-package="com.zkzong.springredis" />
    <context:property-placeholder location="classpath:case1/redis.properties" />

    <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
        <property name="maxIdle" value="${redis.maxIdle}" />
        <property name="maxTotal" value="${redis.maxTotal}" />
        <property name="maxWaitMillis" value="${redis.maxWaitMillis}" />
        <!--<property name="testOnBorrow" value="${redis.testOnBorrow}" />-->
    </bean>

    <bean id="connectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
          p:hostName="${redis.host}" p:port="${redis.port}" p:password="${redis.pass}" p:poolConfig-ref="poolConfig" />

    <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
        <property name="connectionFactory" ref="connectionFactory" />
    </bean>

    <bean id="userDao" class="com.zkzong.springredis.case1.dao.impl.UserDao" />
</beans>

测试用例:

public class RedisTest {
    private IUserDao userDao;

    @Before
    public void init() {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("case1/applicationContext.xml");
        userDao = (IUserDao) ctx.getBean("userDao");
    }

    @Test
    public void testAddUser() {
        User user = new User();
        user.setId("B");
        user.setName("B");
        boolean result = userDao.add(user);
        Assert.assertTrue(result);
    }

    @Test
    public void testDelete() {
        String key = "B";
        User user = userDao.get(key);
        System.out.println("删除前:" + user);
        userDao.delete(key);
        user = userDao.get(key);
        System.out.println("删除后:" + user);
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

你新增的key是使用StringRedisSerializer的,但是你delete的时候是redis是使用redisTemplate默认的JdkSerializationRedisSerializer,你用hasKey方法也会发现redis中有这个key但是hasKey返回false

解决方案:给template设置defaultSerializer

<bean id="defaultRedisSerializer" class="org.springframework.data.redis.serializer.StringRedisSerializer"></bean>

<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
    <property name="connectionFactory" ref="connectionFactory" />
    <property name="defaultSerializer" ref="defaultRedisSerializer"/>
</bean>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to MLink Developer Q&A Community for programmer and developer-Open, Learning and Share
...