mod java code comments

This commit is contained in:
sheyanjie-qq 2024-10-01 10:33:00 +08:00
parent d6b7a8196d
commit 553b57f268
21 changed files with 142 additions and 122 deletions

View File

@ -1,11 +1,11 @@
## TDengine Spring JDBC Template Demo ## TDengine Spring JDBC Template Demo
`Spring JDBC Template` 简化了原生 JDBC Connection 获取释放等操作,使得操作数据库更加方便。 `Spring JDBC Template` simplifies the operations of acquiring and releasing native JDBC Connections, making database operations more convenient.
### 配置 ### Configuration
修改 `src/main/resources/applicationContext.xml` 文件中 TDengine 的配置信息: Modify the TDengine configuration in the `src/main/resources/applicationContext.xml` file:
```xml ```xml
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
@ -20,13 +20,15 @@
</bean> </bean>
``` ```
### 打包运行 ### Package and run
Navigate to the `TDengine/tests/examples/JDBC/SpringJdbcTemplate` directory and execute the following commands to generate an executable jar file.
进入 `TDengine/tests/examples/JDBC/SpringJdbcTemplate` 目录下,执行以下命令可以生成可执行 jar 包。
```shell ```shell
mvn clean package mvn clean package
``` ```
打包成功之后,进入 `target/` 目录下,执行以下命令就可运行测试: After successfully packaging, navigate to the `target/` directory and execute the following commands to run the tests:
```shell ```shell
java -jar target/SpringJdbcTemplate-1.0-SNAPSHOT-jar-with-dependencies.jar java -jar target/SpringJdbcTemplate-1.0-SNAPSHOT-jar-with-dependencies.jar
``` ```

View File

@ -1,21 +1,21 @@
### 设置### ### Settings###
log4j.rootLogger=debug,stdout,DebugLog,ErrorLog log4j.rootLogger=debug,stdout,DebugLog,ErrorLog
### 输出信息到控制抬 ### ### Output information to the console ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=[%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n log4j.appender.stdout.layout.ConversionPattern=[%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n
### 输出DEBUG 级别以上的日志到=logs/debug.log ### Output logs of DEBUG level and above to logs/debug.log
log4j.appender.DebugLog=org.apache.log4j.DailyRollingFileAppender log4j.appender.DebugLog=org.apache.log4j.DailyRollingFileAppender
log4j.appender.DebugLog.File=logs/debug.log log4j.appender.DebugLog.File=logs/debug.log
log4j.appender.DebugLog.Append=true log4j.appender.DebugLog.Append=true
log4j.appender.DebugLog.Threshold=DEBUG log4j.appender.DebugLog.Threshold=DEBUG
log4j.appender.DebugLog.layout=org.apache.log4j.PatternLayout log4j.appender.DebugLog.layout=org.apache.log4j.PatternLayout
log4j.appender.DebugLog.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n log4j.appender.DebugLog.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
### 输出ERROR 级别以上的日志到=logs/error.log ### Output logs of ERROR level and above to logs/error.log
log4j.appender.ErrorLog=org.apache.log4j.DailyRollingFileAppender log4j.appender.ErrorLog=org.apache.log4j.DailyRollingFileAppender
log4j.appender.ErrorLog.File=logs/error.log log4j.appender.ErrorLog.File=logs/error.log
log4j.appender.ErrorLog.Append=true log4j.appender.ErrorLog.Append=true
log4j.appender.ErrorLog.Threshold=ERROR log4j.appender.ErrorLog.Threshold=ERROR
log4j.appender.ErrorLog.layout=org.apache.log4j.PatternLayout log4j.appender.ErrorLog.layout=org.apache.log4j.PatternLayout
log4j.appender.ErrorLog.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n log4j.appender.ErrorLog.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n

View File

@ -1,27 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<something-else-entirely> <something-else-entirely>
<proxool> <proxool>
<!-- Alias for the data source -->
<alias>ds</alias> <alias>ds</alias>
<!--数据源的别名--> <!-- URL connection string -->
<driver-url>jdbc:TAOS-RS://127.0.0.1:6041/log</driver-url> <driver-url>jdbc:TAOS-RS://127.0.0.1:6041/log</driver-url>
<!--url连接串--> <!-- Driver class -->
<driver-class>com.taosdata.jdbc.rs.RestfulDriver</driver-class> <driver-class>com.taosdata.jdbc.rs.RestfulDriver</driver-class>
<!--驱动类-->
<driver-properties> <driver-properties>
<property name="user" value="root"/> <property name="user" value="root"/>
<property name="password" value="taosdata"/> <property name="password" value="taosdata"/>
</driver-properties> </driver-properties>
<!--最大连接数(默认5个),超过了这个连接数,再有请求时,就排在队列中等候,最大的等待请求数由maximum-new-connections决定 --> <!-- Maximum connection count (default is 5). If this number is exceeded, new requests will be queued. The maximum number of queued requests is determined by maximum-new-connections -->
<maximum-connection-count>100</maximum-connection-count> <maximum-connection-count>100</maximum-connection-count>
<!-- 定义连接池中的最大连接数 --> <!-- Defines the maximum number of connections in the connection pool -->
<maximum-active-time>100</maximum-active-time> <maximum-active-time>100</maximum-active-time>
<!--最少保持的空闲连接数(默认2个)--> <!-- Minimum number of idle connections to maintain (default is 2) -->
<prototype-count>1</prototype-count> <prototype-count>1</prototype-count>
<!--最小连接数(默认2个)--> <!-- Minimum connection count (default is 2) -->
<minimum-connection-count>5</minimum-connection-count> <minimum-connection-count>5</minimum-connection-count>
<!--proxool自动侦察各个连接状态的时间间隔(毫秒),侦察到空闲的连接就马上回收,超时的销毁 默认30秒--> <!-- Interval (in milliseconds) for Proxool to automatically check the status of each connection. Idle connections are immediately reclaimed, and timed-out connections are destroyed. Default is 30 seconds -->
<house-keeping-sleep-time>30000</house-keeping-sleep-time> <house-keeping-sleep-time>30000</house-keeping-sleep-time>
<!--用于保持连接的测试语句 --> <!-- Test statement used to maintain the connection -->
<house-keeping-test-sql>select server_version()</house-keeping-test-sql> <house-keeping-test-sql>select server_version()</house-keeping-test-sql>
</proxool> </proxool>
</something-else-entirely> </something-else-entirely>

View File

@ -35,17 +35,18 @@ public class Worker implements Runnable {
public void run() { public void run() {
while (!Thread.interrupted()) { while (!Thread.interrupted()) {
try { try {
// 控制请求频率 // Control request rate
if (semaphore.tryAcquire()) { if (semaphore.tryAcquire()) {
ConsumerRecords<Bean> records = consumer.poll(Duration.ofMillis(sleepTime)); ConsumerRecords<Bean> records = consumer.poll(Duration.ofMillis(sleepTime));
pool.submit(() -> { pool.submit(() -> {
RateLimiter limiter = RateLimiter.create(rate); RateLimiter limiter = RateLimiter.create(rate);
try { try {
for (ConsumerRecord<Bean> record : records) { for (ConsumerRecord<Bean> record : records) {
// 流量控制 // Traffic control
limiter.acquire(); limiter.acquire();
// 业务处理数据 // Business data processing
System.out.println("[" + LocalDateTime.now() + "] Thread id:" + Thread.currentThread().getId() + " -> " + record.value()); System.out.println("[" + LocalDateTime.now() + "] Thread id:"
+ Thread.currentThread().getId() + " -> " + record.value());
} }
} finally { } finally {
semaphore.release(); semaphore.release();

View File

@ -1,14 +1,14 @@
# 使用说明 # Instructions
## 创建使用db ## Create and use the database
```shell ```shell
$ taos $ taos
> create database mp_test > create database mp_test
``` ```
## 执行测试用例 ## Execute test cases
```shell ```shell
$ mvn clean test $ mvn clean test
``` ```

View File

@ -1,6 +1,6 @@
## TDengine SpringBoot + Mybatis Demo ## TDengine SpringBoot + Mybatis Demo
## 需要提前创建 test 数据库 ## Need to create a test database in advance
``` ```
$ taos -s 'create database if not exists test' $ taos -s 'create database if not exists test'
@ -8,7 +8,7 @@ $ taos -s 'create database if not exists test'
$ curl http://localhost:8080/weather/init $ curl http://localhost:8080/weather/init
``` ```
### 配置 application.properties ### Configure application.properties
```properties ```properties
# datasource config # datasource config
spring.datasource.driver-class-name=com.taosdata.jdbc.TSDBDriver spring.datasource.driver-class-name=com.taosdata.jdbc.TSDBDriver
@ -38,9 +38,9 @@ mybatis.mapper-locations=classpath:mapper/*.xml
logging.level.com.taosdata.jdbc.springbootdemo.dao=debug logging.level.com.taosdata.jdbc.springbootdemo.dao=debug
``` ```
### 主要功能 ### Main functions
* 创建数据库和表 * Create databases and tables
```xml ```xml
<!-- weatherMapper.xml --> <!-- weatherMapper.xml -->
<update id="createDB" > <update id="createDB" >
@ -52,14 +52,14 @@ logging.level.com.taosdata.jdbc.springbootdemo.dao=debug
</update> </update>
``` ```
* 插入单条记录 * Insert a single record
```xml ```xml
<!-- weatherMapper.xml --> <!-- weatherMapper.xml -->
<insert id="insert" parameterType="Weather" > <insert id="insert" parameterType="Weather" >
insert into test.weather (ts, temperature, humidity) values (now, #{temperature,jdbcType=INTEGER}, #{humidity,jdbcType=FLOAT}) insert into test.weather (ts, temperature, humidity) values (now, #{temperature,jdbcType=INTEGER}, #{humidity,jdbcType=FLOAT})
</insert> </insert>
``` ```
* 插入多条记录 * Insert multiple records
```xml ```xml
<!-- weatherMapper.xml --> <!-- weatherMapper.xml -->
<insert id="batchInsert" parameterType="java.util.List" > <insert id="batchInsert" parameterType="java.util.List" >
@ -69,7 +69,7 @@ logging.level.com.taosdata.jdbc.springbootdemo.dao=debug
</foreach> </foreach>
</insert> </insert>
``` ```
* 分页查询 * Pagination query
```xml ```xml
<!-- weatherMapper.xml --> <!-- weatherMapper.xml -->
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>

View File

@ -1,11 +1,14 @@
``` ```
cd tests/examples/JDBC/taosdemo cd tests/examples/JDBC/taosdemo
mvn clean package -Dmaven.test.skip=true mvn clean package -Dmaven.test.skip=true
# 先建表,再插入的 # Create tables first, then insert data
java -jar target/taosdemo-2.0.1-jar-with-dependencies.jar -host <hostname> -database <db name> -doCreateTable true -superTableSQL "create table weather(ts timestamp, f1 int) tags(t1 nchar(4))" -numOfTables 1000 -numOfRowsPerTable 100000000 -numOfThreadsForInsert 10 -numOfTablesPerSQL 10 -numOfValuesPerSQL 100 java -jar target/taosdemo-2.0.1-jar-with-dependencies.jar -host <hostname> -database <db name> -doCreateTable true -superTableSQL "create table weather(ts timestamp, f1 int) tags(t1 nchar(4))" -numOfTables 1000 -numOfRowsPerTable 100000000 -numOfThreadsForInsert 10 -numOfTablesPerSQL 10 -numOfValuesPerSQL 100
# 不建表,直接插入的 # Insert data directly without creating tables
java -jar target/taosdemo-2.0.1-jar-with-dependencies.jar -host <hostname> -database <db name> -doCreateTable false -superTableSQL "create table weather(ts timestamp, f1 int) tags(t1 nchar(4))" -numOfTables 1000 -numOfRowsPerTable 100000000 -numOfThreadsForInsert 10 -numOfTablesPerSQL 10 -numOfValuesPerSQL 100 java -jar target/taosdemo-2.0.1-jar-with-dependencies.jar -host <hostname> -database <db name> -doCreateTable false -superTableSQL "create table weather(ts timestamp, f1 int) tags(t1 nchar(4))" -numOfTables 1000 -numOfRowsPerTable 100000000 -numOfThreadsForInsert 10 -numOfTablesPerSQL 10 -numOfValuesPerSQL 100
``` ```
如果发生错误 Exception in thread "main" java.lang.UnsatisfiedLinkError: no taos in java.library.path 如果发生错误 Exception in thread "main" java.lang.UnsatisfiedLinkError: no taos in java.library.path
请检查是否安装 TDengine 客户端安装包或编译 TDengine 安装。如果确定已经安装过还出现这个错误,可以在命令行 java 后加 -Djava.library.path=/usr/lib 来指定寻找共享库的路径。 请检查是否安装 TDengine 客户端安装包或编译 TDengine 安装。如果确定已经安装过还出现这个错误,可以在命令行 java 后加 -Djava.library.path=/usr/lib 来指定寻找共享库的路径。
If you encounter the error Exception in thread "main" `java.lang.UnsatisfiedLinkError: no taos in java.library.path`, please check whether the TDengine client package is installed or TDengine is compiled and installed. If you are sure it is installed and still encounter this error, you can add `-Djava.library.path=/usr/lib` after the `java` command to specify the path to the shared library.

View File

@ -24,14 +24,14 @@ public class TaosDemoApplication {
private static final Logger logger = LogManager.getLogger(TaosDemoApplication.class); private static final Logger logger = LogManager.getLogger(TaosDemoApplication.class);
public static void main(String[] args) throws IOException { public static void main(String[] args) throws IOException {
// 读配置参数 // Read configuration parameters
JdbcTaosdemoConfig config = new JdbcTaosdemoConfig(args); JdbcTaosdemoConfig config = new JdbcTaosdemoConfig(args);
boolean isHelp = Arrays.asList(args).contains("--help"); boolean isHelp = Arrays.asList(args).contains("--help");
if (isHelp || config.host == null || config.host.isEmpty()) { if (isHelp || config.host == null || config.host.isEmpty()) {
JdbcTaosdemoConfig.printHelp(); JdbcTaosdemoConfig.printHelp();
System.exit(0); System.exit(0);
} }
// 初始化 //
final DataSource dataSource = DataSourceFactory.getInstance(config.host, config.port, config.user, final DataSource dataSource = DataSourceFactory.getInstance(config.host, config.port, config.user,
config.password); config.password);
if (config.executeSql != null && !config.executeSql.isEmpty() if (config.executeSql != null && !config.executeSql.isEmpty()
@ -50,7 +50,7 @@ public class TaosDemoApplication {
final SuperTableService superTableService = new SuperTableService(dataSource); final SuperTableService superTableService = new SuperTableService(dataSource);
final SubTableService subTableService = new SubTableService(dataSource); final SubTableService subTableService = new SubTableService(dataSource);
// 创建数据库 // create database
long start = System.currentTimeMillis(); long start = System.currentTimeMillis();
Map<String, String> databaseParam = new HashMap<>(); Map<String, String> databaseParam = new HashMap<>();
databaseParam.put("database", config.database); databaseParam.put("database", config.database);
@ -81,13 +81,13 @@ public class TaosDemoApplication {
config.prefixOfFields, config.numOfTags, config.prefixOfTags); config.prefixOfFields, config.numOfTags, config.prefixOfTags);
} }
/**********************************************************************************/ /**********************************************************************************/
// 建表 // create table
start = System.currentTimeMillis(); start = System.currentTimeMillis();
if (config.doCreateTable) { if (config.doCreateTable) {
superTableService.drop(superTableMeta.getDatabase(), superTableMeta.getName()); superTableService.drop(superTableMeta.getDatabase(), superTableMeta.getName());
superTableService.create(superTableMeta); superTableService.create(superTableMeta);
if (!config.autoCreateTable) { if (!config.autoCreateTable) {
// 批量建子表 // create sub tables in batch
subTableService.createSubTable(superTableMeta, config.numOfTables, config.prefixOfTable, subTableService.createSubTable(superTableMeta, config.numOfTables, config.prefixOfTable,
config.numOfThreadsForCreate); config.numOfThreadsForCreate);
} }
@ -95,7 +95,7 @@ public class TaosDemoApplication {
end = System.currentTimeMillis(); end = System.currentTimeMillis();
logger.info(">>> create table time cost : " + (end - start) + " ms."); logger.info(">>> create table time cost : " + (end - start) + " ms.");
/**********************************************************************************/ /**********************************************************************************/
// 插入 // insert data
long tableSize = config.numOfTables; long tableSize = config.numOfTables;
int threadSize = config.numOfThreadsForInsert; int threadSize = config.numOfThreadsForInsert;
long startTime = getProperStartTime(config.startTime, config.days); long startTime = getProperStartTime(config.startTime, config.days);
@ -111,10 +111,9 @@ public class TaosDemoApplication {
end = System.currentTimeMillis(); end = System.currentTimeMillis();
logger.info("insert " + affectedRows + " rows, time cost: " + (end - start) + " ms"); logger.info("insert " + affectedRows + " rows, time cost: " + (end - start) + " ms");
/**********************************************************************************/ /**********************************************************************************/
// 查询
/**********************************************************************************/ /**********************************************************************************/
// 删除表 // drop table
if (config.dropTable) { if (config.dropTable) {
superTableService.drop(config.database, config.superTable); superTableService.drop(config.database, config.superTable);
} }

View File

@ -9,21 +9,22 @@ import java.util.List;
@Repository @Repository
public interface SubTableMapper { public interface SubTableMapper {
// 创建子表 // Create: SubTable
void createUsingSuperTable(SubTableMeta subTableMeta); void createUsingSuperTable(SubTableMeta subTableMeta);
// 插入一张子表多个values // Insert: Multiple records into one SubTable
int insertOneTableMultiValues(SubTableValue subTableValue); int insertOneTableMultiValues(SubTableValue subTableValue);
// 插入一张子表多个values, 自动建表 // Insert: Multiple records into one SubTable, auto create SubTables
int insertOneTableMultiValuesUsingSuperTable(SubTableValue subTableValue); int insertOneTableMultiValuesUsingSuperTable(SubTableValue subTableValue);
// 插入多张表多个values // Insert: Multiple records into multiple SubTable
int insertMultiTableMultiValues(List<SubTableValue> tables); int insertMultiTableMultiValues(List<SubTableValue> tables);
// 插入多张表多个values自动建表 // Insert: Multiple records into multiple SubTable, auto create SubTables
int insertMultiTableMultiValuesUsingSuperTable(List<SubTableValue> tables); int insertMultiTableMultiValuesUsingSuperTable(List<SubTableValue> tables);
//<!-- TODO:修改子表标签值 alter table ${tablename} set tag tagName=newTagValue--> // <!-- TODO: Modify SubTable tag value: alter table ${tablename} set tag
// tagName=newTagValue-->
} }

View File

@ -6,24 +6,26 @@ import org.springframework.stereotype.Repository;
@Repository @Repository
public interface SuperTableMapper { public interface SuperTableMapper {
// 创建超级表 create table if not exists xxx.xxx (f1 type1, f2 type2, ... ) tags( t1 type1, t2 type2 ...) // Create super table: create table if not exists xxx.xxx (f1 type1, f2 type2,
// ... ) tags( t1 type1, t2 type2 ...)
void createSuperTable(SuperTableMeta tableMetadata); void createSuperTable(SuperTableMeta tableMetadata);
// 删除超级表 drop table if exists xxx; // Drop super table: drop table if exists xxx;
void dropSuperTable(String database, String name); void dropSuperTable(String database, String name);
//<!-- TODO:查询所有超级表信息 show stables --> // <!-- TODO: Query all super table information show stables -->
//<!-- TODO:查询表结构 describe stable --> // <!-- TODO: Query table structure describe stable -->
//<!-- TODO:增加列 alter table ${tablename} add column fieldName dataType --> // <!-- TODO: Add column alter table ${tablename} add column fieldName dataType
// -->
//<!-- TODO:删除列 alter table ${tablename} drop column fieldName --> // <!-- TODO: Drop column alter table ${tablename} drop column fieldName -->
//<!-- TODO:添加标签 alter table ${tablename} add tag new_tagName tag_type --> // <!-- TODO: Add tag alter table ${tablename} add tag new_tagName tag_type -->
//<!-- TODO:删除标签 alter table ${tablename} drop tag_name --> // <!-- TODO: Drop tag alter table ${tablename} drop tag_name -->
//<!-- TODO:修改标签名 alter table ${tablename} change tag old_tagName new_tagName -->
// <!-- TODO: Change tag name alter table ${tablename} change tag old_tagName
// new_tagName -->
} }

View File

@ -9,19 +9,18 @@ import java.util.List;
@Repository @Repository
public interface TableMapper { public interface TableMapper {
// 创建普通表 // Create: Normal table
void create(TableMeta tableMeta); void create(TableMeta tableMeta);
// 插入一张表多个value // Insert: Multiple records into one table
int insertOneTableMultiValues(TableValue values); int insertOneTableMultiValues(TableValue values);
// 插入: 一张表多个value指定的列 // Insert: Multiple records into one table, specified columns
int insertOneTableMultiValuesWithColumns(TableValue values); int insertOneTableMultiValuesWithColumns(TableValue values);
// 插入多个表多个value // Insert: Multiple records into multiple tables
int insertMultiTableMultiValues(List<TableValue> tables); int insertMultiTableMultiValues(List<TableValue> tables);
// 插入多个表多个value, 指定的列 // Insert: Multiple records into multiple tables, specified columns
int insertMultiTableMultiValuesWithColumns(List<TableValue> tables); int insertMultiTableMultiValuesWithColumns(List<TableValue> tables);
}
}

View File

@ -14,12 +14,12 @@ public class DatabaseService {
this.databaseMapper = new DatabaseMapperImpl(dataSource); this.databaseMapper = new DatabaseMapperImpl(dataSource);
} }
// 建库指定 name // Create database with specified name
public void createDatabase(String database) { public void createDatabase(String database) {
databaseMapper.createDatabase(database); databaseMapper.createDatabase(database);
} }
// 建库指定参数 keep,days,replica等 // Create database with specified parameters such as keep, days, replica, etc.
public void createDatabase(Map<String, String> map) { public void createDatabase(Map<String, String> map) {
if (map.isEmpty()) if (map.isEmpty())
return; return;

View File

@ -27,7 +27,8 @@ public class SubTableService extends AbstractService {
this.mapper = new SubTableMapperImpl(datasource); this.mapper = new SubTableMapperImpl(datasource);
} }
public void createSubTable(SuperTableMeta superTableMeta, long numOfTables, String prefixOfTable, int numOfThreadsForCreate) { public void createSubTable(SuperTableMeta superTableMeta, long numOfTables, String prefixOfTable,
int numOfThreadsForCreate) {
ExecutorService executor = Executors.newFixedThreadPool(numOfThreadsForCreate); ExecutorService executor = Executors.newFixedThreadPool(numOfThreadsForCreate);
for (long i = 0; i < numOfTables; i++) { for (long i = 0; i < numOfTables; i++) {
long tableIndex = i; long tableIndex = i;
@ -35,54 +36,58 @@ public class SubTableService extends AbstractService {
} }
executor.shutdown(); executor.shutdown();
try { try {
executor.awaitTermination(Long.MAX_VALUE,TimeUnit.NANOSECONDS); executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
} catch (InterruptedException e) { } catch (InterruptedException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
public void createSubTable(SuperTableMeta superTableMeta, String tableName) { public void createSubTable(SuperTableMeta superTableMeta, String tableName) {
// 构造数据 // Construct data
SubTableMeta meta = SubTableMetaGenerator.generate(superTableMeta, tableName); SubTableMeta meta = SubTableMetaGenerator.generate(superTableMeta, tableName);
createSubTable(meta); createSubTable(meta);
} }
// 创建一张子表可以指定databasesupertabletablenametag值 // Create a sub-table, specifying database, super table, table name, and tag
// values
public void createSubTable(SubTableMeta subTableMeta) { public void createSubTable(SubTableMeta subTableMeta) {
mapper.createUsingSuperTable(subTableMeta); mapper.createUsingSuperTable(subTableMeta);
} }
/*************************************************************************************************************************/ /*************************************************************************************************************************/
// 插入多线程多表 // Insert: Multi-threaded, multiple tables
public int insert(List<SubTableValue> subTableValues, int threadSize, int frequency) { public int insert(List<SubTableValue> subTableValues, int threadSize, int frequency) {
ExecutorService executor = Executors.newFixedThreadPool(threadSize); ExecutorService executor = Executors.newFixedThreadPool(threadSize);
Future<Integer> future = executor.submit(() -> insert(subTableValues)); Future<Integer> future = executor.submit(() -> insert(subTableValues));
executor.shutdown(); executor.shutdown();
//TODOfrequency // TODOfrequency
return getAffectRows(future); return getAffectRows(future);
} }
// 插入单表insert into xxx values(),()... // Insert: Single table, insert into xxx values(),()...
public int insert(SubTableValue subTableValue) { public int insert(SubTableValue subTableValue) {
return mapper.insertOneTableMultiValues(subTableValue); return mapper.insertOneTableMultiValues(subTableValue);
} }
// 插入: 多表insert into xxx values(),()... xxx values(),()... // Insert: Multiple tables, insert into xxx values(),()... xxx values(),()...
public int insert(List<SubTableValue> subTableValues) { public int insert(List<SubTableValue> subTableValues) {
return mapper.insertMultiTableMultiValues(subTableValues); return mapper.insertMultiTableMultiValues(subTableValues);
} }
// 插入单表自动建表, insert into xxx using xxx tags(...) values(),()... // Insert: Single table, auto-create table, insert into xxx using xxx tags(...)
// values(),()...
public int insertAutoCreateTable(SubTableValue subTableValue) { public int insertAutoCreateTable(SubTableValue subTableValue) {
return mapper.insertOneTableMultiValuesUsingSuperTable(subTableValue); return mapper.insertOneTableMultiValuesUsingSuperTable(subTableValue);
} }
// 插入多表自动建表, insert into xxx using XXX tags(...) values(),()... xxx using XXX tags(...) values(),()... // Insert: Multiple tables, auto-create tables, insert into xxx using XXX
// tags(...) values(),()... xxx using XXX tags(...) values(),()...
public int insertAutoCreateTable(List<SubTableValue> subTableValues) { public int insertAutoCreateTable(List<SubTableValue> subTableValues) {
return mapper.insertMultiTableMultiValuesUsingSuperTable(subTableValues); return mapper.insertMultiTableMultiValuesUsingSuperTable(subTableValues);
} }
public int insertMultiThreads(SuperTableMeta superTableMeta, int threadSize, long tableSize, long startTime, long gap, JdbcTaosdemoConfig config) { public int insertMultiThreads(SuperTableMeta superTableMeta, int threadSize, long tableSize, long startTime,
long gap, JdbcTaosdemoConfig config) {
List<FutureTask> taskList = new ArrayList<>(); List<FutureTask> taskList = new ArrayList<>();
List<Thread> threads = IntStream.range(0, threadSize) List<Thread> threads = IntStream.range(0, threadSize)
.mapToObj(i -> { .mapToObj(i -> {
@ -94,8 +99,7 @@ public class SubTableService extends AbstractService {
startTime, config.timeGap, startTime, config.timeGap,
config.numOfRowsPerTable, config.numOfTablesPerSQL, config.numOfValuesPerSQL, config.numOfRowsPerTable, config.numOfTablesPerSQL, config.numOfValuesPerSQL,
config.order, config.rate, config.range, config.order, config.rate, config.range,
config.prefixOfTable, config.autoCreateTable) config.prefixOfTable, config.autoCreateTable));
);
taskList.add(task); taskList.add(task);
return new Thread(task, "InsertThread-" + i); return new Thread(task, "InsertThread-" + i);
}).collect(Collectors.toList()); }).collect(Collectors.toList());
@ -126,7 +130,7 @@ public class SubTableService extends AbstractService {
private class InsertTask implements Callable<Integer> { private class InsertTask implements Callable<Integer> {
private final long startTableInd; // included private final long startTableInd; // included
private final long endTableInd; // excluded private final long endTableInd; // excluded
private final long startTime; private final long startTime;
private final long timeGap; private final long timeGap;
private final long numOfRowsPerTable; private final long numOfRowsPerTable;
@ -140,10 +144,10 @@ public class SubTableService extends AbstractService {
private final boolean autoCreateTable; private final boolean autoCreateTable;
public InsertTask(SuperTableMeta superTableMeta, long startTableInd, long endTableInd, public InsertTask(SuperTableMeta superTableMeta, long startTableInd, long endTableInd,
long startTime, long timeGap, long startTime, long timeGap,
long numOfRowsPerTable, long numOfTablesPerSQL, long numOfValuesPerSQL, long numOfRowsPerTable, long numOfTablesPerSQL, long numOfValuesPerSQL,
int order, int rate, long range, int order, int rate, long range,
String prefixOfTable, boolean autoCreateTable) { String prefixOfTable, boolean autoCreateTable) {
this.superTableMeta = superTableMeta; this.superTableMeta = superTableMeta;
this.startTableInd = startTableInd; this.startTableInd = startTableInd;
this.endTableInd = endTableInd; this.endTableInd = endTableInd;
@ -159,7 +163,6 @@ public class SubTableService extends AbstractService {
this.autoCreateTable = autoCreateTable; this.autoCreateTable = autoCreateTable;
} }
@Override @Override
public Integer call() { public Integer call() {
@ -171,23 +174,27 @@ public class SubTableService extends AbstractService {
int affectRows = 0; int affectRows = 0;
// row // row
for (long rowCnt = 0; rowCnt < numOfRowsPerTable; ) { for (long rowCnt = 0; rowCnt < numOfRowsPerTable;) {
long rowSize = numOfValuesPerSQL; long rowSize = numOfValuesPerSQL;
if (rowCnt + rowSize > numOfRowsPerTable) { if (rowCnt + rowSize > numOfRowsPerTable) {
rowSize = numOfRowsPerTable - rowCnt; rowSize = numOfRowsPerTable - rowCnt;
} }
//table // table
for (long tableCnt = startTableInd; tableCnt < endTableInd; ) { for (long tableCnt = startTableInd; tableCnt < endTableInd;) {
long tableSize = numOfTablesPerSQL; long tableSize = numOfTablesPerSQL;
if (tableCnt + tableSize > endTableInd) { if (tableCnt + tableSize > endTableInd) {
tableSize = endTableInd - tableCnt; tableSize = endTableInd - tableCnt;
} }
long startTime = this.startTime + rowCnt * timeGap; long startTime = this.startTime + rowCnt * timeGap;
// System.out.println(Thread.currentThread().getName() + " >>> " + "rowCnt: " + rowCnt + ", rowSize: " + rowSize + ", " + "tableCnt: " + tableCnt + ",tableSize: " + tableSize + ", " + "startTime: " + startTime + ",timeGap: " + timeGap + ""); // System.out.println(Thread.currentThread().getName() + " >>> " + "rowCnt: " +
// rowCnt + ", rowSize: " + rowSize + ", " + "tableCnt: " + tableCnt +
// ",tableSize: " + tableSize + ", " + "startTime: " + startTime + ",timeGap: "
// + timeGap + "");
/***********************************************/ /***********************************************/
// 生成数据 // Construct data
List<SubTableValue> data = SubTableValueGenerator.generate(superTableMeta, prefixOfTable, tableCnt, tableSize, rowSize, startTime, timeGap); List<SubTableValue> data = SubTableValueGenerator.generate(superTableMeta, prefixOfTable, tableCnt,
// 乱序 tableSize, rowSize, startTime, timeGap);
// disorder
if (order != 0) if (order != 0)
SubTableValueGenerator.disrupt(data, rate, range); SubTableValueGenerator.disrupt(data, rate, range);
// insert // insert
@ -205,5 +212,4 @@ public class SubTableService extends AbstractService {
} }
} }
} }

View File

@ -14,7 +14,7 @@ public class SuperTableService {
this.superTableMapper = new SuperTableMapperImpl(dataSource); this.superTableMapper = new SuperTableMapperImpl(dataSource);
} }
// 创建超级表指定每个field的名称和类型每个tag的名称和类型 // Create super table, specifying the name and type of each field and each tag
public void create(SuperTableMeta superTableMeta) { public void create(SuperTableMeta superTableMeta) {
superTableMapper.createSuperTable(superTableMeta); superTableMapper.createSuperTable(superTableMeta);
} }

View File

@ -11,15 +11,14 @@ public class TableService extends AbstractService {
private TableMapper tableMapper; private TableMapper tableMapper;
//创建一张表 // Create a table
public void create(TableMeta tableMeta) { public void create(TableMeta tableMeta) {
tableMapper.create(tableMeta); tableMapper.create(tableMeta);
} }
//创建多张表 // Create multiple tables
public void create(List<TableMeta> tables) { public void create(List<TableMeta> tables) {
tables.stream().forEach(this::create); tables.stream().forEach(this::create);
} }
} }

View File

@ -11,7 +11,8 @@ public class FieldValueGenerator {
public static Random random = new Random(System.currentTimeMillis()); public static Random random = new Random(System.currentTimeMillis());
// 生成start到end的时间序列时间戳为顺序不含有乱序field的value为随机生成 // Generate a time series from start to end, timestamps are in order without
// disorder, field values are randomly generated
public static List<RowValue> generate(long start, long end, long timeGap, List<FieldMeta> fieldMetaList) { public static List<RowValue> generate(long start, long end, long timeGap, List<FieldMeta> fieldMetaList) {
List<RowValue> values = new ArrayList<>(); List<RowValue> values = new ArrayList<>();
@ -29,9 +30,12 @@ public class FieldValueGenerator {
return values; return values;
} }
// 生成start到end的时间序列时间戳为顺序含有乱序rate为乱序的比例range为乱序前跳范围field的value为随机生成 // Generate a time series from start to end, timestamps are in order but include
// disorder, rate is the proportion of disorder, range is the jump range before
// disorder, field values are randomly generated
public static List<RowValue> disrupt(List<RowValue> values, int rate, long range) { public static List<RowValue> disrupt(List<RowValue> values, int rate, long range) {
long timeGap = (long) (values.get(1).getFields().get(0).getValue()) - (long) (values.get(0).getFields().get(0).getValue()); long timeGap = (long) (values.get(1).getFields().get(0).getValue())
- (long) (values.get(0).getFields().get(0).getValue());
int bugSize = values.size() * rate / 100; int bugSize = values.size() * rate / 100;
Set<Integer> bugIndSet = new HashSet<>(); Set<Integer> bugIndSet = new HashSet<>();
while (bugIndSet.size() < bugSize) { while (bugIndSet.size() < bugSize) {

View File

@ -9,7 +9,7 @@ import java.util.List;
public class SubTableMetaGenerator { public class SubTableMetaGenerator {
// 创建tableSize张子表使用tablePrefix作为子表名的前缀使用superTableMeta的元数据 // Create tableSize sub-tables, using tablePrefix as the prefix for sub-table names, and using the metadata from superTableMeta
// create table xxx using XXX tags(XXX) // create table xxx using XXX tags(XXX)
public static List<SubTableMeta> generate(SuperTableMeta superTableMeta, int tableSize, String tablePrefix) { public static List<SubTableMeta> generate(SuperTableMeta superTableMeta, int tableSize, String tablePrefix) {
List<SubTableMeta> subTableMetaList = new ArrayList<>(); List<SubTableMeta> subTableMetaList = new ArrayList<>();

View File

@ -10,10 +10,11 @@ import java.util.List;
public class SuperTableMetaGenerator { public class SuperTableMetaGenerator {
// 创建超级表使用指定SQL语句 // Create super table using the specified SQL statement
public static SuperTableMeta generate(String superTableSQL) { public static SuperTableMeta generate(String superTableSQL) {
SuperTableMeta tableMeta = new SuperTableMeta(); SuperTableMeta tableMeta = new SuperTableMeta();
// for example : create table superTable (ts timestamp, temperature float, humidity int) tags(location nchar(64), groupId int) // for example : create table superTable (ts timestamp, temperature float,
// humidity int) tags(location nchar(64), groupId int)
superTableSQL = superTableSQL.trim().toLowerCase(); superTableSQL = superTableSQL.trim().toLowerCase();
if (!superTableSQL.startsWith("create")) if (!superTableSQL.startsWith("create"))
throw new RuntimeException("invalid create super table SQL"); throw new RuntimeException("invalid create super table SQL");
@ -54,8 +55,9 @@ public class SuperTableMetaGenerator {
return tableMeta; return tableMeta;
} }
// 创建超级表,指定field和tag的个数 // Create super table with specified number of fields and tags
public static SuperTableMeta generate(String database, String name, int fieldSize, String fieldPrefix, int tagSize, String tagPrefix) { public static SuperTableMeta generate(String database, String name, int fieldSize, String fieldPrefix, int tagSize,
String tagPrefix) {
if (fieldSize < 2 || tagSize < 1) { if (fieldSize < 2 || tagSize < 1) {
throw new RuntimeException("create super table but fieldSize less than 2 or tagSize less than 1"); throw new RuntimeException("create super table but fieldSize less than 2 or tagSize less than 1");
} }
@ -66,7 +68,8 @@ public class SuperTableMetaGenerator {
List<FieldMeta> fields = new ArrayList<>(); List<FieldMeta> fields = new ArrayList<>();
fields.add(new FieldMeta("ts", "timestamp")); fields.add(new FieldMeta("ts", "timestamp"));
for (int i = 1; i <= fieldSize; i++) { for (int i = 1; i <= fieldSize; i++) {
fields.add(new FieldMeta(fieldPrefix + "" + i, TaosConstants.DATA_TYPES[i % TaosConstants.DATA_TYPES.length])); fields.add(
new FieldMeta(fieldPrefix + "" + i, TaosConstants.DATA_TYPES[i % TaosConstants.DATA_TYPES.length]));
} }
tableMetadata.setFields(fields); tableMetadata.setFields(fields);
// tags // tags

View File

@ -9,7 +9,7 @@ import java.util.List;
public class TagValueGenerator { public class TagValueGenerator {
// 创建标签值使用tagMetas // Create tag values using tagMetas
public static List<TagValue> generate(List<TagMeta> tagMetas) { public static List<TagValue> generate(List<TagMeta> tagMetas) {
List<TagValue> tagValues = new ArrayList<>(); List<TagValue> tagValues = new ArrayList<>();
for (int i = 0; i < tagMetas.size(); i++) { for (int i = 0; i < tagMetas.size(); i++) {

View File

@ -41,17 +41,17 @@ public class TimeStampUtil {
if (start == 0) if (start == 0)
start = now - size * timeGap; start = now - size * timeGap;
// 如果size小于1异常 // If size is less than 1, throw an exception
if (size < 1) if (size < 1)
throw new IllegalArgumentException("size less than 1."); throw new IllegalArgumentException("size less than 1.");
// 如果timeGap为1已经超长需要前移start // If timeGap is 1 and it exceeds the limit, move start forward
if (start + size > now) { if (start + size > now) {
start = now - size; start = now - size;
return new TimeTuple(start, now, 1); return new TimeTuple(start, now, 1);
} }
long end = start + (long) (timeGap * size); long end = start + (long) (timeGap * size);
if (end > now) { if (end > now) {
//压缩timeGap // Compress timeGap
end = now; end = now;
double gap = (end - start) / (size * 1.0f); double gap = (end - start) / (size * 1.0f);
if (gap < 1.0f) { if (gap < 1.0f) {

View File

@ -1,21 +1,21 @@
### 设置### ### Settings ###
log4j.rootLogger=info,stdout log4j.rootLogger=info,stdout
### 输出信息到控制抬 ### ### Output information to the console ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=[%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n log4j.appender.stdout.layout.ConversionPattern=[%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n
### 输出DEBUG 级别以上的日志到=logs/debug.log ### Output logs of DEBUG level and above to logs/debug.log ###
log4j.appender.DebugLog=org.apache.log4j.DailyRollingFileAppender log4j.appender.DebugLog=org.apache.log4j.DailyRollingFileAppender
log4j.appender.DebugLog.File=logs/debug.log log4j.appender.DebugLog.File=logs/debug.log
log4j.appender.DebugLog.Append=true log4j.appender.DebugLog.Append=true
log4j.appender.DebugLog.Threshold=DEBUG log4j.appender.DebugLog.Threshold=DEBUG
log4j.appender.DebugLog.layout=org.apache.log4j.PatternLayout log4j.appender.DebugLog.layout=org.apache.log4j.PatternLayout
log4j.appender.DebugLog.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n log4j.appender.DebugLog.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
### 输出ERROR 级别以上的日志到=logs/error.log ### Output logs of ERROR level and above to logs/error.log ###
log4j.appender.ErrorLog=org.apache.log4j.DailyRollingFileAppender log4j.appender.ErrorLog=org.apache.log4j.DailyRollingFileAppender
log4j.appender.ErrorLog.File=logs/error.log log4j.appender.ErrorLog.File=logs/error.log
log4j.appender.ErrorLog.Append=true log4j.appender.ErrorLog.Append=true
log4j.appender.ErrorLog.Threshold=ERROR log4j.appender.ErrorLog.Threshold=ERROR
log4j.appender.ErrorLog.layout=org.apache.log4j.PatternLayout log4j.appender.ErrorLog.layout=org.apache.log4j.PatternLayout
log4j.appender.ErrorLog.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n log4j.appender.ErrorLog.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n