influxDB学习笔记-java操作篇

本文实例项目中使用的是idea工具创建maven项目,如果不清楚怎么在idea中建立maven项目的可参考https://blog.csdn.net/stevensam_lin/article/details/81978041文章。言归正传,直接进入操作步骤。

1、搭建maven项目

在idea中新建一个maven工程。

2、导入influx相关依赖


<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0modelVersion>

    <groupId>com.soso.influxdb-demogroupId>
    <artifactId>influxdb-demoartifactId>
    <version>1.0-SNAPSHOTversion>

    <dependencies>
        
            
            
            
        
        <dependency>
            <groupId>org.influxdbgroupId>
            <artifactId>influxdb-javaartifactId>
            <version>2.5version>
        dependency>

    dependencies>

project>

3、书写influxUtil工具类

package com.soso.influx.utils;

import org.influxdb.InfluxDB;
import org.influxdb.InfluxDBFactory;
import org.influxdb.dto.Point;
import org.influxdb.dto.Query;
import org.influxdb.dto.QueryResult;

import java.util.Map;

/**
 * author:seven lin
 * date:2020/7/16 10:58
 * description:
 **/
public class InfluxDbUtil {
    private static String openurl = "http://192.168.25.161:8086";//连接地址
    private static String username = "root";//用户名
    private static String password = "root";//密码
    private static String database = "mydb";//数据库
    private static String measurement = "cpu";//表名

    private InfluxDB influxDB;


    public InfluxDbUtil(String username, String password, String openurl, String database){
        this.username = username;
        this.password = password;
        this.openurl = openurl;
        this.database = database;
    }

    public static InfluxDbUtil setUp(){
        //创建 连接
        InfluxDbUtil influxDbUtil = new InfluxDbUtil(username, password, openurl, database);

        influxDbUtil.influxDbBuild();

        influxDbUtil.createRetentionPolicy();

//   influxDB.deleteDB(database);
//   influxDB.createDB(database);
        return influxDbUtil;
    }

    /**
     * 连接时序数据库;获得InfluxDB
     * @return InfluxDB
     */
    public InfluxDB influxDbBuild(){
        if(influxDB == null){
            influxDB = InfluxDBFactory.connect(openurl, username, password);
            influxDB.createDatabase(database);
        }
        return influxDB;
    }

    /**
     * 设置数据保存策略
     * defalut 策略名 /database 数据库名/ 30d 数据保存时限30天/ 1 副本个数为1/ 结尾DEFAULT 表示 设为默认的策略
     */
    public void createRetentionPolicy(){
        String command = String.format("CREATE RETENTION POLICY \"%s\" ON \"%s\" DURATION %s REPLICATION %s DEFAULT",
                "defalut", database, "30d", 1);
        this.query(command);
    }

    /**
     * 查询
     * @param command 查询语句
     * @return
     */
    public QueryResult query(String command){
        return influxDB.query(new Query(command, database));
    }

    /**
     * 插入
     * @param tags 标签
     * @param fields 字段
     */
    public void insert(Map<String, String> tags, Map<String, Object> fields){
        Point.Builder builder = Point.measurement(measurement);
        builder.tag(tags);
        builder.fields(fields);

        influxDB.write(database, "", builder.build());
    }

    /**
     * 删除
     * @param command 删除语句
     * @return 返回错误信息
     */
    public String deleteMeasurementData(String command){
        QueryResult result = influxDB.query(new Query(command, database));
        return result.getError();
    }

    /**
     * 创建数据库
     * @param dbName
     */
    public void createDB(String dbName){
        influxDB.createDatabase(dbName);
    }

    /**
     * 删除数据库
     * @param dbName
     */
    public void deleteDB(String dbName){
        influxDB.deleteDatabase(dbName);
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getOpenurl() {
        return openurl;
    }

    public void setOpenurl(String openurl) {
        this.openurl = openurl;
    }

    public void setDatabase(String database) {
        this.database = database;
    }
}

4、创建库并查询库

自创一个主类InfluxDemo,代码如下:

package com.soso.influx.demo;

import com.soso.influx.utils.InfluxDbUtil;
import org.influxdb.dto.QueryResult;
import org.influxdb.dto.QueryResult.*;
import java.util.List;

/**
 * author:seven lin
 * date:2020/7/16 10:19
 * description:
 **/
public class InfluxDemo {
    private static InfluxDbUtil influxDbUtil = InfluxDbUtil.setUp();
    public static void main(String[] args) {
        //查看数据库
        testShowDB();
        //创建数据库
        String new_db = "new_db";
        testCreateDB(new_db);
        //查看数据库
        testShowDB();
    }
    
    private static void testCreateDB(String new_db) {
        influxDbUtil.createDB(new_db);
    }
    
    private static void testShowDB() {
        QueryResult showDatabases = influxDbUtil.query("show databases");
        System.out.println("数据库库名有:");
        printResult(showDatabases);
    }
    
    /**
     * 打印结果
     * @param qr
     */
    public static void printResult(QueryResult qr){
        for (Result rs : qr.getResults()){
            for(Series sr:rs.getSeries()){
                for(List values: sr.getValues()){
                    for(Object value:values){
                        System.out.print(value + " ");
                    }
                }
                System.out.println();
            }
        }
        System.out.println();
    }
}

结果:

数据库库名有:
_internal mydb db01 copy_mydb_database  -- 原先的数据库列表
数据库库名有:
_internal mydb db01 copy_mydb_database new_db -- 增加新库后的数据库列表

Process finished with exit code 0

此处值得注意的是,在创建数据库的时候并不需要担心原先是否有该数据库而执行后报错。因为在influxdb1.0之后的版本内部已经是进行了处理,如果是已经有该数据库,返回空而不是报错。各位可以通过CLI命令进行尝试。这里不做测试,只给大家看看创建数据库调用的实质是什么。

4.1、解析调用过程

InfluxDbUtil创建的时候会通过以下代码创建一个InfluxDB实例:

influxDB = InfluxDBFactory.connect(openurl, username, password);

InfluxDBFactory.connect(openurl, username, password)的源码如下:

/**
 * Create a connection to a InfluxDB.
 *
 * @param url
 *            the url to connect to.
 * @param username
 *            the username which is used to authorize against the influxDB instance.
 * @param password
 *            the password for the username which is used to authorize against the influxDB
 *            instance.
 * @return a InfluxDB adapter suitable to access a InfluxDB.
 */
public static InfluxDB connect(final String url, final String username, final String password) {
  Preconditions.checkArgument(!Strings.isNullOrEmpty(url), "The URL may not be null or empty.");
  Preconditions.checkArgument(!Strings.isNullOrEmpty(username), "The username may not be null or empty.");
  return new InfluxDBImpl(url, username, password, new OkHttpClient.Builder());
}

所以InfluxDbUtil调用的各个方法其实都是调用InfluxDBImpl实现类中的方法。

InfluxDBImpl的createDatabase方法代码如下:

/**
   * {@inheritDoc}
   */
  @Override
  public void createDatabase(final String name) {
    Preconditions.checkArgument(!Strings.isNullOrEmpty(name), "Database name may not be null or empty");
    String createDatabaseQueryString = String.format("CREATE DATABASE \"%s\"", name);
    //注意此处,如果influxdb的版本是1.0以下的,这里也会做一个异常处理,所以并不需要再做异常处理。
    if (this.version().startsWith("0.")) {
      createDatabaseQueryString = String.format("CREATE DATABASE IF NOT EXISTS \"%s\"", name);
    }
    //最后调用这个execute方法进行请求数据,而这里面的调用的方法才是重点
    //注:influxDBService在InfluxDBImpl初始化的时候已经通过反向代理实现了一个实例作为它的一个属性值。
    execute(this.influxDBService.postQuery(this.username, this.password, 		Query.encode(createDatabaseQueryString)));
  }

execute方法中调用到了influxDBService.postQuery方法,而此方法源码如下:

@POST("/query")
  public Call<QueryResult> postQuery(@Query(U) String username,
      @Query(P) String password, @Query(value = Q, encoded = true) String query);

熟悉java的同学都知道,此方法通过post方式发送http请求,这也是influxdb的另一种请求数据的方式。其他的方法类似这样的请求数据。

5、查询measurements

public static void main(String[] args) {
    ......
    //查看mydb中的measurements
    testShowMeasurements("mydb");
}
private static void testShowMeasurements(String dbName) {
    //设置当前操作的数据库,相当于use databasse
    influxDbUtil.setDatabase(dbName);
    QueryResult showMeasurements = influxDbUtil.query("show measurements");
    System.out.println(dbName + "库中表:");
    printResult(showMeasurements);
}

6、插入数据

public static void main(String[] args) {
    ......
    //插入一行数据
    influxDbUtil.query("insert cpu,host=serverA,region=us_west value=0.74 1594854900000");
}

7、查询表数据

public static void main(String[] args) {
    ......
    //查询数据
    QueryResult result = influxDbUtil.query("select * from mydb.defalut.cpu group by host");
    printResult(result);
}

此处使用了group by tag语法来进行查询所有字段,结果会有不同的series:

Series [name=cpu, tags={host=serverA}, columns=[time, region, value], values=[[2020-07-16T06:54:29.809600627Z, us_west, 0.64]]]
Series [name=cpu, tags={host=serverB}, columns=[time, region, value], values=[[2020-07-15T23:16:08.359600627Z, us_east, 0.74]]]

一般情况下,不建议直接查表,最好有聚合分类,否则如果直接使用select * from measurement,那么所有的value都会集合在一个序列中。

其他的操作基本上都是调用query方法。不做过多的赘述。

你可能感兴趣的:(influxDB,大数据,数据库)