1. 程式人生 > >Springboot 通過Jedis-clients 操作Redis

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進行解析(引入協議解析表進行原訊號解析)。

  1. 原始訊號簡化為字串------->>>如:01AB02ABBA等,其中兩位字元代表一個屬性,如前兩位表示裝置類別,其後依次為裝置通道號、裝置編號、溫度訊號及報警訊號。
  2. 分析訊號,採用redis中hash型別儲存為最佳方案。                                                                                                                                                            
  3. 鍵名為訊號的各個屬性(如裝置編號、溫度訊號等),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軟體中檢視