把已有物联网数据库稍加修改搬迁到自己数据库,用timescale DB(时序数据库)来存储。
用java的 jdbc来操作数据库。查询读出数据+创建新数据表+把数据写入新表。
ideal本身的数据库管理工具也挺好用,以后可以写一篇
1.加载mysql驱动 Class.forName("com.mysql.jdbc.Driver")
2.连接数据库,注意配置时区 DriverManager.getConnection(url,user,password)
3.创建执行环境 Connection conn_mgr.createStatement();
4.执行sql语句 statement_data.executeQuery(sql)
4.1创建表
4.2把表设置为timescaledb表
4.3先构造id对应表(id_match),插入一遍就好,第二遍会有主键冲突,抛出异常
4.4主要操作,向timescale新表里插入数据
package com.cwl.JDBC;
import java.sql.*;
import java.util.concurrent.*;
public class JDBC {
// 建表sql
static String create_id_match="CREATE TABLE id_match\n" +
"(new_devId VARCHAR(35) NOT NULL,\n" +
"old_devId VARCHAR(35) NOT NULL,\n" +
"primary key(new_devId,old_devId)\n" +
");";
static String create_water_0011801="CREATE TABLE hourdata_0011801\n" +
"(new_devId VARCHAR,\n" +
"read_time TIMESTAMPTZ,\n" +
"real_value NUMERIC,\n" +
"dev_source int,\n" +
"in_range int,\n" +
"in_cycle int ,\n" +
"Vorigin NUMERIC,\n"+
"primary key(new_devId,read_time)\n" +
");";
static String create_electricity_00118A0="CREATE TABLE hourdata_00118A0\n" +
"(new_devId VARCHAR,\n" +
"read_time TIMESTAMPTZ,\n" +
"real_value NUMERIC,\n" +
"dev_source int,\n" +
"in_range int,\n" +
"in_cycle int ,\n" +
"Vorigin NUMERIC,\n"+
"primary key(new_devId,read_time)\n" +
");";
public static void main(String[] args) throws Exception {
// 1.加载mysql驱动 Class.forName("com.mysql.jdbc.Driver")
Class.forName("com.mysql.cj.jdbc.Driver");
Class.forName("org.postgresql.Driver");
System.out.println("驱动加载成功");
// 2.连接数据库,注意配置时区 DriverManager.getConnection(url,user,password)
// 注:连接东莞mysql数据库的时候记得开学长VPN(出于保密,去掉)
Connection conn_postgres = DriverManager.getConnection("jdbc:postgresql://localhost:5432/energy", "postgres", "123456");
System.out.println("数据库连接成功");
// 3.创建执行环境 Connection conn_mgr.createStatement();
Statement statement_mgr = conn_mgr.createStatement();
Statement statement_data = conn_data.createStatement();
Statement statement_postgres = conn_postgres.createStatement();
System.out.println("执行环境创建成功");
// 4.执行sql语句 statement_data.executeQuery(sql)
// 4.1创建表
DatabaseMetaData meta = conn_postgres.getMetaData();//获取数据库信息
java.sql.ResultSet tables0 = meta.getTables (null, null, "id_match", null);//获取表的信息
java.sql.ResultSet tables1 = meta.getTables (null, null, "hourdata_0011801", null);//获取表的信息
java.sql.ResultSet tables2 = meta.getTables (null, null, "hourdata_00118a0", null);//获取表的信息,要注意若是A0会匹配不上
// 缺:数据库不存在则创建数据库
if (tables0.next()) {
//表存在,则直接输出
System.out.println("id_match: "+"table exist!");
}else{
//表不存在则创建表
if(statement_postgres.executeUpdate(create_id_match)==0)
System.out.println("create table success!");
}
if (tables1.next()) {
//表存在,则直接输出
System.out.println("hourdata_0011801: "+"table exist!");
}else{
//表不存在则创建表
if(statement_postgres.executeUpdate(create_water_0011801)==0)
System.out.println("create table success!");
}
if (tables2.next()) {
//表存在,则直接输出
System.out.println("hourdata_00118A0: "+"table exist!");
}else{
//表不存在则创建表
if(statement_postgres.executeUpdate(create_electricity_00118A0)==0)
System.out.println("create table success!");
}
// 4.2把表设置为timescaledb表
statement_postgres.execute("CREATE EXTENSION IF NOT EXISTS timescaledb CASCADE");
System.out.println("导入timescaledb拓展成功");
// 一张表设置为timescaledb后就不能执行多次,否则会抛出异常;table "hourdata_0011801" is already a hypertable
// statement_postgres.executeQuery("SELECT create_hypertable('hourdata_0011801', 'read_time','new_devid')");
// statement_postgres.executeQuery("SELECT create_hypertable('hourdata_00118A0', 'read_time,'new_devid')");
System.out.println("设置两表为timescale表成功");
// 4.3先构造id对应表,插入一遍就好,第二遍会有主键冲突,抛出异常
// ResultSet old_devId_electricity = statement_mgr.executeQuery("SELECT id FROM `t_device_info`\n" +
// "where eId=\"e01\"");
// int a=1;
// while(old_devId_electricity.next()){
// String old_devId=old_devId_electricity.getString("id");
// System.out.println(old_devId+" ");
// String new_devId = "00118A0"+String.format("%04d", a)+"01";
// System.out.println(new_devId+" ");
// PreparedStatement preparedStatement = conn_postgres.prepareStatement("insert into id_match(new_devId,old_devId) VALUES(?,?)");
// preparedStatement.setString(1,new_devId);
// preparedStatement.setString(2,old_devId);
// preparedStatement.executeUpdate();
// a=a+1;
// }
// ResultSet old_devId_water = statement_mgr.executeQuery("SELECT id FROM `t_device_info`\n" +
// "where eId=\"e02\"");
// int b=1;
// while(old_devId_water.next()){
// String old_devId=old_devId_water.getString("id");
// System.out.println(old_devId+" ");
// String new_devId = "0011801"+String.format("%04d", b)+"01";
// System.out.println(new_devId+" ");
// PreparedStatement preparedStatement = conn_postgres.prepareStatement("insert into id_match(new_devId,old_devId) VALUES(?,?)");
// preparedStatement.setString(1,new_devId);
// preparedStatement.setString(2,old_devId);
// preparedStatement.executeUpdate();
// b=b+1;
// }
// 缺:多线程处理事务,最大程度利用电脑资源
// 缺:分布式处理事务
// ExecutorService executorService = Executors.newFixedThreadPool(6);
for(int i=1;i<=12;i++)
{
String tablename="t_energy_hourdata_2020"+String.format("%02d", i);
System.out.println("select * from " + tablename + "");
ResultSet hourdata_resultSet = statement_data.executeQuery("select * from " + tablename + "");
System.out.println("sucess load hourdata(big table)");
while(hourdata_resultSet.next()){
String deviceId = hourdata_resultSet.getString("DeviceId");
System.out.println(deviceId);
String read_time = hourdata_resultSet.getString("Read_Time");
String read_value = hourdata_resultSet.getString("Read_Value");
PreparedStatement getNewId = conn_postgres.prepareStatement("select new_devId from id_match where old_devId=?");
getNewId.setString(1,deviceId);
ResultSet newIdList = getNewId.executeQuery();
System.out.println("sucess to get new_devId ");
// 缺:insert不能重复插入,若在表里则不能重复插入
while(newIdList.next()){
String new_devId = newIdList.getString("new_devId");
System.out.println(new_devId);
String table_name = "hourdata_"+new_devId.substring(0, 7);
System.out.println(table_name);
String sql="insert into " + table_name + " values("+new_devId+ "," + read_time + "," + read_value + ",1,1,1," + read_value + ")";
System.out.println(sql);
System.out.println(Timestamp.valueOf(read_time));
PreparedStatement insert_into = conn_postgres.prepareStatement("insert into " + table_name + " values( ?,'"+Timestamp.valueOf(read_time)+"'," + read_value + ",1,1,1," + read_value + ")");
insert_into.setString(1,new_devId);
insert_into.executeUpdate();
// statement_postgres.executeUpdate("insert into "+table_name+" values( "+new_devId+","+read_time+","+read_value+",1,1,1,"+read_value+")");
System.out.println(new_devId);
}
}
}
}
}
可以多在Navicat里面尝试sql语句的正确性,确定没问题之后再搬迁到java中实现
对sql语句的符号需要格外注意,有些需要加 ''
的地方,比如time的地方,id的地方,作为sql语句的一个参数的时候。都声明为String再拼接起来是可以的。 eg:" xxxx ' "+time+" ' xxxx"
PreparedStatement insert_into =conn_postgres.prepareStatement("insert into " + table_name + "values( ?,'"+Timestamp.valueOf(read_time)+"'," + read_value +",1,1,1," + read_value + ")");
要熟记用到的函数
事件 | 函数 |
---|---|
加载mysql驱动 | Class.forName("com.mysql.jdbc.Driver") |
连接数据库,注意配置时区 | DriverManager.getConnection(url,user,password) |
创建执行环境 | Connection conn_mgr.createStatement(); |
把表设置为timescaledb表 | SELECT create_hypertable('hourdata_0011801', 'read_time','new_devid') |
循环展示获取的数据 | while(hourdata_resultSet.next()) {String deviceId = hourdata_resultSet.getString("DeviceId"); |
设定变量代入sql语句执行 | PreparedStatement getNewId = conn_postgres.prepareStatement("select new_devId from id_match where old_devId=?");getNewId.setString(1,deviceId); ResultSet newIdList = getNewId.executeQuery(); |
执行sql语句 | executeQuery(查询sql) executeUpdate(修改sql) |
补齐格式 | String tablename="t_energy_hourdata_2020"+String.format("%02d", i); |
取String前n位 | String table_name = "hourdata_"+new_devId.substring(0, 7) |
b站课程Java与数据库连接实际操作视频(学生管理系统)
易百:JDBC快速入门教程
JDBC数据库驱动的下载、安装与连接
Java数据库连接——JDBC基础知识(操作数据库:增删改查)