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

时间:2021-09-27 17:26:31

一,通过函数指针避免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)@Componentpublic 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));	}

搞掂,嘿嘿