BaseRedis

import com.iba.frame.redis.PojoSerializable;
import com.iba.frame.util.CommonUtil;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisConnectionUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.stereotype.Repository;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

@Repository("baseRedis")
public abstract class BaseRedis<K, V> {

    // 加载数据的时候每页加载1000条,免得数据库超时
    protected final Integer LOAD_PAGE_SIZE = 1000;
    @Autowired
    protected RedisTemplate<K, V> redisTemplate;
    @Autowired
    protected RedisTemplate<K, V> transRedisTemplate;
    private Logger logger = Logger.getLogger(BaseRedis.class);

    // @Autowired
    // protected Jedis jedis;

    /////////////////////////////////////////////////////////////////
    /////////////////////////// 普通通用接口////////////////////////////
    /////////////////////////////////////////////////////////////////

    /**
     * 设置一个结构数据
     *
     * @param key
     * @param value
     * @param seconds
     * @return
     */
    protected Long incr(final String key) {
        Long result = redisTemplate.execute(new RedisCallback<Long>() {
            @Override
            public Long doInRedis(RedisConnection connection) throws DataAccessException {
                RedisSerializer<String> serializer = getRedisSerializer();
                byte[] byteKey = serializer.serialize(key);
                return connection.incr(byteKey);
            }
        });
        return result;
    }

    /**
     * 设置一个结构数据
     *
     * @param key
     * @param value
     * @param seconds
     * @return
     */
    protected Long decr(final String key) {
        Long result = redisTemplate.execute(new RedisCallback<Long>() {
            @Override
            public Long doInRedis(RedisConnection connection) throws DataAccessException {
                RedisSerializer<String> serializer = getRedisSerializer();
                byte[] byteKey = serializer.serialize(key);
                return connection.decr(byteKey);
            }
        });
        return result;
    }

    /**
     * 设置一个结构数据
     *
     * @param key
     * @param value
     * @param seconds
     * @return
     */
    protected boolean set(final String key, final String value, final long seconds) {
        boolean result = transRedisTemplate.execute(new RedisCallback<Boolean>() {
            @Override
            public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
                RedisSerializer<String> serializer = getRedisSerializer();
                byte[] byteKey = serializer.serialize(key);
                byte[] byteValue = serializer.serialize(value);
                if (seconds > 0) {
                    connection.setEx(byteKey, seconds, byteValue);
                } else {
                    connection.set(byteKey, byteValue);
                }
                return true;
            }
        });
        return result;
    }

    /**
     * @param key
     * @param value
     * @param seconds
     * @param suppressTran 是否压制事务,true,表示在事务环境中立即执行(不进redis队列)
     * @return
     */
    protected boolean set(final String key, final String value, final long seconds, final boolean suppressTran) {
        RedisTemplate<K, V> realTemp = suppressTran ? redisTemplate : transRedisTemplate;
        boolean result = realTemp.execute(new RedisCallback<Boolean>() {
            @Override
            public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
                RedisSerializer<String> serializer = getRedisSerializer();
                byte[] byteKey = serializer.serialize(key);
                byte[] byteValue = serializer.serialize(value);
                if (seconds > 0) {
                    connection.setEx(byteKey, seconds, byteValue);
                } else {
                    connection.set(byteKey, byteValue);
                }
                return true;
            }
        });
        return result;
    }

    /**
     * 设置一个结构数据(主要用于保存bean对象,初始化incr值请使用String类型的方法)
     *
     * @param key
     * @param value
     * @param seconds
     * @return
     */
    protected boolean set(final String key, final Serializable value, final long seconds) {
        boolean result = transRedisTemplate.execute((RedisCallback<Boolean>) connection -> {
            if(transRedisTemplate.getValueSerializer() instanceof  Jackson2JsonRedisSerializer){
                Jackson2JsonRedisSerializer valueSerializer = (Jackson2JsonRedisSerializer)transRedisTemplate.getValueSerializer();
                RedisSerializer<String> serializer = getRedisSerializer();
                byte[] byteKey = serializer.serialize(key);
                byte[] byteValue = valueSerializer.serialize(value);
                if (seconds > 0) {
                    connection.setEx(byteKey, seconds, byteValue);
                } else {
                    connection.set(byteKey, byteValue);
                }
            }else{
                RedisSerializer<String> serializer = getRedisSerializer();
                byte[] byteKey = serializer.serialize(key);
                byte[] byteValue = CommonUtil.transObj2ByteArray(value);
                if (seconds > 0) {
                    connection.setEx(byteKey, seconds, byteValue);
                } else {
                    connection.set(byteKey, byteValue);
                }
            }

            return true;
        });
        return result;
    }

    /**
     * 根据Key获取对象
     *
     * @param key
     * @return
     */
    protected Object get(final String key) {
        Object result = redisTemplate.execute((RedisCallback<Object>) connection -> {
            RedisSerializer<String> serializer = getRedisSerializer();
            byte[] byteKey = serializer.serialize(key);
            byte[] value = connection.get(byteKey);
            if (value == null) {
                return null;
            }
            Object dataObj = serializer.deserialize(value);
            return dataObj;
        });
        return result;
    }

    /**
     * 根据Key获取对象
     *
     * @param key
     * @return
     */
    protected <T extends Serializable> T get(final String key, final Class<T> clazz) {
        T result = redisTemplate.execute((RedisCallback<T>) connection -> {
            RedisSerializer<String> serializer = getRedisSerializer();
            byte[] byteKey = serializer.serialize(key);
            byte[] value = connection.get(byteKey);
            if (value == null) {
                return null;
            }
            if(transRedisTemplate.getValueSerializer() instanceof  Jackson2JsonRedisSerializer){
                Jackson2JsonRedisSerializer valueSerializer = (Jackson2JsonRedisSerializer)transRedisTemplate.getValueSerializer();
                Object dataObj = valueSerializer.deserialize(value);
                System.out.println("dataObj1::"+dataObj);
                return (T)dataObj;
            }else{
                T dataObj = CommonUtil.transByteArray2Obj(value, clazz);
                System.out.println("dataObj1::"+dataObj);
                return dataObj;
            }

        });
        return result;
    }

    protected Object mget(final List<String> keys) {
        Object result = redisTemplate.execute(new RedisCallback<Object>() {
            @Override
            public List<Object> doInRedis(RedisConnection connection) throws DataAccessException {
                RedisSerializer<String> serializer = getRedisSerializer();
                List<byte[]> listByteKeys = new ArrayList<byte[]>();
                for (String key : keys) {
                    byte[] byteKey = serializer.serialize(key);
                    listByteKeys.add(byteKey);
                }

                List<byte[]> listByteValues = connection.mGet(listByteKeys.toArray(new byte[listByteKeys.size()][]));
                List<Object> listValue = new ArrayList<Object>();
                for (byte[] value : listByteValues) {
                    listValue.add(serializer.deserialize(value));
                }
                return listValue;
            }
        });
        return result;
    }

    /**
     * @param argKey
     * @return
     */
    protected Object keys(final String argKey) {
        Object result = redisTemplate.execute(new RedisCallback<Object>() {
            @Override
            public List<Object> doInRedis(RedisConnection connection) throws DataAccessException {
                RedisSerializer<String> serializer = getRedisSerializer();
                byte[] byteKey = serializer.serialize(argKey);
                Set<byte[]> setBytes = connection.keys(byteKey);
                List<Object> listValue = new ArrayList<Object>();
                for (byte[] value : setBytes) {
                    listValue.add(serializer.deserialize(value));
                }
                return listValue;
            }
        });
        return result;
    }

    protected <T extends Serializable> List<T> mget(final List<String> keys, final Class<T> clazz) {
        List<T> result = redisTemplate.execute(new RedisCallback<List<T>>() {
            @Override
            public List<T> doInRedis(RedisConnection connection) throws DataAccessException {
                RedisSerializer<String> serializer = getRedisSerializer();
                List<byte[]> listByteKeys = new ArrayList<byte[]>();
                for (String key : keys) {
                    byte[] byteKey = serializer.serialize(key);
                    listByteKeys.add(byteKey);
                }

                List<byte[]> listByteValues = connection.mGet(listByteKeys.toArray(new byte[listByteKeys.size()][]));
                List<T> listValue = new ArrayList<T>();
                for (byte[] value : listByteValues) {
                    listValue.add(CommonUtil.transByteArray2Obj(value, clazz));
                }
                return listValue;
            }
        });
        return result;
    }

    protected boolean exists(final String key) {
        boolean result = redisTemplate.execute(new RedisCallback<Boolean>() {
            @Override
            public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
                RedisSerializer<String> serializer = getRedisSerializer();
                byte[] byteKey = serializer.serialize(key);
                return connection.exists(byteKey);
            }
        });
        return result;
    }

    protected Long ttl(final String key) {
        Long result = redisTemplate.execute(new RedisCallback<Long>() {
            @Override
            public Long doInRedis(RedisConnection connection) throws DataAccessException {
                RedisSerializer<String> serializer = getRedisSerializer();
                byte[] byteKey = serializer.serialize(key);

                return connection.ttl(byteKey);
            }
        });
        return result;
    }

    /////////////////////////////////////////////////////////////////
    /////////////////////////// Set 操作接口 //////////////////////////
    /////////////////////////////////////////////////////////////////
    protected boolean sadd(final String key, final String value) {
        boolean result = transRedisTemplate.execute(new RedisCallback<Boolean>() {
            @Override
            public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
                RedisSerializer<String> serializer = getRedisSerializer();
                byte[] byteKey = serializer.serialize(key);
                byte[] byteValue = serializer.serialize(value);
                connection.sAdd(byteKey, byteValue);
                return true;
            }
        });
        return result;
    }

    /**
     * 仅限于基本对象使用,Bean对象禁止使用
     *
     * @param key
     * @param value
     * @return
     */
    protected boolean sadd(final String key, final Serializable value) {
        boolean result = transRedisTemplate.execute(new RedisCallback<Boolean>() {
            @Override
            public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
                RedisSerializer<String> serializer = getRedisSerializer();
                byte[] byteKey = serializer.serialize(key);
                byte[] byteValue = CommonUtil.transObj2ByteArray(value);
                connection.sAdd(byteKey, byteValue);
                return true;
            }
        });
        return result;
    }

    protected boolean sadd(final String key, final List<String> values) {
        boolean result = transRedisTemplate.execute(new RedisCallback<Boolean>() {
            @Override
            public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
                RedisSerializer<String> serializer = getRedisSerializer();
                byte[] byteKey = serializer.serialize(key);
                List<byte[]> byteValues = new ArrayList<byte[]>(values.size());
                for (String v : values) {
                    byteValues.add(serializer.serialize(v));
                }
                connection.sAdd(byteKey, byteValues.toArray(new byte[values.size()][]));

                return true;
            }
        });
        return result;
    }

    protected boolean sadd(final String key, final Set<Serializable> values) {
        boolean result = transRedisTemplate.execute(new RedisCallback<Boolean>() {
            @Override
            public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
                RedisSerializer<String> serializer = getRedisSerializer();
                byte[] byteKey = serializer.serialize(key);
                byte[][] byteValues = new byte[values.size()][];
                int i = 0;
                for (Serializable v : values) {
                    byteValues[i++] = CommonUtil.transObj2ByteArray(v);
                }
                connection.sAdd(byteKey, byteValues);
                return true;
            }
        });
        return result;
    }

    /**
     * 增加sadd类型
     *
     * @param key
     * @param values
     * @return
     */
    protected boolean sadd(final String key, final Collection<? extends Serializable> values) {
        boolean result = transRedisTemplate.execute(new RedisCallback<Boolean>() {
            @Override
            public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
                RedisSerializer<String> serializer = getRedisSerializer();
                byte[] byteKey = serializer.serialize(key);
                byte[][] byteValues = new byte[values.size()][];
                int i = 0;
                for (Serializable v : values) {
                    byteValues[i++] = CommonUtil.transObj2ByteArray(v);
                }
                connection.sAdd(byteKey, byteValues);
                return true;
            }
        });
        return result;
    }

    protected Long scard(final String key) {
        Object result = redisTemplate.execute(new RedisCallback<Object>() {
            @Override
            public Long doInRedis(RedisConnection connection) throws DataAccessException {
                RedisSerializer<String> serializer = getRedisSerializer();
                byte[] byteKey = serializer.serialize(key);
                Long count = connection.sCard(byteKey);
                return count;
            }
        });
        return Long.parseLong(String.valueOf(result));
    }

    @SuppressWarnings("rawtypes")
    protected Object smembers(final String key) {
        Object result = redisTemplate.execute(new RedisCallback<Object>() {
            @Override
            public Object doInRedis(RedisConnection connection) throws DataAccessException {
                RedisSerializer<String> serializer = getRedisSerializer();
                byte[] byteKey = serializer.serialize(key);

                Set setValue = connection.sMembers(byteKey);

                Iterator iter = setValue.iterator();

                List<Object> listObj = new ArrayList<Object>();
                while (iter.hasNext()) {
                    Object obj = serializer.deserialize((byte[]) iter.next());
                    listObj.add(obj);
                }
                return listObj;
            }
        });
        return result;
    }

    protected <T extends Serializable> Set<T> smembers(final String key, final Class<T> clazz) {
        Set<T> result = redisTemplate.execute(new RedisCallback<Set<T>>() {
            @Override
            public Set<T> doInRedis(RedisConnection connection) throws DataAccessException {
                RedisSerializer<String> serializer = getRedisSerializer();
                byte[] byteKey = serializer.serialize(key);
                Set<byte[]> setValue = connection.sMembers(byteKey);
                Iterator<byte[]> iter = setValue.iterator();
                Set<T> result = new HashSet<T>();
                while (iter.hasNext()) {
                    T tmp = CommonUtil.transByteArray2Obj(iter.next(), clazz);
                    result.add(tmp);
                }
                if (result.size() == 0) {
                    return null;
                }
                return result;
            }
        });
        return result;
    }

    protected Set<String> smembersString(final String key) {
        Set<String> result = redisTemplate.execute(new RedisCallback<Set<String>>() {
            @Override
            public Set<String> doInRedis(RedisConnection connection) throws DataAccessException {
                RedisSerializer<String> serializer = getRedisSerializer();
                byte[] byteKey = serializer.serialize(key);
                Set<byte[]> setValue = connection.sMembers(byteKey);
                Iterator<byte[]> iter = setValue.iterator();
                Set<String> setStr = new HashSet<String>();
                while (iter.hasNext()) {
                    String obj = serializer.deserialize(iter.next());
                    setStr.add(obj);
                }
                return setStr;
            }
        });
        return result;
    }

    /**
     * 移出set中指定元素,在事务中无法返回结果,若业务需要判断移出是否成功,请使用smember判断
     *
     * @param key
     * @param value
     * @return
     */
    protected boolean srem(final String key, final String value) {
        boolean result = transRedisTemplate.execute(new RedisCallback<Boolean>() {
            @Override
            public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
                RedisSerializer<String> serializer = getRedisSerializer();
                byte[] byteKey = serializer.serialize(key);
                byte[] byteValue = serializer.serialize(value);
                Long index = connection.sRem(byteKey, byteValue);
                return index != null && index > 0L;
            }
        });
        return result;
    }

    protected boolean srem(final String key, final Serializable value) {
        boolean result = transRedisTemplate.execute(new RedisCallback<Boolean>() {
            @Override
            public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
                RedisSerializer<String> serializer = getRedisSerializer();
                byte[] byteKey = serializer.serialize(key);
                byte[] byteValue = CommonUtil.transObj2ByteArray(value);
                Long index = connection.sRem(byteKey, byteValue);
                return index != null && index > 0L;
            }
        });
        return result;

    }

    protected boolean srem(final String key, final List<String> values) {
        boolean result = transRedisTemplate.execute(new RedisCallback<Boolean>() {
            @Override
            public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
                RedisSerializer<String> serializer = getRedisSerializer();
                byte[] byteKey = serializer.serialize(key);
                byte[][] byteValues = new byte[values.size()][];
                for (int i = 0; i < values.size(); i++) {
                    byteValues[i] = serializer.serialize(values.get(i));
                }
                Long index = connection.sRem(byteKey, byteValues);
                return true;
            }
        });
        return result;

    }

    /////////////////////////////////////////////////////////////////
    /////////////////////////// ZSet接口//////////////////////////////
    /////////////////////////////////////////////////////////////////
    protected boolean zadd(final String key, final Double score, final String value) {
        boolean result = transRedisTemplate.execute(new RedisCallback<Boolean>() {
            @Override
            public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
                RedisSerializer<String> serializer = getRedisSerializer();
                byte[] byteKey = serializer.serialize(key);
                byte[] byteValue = serializer.serialize(value);
                connection.zAdd(byteKey, score, byteValue);
                return true;
            }
        });
        return result;
    }

    protected boolean zrem(final String key, final String value) {
        boolean result = transRedisTemplate.execute(new RedisCallback<Boolean>() {
            @Override
            public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
                RedisSerializer<String> serializer = getRedisSerializer();
                byte[] byteKey = serializer.serialize(key);
                byte[] byteValue = serializer.serialize(value);
                connection.zRem(byteKey, byteValue);
                return true;
            }
        });
        return result;
    }

    protected Object zrange(final String key, final Long begin, final Long end) {
        Object result = redisTemplate.execute(new RedisCallback<Object>() {
            @Override
            public Object doInRedis(RedisConnection connection) throws DataAccessException {
                RedisSerializer<String> serializer = getRedisSerializer();
                byte[] byteKey = serializer.serialize(key);

                Set<byte[]> setValue = connection.zRange(byteKey, begin, end);
                Iterator<byte[]> iter = setValue.iterator();
                List<Object> listObj = new ArrayList<Object>();
                while (iter.hasNext()) {
                    Object obj = serializer.deserialize(iter.next());
                    listObj.add(obj);
                }
                return listObj;
            }
        });
        return result;
    }

    @SuppressWarnings("rawtypes")
    protected Object zrangebyscore(final String key, final Double begin, final Double end) {
        Object result = redisTemplate.execute(new RedisCallback<Object>() {
            @Override
            public Object doInRedis(RedisConnection connection) throws DataAccessException {
                RedisSerializer<String> serializer = getRedisSerializer();
                byte[] byteKey = serializer.serialize(key);

                Set setValue = connection.zRangeByScore(byteKey, begin, end);
                Iterator iter = setValue.iterator();
                List<Object> listObj = new ArrayList<Object>();
                while (iter.hasNext()) {
                    Object obj = serializer.deserialize((byte[]) iter.next());
                    listObj.add(obj);
                }
                return listObj;
            }
        });
        return result;
    }

    /////////////////////////////////////////////////////////////////
    /////////////////////////// HSet接口//////////////////////////////
    /////////////////////////////////////////////////////////////////
    protected boolean hset(final String key, final String field, final String value, final Long seconds) {
        boolean result = transRedisTemplate.execute(new RedisCallback<Boolean>() {
            @Override
            public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
                RedisSerializer<String> serializer = getRedisSerializer();
                byte[] byteKey = serializer.serialize(key);
                byte[] byteField = serializer.serialize(field);
                byte[] byteValue = serializer.serialize(value);
                connection.hSet(byteKey, byteField, byteValue);
                if (seconds.equals(0L)) {
                    connection.persist(byteKey);
                } else {
                    connection.expire(byteKey, seconds);// 设置过期时间
                }
                return true;
            }
        });
        return result;
    }

    protected boolean hset(final String key, final String field, final Serializable value, final Long seconds) {
        boolean result = transRedisTemplate.execute(new RedisCallback<Boolean>() {
            @Override
            public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
                RedisSerializer<String> serializer = getRedisSerializer();
                byte[] byteKey = serializer.serialize(key);
                byte[] byteField = serializer.serialize(field);
                byte[] byteValue = CommonUtil.transObj2ByteArray(value);
                connection.hSet(byteKey, byteField, byteValue);
                if (seconds.equals(0L)) {
                    connection.persist(byteKey);
                } else {
                    connection.expire(byteKey, seconds);// 设置过期时间
                }
                return true;
            }
        });
        return result;
    }

    protected Object hget(final String key, final String field) {
        Object result = redisTemplate.execute(new RedisCallback<Object>() {
            @Override
            public Object doInRedis(RedisConnection connection) throws DataAccessException {
                RedisSerializer<String> serializer = getRedisSerializer();
                byte[] byteKey = serializer.serialize(key);
                byte[] byteField = serializer.serialize(field);
                byte[] value = connection.hGet(byteKey, byteField);
                if (value == null) {
                    logger.error("未找到redis中保存的数据" + new String(byteKey));
                    return null;
                }
                Object dataObj = serializer.deserialize(value);
                return dataObj;
            }
        });
        return result;
    }

    protected <T extends Serializable> T hget(final String key, final String field, final Class<T> clazz) {
        T result = redisTemplate.execute(new RedisCallback<T>() {
            @Override
            public T doInRedis(RedisConnection connection) throws DataAccessException {
                RedisSerializer<String> serializer = getRedisSerializer();
                byte[] byteKey = serializer.serialize(key);
                byte[] byteField = serializer.serialize(field);
                byte[] value = connection.hGet(byteKey, byteField);
                if (value == null) {

                    return null;
                }
                T dataObj = CommonUtil.transByteArray2Obj(value, clazz);
                return dataObj;
            }
        });
        return result;
    }

    protected Long hincrBy(final String key, final String field, Long incrBy) {
        Long result = redisTemplate.execute(new RedisCallback<Long>() {
            @Override
            public Long doInRedis(RedisConnection connection) throws DataAccessException {
                RedisSerializer<String> serializer = getRedisSerializer();
                byte[] byteKey = serializer.serialize(key);
                byte[] byteField = serializer.serialize(field);
                Long value = connection.hIncrBy(byteKey, byteField, incrBy);
                if (value == null) {
                    return 0L;
                }
                return value;
            }
        });
        return result;
    }

    protected Double hincrFloatBy(final String key, final String field, Double incrBy) {
        Double result = redisTemplate.execute(new RedisCallback<Double>() {
            @Override
            public Double doInRedis(RedisConnection connection) throws DataAccessException {
                RedisSerializer<String> serializer = getRedisSerializer();
                byte[] byteKey = serializer.serialize(key);
                byte[] byteField = serializer.serialize(field);
                Double value = connection.hIncrBy(byteKey, byteField, incrBy);
                if (value == null) {
                    return 0.0;
                }
                return value;
            }
        });
        return result;
    }

    @SuppressWarnings("rawtypes")
    protected Object hkeys(final String key) {
        Object result = redisTemplate.execute(new RedisCallback<Object>() {
            @Override
            public Object doInRedis(RedisConnection connection) throws DataAccessException {
                RedisSerializer<String> serializer = getRedisSerializer();
                byte[] byteKey = serializer.serialize(key);

                Set setValue = connection.hKeys(byteKey);

                Iterator iter = setValue.iterator();

                List<Object> listObj = new ArrayList<Object>();
                while (iter.hasNext()) {
                    Object obj = serializer.deserialize((byte[]) iter.next());
                    listObj.add(obj);
                }
                return listObj;
            }
        });
        return result;
    }

    protected Set<String> hkeysSerial(final String key) {
        Set<String> result = redisTemplate.execute(new RedisCallback<Set<String>>() {
            @Override
            public Set<String> doInRedis(RedisConnection connection) throws DataAccessException {
                RedisSerializer<String> serializer = getRedisSerializer();
                byte[] byteKey = serializer.serialize(key);

                Set<byte[]> setValue = connection.hKeys(byteKey);

                Iterator<byte[]> iter = setValue.iterator();

                Set<String> keys = new HashSet<String>();
                while (iter.hasNext()) {
                    String obj = serializer.deserialize(iter.next());
                    keys.add(obj);
                }
                return keys;
            }
        });
        return result;
    }

    protected boolean hdel(final String key, final String field) {
        boolean result = transRedisTemplate.execute(new RedisCallback<Boolean>() {
            @Override
            public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
                RedisSerializer<String> serializer = getRedisSerializer();
                byte[] byteKey = serializer.serialize(key);
                byte[] byteField = serializer.serialize(field);
                connection.hDel(byteKey, byteField);
                return true;
            }
        });
        return result;
    }

    /**
     * 设置redis键过期时间
     *
     * @param key
     * @param seconds
     */
    protected boolean expire(final String key, final Long seconds) {
        boolean result = transRedisTemplate.execute(new RedisCallback<Boolean>() {
            @Override
            public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
                RedisSerializer<String> serializer = getRedisSerializer();
                byte[] byteKey = serializer.serialize(key);
                connection.expire(byteKey, seconds);// 设置过期时间
                return true;
            }
        });
        return result;
    }

    /**
     * @param keys
     */
    public void delete(List<K> keys) {
        transRedisTemplate.delete(keys);
    }

    /**
     * 根据条件删除分页查询结果。
     */
    protected void deleteHashSetByPage(K hsetKey) {
        List<K> listKeys = new ArrayList<K>(1);
        listKeys.add(hsetKey);
        delete(listKeys);
    }

    /**
     * @param key
     * @param suppressTran 是否压制事务,true,表示在立即执行到redis(不需要等事务提交,同时也不会因事务失败而回滚)
     */
    public void delete(K key, final boolean suppressTran) {
        RedisTemplate<K, V> realTemp = suppressTran ? redisTemplate : transRedisTemplate;
        realTemp.delete(key);
    }

    /**
     * 将 key 的值设为 value ,当且仅当 key 不存在, 若给定的 key 已经存在,则 SETNX 不做任何动作。
     *
     * @param key
     * @param value
     * @param seconds
     * @param suppressTran 是否压制事务,true,表示在立即执行到redis(不需要等事务提交,同时也不会因事务失败而回滚)
     * @return
     */
    protected Boolean setNx(final String key, final Serializable value, final long seconds, final boolean suppressTran) {
        RedisTemplate<K, V> realTemp = suppressTran ? redisTemplate : transRedisTemplate;
        boolean result = realTemp.execute(new RedisCallback<Boolean>() {
            @Override
            public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
                RedisSerializer<String> serializer = getRedisSerializer();
                byte[] byteKey = serializer.serialize(key);
                byte[] byteValue = CommonUtil.transObj2ByteArray(value);
                Boolean result = connection.setNX(byteKey, byteValue);
                if (seconds > 0 && (null == result && !suppressTran) || (result && suppressTran)) {
                    connection.expire(byteKey, seconds);
                }
                return result;
            }
        });
        return result;
    }

    /**
     * @param keys
     */
    public Long dbSize() {
        Long result = transRedisTemplate.execute(new RedisCallback<Long>() {
            @Override
            public Long doInRedis(RedisConnection connection) throws DataAccessException {
                return connection.dbSize();
            }
        });
        return result;
    }

    // public Set<K> keys(K pattern) {
    // return redisTemplate.keys(pattern);
    // }

    public void clean(K pattern) {
        Set<K> keySet = transRedisTemplate.keys(pattern);
        if (keySet != null && keySet.size() > 0) {
            List<K> keyList = new ArrayList<K>(keySet);
            delete(keyList);
        }
    }

    /**
     * pipeline方式获取数据
     *
     * @param keys
     * @return
     */
    protected List<Object> pipelineGet(final List<String> keys) {
        return redisTemplate.executePipelined(new RedisCallback<Object>() {

            @Override
            public Object doInRedis(RedisConnection connection) throws DataAccessException {
                // 直接执行所有需要执行的命令,返回值由jedis通过底层connection.closePipeline()实现
                RedisSerializer<String> serializer = getRedisSerializer();
                for (String key : keys) {
                    byte[] byteKey = serializer.serialize(key);
                    connection.get(byteKey);
                }
                // jedis api限制 只能返回null 否则会抛异常
                return null;
            }

        }, getRedisSerializer());

    }

    protected <T extends Serializable> List<T> pipelineGet(final Collection<String> keys, final Class<T> clazz) {
        List<?> tmps = redisTemplate.executePipelined(new RedisCallback<Object>() {

            @Override
            public Object doInRedis(RedisConnection connection) throws DataAccessException {
                // 直接执行所有需要执行的命令,返回值由jedis通过底层connection.closePipeline()实现
                RedisSerializer<String> serializer = getRedisSerializer();
                for (String key : keys) {
                    byte[] byteKey = serializer.serialize(key);
                    connection.get(byteKey);
                }
                // jedis api限制 只能返回null 否则会抛异常
                return null;
            }

        }, getPojoSerializer(clazz));
        List<T> result = new ArrayList<T>(tmps.size());
        for (Object obj : tmps) {
            result.add(clazz.cast(obj));
        }
        return result;
    }

    /////////////////////////////////////////////////////////////////
    /////////////////////////// List 操作接口//////////////////////////
    /////////////////////////////////////////////////////////////////

    /**
     * 使用redis自身事物,向一个定长的列表加入元素,每次都要传入list的长度。即外部可以不用放入事务中。
     *
     * @param key
     * @param length
     * @param value
     * @param seconds
     * @return
     */
    protected boolean lpushWithTrim(final String key, final long length, final Serializable value, final Long seconds) {
        boolean result = redisTemplate.execute(new RedisCallback<Boolean>() {
            @Override
            public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
                RedisSerializer<String> serializer = getRedisSerializer();
                byte[] byteKey = serializer.serialize(key);
                byte[] byteValue = CommonUtil.transObj2ByteArray(value);
                if (length > 0L) {
                    connection.multi();
                    connection.lPush(byteKey, byteValue);
                    connection.lTrim(byteKey, 0, length - 1);
                    connection.exec();
                } else {
                    connection.lPush(byteKey, byteValue);
                }
                if (seconds.equals(0L)) {
                    connection.persist(byteKey);
                } else {
                    connection.expire(byteKey, seconds);// 设置过期时间
                }
                return true;
            }
        });
        return result;
    }

    /**
     * @param key
     * @param value
     * @param seconds
     * @return
     */
    protected boolean lpush(final String key, final Serializable value, final Long seconds) {
        boolean result = transRedisTemplate.execute(new RedisCallback<Boolean>() {
            @Override
            public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
                RedisSerializer<String> serializer = getRedisSerializer();
                byte[] byteKey = serializer.serialize(key);
                byte[] byteValue = CommonUtil.transObj2ByteArray(value);
                connection.lPush(byteKey, byteValue);
                if (seconds.equals(0L)) {
                    connection.persist(byteKey);
                } else {
                    connection.expire(byteKey, seconds);// 设置过期时间
                }
                return true;
            }
        });
        return result;
    }

    /**
     * @param key
     * @param begin
     * @param end
     * @return
     */
    protected boolean ltrim(final String key, long begin, long end) {
        boolean result = transRedisTemplate.execute(new RedisCallback<Boolean>() {
            @Override
            public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
                RedisSerializer<String> serializer = getRedisSerializer();
                byte[] byteKey = serializer.serialize(key);
                connection.multi();
                connection.lTrim(byteKey, begin, end);
                connection.exec();
                return true;
            }
        });
        return result;
    }

    /**
     * @param key
     * @param begin
     * @param end
     * @return
     */
    protected <T extends Serializable> List<T> lrange(final String key, long begin, long end, final Class<T> clazz) {
        List<T> result = redisTemplate.execute(new RedisCallback<List<T>>() {
            @Override
            public List<T> doInRedis(RedisConnection connection) throws DataAccessException {
                RedisSerializer<String> serializer = getRedisSerializer();
                byte[] byteKey = serializer.serialize(key);
                List<byte[]> listByteValues = connection.lRange(byteKey, begin, end);
                List<T> listValue = new ArrayList<T>(listByteValues.size());
                for (byte[] value : listByteValues) {
                    listValue.add(CommonUtil.transByteArray2Obj(value, clazz));
                }
                return listValue;
            }
        });
        return result;
    }

    /////////////////////////////////////////////////////////////
    /////////////////////// Pipeline 方式 /////////////////////////
    /////////////////////////////////////////////////////////////
    // 用pipeline的方式实现get多个数据
    protected List<String> pget(final List<String> keys) {

        @SuppressWarnings("unchecked")
        List<String> result = (List<String>) redisTemplate.execute(new RedisCallback<Object>() {
            @Override
            public List<String> doInRedis(RedisConnection connection) throws DataAccessException {
                connection.openPipeline();

                RedisSerializer<String> serializer = getRedisSerializer();
                for (String key : keys) {
                    byte[] byteKey = serializer.serialize(key);
                    connection.get(byteKey);
                }
                List<?> pipeResult = connection.closePipeline();
                List<String> strObjs = new ArrayList<String>();
                for (Object tmp : pipeResult) {
                    byte[] bytes = (byte[]) tmp;
                    String tmpObj = serializer.deserialize(bytes);
                    strObjs.add(tmpObj);
                }
                return strObjs;
            }
        });

        return result;
    }

    /**
     * 判断 value 元素是否集合(set) key 的成员
     *
     * @param key
     * @param value
     * @return
     */
    protected boolean sIsMember(final String key, final String value) {
        boolean result = redisTemplate.execute(new RedisCallback<Boolean>() {
            @Override
            public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
                RedisSerializer<String> serializer = getRedisSerializer();
                byte[] byteKey = serializer.serialize(key);
                byte[] byteVal = serializer.serialize(value);
                return connection.sIsMember(byteKey, byteVal);
            }
        });
        return result;
    }

    /**
     * 设置RedisTemplate 可以注入,不需要显示调用
     *
     * @return
     */
    protected RedisTemplate<K, V> getRedisTemplate() {
        return transRedisTemplate;
    }

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

    /**
     * @return
     */
    protected RedisSerializer<String> getRedisSerializer() {

        return transRedisTemplate.getStringSerializer();
    }

    protected <T extends Serializable> RedisSerializer<T> getPojoSerializer(Class<T> clazz) {
        return new PojoSerializable<T>(clazz);
    }

    public void closeConn() {
        RedisConnection conn = RedisConnectionUtils.getConnection(transRedisTemplate.getConnectionFactory());
        conn.close();
    }

}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容

  • 有些话只适合给自己说,自己安慰自己,而生活常常会给你出难题,社会昏暗,人情淡薄,毫无感情可见,唯有利益二字,能拉近...
    生活不易你要勇敢阅读 154评论 0 1
  • 生活中,有很多时候都把自己想得太重要。 其实事实证明,你不过是一颗无人注意的小草罢了。 你的喜怒哀乐,对别人来说都...
    宁静致远_e0d7阅读 1,860评论 4 18
  • computed被叫做计算属性: 1.在页面中使用大量或是复杂的表达式去处理数据,对页面的维护会有很大的影响。这个...
    Annie_070c阅读 7,358评论 1 0
  • 儿子好久不写诗了。白天带他出去玩,问他,怎么不写诗了?这儿风景这么优美。儿子答曰:这段时间你老嚷(方言:批...
    闲来看瓜也开花阅读 414评论 3 8
  • 感恩先生开车带着我们一路前行赶到丽江束河古镇,这是带着妈妈第二次来到束河古镇,这里比以前热闹了很多,天空还是一样的...
    归韵阅读 206评论 0 0