spring-data-redis高级使用

1 StringRedisTemplate 继承 RedisTemplate 实现redis操作功能

public class StringRedisTemplate extends RedisTemplate {

	/**
	 * Constructs a new StringRedisTemplate instance. {@link #setConnectionFactory(RedisConnectionFactory)}
	 * and {@link #afterPropertiesSet()} still need to be called.
	 */
	public StringRedisTemplate() {
		RedisSerializer stringSerializer = new StringRedisSerializer();
		setKeySerializer(stringSerializer);
		setValueSerializer(stringSerializer);
		setHashKeySerializer(stringSerializer);
		setHashValueSerializer(stringSerializer);
	}

2 RedisTemplate中redis操作是通过RedisConnection实现

public void delete(K key) {
		final byte[] rawKey = rawKey(key);

		execute(new RedisCallback() {

			public Object doInRedis(RedisConnection connection) {
				connection.del(rawKey);
				return null;
			}
		}, true);
	}


public void rename(K oldKey, K newKey) {
		final byte[] rawOldKey = rawKey(oldKey);
		final byte[] rawNewKey = rawKey(newKey);

		execute(new RedisCallback() {

			public Object doInRedis(RedisConnection connection) {
				connection.rename(rawOldKey, rawNewKey);
				return null;
			}
		}, true);
	} 
  

3 RedisConnection继承RedisCommands

public interface RedisConnection extends RedisCommands {

      .........
}

4 RedisCommands继承所有命令,拥有所有的redis操作命令

public interface RedisCommands extends RedisKeyCommands, RedisStringCommands, RedisListCommands, RedisSetCommands,
		RedisZSetCommands, RedisHashCommands, RedisTxCommands, RedisPubSubCommands, RedisConnectionCommands,
		RedisServerCommands, RedisScriptingCommands, RedisGeoCommands, HyperLogLogCommands {

	/**
	 * 'Native' or 'raw' execution of the given command along-side the given arguments. The command is executed as is,
	 * with as little 'interpretation' as possible - it is up to the caller to take care of any processing of arguments or
	 * the result.
	 * 
	 * @param command Command to execute
	 * @param args Possible command arguments (may be null)
	 * @return execution result.
	 */
	Object execute(String command, byte[]... args);
}

那么只要拥有RedisConnection就能执行redis客户端的所有命令。

5 编写RedisServiceExtend

/**
* @Title: RedisServiceExtend
* @Description: redis 扩展
* @author chy
* @date 2018/5/8 8:27
*/
@Repository
public class RedisServiceExtend  {

    private static String redisCode = "utf-8";

    @Autowired
    RedisTemplate redisTemplate;

    public RedisTemplate getRedisTemplate() {
        return redisTemplate;
    }

    public void setRedisTemplate(RedisTemplate redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    /**
     * 统计bit位为1的总数
     * @param key
     */
    public long bitCount(final String key) {
        return redisTemplate.execute(new RedisCallback() {
            @Override
            public Long doInRedis(RedisConnection connection) throws DataAccessException {
                long result = 0;
                result = connection.bitCount(key.getBytes());
                return result;
            }
        });
    }

    /**
     * 批处理命令
     * @param callback
     * @return
     */
    public List multi(RedisCallback> callback) {
        return redisTemplate.execute(callback);
    }

} 
  

5 编写测试用例

/**
* @Title: DemoRedisTransactionTest
* @Description: redis 事物测试
* @author chy
* @date 2018/8/1 14:46
*/
@RunWith(SpringRunner.class)
@SpringBootTest
public class DemoRedisTransactionTest {

    @Autowired
    RedisServiceExtend redisServiceExtend;

    /**
     * 测试 事物
      * @return
     */
    @Test
    public void multi() {
        List objects = redisServiceExtend.multi(new RedisCallback>() {
            @Override
            public List doInRedis(RedisConnection connection) throws DataAccessException {
                connection.multi();
                connection.set("trans1".getBytes(), "事物1".getBytes());
                connection.set("trans2".getBytes(), "trans2".getBytes());
                connection.mGet("trans1".getBytes(), "trans2".getBytes());
                List list = connection.exec();
                return list;
            }
        });

        List data = (ArrayList) objects.get(0);

        List rData = data.stream()
                .map(x -> {
                    byte[] t = (byte[]) x;
                    System.out.println("数据------>" + new String(t));
                    return new String(t);
                }).collect(Collectors.toList());

        rData.forEach(System.out::println);
    }

    /**
     * 事务只能在所有被监视键都没有被修改的前提下执行,
     * 如果这个前提不能满足的话,事务就不会被执行。
     */
    @Test
    public void watch() {
        List objects = redisServiceExtend.multi(new RedisCallback>() {
            @Override
            public List doInRedis(RedisConnection connection) throws DataAccessException {
                List list = null;
                do {
                    //观察key
                    connection.watch("mykey".getBytes());
                    connection.multi();
                    //自增
                    connection.incrBy("mykey".getBytes(), 1);
                    connection.incrBy("mykey".getBytes(), 1);
                    //如果事物执行期间mykey的值没有被修改则执行成功,否则执行失败
                    list = connection.exec();
                    //如果执行失败  list.size()==0
                }
                //失败重试,直到执行成功
                while (list == null || list.size() == 0);
                return list;
            }
        });

        if(objects.size()>0) {
            System.out.println("mykey-------->" + (long) objects.get(0));
        }

        if(objects.size()>1) {
            System.out.println("mykey-------->" + (long) objects.get(1));
        }
    }

} 
  

RedisConnection 是不是很强大可以实现redis的任意命令

你可能感兴趣的:(缓存)