Springboot 通過Jedis-clients 操作Redis
Springboot中整合了Rdis(Springboot2.0 spring-boot-starter-data-redis)可直接使用RedisTemplate進行資料操作。出於學習的目的,加深對Redis配置及其資料操作的理解,本專案採用redis原生API(引入redis.clients--Jedis)進行有關redis操作的實現。採用Redis快取物聯網訊號[二進位制bit字串]對應的協議解析表,實現訊號接入後,經閘道器篩選及分類寫入kafka對應的topic,經過storm進行解析(引入協議解析表進行原訊號解析)。
- 原始訊號簡化為字串------->>>如:01AB02ABBA等,其中兩位字元代表一個屬性,如前兩位表示裝置類別,其後依次為裝置通道號、裝置編號、溫度訊號及報警訊號。
- 分析訊號,採用redis中hash型別儲存為最佳方案。
- 鍵名為訊號的各個屬性(如裝置編號、溫度訊號等),sub-key為原始訊號字元(如01、AB等--2個字元一組),value為原始訊號字元對應的協議解析值(如01-->第一類裝置(煙感),AB-->1#裝置,02-->02channal,AB-->存在超溫風險,BA-->報警風險)。
分析好目標及資料儲存方式之後,開始編碼。專案整體使用Springboot框架,引入Jedis進行資料儲存操作。
一、POM檔案
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.0.RELEASE</version> </parent> <properties> <java.version>1.8</java.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <!-- Json --> <!-- <dependency> --> <!-- <groupId>com.alibaba</groupId> --> <!-- <artifactId>fastjson</artifactId> --> <!-- <version>1.2.9</version> --> <!-- </dependency> --> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> </dependency> </dependencies>
二、配置檔案application.properties(只進行log配置,使用springboot logback)及redis.properties
logging.file=protocol-redis.log
#Redis伺服器(IP)
spring.redis.host=
#Redis服務埠號
spring.redis.port=
#Redis服務密碼
spring.redis.password=
#Redis伺服器連線超時的時間(0代表不超時)
spring.redis.timeout=0
#在borrow一個jedis例項時,是否提前進行validate操作;如果為true,則得到的jedis例項均是可用的
spring.redis.testOnBorrow=true
#控制一個pool最多有多少個狀態為idle(空閒的)的jedis例項,預設值也是8
spring.redis.maxIdle=8
#連線超時時是否阻塞,false時報異常,ture阻塞直到超時, 預設true
spring.redis.blockWhenExhausted=true
#等待可用連線的最大時間,單位毫秒,預設值為-1,表示永不超時。如果超過等待時間,則直接丟擲JedisConnectionException
spring.redis.maxWaitMillis=-1
#最大空連線數
spring.redis.maxTotal=200
三、Redis配置類,RedisConfig,寫入配置引數,返回連線池例項
package com.protocol.redis;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
@Configuration
@EnableAutoConfiguration
@PropertySource("classpath:redisConfig/redis.properties")
public class RedisConfig {
@Value("${spring.redis.host}")
private String host;
@Value("${spring.redis.port}")
private int port;
@Value("${spring.redis.password}")
private String passwd;
@Value("${spring.redis.timeout}")
private int timeout;
@Value("${spring.redis.blockWhenExhausted}")
private boolean blockWhenExhausted;
@Value("${spring.redis.maxIdle}")
private int maxIdle;
@Value("${spring.redis.maxWaitMillis}")
private int maxWaitMillis;
@Value("${spring.redis.maxTotal}")
private int maxTotal;
@Value("${spring.redis.testOnBorrow}")
private boolean testOnBorrow;
private JedisPool jedisPool;
@Bean
public JedisPoolConfig getRedisConfig() {
JedisPoolConfig config=new JedisPoolConfig();
return config;
}
@Bean
public JedisPool getJedisPool() {
JedisPoolConfig config=getRedisConfig();
config.setMaxIdle(maxIdle);
config.setMaxTotal(maxTotal);
config.setBlockWhenExhausted(blockWhenExhausted);
config.setTestOnBorrow(testOnBorrow);
config.setMaxWaitMillis(maxWaitMillis);
JedisPool jedisPool=new JedisPool(config,host,port,timeout,passwd);
return jedisPool;
}
}
四、編寫redis資料操作的redisService介面及其實現類redisServiceImpl(本例中只使用hash操作)
service介面類:定義資料操作的redis 連線池資源獲取方法、釋放資源、寫入資料(setInfo)及查詢資料get方法。
package com.protocol.redis;
import java.util.Map;
import redis.clients.jedis.Jedis;
public interface RedisService {
public redis.clients.jedis.Jedis getResource();
public void returnResource(Jedis jedis);
public void setInfo(String key, Map<String, String> value);
public Map<String, String> get(String key);
}
serviceImplements類,用於實現service類定義的方法:
package com.protocol.redis;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import redis.clients.jedis.JedisPool;
@Service
public class RedisServiceImpl implements RedisService{
@Autowired
private JedisPool jedisPool;
public redis.clients.jedis.Jedis getResource() {
//獲取Jedis連線池資源
return jedisPool.getResource();
}
@SuppressWarnings("deprecation")
public void returnResource(redis.clients.jedis.Jedis jedis) {
if(jedis!=null) {
//釋放jedisPool資源
jedisPool.returnResource(jedis);
}
}
/**
*實現資料寫入的setInfo方法
*/
public void setInfo(String key, Map<String, String> value) {
redis.clients.jedis.Jedis jedis=null;
try {
//獲取jedis例項連線
jedis=getResource();
//選擇使用的資料庫(0-15,如不指定預設為0)
jedis.select(15);
//使用hmset方法(key,value(hashmap<key,value>))
jedis.hmset(key, value);
}catch (Exception e) {
e.printStackTrace();// TODO: handle exception
}finally {
returnResource(jedis);
}
}
/**
*實現資料查詢的get方法
*/
public Map<String, String> get(String key){
redis.clients.jedis.Jedis jedis=null;
Map<String, String> result=null;
try {
jedis=getResource();
jedis.select(15);
//通過key返回其所有的subkey及value
jedis.hgetAll(key);
result=jedis.hgetAll(key);
}catch (Exception e) {
e.printStackTrace();// TODO: handle exception
}finally {
returnResource(jedis);
}
return result;
}
}
五、資料操作示例的類RunCreatA.class(本例中資料寫在程式碼裡了,也可通過定義controller,採用restful API的方式實現資料互動,此類繼承runnable,通過springboot application管理執行),分別寫入訊號字元對應的欄位及其值。
package com.protocol.setprotocol;
import java.util.HashMap;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
import com.protocol.redis.RedisService;
@Component
public class RunCreateA implements ApplicationRunner{
@Autowired
private RedisService redisService;
public void setType() {
String keyType="ProtocolA:Type";
Map<String, String> type=new HashMap<>();
type.put("01", "SmokeSensor");
type.put("02", "TemperatureSensor");
redisService.setInfo(keyType, type);
System.out.println("#######--Done With Write--#########");
redisService.get(keyType);
System.out.println("------------"+redisService.get(keyType)+"---------");
}
public void setNo() {
String keyNo="ProtocolA:No";
Map<String, String> No=new HashMap<>();
No.put("AA", "1# equipment");
No.put("AB", "2# equipment");
No.put("AC", "5# equipment");
redisService.setInfo(keyNo, No);
redisService.get(keyNo);
System.out.println("------------"+redisService.get(keyNo)+"---------");
}
public void setChannal() {
String keyChannal="ProtocolA:Channal";
Map<String, String> channal=new HashMap<>();
channal.put("01", "channal:1");
channal.put("02", "channal:2");
redisService.setInfo(keyChannal, channal);
redisService.get(keyChannal);
System.out.println("------------"+redisService.get(keyChannal)+"---------");
}
public void setTem() {
String keyTem="ProtocolA:Temperature";
Map<String, String> temperature=new HashMap<>();
temperature.put("AA", "Normal");
temperature.put("AB", "Risk:normal, little high");
temperature.put("BA", "Big Risk,too high");
temperature.put("BB", "Fire!");
redisService.setInfo(keyTem, temperature);
redisService.get(keyTem);
System.out.println("------------"+redisService.get(keyTem)+"---------");
}
public void setAlarm() {
String keyAlarm="ProtocolA:Alarm";
Map<String, String> alarm=new HashMap<>();
alarm.put("AA", "Normal");
alarm.put("BA", "Risk");
alarm.put("BB", "FireAlarm!");
redisService.setInfo(keyAlarm, alarm);
redisService.get(keyAlarm);
System.out.println("------------"+redisService.get(keyAlarm)+"---------");
}
public void run(ApplicationArguments args) throws Exception{
setType();
setNo();
setChannal();
setTem();
setAlarm();
System.out.println("start write!");
}
}
六、執行結果:
在redisclient軟體中檢視