一.SpringBoot集成InfluxDB 1.x
既然准备SpringBoot整合InfluxDB,想必你已经了解了InfluxDB的安装、配置、使用。
那么就直奔正文。
目前本人已知可以实现的方式有3种:
集成原生的InfluxDB
集成封装的InfluxDBTemplate
集成InfluxDB封装的框架
环境:
influxDB 1.8
二.集成原生的InfluxDB
- 导入依赖
<!-- InfluxDB 原生依赖 -->
<dependency>
<groupId>org.influxdb</groupId>
<artifactId>influxdb-java</artifactId>
<version>2.18</version>
</dependency>
- 配置YAML文件
influxdb:
url: http://127.0.0.1:8086
username: root #用户
password: 123 #密码
database: test #库
retention: autogen #保存策略
- 创建InfluxDB工具类
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.influxdb.InfluxDB;
import org.influxdb.InfluxDB.ConsistencyLevel;
import org.influxdb.InfluxDBFactory;
import org.influxdb.dto.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.influxdb.dto.Point.Builder;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
* InfluxDB数据库连接操作类
*/
@Data
@Component
@Slf4j
public class InfluxDbComUtil {
// 用户名
@Value("${influxdb.username}")
private String username;
// 密码
@Value("${influxdb.password}")
private String password;
// 连接地址
@Value("${influxdb.url}")
private String openurl;
// 数据库名称
@Value("${influxdb.database}")
private String dbName;
// 保留策略
@Value("${influxdb.retention}")
private String retentionPolicy;
@Autowired
private InfluxDB influxDB;
public InfluxDbComUtil() {
}
/**
* 连接时序数据库 ,若不存在则创建
*
* @return
*/
@Bean
public InfluxDB influxDbBuild() {
if (influxDB == null) {
influxDB = InfluxDBFactory.connect(openurl, username, password);
}
try {
if (!influxDB.databaseExists(dbName)) {
influxDB.createDatabase(dbName);
}
} catch (Exception e) {
// 该数据库可能设置动态代理,不支持创建数据库
e.printStackTrace();
} finally {
influxDB.setRetentionPolicy(retentionPolicy);
}
influxDB.setLogLevel(InfluxDB.LogLevel.NONE);
return influxDB;
}
/**
* 测试连接是否正常
*
* @return true 正常
*/
public boolean ping() {
boolean isConnected = false;
Pong pong;
try {
pong = influxDB.ping();
if (pong != null) {
isConnected = true;
}
} catch (Exception e) {
e.printStackTrace();
}
return isConnected;
}
/**
* 创建数据库
*
* @param dbName
*/
@SuppressWarnings("deprecation")
public void createDB(String dbName) {
influxDB.createDatabase(dbName);
}
/**
* 删除数据库
*
* @param dbName
*/
@SuppressWarnings("deprecation")
public void deleteDB(String dbName) {
influxDB.deleteDatabase(dbName);
}
/**
* 切换数据库
*/
@SuppressWarnings("deprecation")
public void setDB(String dbName){
influxDB.setDatabase(dbName);
}
/**
* 关闭数据库
*/
public void close() {
influxDB.close();
}
/**
* 切换数据库策略
* @param dataBaseName 数据库
* @param policyName 策略名
*/
public void updRetentionPolicy(String dataBaseName,String policyName){
String sql=String.format("ALTER RETENTION POLICY \""+policyName+"\" ON \""+dataBaseName+"\" DEFAULT");
query(sql);
this.dbName=dataBaseName;
this.retentionPolicy=policyName;
}
/**
* 切换策略
* @param policyName 策略名
*/
public void updRetentionPolicy(String policyName){
String sql=String.format("ALTER RETENTION POLICY \""+policyName+"\" ON \""+dbName+"\" DEFAULT");
query(sql);
this.retentionPolicy=policyName;
}
/**
* 创建自定义保留策略
*
* @param policyName 策略名
* @param days 保存天数
* @param replication 保存副本数量
* @param isDefault 是否设为默认保留策略
*/
public void createRetentionPolicy(String dataBaseName, String policyName, int days, int replication, Boolean isDefault) {
String sql = String.format("CREATE RETENTION POLICY \"%s\" ON \"%s\" DURATION %sd REPLICATION %s ", policyName,
dataBaseName, days, replication);
if (isDefault) {
sql = sql + " DEFAULT";
}
query(sql);
}
/**
* 创建默认的保留策略
*
* 策略名:hour,保存天数:30天,保存副本数量:1,设为默认保留策略
*/
public void createDefaultRetentionPolicy() {
String command = String
.format("CREATE RETENTION POLICY \"%s\" ON \"%s\" DURATION %s REPLICATION %s DEFAULT", "hour", dbName,
"30d", 1);
this.query(command);
}
/*********************************增删查**************************************************/
/**
* 查询
*
* @param command 查询语句
* @return
*/
public QueryResult query(String command) {
return influxDB.query(new Query(command, dbName));
}
/**
* 插入
*
* @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);
builder.tag(tags);
builder.fields(fields);
if (0 != time) {
builder.time(time, timeUnit);
}
influxDB.write(dbName, retentionPolicy, builder.build());
}
/**
* 删除
*
* @param command 删除语句
* @return 返回错误信息
*/
public String deleteMeasurementData(String command) {
QueryResult result = influxDB.query(new Query(command, dbName));
return result.getError();
}
/**
* 构建Point
* @param measurement 表
* @param time 时间
* @param timeUnit 延迟
* @param tags tags
* @param fields
* @return
*/
public Point pointBuilder(String measurement, long time, TimeUnit timeUnit, Map<String, String> tags, Map<String, Object> fields) {
Point point = Point.measurement(measurement).time(time, timeUnit).tag(tags).fields(fields).build();
return point;
}
/**
* 批量写入测点
*
* @param batchPoints
*/
public void batchInsert(BatchPoints batchPoints, TimeUnit timeUnit) {
influxDB.write(batchPoints);
// influxDB.enableGzip();
// influxDB.enableBatch(2000,100,timeUnit);
// influxDB.disableGzip();
// influxDB.disableBatch();
}
/**
* 批量写入数据
*
* @param database 数据库
* @param retentionPolicy 保存策略
* @param consistency 一致性
* @param records 要保存的数据(调用BatchPoints.lineProtocol()可得到一条record)
*/
public void batchInsert(final String database, final String retentionPolicy, final ConsistencyLevel consistency, TimeUnit timeUnit, final List<String> records) {
influxDB.write(database, retentionPolicy, consistency, timeUnit, records);
}
}
- 使用
/**
* 测试例子
*/
/**新增测试Util*/
InfluxDbComUtil influxDbComUtil = SpringUtils.getBean(InfluxDbComUtil.class);
Map<String, String> tags = new HashMap<>();
tags.put("tag1", "标签值");
Map<String, Object> fields = new HashMap<String, Object>();
fields.put("field1", "String类型");
// 数值型,InfluxDB的字段类型,由第一天插入的值得类型决定
fields.put("field2", 3.141592657);
// 时间使用毫秒为单位
influxDbComUtil.insert("表名", tags, fields, System.currentTimeMillis(), TimeUnit.MILLISECONDS);
/**查询*/
QueryResult result = influxDbComUtil.query("SELECT * FROM alarm_album");
QueryResult.Result oneResult=result.getResults().get(0);
if (oneResult.getSeries() != null) {
List<List<Object>> valueList = oneResult.getSeries().stream()
.map(QueryResult.Series::getValues)
.collect(Collectors.toList()).get(0);
if (valueList != null && valueList.size() > 0) {
for (List<Object> value : valueList) {
Map<String, String> map = new HashMap<String, String>();
// 数据库中字段1取值
String field1 = value.get(0) == null ? null : value.get(0).toString();
// 数据库中字段2取值
String field2 = value.get(1) == null ? null : value.get(1).toString();
// TODO 用取出的字段做你自己的业务逻辑……
System.out.println(value);
}
}
}
新增结果
查询结果(数据库内仅有一条数据)
- 配置实体类
@Data
@Measurement(name="terminal_heart_beat")
public class TerminalHeartBeatModel{
@Column(name="id", tag = true) //tag 可以理解为influxdb的索引
private Long id;
@Column(name="mac")
private String mac;
}
- 使用InfluxDBMapper
InfluxDbComUtil influxDbComUtil = SpringUtils.getBean(InfluxDbComUtil.class);
influxDbComUtil.setDB(influxDbComUtil.getDbName());//讲influxdb的库设置成默认的库 你也可以自己填。
InfluxDBMapper influxDBMapper = new InfluxDBMapper(influxDbComUtil.getInfluxDB());
//根据对象进行新增或查询
Test test=new Test();
test.setId(new Long(10));
test.setMac("aa:bb:cc...");
influxDBMapper.save(test);
List<Test> testList = influxDBMapper.query(Test.class);
但是关于time列,通过原生InfluxDB:Point进行新增操作,是以long型或Number型
三.集成Spring封装的InfluxDB Template
- 导入依赖
<!-- Spring封装的InfluxDB -->
<dependency>
<groupId>plus.ojbk</groupId>
<artifactId>influxdb-spring-boot-starter</artifactId>
<version>1.0.2</version>
</dependency>
- 配置YAML
influxdb:
url: http://127.0.0.1:8086
username: root #用户
password: 123 #密码
database: test #库
- 配置实体类
@Data
@Measurement(name="terminal_heart_beat")
public class TerminalHeartBeatModel{
@Column(name="id", tag = true) //tag 可以理解为influxdb的索引
private Long id;
@Column(name="mac")
private String mac;
@Column(name="time")
private LocalDateTime time;
}
- 使用
@Resource
private InfluxdbTemplate influxdbTemplate;
/**
* 获取集合
* @param map
* @param start
* @param end
* @return
*/
public List<TerminalHeartBeatModel> getList(Map<String,Object> map,LocalDateTime start, LocalDateTime end){
//类似MybatisPlus中的QueryWrapper
QueryModel queryModel = new QueryModel();
queryModel.setMeasurement(InfluxdbUtils.getMeasurement(TerminalHeartBeatModel.class));
//Map<String, Object> map = new TreeMap<>();
//map.put("mac", "00:aa:00:aa:00:00");
queryModel.setMap(map);
queryModel.setStart(start);
queryModel.setEnd(end);
queryModel.setUseTimeZone(true); //时区
queryModel.setOrder(Order.DESC); //排序
//where 条件中额外参数可放入model.setMap();
queryModel.setWhere(Op.where(queryModel));
return influxdbTemplate.selectList(Query.build(queryModel), TerminalHeartBeatModel.class);
}
/** 新增 */
public void save(TerminalHeartBeatModel model){
influxdbTemplate.insert(model);
}
相较于原版,它封装了自有的Util以及Template等
对于原版Point的time列类型问题,它对number和long 型转换成了LocalDateTime类型
并且封装了更多的方法(具体自行拓展)
四.集成InfluxDB封装的框架
- 导入依赖
<!-- git作者个人封装的框架 -->
<dependency>
<groupId>io.github.betacatcode</groupId>
<artifactId>spring-boot-starter-influxdb</artifactId>
<version>0.0.4-RELEASE</version>
</dependency>
<dependency>
<groupId>org.influxdb</groupId>
<artifactId>influxdb-java</artifactId>
<version>2.18</version>
</dependency>
- 配置YAML
spring:
influx:
url: http://127.0.0.1:8086
user: admin
password: 123456
mapper-location: com.github.betacatcode
- 配置实体类
@Data
@Measurement(database = "test",name = "student")
public class Student {
private String id;
@Column(name = "sname",tag = true)
private String sname;
@Column(name = "value")
private Double value;
@TimeColumn
@Column(name = "time")
private Instant time;
}
- 创建Mapper 继承InfluxDBBaseMapper接口
public interface StudentMapper extends InfluxDBBaseMapper {
@Select(value = "select * from test.autogen.student where sname=#{sname}",
resultType = Student.class)
List<Student> selectByName(String sname);
@Delete(value = "delete from student",database = "test")
void deleteAll();
@Insert
void insertOne(Student student);
@Insert
void insertBatch(List<Student> students);
}
- 使用
调用即可
类似于mybatis 本人不常用,自行拓展。
本处集成框架 引用源自:https://gitee.com/ruin97/spring-boot-starter-influxdb
五.总结
不论是使用哪种方式 都各有利弊 根据项目的需求 决定使用的方式
如有疑问或文中有误 可以私信
版权归原作者 格栅看海 所有, 如有侵权,请联系我们删除。