最近在使用influxDB,但是在網上找了很多工具類都不是很好用。
大家都知道influxDB查詢出來的數據格式不是json格式,比較難以處理,很多網上的工具類都沒有對查詢的結果進行封裝,都是返回一個QueryResult對象。
遂本文在其基礎上進行了一定的修改。
1、主要修改的地方:
對查詢結果進行封裝,使用泛型,直接返回javaBean對象。
說明:本項目使用了springboot,但是大家如果不想用,可以自行稍做修改
2、本工具類依賴:
<dependency>
<groupId>org.influxdb</groupId>
<artifactId>influxdb-java</artifactId>
<version>2.15</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.58</version>
</dependency>
3、工具類
package cc.wllfengshu.utils;
import cc.wellcloud.rtstat.configs.EnvConfig;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.influxdb.InfluxDB;
import org.influxdb.dto.*;
import org.influxdb.dto.Point.Builder;
import org.influxdb.InfluxDBFactory;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
* 配置influxdb
*
* @author wangll
*/
@Slf4j
public class InfluxDbUtil {
public static final String DATABASE = "CMBC_RTSTAT";
public static final String RETENTION_POLICY = "";
private InfluxDB influxdb = null;
public InfluxDbUtil(EnvConfig envConfig){
if(influxdb == null){
influxdb = InfluxDBFactory.connect(envConfig.getInfluxdbUrl(),envConfig.getInfluxdbUsername(),envConfig.getInfluxdbPassword());
if (!this.ping()){
log.error("無法連接到influxDB");
}
if (!influxdb.databaseExists(DATABASE)) {
influxdb.enableBatch(2000,10000, TimeUnit.MILLISECONDS);
//創建數據庫(注意:本文使用默認數據保留策略,如需要修改請自行查資料)
influxdb.query(new Query("CREATE DATABASE " + DATABASE));
influxdb.setDatabase(DATABASE);
influxdb.setLogLevel(InfluxDB.LogLevel.NONE);
}
log.info("influxDb初始化完畢");
}
}
/**
* 查詢
*
* @param command 查詢語句
* @return
*/
public <T> List<T> query(String command,Class<T> clazz) {
log.info("query command:{}",command);
JSONArray resultArr = new JSONArray();
QueryResult query = influxdb.query(new Query(command, DATABASE));
for (QueryResult.Result result : query.getResults()) {
List<QueryResult.Series> series = result.getSeries();
if(series==null){
continue;
}
for (QueryResult.Series serie : series) {
List<List<Object>> values = serie.getValues();
List<String> colums = serie.getColumns();
Map<String, String> tags = serie.getTags();
// 封裝查詢結果
for (int i=0;i<values.size();++i){
JSONObject jsonData = new JSONObject();
if (tags!=null && tags.keySet().size()>0){
tags.forEach((k,v)-> jsonData.put(k,v));
}
for (int j=0;j<colums.size();++j){
jsonData.put(colums.get(j),values.get(i).get(j));
}
resultArr.add(jsonData);
}
}
}
return JSONObject.parseArray(resultArr.toJSONString(), clazz);
}
/**
* 插入
*
* @param measurement 表
* @param tags 標籤
* @param fields 字段
*/
public void insert(String measurement, Map<String, String> tags, Map<String, Object> fields, long time,TimeUnit timeUnit) {
Builder builder = Point.measurement(measurement).tag(tags).fields(fields).time(time, timeUnit);
influxdb.write(DATABASE, RETENTION_POLICY, builder.build());
}
/**
* 插入
*
* @param point
*/
public void insert(Point point) {
if (null==point){
return;
}
influxdb.write(DATABASE, RETENTION_POLICY, point);
}
/**
* 批量寫入數據
*
* @param points
*/
public void batchInsert(List<Point> points) {
if (points==null || points.size()<=0){
log.info("數據爲空");
return;
}
BatchPoints batchPoints = BatchPoints.database(InfluxDbUtil.DATABASE).retentionPolicy(InfluxDbUtil.RETENTION_POLICY).build();
for(Point p:points){
batchPoints.point(p);
}
influxdb.write(batchPoints);
}
/**
* 刪除表
*
* @param measurement
* @return 返回錯誤信息
*/
public void deleteMeasurement(String measurement) {
log.info("dropMeasurement measurement:{}",measurement);
influxdb.query(new Query("drop measurement \"" + measurement + "\"", DATABASE));
}
/**
* 刪除數據庫
*/
public void deleteDb() {
influxdb.query(new Query("DROP DATABASE \"" + DATABASE + "\""));
}
/**
* 測試連接是否正常
*
* @return true 正常
*/
public boolean ping() {
Pong pong = influxdb.ping();
if (pong != null) {
return true;
}
return false;
}
/**
* 關閉數據庫
*/
public void close() {
influxdb.close();
}
}
說明:EnvConfig類裏面包含influxDB的url/用戶名/密碼。類如下,如果大家嫌麻煩,可以修改工具類的構造函數即可。EnvConfig類如下:
package cc.wellcloud.rtstat.configs;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
@Slf4j
@Data
@Component
@Order(0)
public class EnvConfig implements InitializingBean {
/**
* influxDB配置
*/
@Value("${influxdb_url:http://192.168.40.107:32099}")
private String influxdbUrl;
@Value("${influxdb_username:rtstat}")
private String influxdbUsername;
@Value("${influxdb_password:rtstat}")
private String influxdbPassword;
@Override
public void afterPropertiesSet() throws Exception {
log.info("環境變量:{}",this.toString());
}
}
4、工具類的使用
import cc.wellcloud.rtstat.common.Constant;
import cc.wellcloud.rtstat.configs.EnvConfig;
import cc.wellcloud.rtstat.entity.model.AgentData;
import lombok.extern.slf4j.Slf4j;
import org.influxdb.dto.Point;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest
public class InfluxDbUtilTest {
@Autowired
private EnvConfig envConfig;
private InfluxDbUtil influxDbUtil=null;
@Before
public void setUp(){
influxDbUtil=new InfluxDbUtil(envConfig);
}
@Test
public void ping(){
System.out.println(influxDbUtil.ping());
}
@Test
public void query() {
List<AgentData> ads = influxDbUtil.query("select * from " + Constant.INFLUXDB_MEASUREMENT_AGENT_DATA, AgentData.class);
System.out.println(ads);
}
@Test
public void insert1() {
//測試插入數據
Map<String, String> ts = new HashMap<>();
ts.put("name","張三");
Map<String, Object> fs = new HashMap<>();
fs.put("SEX","男");
fs.put("AGE", 32);
influxDbUtil.insert("test",ts, fs,System.currentTimeMillis(), TimeUnit.MILLISECONDS);
}
/**
* 查看過期時間:SHOW RETENTION POLICIES ON CMBC_RTSTAT
* 查看錶:show measurements
*/
@Test
public void insert2() {
//測試插入數據
Map<String, String> ts = new HashMap<>();
ts.put("name","王2");
Map<String, Object> fs = new HashMap<>();
fs.put("SEX","女");
fs.put("AGE", 66);
Point point = Point.measurement("test").time(System.currentTimeMillis(), TimeUnit.MILLISECONDS).tag(ts).fields(fs).build();
influxDbUtil.insert(point);
}
@Test
public void batchInsert() {
List<AgentData> as = new ArrayList<>();
AgentData ad1=new AgentData();
ad1.setPlatform(4);
ad1.setAgentNo("wll");
ad1.setCallLength(999);
ad1.setCallNum(222);
ad1.setTalkNum(100);
as.add(ad1);
AgentData ad2=new AgentData();
ad2.setPlatform(5);
ad2.setAgentNo("liang");
ad2.setCallLength(888);
ad2.setCallNum(78);
as.add(ad2);
List<Point> records = new ArrayList<>();
for (AgentData a:as) {
//1 tags
Map<String, String> ts = new HashMap<>(6);
ts.put("platform", String.valueOf(a.getPlatform()));
ts.put("agentNo",a.getAgentNo());
//2 fields
Map<String, Object> fs = new HashMap<>(7);
fs.put("callLength", a.getCallLength());
fs.put("callNum",a.getCallNum());
//3 point
Point point = Point.measurement(Constant.INFLUXDB_MEASUREMENT_AGENT_DATA).tag(ts).fields(fs).time(System.currentTimeMillis(), TimeUnit.MILLISECONDS).build();
records.add(point);
}
influxDbUtil.batchInsert(records);
}
@Test
public void deleteDb() {
influxDbUtil.deleteDb();
}
@Test
public void deleteMeasurementData() {
influxDbUtil.deleteMeasurement(Constant.INFLUXDB_MEASUREMENT_AGENT_DATA);
}
@After
public void close(){
influxDbUtil.close();
}
}