自定義超實用Redis工具類(滿足物件,list,map等型別)

CatalpaFlat發表於2017-11-12

該工具類,可以儲存物件、list,map等各種資料型別到Redis中,大大有效提高開發效率。

1.新增maven依賴

    <!--序列化工具-->
    <dependency>
        <groupId>org.objenesis</groupId>
        <artifactId>objenesis</artifactId>
        <version>${objenesis.version}</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/com.dyuproject.protostuff/protostuff-core -->
    <dependency>
        <groupId>com.dyuproject.protostuff</groupId>
        <artifactId>protostuff-core</artifactId>
        <version>${dyuproject.version}</version>
    </dependency>
    <dependency>
        <groupId>com.dyuproject.protostuff</groupId>
        <artifactId>protostuff-runtime</artifactId>
        <version>${dyuproject.version}</version>
    </dependency>複製程式碼

注:採用序列化工具進行解析。版本如下:

    <dyuproject.version>1.1.3</dyuproject.version>
    <objenesis.version>2.6</objenesis.version>複製程式碼

2.序列化工具類

/**
 * 序列化工具類
 * @Author: CatalpaFlat
 * @Descrition:
 * @Date: Create in 15:04 2017/11/11
 * @Modified BY:
 */
public class ProtoStuffSerializerUtil {
    public static <T> byte[] serialize(T obj) {
        if (obj == null) {
            throw new RuntimeException("序列化物件(" + obj + ")!");
        }
        @SuppressWarnings("unchecked")
        Schema<T> schema = (Schema<T>) RuntimeSchema.getSchema(obj.getClass());
        LinkedBuffer buffer = LinkedBuffer.allocate(1024 * 1024);
        byte[] protostuff = null;
        try {
            protostuff = ProtostuffIOUtil.toByteArray(obj, schema, buffer);
        } catch (Exception e) {
            throw new RuntimeException("序列化(" + obj.getClass() + ")物件(" + obj + ")發生異常!", e);
        } finally {
            buffer.clear();
        }
        return protostuff;
    }
    public static <T> T deserialize(byte[] paramArrayOfByte, Class<T> targetClass) {
        if (paramArrayOfByte == null || paramArrayOfByte.length == 0) {
            throw new RuntimeException("反序列化物件發生異常,byte序列為空!");
        }
        T instance = null;
        try {
            // T message = objenesis.newInstance(cls);
            instance = targetClass.newInstance();
        } catch (InstantiationException | IllegalAccessException e) {
            throw new RuntimeException("反序列化過程中依據型別建立物件失敗!", e);
        }
        Schema<T> schema = RuntimeSchema.getSchema(targetClass);
        ProtostuffIOUtil.mergeFrom(paramArrayOfByte, instance, schema);
        return instance;
    }
    public static <T> byte[] serializeList(List<T> objList) {
        if (objList == null || objList.isEmpty()) {
            throw new RuntimeException("序列化物件列表(" + objList + ")引數異常!");
        }
        @SuppressWarnings("unchecked")
        Schema<T> schema = (Schema<T>) RuntimeSchema.getSchema(objList.get(0).getClass());
        LinkedBuffer buffer = LinkedBuffer.allocate(1024 * 1024);
        byte[] protostuff = null;
        ByteArrayOutputStream bos = null;
        try {
            bos = new ByteArrayOutputStream();
            ProtostuffIOUtil.writeListTo(bos, objList, schema, buffer);
            protostuff = bos.toByteArray();
        } catch (Exception e) {
            throw new RuntimeException("序列化物件列表(" + objList + ")發生異常!", e);
        } finally {
            buffer.clear();
            try {
                if(bos!=null){
                    bos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return protostuff;
    }
    public static <T> List<T> deserializeList(byte[] paramArrayOfByte, Class<T> targetClass) {
        if (paramArrayOfByte == null || paramArrayOfByte.length == 0) {
            throw new RuntimeException("反序列化物件發生異常,byte序列為空!");
        }

        Schema<T> schema = RuntimeSchema.getSchema(targetClass);
        List<T> result = null;
        try {
            result = ProtostuffIOUtil.parseListFrom(new ByteArrayInputStream(paramArrayOfByte), schema);
        } catch (IOException e) {
            throw new RuntimeException("反序列化物件列表發生異常!",e);
        }
        return result;
    }
    public static class Person{
        int id;
        String name;

        public Person(){

        }

        public Person(int id, String name){
            this.id = id;
            this.name = name;
        }

        public int getId() {
            return id;
        }
        public String getName() {
            return name;
        }

    }
}複製程式碼

3.配置redisConfig類進行儲存

/**
 * redis配置類
 * @Author: CatalpaFlat
 * @Descrition:
 * @Date: Create in 15:04 2017/11/11
 * @Modified BY:
 */
@Component
public class RedisConfig {

    public final static String CAHCENAME = "CatalpaFlat";// 快取名
    public final static int CAHCETIME = 60;// 預設快取時間 60S
    public final static int CAHCEHOUR = 60 * 60;// 預設快取時間 1hr
    public final static int CAHCEDAY = 60 * 60 * 24;// 預設快取時間 1Day
    public final static int CAHCEWEEK = 60 * 60 * 24 * 7;// 預設快取時間 1week
    public final static int CAHCEMONTH = 60 * 60 * 24 * 7 * 30;// 預設快取時間 1month
    public final static int CAHCEYEAR = 60 * 60 * 24 * 7 * 30 * 12;// 預設快取時間 1年
    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    public <T> boolean putCache(String key, T obj) {
        final byte[] bkey = key.getBytes();
        final byte[] bvalue = ProtoStuffSerializerUtil.serialize(obj);
        boolean result = redisTemplate.execute((RedisCallback<Boolean>) connection -> connection.setNX(bkey, bvalue));
        return result;
    }
    public <T> void putCacheWithExpireTime(String key, T obj, final long expireTime) {
        final byte[] bkey = key.getBytes();
        final byte[] bvalue = ProtoStuffSerializerUtil.serialize(obj);
        redisTemplate.execute((RedisCallback<Boolean>) connection -> {
            connection.setEx(bkey, expireTime, bvalue);
            return true;
        });
    }
    public <T> boolean putListCache(String key, List<T> objList) {
        final byte[] bkey = key.getBytes();
        final byte[] bvalue = ProtoStuffSerializerUtil.serializeList(objList);
        boolean result = redisTemplate.execute((RedisCallback<Boolean>) connection -> connection.setNX(bkey, bvalue));
        return result;
    }
    public <T> boolean putListCacheWithExpireTime(String key, List<T> objList, final long expireTime) {
        final byte[] bkey = key.getBytes();
        final byte[] bvalue = ProtoStuffSerializerUtil.serializeList(objList);
        boolean result = redisTemplate.execute((RedisCallback<Boolean>) connection -> {
            connection.setEx(bkey, expireTime, bvalue);
            return true;
        });
        return result;
    }
    public <T> T getCache(final String key, Class<T> targetClass) {
        byte[] result = redisTemplate.execute(new RedisCallback<byte[]>() {
            @Override
            public byte[] doInRedis(RedisConnection connection) throws DataAccessException {
                return connection.get(key.getBytes());
            }
        });
        if (result == null) {
            return null;
        }
        return ProtoStuffSerializerUtil.deserialize(result, targetClass);
    }
    public <T> List<T> getListCache(final String key, Class<T> targetClass) {
        byte[] result = redisTemplate.execute(new RedisCallback<byte[]>() {
            @Override
            public byte[] doInRedis(RedisConnection connection) throws DataAccessException {
                return connection.get(key.getBytes());
            }
        });
        if (result == null) {
            return null;
        }
        return ProtoStuffSerializerUtil.deserializeList(result, targetClass);
    }
    /**
     * 精確刪除key
     *
     * @param key
     */
    public void deleteCache(String key) {
        redisTemplate.delete(key);
    }

    /**
     * 模糊刪除key
     *
     * @param pattern
     */
    public void deleteCacheWithPattern(String pattern) {
        Set<String> keys = redisTemplate.keys(pattern);
        redisTemplate.delete(keys);
    }

    /**
     * 清空所有快取
     */
    public void clearCache() {
        deleteCacheWithPattern(RedisConfig.CAHCENAME + "|*");
    }
}複製程式碼

4.測試序列化工具類

注:基於這篇文章
blog.csdn.net/DuShiWoDeCu…

/**
 * @Author: CatalpaFlat
 * @Descrition:
 * @Date: Create in 10:08 2017/11/8
 * @Modified BY:
 */
@RunWith(SpringRunner.class)
@ContextConfiguration({"classpath:spring/*.xml"})
public class TestRedis {

    @Resource
    private RedisConfig redisConfig;
    @Autowired(required=true)
    private RedisKeyUtil redisKeyUtil;
    @Autowired
    private RedisTemplate redisTemplate;

    private static final Logger log  = Logger.getLogger(TestRedis.class.getName());

    @Test
    public void test(){
//        redisTemplate.opsForValue().set("chen", "陳梓平");
//        log.info("value:"+redisTemplate.opsForValue().get("chen"));
        String key = redisKeyUtil.getSystemRedisKeyDistribution("Test", this.getClass().getName(), "test");
        log.info("cache-key:"+key);
        redisConfig.putCache(key,"測試連結");
        String cache = redisConfig.getCache(key, String.class);
        log.info("cache-value:"+cache);
    }
}複製程式碼

相關文章