REDIS 学习(9) 使用java8写jedis的技巧,经典jedis池,附配置文件的读取

一,通过函数指针避免try-cath的书写

使用jedis灵活可靠,而且用微不足道的序列化消耗提高开发效率。

首先看一段try-with-resoure风格的jedis片,这种方式jedis会在cath(Excepiton e)或者try代码结束后调用jedis.close()方法

try (Jedis jedis = new Jedis("119.29.111.111", 6379);) {
	jedis.select(3);// 选择数据库
	// 增
	jedis.set("gao", "tia n");// 每次都会覆盖旧的key <gao,tian>
	// 查
	Logger.getGlobal().info(jedis.get("a"));
} catch (Exception e) {
	e.printStackTrace();
}
为了减少redis创建和销毁连接的消耗,我们使用jedis池
JedisPool pool = new JedisPool(poolConfig, "119.29.111.111", 6379, 0, "foobared", 3);
	try (Jedis jedis = pool.getResource()) {
			
	} catch (Exception e) {
		e.printStackTrace();
	}
pool.close();
注意jedis的close方法,会尝试还给自己的jedis池,而不是关闭链接,这里不再赘述。

这样每次try是不是很不方便?

我们可以用一个函数指针,来描述给我一个Jedis对象,我对他进行某些操作,然后返回给我某个类型的值来传入到这个try-with-resource的代码片段里

定义函数指针:

public interface JedisCallBack<T> {
	T doInRedis(Jedis jedis) throws DataAccessException;
}
定义一个jedis池的包装类

public class JedisPoolHandler {

	private JedisPool pool;
	...
	public <T> T excute(JedisCallBack<T> action){
		try (Jedis jedis = pool.getResource()){
			return action.doInRedis(jedis);
		} catch (Exception e) {
			LogCore.BASE.error("jedisHandler err", e);
			return null;
		}
	}
	
}
我们接下来看看使用

long num = handler.excute((jedis) -> jedis.incr(name));
是不是很方便?!

二,配置文件和bean的注入

之前的jedis.property

jedis.database=0
jedis.host=localhost
jedis.password=foobared
jedis.port=6379
jedis.timeout=0
java文件
public class JedisConfigBase {
	private int database;
	private String host;
	private String password;
	private int port;
	private int timeout;
	...get,set's methods
	@Override
	public String toString() {
		return ReflectionToStringBuilder.toString(this, ToStringStyle.SHORT_PREFIX_STYLE);
	}
}
@Order(value = 1)
@Component
public class JedisPoolHandlerInstances implements CommandLineRunner{
	
	@Component //外部tomcat不可以配置为component,嵌入式tomcat需要此注解
	@ConfigurationProperties(prefix="jedis",locations="classpath:jedis.properties")
	public static class JedisConfigStats extends JedisConfigBase{}
	
	@Autowired
	JedisConfigStats stats_jedis_cf;
	
	private static JedisPoolHandler STATS_HANDLER;
	public static JedisPoolHandler getSTATSHandler(){
		return STATS_HANDLER;
	}
	
	@Override
	public void run(String... args) throws Exception {
		STATS_HANDLER = new JedisPoolHandler(stats_jedis_cf);
	}
}
这样写每次都需要getSTATSHander(),不能直接用静态变量STATAS_HANDER,因为别的类的属性在定义时引用的时候,这个对象还没有被Spring注入

但是这样,依然很丑陋。


三,我们重新梳理一下

jedis.properties文件

jedis.database=10
jedis.host=localhost
jedis.auth=foobared
jedis.port=6377
jedis.timeout=0

public interface JedisCallBack<T> {
	T doInRedis(Jedis jedis) throws DataAccessException;
}

public class JedisPoolTemplate {
	private JedisPool pool;

	public JedisPoolTemplate(String host, int port, int timeout, String psw, int database) {
		JedisPoolConfig poolConfig = new JedisPoolConfig();
		pool = new JedisPool(poolConfig, host, port, timeout, psw, database);
	}

	public <T> T excute(JedisCallBack<T> action){
		try (Jedis jedis = pool.getResource()){
			return action.doInRedis(jedis);
		} catch (Exception e) {
			LogCore.BASE.error("jedisHandler err", e);
			return null;
		}
	}
}
@Configuration
@PropertySource("classpath:jedis.properties")
public class JedisPoolConfig {
	@Bean
	JedisPoolTemplate getJedisPoolTemplate(
			@Value("${jedis.host}") String host,
			@Value("${jedis.port}") int port,
			@Value("${jedis.auth}") String auth,
			@Value("${jedis.timeout}") int timeout,
			@Value("${jedis.database}") int	database
			) {
		JedisPoolTemplate template = new JedisPoolTemplate(host, port, timeout, auth, database);
		return template;
	}

}
使用方法

	@Autowired
	JedisPoolTemplate jedisTemplate;
	public long incrBy(String name, long value) {
		return jedisTemplate.excute((jedis) -> jedis.incrBy(name, value));
	}
	public Long zadd(String key, double score, String value) {
		return jedisTemplate.excute((jedis) -> jedis.zadd(key, score, value));
	}

搞掂,嘿嘿

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值