Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
慢慢CG
TDengine
提交
02e39aab
T
TDengine
项目概览
慢慢CG
/
TDengine
与 Fork 源项目一致
Fork自
taosdata / TDengine
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
T
TDengine
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
02e39aab
编写于
12月 07, 2019
作者:
S
slguan
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'develop' into feature/slguan
上级
6864dcb5
4b15fd32
变更
35
隐藏空白更改
内联
并排
Showing
35 changed file
with
2092 addition
and
99 deletion
+2092
-99
documentation/webdocs/markdowndocs/connector-ch.md
documentation/webdocs/markdowndocs/connector-ch.md
+308
-59
packaging/tools/install.sh
packaging/tools/install.sh
+2
-2
src/client/src/tscAst.c
src/client/src/tscAst.c
+12
-9
src/client/src/tscAsync.c
src/client/src/tscAsync.c
+0
-1
src/client/src/tscParseInsert.c
src/client/src/tscParseInsert.c
+52
-13
src/connector/jdbc/readme.md
src/connector/jdbc/readme.md
+329
-0
src/kit/shell/src/shellEngine.c
src/kit/shell/src/shellEngine.c
+2
-0
src/sdb/src/sdbEngine.c
src/sdb/src/sdbEngine.c
+14
-1
src/system/detail/src/mgmtMeter.c
src/system/detail/src/mgmtMeter.c
+34
-3
src/system/detail/src/vnodeFile.c
src/system/detail/src/vnodeFile.c
+1
-0
src/util/src/ttimer.c
src/util/src/ttimer.c
+10
-10
src/util/src/ttokenizer.c
src/util/src/ttokenizer.c
+7
-1
tests/examples/JDBC/JDBCDemo/readme.md
tests/examples/JDBC/JDBCDemo/readme.md
+0
-0
tests/examples/JDBC/SpringJdbcTemplate/.gitignore
tests/examples/JDBC/SpringJdbcTemplate/.gitignore
+31
-0
tests/examples/JDBC/SpringJdbcTemplate/pom.xml
tests/examples/JDBC/SpringJdbcTemplate/pom.xml
+85
-0
tests/examples/JDBC/SpringJdbcTemplate/readme.md
tests/examples/JDBC/SpringJdbcTemplate/readme.md
+34
-0
tests/examples/JDBC/SpringJdbcTemplate/src/main/java/com/taosdata/jdbc/App.java
...ringJdbcTemplate/src/main/java/com/taosdata/jdbc/App.java
+44
-0
tests/examples/JDBC/SpringJdbcTemplate/src/main/resources/applicationContext.xml
...ingJdbcTemplate/src/main/resources/applicationContext.xml
+24
-0
tests/examples/JDBC/SpringJdbcTemplate/src/test/java/com/taosdata/jdbc/AppTest.java
...JdbcTemplate/src/test/java/com/taosdata/jdbc/AppTest.java
+20
-0
tests/examples/JDBC/springbootdemo/.gitignore
tests/examples/JDBC/springbootdemo/.gitignore
+30
-0
tests/examples/JDBC/springbootdemo/.mvn/wrapper/MavenWrapperDownloader.java
...C/springbootdemo/.mvn/wrapper/MavenWrapperDownloader.java
+118
-0
tests/examples/JDBC/springbootdemo/.mvn/wrapper/maven-wrapper.jar
...amples/JDBC/springbootdemo/.mvn/wrapper/maven-wrapper.jar
+0
-0
tests/examples/JDBC/springbootdemo/.mvn/wrapper/maven-wrapper.properties
...JDBC/springbootdemo/.mvn/wrapper/maven-wrapper.properties
+2
-0
tests/examples/JDBC/springbootdemo/mvnw
tests/examples/JDBC/springbootdemo/mvnw
+310
-0
tests/examples/JDBC/springbootdemo/mvnw.cmd
tests/examples/JDBC/springbootdemo/mvnw.cmd
+182
-0
tests/examples/JDBC/springbootdemo/pom.xml
tests/examples/JDBC/springbootdemo/pom.xml
+87
-0
tests/examples/JDBC/springbootdemo/readme.md
tests/examples/JDBC/springbootdemo/readme.md
+96
-0
tests/examples/JDBC/springbootdemo/src/main/java/com/taosdata/jdbc/springbootdemo/SpringbootdemoApplication.java
...osdata/jdbc/springbootdemo/SpringbootdemoApplication.java
+15
-0
tests/examples/JDBC/springbootdemo/src/main/java/com/taosdata/jdbc/springbootdemo/controller/WeatherController.java
...ata/jdbc/springbootdemo/controller/WeatherController.java
+60
-0
tests/examples/JDBC/springbootdemo/src/main/java/com/taosdata/jdbc/springbootdemo/dao/WeatherMapper.java
...a/com/taosdata/jdbc/springbootdemo/dao/WeatherMapper.java
+19
-0
tests/examples/JDBC/springbootdemo/src/main/java/com/taosdata/jdbc/springbootdemo/domain/Weather.java
...java/com/taosdata/jdbc/springbootdemo/domain/Weather.java
+36
-0
tests/examples/JDBC/springbootdemo/src/main/java/com/taosdata/jdbc/springbootdemo/service/WeatherService.java
.../taosdata/jdbc/springbootdemo/service/WeatherService.java
+40
-0
tests/examples/JDBC/springbootdemo/src/main/resources/application.properties
.../springbootdemo/src/main/resources/application.properties
+26
-0
tests/examples/JDBC/springbootdemo/src/main/resources/mapper/WeatherMapper.xml
...pringbootdemo/src/main/resources/mapper/WeatherMapper.xml
+49
-0
tests/examples/JDBC/springbootdemo/src/test/java/com/taosdata/jdbc/springbootdemo/SpringbootdemoApplicationTests.java
...a/jdbc/springbootdemo/SpringbootdemoApplicationTests.java
+13
-0
未找到文件。
documentation/webdocs/markdowndocs/connector-ch.md
浏览文件 @
02e39aab
...
...
@@ -188,58 +188,107 @@ TDengine提供时间驱动的实时流式计算API。可以每隔一指定的时
## Java Connector
### JDBC接口
TDengine 为了方便 Java 应用使用,提供了遵循 JDBC 标准(3.0)API 规范的
`taos-jdbcdriver`
实现。目前可以通过
[
Sonatype Repository
][
1
]
搜索并下载。
如果用户使用Java开发企业级应用,可选用 TDengine 提供的 JDBC Driver 来调用服务。TDengine 提供的 JDBC Driver 是标准 JDBC 规范的子集,遵循 JDBC 标准 (3.0)API 规范,支持现有的各种 Java 开发框架。目前 TDengine 的 JDBC driver 已经发布到 Sonatype Maven Repository。因此用户开发时,需要在 pom.xml 文件中进行如下配置:
由于 TDengine 是使用 c 语言开发的,使用 taos-jdbcdriver 驱动包时需要依赖系统对应的本地函数库。
```
xml
*
libtaos.so
在 linux 系统中成功安装 TDengine 后,依赖的本地函数库 libtaos.so 文件会被自动拷贝至 /usr/lib/libtaos.so,该目录包含在 Linux 自动扫描路径上,无需单独指定。
*
taos.dll
在 windows 系统中安装完客户端之后,驱动包依赖的 taos.dll 文件会自动拷贝到系统默认搜索路径 C:/Windows/System32 下,同样无需要单独指定。
> 注意:在 windows 环境开发时需要安装 TDengine 对应的 windows 版本客户端,由于目前没有提供 Linux 环境单独的客户端,需要安装 TDengine 才能使用。
<repositories>
<repository>
<id>
oss-sonatype
</id>
<name>
oss-sonatype
</name>
<url>
https://oss.sonatype.org/content/groups/public
</url>
</repository>
</repositories>
TDengine 的 JDBC 驱动实现尽可能的与关系型数据库驱动保持一致,但时序空间数据库与关系对象型数据库服务的对象和技术特征的差异导致 taos-jdbcdriver 并未完全实现 JDBC 标准规范。在使用时需要注意以下几点:
*
TDengine 不提供针对单条数据记录的删除和修改的操作,驱动中也没有支持相关方法。
*
由于不支持删除和修改,所以也不支持事务操作。
*
目前不支持表间的 union 操作。
*
目前不支持嵌套查询(nested query),
`对每个 Connection 的实例,至多只能有一个打开的 ResultSet 实例;如果在 ResultSet还没关闭的情况下执行了新的查询,TSDBJDBCDriver 则会自动关闭上一个 ResultSet`
。
## TAOS-JDBCDriver 版本以及支持的 TDengine 版本和 JDK 版本
| taos-jdbcdriver 版本 | TDengine 版本 | JDK 版本 |
| --- | --- | --- |
| 1.0.3 | 1.6.1.x 及以上 | 1.8.x |
| 1.0.2 | 1.6.1.x 及以上 | 1.8.x |
| 1.0.1 | 1.6.1.x 及以上 | 1.8.x |
## TDengine DataType 和 Java DataType
TDengine 目前支持时间戳、数字、字符、布尔类型,与 Java 对应类型转换如下:
| TDengine DataType | Java DataType |
| --- | --- |
| TIMESTAMP | java.sql.Timestamp |
| INT | java.lang.Integer |
| BIGINT | java.lang.Long |
| FLOAT | java.lang.Float |
| DOUBLE | java.lang.Double |
| SMALLINT, TINYINT |java.lang.Short |
| BOOL | java.lang.Boolean |
| BINARY, NCHAR | java.lang.String |
## 如何获取 TAOS-JDBCDriver
### maven 仓库
目前 taos-jdbcdriver 已经发布到
[
Sonatype Repository
][
1
]
仓库,且各大仓库都已同步。
*
[
sonatype
][
8
]
*
[
mvnrepository
][
9
]
*
[
maven.aliyun
][
10
]
maven 项目中使用如下 pom.xml 配置即可:
```
xml
<dependencies>
<dependency>
<groupId>
com.taosdata.jdbc
</groupId>
<artifactId>
taos-jdbcdriver
</artifactId>
<version>
1.0.
1
</version>
<version>
1.0.
3
</version>
</dependency>
</dependencies>
```
TDengine 的驱动程序包的在不同操作系统上依赖不同的本地函数库(均由C语言编写)。Linux系统上,依赖一个名为
`libtaos.so`
的本地库,.so即"Shared Object"缩写。成功安装TDengine后,
`libtaos.so`
文件会被自动拷贝至
`/usr/local/lib/taos`
目录下,该目录也包含在Linux上自动扫描路径上。Windows系统上,JDBC驱动程序依赖于一个名为
`taos.dll`
的本地库,.dll是动态链接库"Dynamic Link Library"的缩写。Windows上成功安装客户端后,JDBC驱动程序包默认位于
`C:/TDengine/driver/JDBC/`
目录下;其依赖的动态链接库
`taos.dll`
文件位于
`C:/TDengine/driver/C`
目录下,
`taos.dll`
会被自动拷贝至系统默认搜索路径
`C:/Windows/System32`
下。
### 源码编译打包
TDengine的JDBC Driver遵循标准JDBC规范,开发人员可以参考Oracle官方的JDBC相关文档来找到具体的接口和方法的定义与用法。TDengine的JDBC驱动在连接配置和支持的方法上与传统数据库驱动稍有不同。
下载
[
TDengine
][
3
]
源码之后,进入 taos-jdbcdriver 源码目录
`src/connector/jdbc`
执行
`mvn clean package`
即可生成相应 jar 包。
TDengine的JDBC URL规范格式为:
`jdbc:TSDB://{host_ip}:{port}/{database_name}?[user={user}|&password={password}|&charset={charset}|&cfgdir={config_dir}|&locale={locale}|&timezone={timezone}]`
## 使用说明
其中,
`{}`
中的内容必须,
`[]`
中为可选。配置参数说明如下:
### 获取连接
-
user:登陆TDengine所用用户名;默认值root
-
password:用户登陆密码;默认值taosdata
-
charset:客户端使用的字符集;默认值为系统字符集
-
cfgdir:客户端配置文件目录路径;Linux OS上默认值
`/etc/taos`
,Windows OS上默认值
`C:/TDengine/cfg`
-
locale:客户端语言环境;默认值系统当前locale
-
timezone:客户端使用的时区;默认值为系统当前时区
如下所示配置即可获取 TDengine Connection:
```
java
Class
.
forName
(
"com.taosdata.jdbc.TSDBDriver"
);
String
jdbcUrl
=
"jdbc:TAOS://127.0.0.1:6030/log?user=root&password=taosdata"
;
Connection
conn
=
DriverManager
.
getConnection
(
jdbcUrl
);
```
> 端口 6030 为默认连接端口,JDBC URL 中的 log 为系统本身的监控数据库。
以上所有参数均可在调用java.sql.DriverManager类创建连接时指定,示例如下:
TDengine 的 JDBC URL 规范格式为:
`jdbc:TSDB://{host_ip}:{port}/[database_name]?[user={user}|&password={password}|&charset={charset}|&cfgdir={config_dir}|&locale={locale}|&timezone={timezone}]`
```
java
import
java.sql.Connection
;
import
java.sql.DriverManager
;
import
java.util.Properties
;
import
com.taosdata.jdbc.TSDBDriver
;
其中,
`{}`
中的内容必须,
`[]`
中为可选。配置参数说明如下:
*
user:登录 TDengine 用户名,默认值 root。
*
password:用户登录密码,默认值 taosdata。
*
charset:客户端使用的字符集,默认值为系统字符集。
*
cfgdir:客户端配置文件目录路径,Linux OS 上默认值 /etc/taos ,Windows OS 上默认值 C:/TDengine/cfg。
*
locale:客户端语言环境,默认值系统当前 locale。
*
timezone:客户端使用的时区,默认值为系统当前时区。
以上参数可以在 3 处配置,
`优先级由高到低`
分别如下:
1.
JDBC URL 参数
如上所述,可以在 JDBC URL 的参数中指定。
2.
java.sql.DriverManager.getConnection(String jdbcUrl, Properties connProps)
```
java
public
Connection
getConn
()
throws
Exception
{
Class
.
forName
(
"com.taosdata.jdbc.TSDBDriver"
);
String
jdbcUrl
=
"jdbc:TAOS://127.0.0.1:0/
db
?user=root&password=taosdata"
;
Class
.
forName
(
"com.taosdata.jdbc.TSDBDriver"
);
String
jdbcUrl
=
"jdbc:TAOS://127.0.0.1:0/
log
?user=root&password=taosdata"
;
Properties
connProps
=
new
Properties
();
connProps
.
setProperty
(
TSDBDriver
.
PROPERTY_KEY_USER
,
"root"
);
connProps
.
setProperty
(
TSDBDriver
.
PROPERTY_KEY_PASSWORD
,
"taosdata"
);
...
...
@@ -252,16 +301,203 @@ public Connection getConn() throws Exception{
}
```
这些配置参数中除了cfgdir外,均可在客户端配置文件taos.cfg中进行配置。调用java.sql.DriverManager时声明的配置参数优先级最高,JDBC URL的优先级次之,配置文件的优先级最低。例如charset同时在配置文件taos.cfg中配置,也在JDBC URL中配置,则使用JDBC URL中的配置值。
3.
客户端配置文件 taos.cfg
linux 系统默认配置文件为 /var/lib/taos/taos.cfg,windows 系统默认配置文件路径为 C:\TDengine\cfg\taos.cfg。
```
properties
# client default username
# defaultUser root
# client default password
# defaultPass taosdata
# default system charset
# charset UTF-8
# system locale
#
locale
en_US.UTF-8
```
> 更多详细配置请参考[客户端配置][13]
### 创建数据库和表
```
java
Statement
stmt
=
conn
.
createStatement
();
// create database
stmt
.
executeUpdate
(
"create database if not exists db"
);
// use database
stmt
.
executeUpdate
(
"use db"
);
// create table
stmt
.
executeUpdate
(
"create table if not exists tb (ts timestamp, temperature int, humidity float)"
);
```
> 注意:如果不使用 `use db` 指定数据库,则后续对表的操作都需要增加数据库名称作为前缀,如 db.tb。
### 插入数据
```
java
// insert data
int
affectedRows
=
stmt
.
executeUpdate
(
"insert into tb values(now, 23, 10.3) (now + 1s, 20, 9.3)"
);
System
.
out
.
println
(
"insert "
+
affectedRows
+
" rows."
);
```
> now 为系统内部函数,默认为服务器当前时间。
> `now + 1s` 代表服务器当前时间往后加 1 秒,数字后面代表时间单位:a(毫秒), s(秒), m(分), h(小时), d(天),w(周), n(月), y(年)。
### 查询数据
```
java
// query data
ResultSet
resultSet
=
stmt
.
executeQuery
(
"select * from tb"
);
此外,尽管TDengine的JDBC驱动实现尽可能的与关系型数据库驱动保持一致,但时序空间数据库与关系对象型数据库服务的对象和技术特征的差异导致TDengine的Java API并不能与标准完全相同。对于有大量关系型数据库开发经验而初次接触TDengine的开发者来说,有以下一些值的注意的地方:
Timestamp
ts
=
null
;
int
temperature
=
0
;
float
humidity
=
0
;
while
(
resultSet
.
next
()){
*
TDengine不提供针对单条数据记录的删除和修改的操作,驱动中也没有支持相关方法
*
目前TDengine不支持表间的join或union操作,因此也缺乏对该部分API的支持
*
TDengine支持批量写入,但是支持停留在SQL语句级别,而不是API级别,也就是说用户需要通过写特殊的SQL语句来实现批量
*
目前TDengine不支持嵌套查询(nested query),对每个Connection的实例,至多只能有一个打开的ResultSet实例;如果在ResultSet还没关闭的情况下执行了新的查询,TSDBJDBCDriver则会自动关闭上一个ResultSet
ts
=
resultSet
.
getTimestamp
(
1
);
temperature
=
resultSet
.
getInt
(
2
);
humidity
=
resultSet
.
getFloat
(
"humidity"
);
System
.
out
.
printf
(
"%s, %d, %s\n"
,
ts
,
temperature
,
humidity
);
}
```
> 查询和操作关系型数据库一致,使用下标获取返回字段内容时从 1 开始,建议使用字段名称获取。
### 关闭资源
```
java
resultSet
.
close
();
stmt
.
close
();
conn
.
close
();
```
> `注意务必要将 connection 进行关闭`,否则会出现连接泄露。
## 与连接池使用
**HikariCP**
*
引入相应 HikariCP maven 依赖:
```
xml
<dependency>
<groupId>
com.zaxxer
</groupId>
<artifactId>
HikariCP
</artifactId>
<version>
3.4.1
</version>
</dependency>
```
*
使用示例如下:
```
java
public
static
void
main
(
String
[]
args
)
throws
SQLException
{
HikariConfig
config
=
new
HikariConfig
();
config
.
setJdbcUrl
(
"jdbc:TAOS://127.0.0.1:6030/log"
);
config
.
setUsername
(
"root"
);
config
.
setPassword
(
"taosdata"
);
config
.
setMinimumIdle
(
3
);
//minimum number of idle connection
config
.
setMaximumPoolSize
(
10
);
//maximum number of connection in the pool
config
.
setConnectionTimeout
(
10000
);
//maximum wait milliseconds for get connection from pool
config
.
setIdleTimeout
(
60000
);
// max idle time for recycle idle connection
config
.
setConnectionTestQuery
(
"describe log.dn"
);
//validation query
config
.
setValidationTimeout
(
3000
);
//validation query timeout
HikariDataSource
ds
=
new
HikariDataSource
(
config
);
//create datasource
Connection
connection
=
ds
.
getConnection
();
// get connection
Statement
statement
=
connection
.
createStatement
();
// get statement
//query or insert
// ...
connection
.
close
();
// put back to conneciton pool
}
```
> 通过 HikariDataSource.getConnection() 获取连接后,使用完成后需要调用 close() 方法,实际上它并不会关闭连接,只是放回连接池中。
> 更多 HikariCP 使用问题请查看[官方说明][5]
**Druid**
*
引入相应 Druid maven 依赖:
```
xml
<dependency>
<groupId>
com.alibaba
</groupId>
<artifactId>
druid
</artifactId>
<version>
1.1.20
</version>
</dependency>
```
*
使用示例如下:
```
java
public
static
void
main
(
String
[]
args
)
throws
Exception
{
Properties
properties
=
new
Properties
();
properties
.
put
(
"driverClassName"
,
"com.taosdata.jdbc.TSDBDriver"
);
properties
.
put
(
"url"
,
"jdbc:TAOS://127.0.0.1:6030/log"
);
properties
.
put
(
"username"
,
"root"
);
properties
.
put
(
"password"
,
"taosdata"
);
properties
.
put
(
"maxActive"
,
"10"
);
//maximum number of connection in the pool
properties
.
put
(
"initialSize"
,
"3"
);
//initial number of connection
properties
.
put
(
"maxWait"
,
"10000"
);
//maximum wait milliseconds for get connection from pool
properties
.
put
(
"minIdle"
,
"3"
);
//minimum number of connection in the pool
properties
.
put
(
"timeBetweenEvictionRunsMillis"
,
"3000"
);
// the interval milliseconds to test connection
properties
.
put
(
"minEvictableIdleTimeMillis"
,
"60000"
);
//the minimum milliseconds to keep idle
properties
.
put
(
"maxEvictableIdleTimeMillis"
,
"90000"
);
//the maximum milliseconds to keep idle
properties
.
put
(
"validationQuery"
,
"describe log.dn"
);
//validation query
properties
.
put
(
"testWhileIdle"
,
"true"
);
// test connection while idle
properties
.
put
(
"testOnBorrow"
,
"false"
);
// don't need while testWhileIdle is true
properties
.
put
(
"testOnReturn"
,
"false"
);
// don't need while testWhileIdle is true
//create druid datasource
DataSource
ds
=
DruidDataSourceFactory
.
createDataSource
(
properties
);
Connection
connection
=
ds
.
getConnection
();
// get connection
Statement
statement
=
connection
.
createStatement
();
// get statement
//query or insert
// ...
connection
.
close
();
// put back to conneciton pool
}
```
> 更多 druid 使用问题请查看[官方说明][6]
**注意事项**
*
TDengine
`v1.6.4.1`
版本开始提供了一个专门用于心跳检测的函数
`select server_status()`
,所以在使用连接池时推荐使用
`select server_status()`
进行 Validation Query。
如下所示,
`select server_status()`
执行成功会返回
`1`
。
```
shell
taos>
select
server_status
()
;
server_status
()
|
================
1 |
Query OK, 1 row
(
s
)
in
set
(
0.000141s
)
```
## 与框架使用
*
Spring JdbcTemplate 中使用 taos-jdbcdriver,可参考
[
SpringJdbcTemplate
][
11
]
*
Springboot + Mybatis 中使用,可参考
[
springbootdemo
][
12
]
## 常见问题
*
java.lang.UnsatisfiedLinkError: no taos in java.library.path
**原因**
:程序没有找到依赖的本地函数库 taos。
**解决方法**
:windows 下可以将 C:
\T
Dengine
\d
river
\t
aos.dll 拷贝到 C:
\W
indows
\S
ystem32
\
目录下,linux 下将建立如下软链
` ln -s /usr/local/taos/driver/libtaos.so.x.x.x.x /usr/lib/libtaos.so`
即可。
*
java.lang.UnsatisfiedLinkError: taos.dll Can't load AMD 64 bit on a IA 32-bit platform
**原因**
:目前 TDengine 只支持 64 位 JDK。
**解决方法**
:重新安装 64 位 JDK。
对于TDengine操作的报错信息,用户可使用JDBCDriver包里提供的枚举类TSDBError.java来获取error message和error code的列表。对于更多的具体操作的相关代码,请参考TDengine提供的使用示范项目
`JDBCDemo`
。
*
其它问题请参考
[
Issues
][
7
]
## Python Connector
...
...
@@ -811,30 +1047,30 @@ https://gitee.com/maikebing/Maikebing.EntityFrameworkCore.Taos
```
├── cfg
│
└── taos.cfg
├───
└── taos.cfg
├── connector
│
├── go
│
├── grafana
│
├── jdbc
│
└── python
├───
├── go
├───
├── grafana
├───
├── jdbc
├───
└── python
├── driver
│
├── taos.dll
│
├── taos.exp
│
└── taos.lib
├───
├── taos.dll
├───
├── taos.exp
├───
└── taos.lib
├── examples
│
├── bash
│
├── c
│
├── C#
│
├── go
│
├── JDBC
│
├── lua
│
├── matlab
│
├── nodejs
│
├── python
│
├── R
│
└── rust
├───
├── bash
├───
├── c
├───
├── C#
├───
├── go
├───
├── JDBC
├───
├── lua
├───
├── matlab
├───
├── nodejs
├───
├── python
├───
├── R
├───
└── rust
├── include
│
└── taos.h
├───
└── taos.h
└── taos.exe
```
...
...
@@ -879,3 +1115,16 @@ TDengine在Window系统上提供的API与Linux系统是相同的, 应用程序
+
将Windows开发包(taos.dll)放置到system32目录下。
[
1
]:
https://search.maven.org/artifact/com.taosdata.jdbc/taos-jdbcdriver
[
2
]:
https://mvnrepository.com/artifact/com.taosdata.jdbc/taos-jdbcdriver
[
3
]:
https://github.com/taosdata/TDengine
[
4
]:
https://www.taosdata.com/blog/2019/12/03/jdbcdriver%e6%89%be%e4%b8%8d%e5%88%b0%e5%8a%a8%e6%80%81%e9%93%be%e6%8e%a5%e5%ba%93/
[
5
]:
https://github.com/brettwooldridge/HikariCP
[
6
]:
https://github.com/alibaba/druid
[
7
]:
https://github.com/taosdata/TDengine/issues
[
8
]:
https://search.maven.org/artifact/com.taosdata.jdbc/taos-jdbcdriver
[
9
]:
https://mvnrepository.com/artifact/com.taosdata.jdbc/taos-jdbcdriver
[
10
]:
https://maven.aliyun.com/mvn/search
[
11
]:
https://github.com/taosdata/TDengine/tree/develop/tests/examples/JDBC/SpringJdbcTemplate
[
12
]:
https://github.com/taosdata/TDengine/tree/develop/tests/examples/JDBC/springbootdemo
[
13
]:
https://www.taosdata.com/cn/documentation/administrator/#%E5%AE%A2%E6%88%B7%E7%AB%AF%E9%85%8D%E7%BD%AE
packaging/tools/install.sh
浏览文件 @
02e39aab
...
...
@@ -313,9 +313,9 @@ vercomp () {
function
is_version_compatible
()
{
curr_version
=
$(
${
bin_dir
}
/taosd
-V
|
head
-1
|
cut
-d
' '
-f
2
)
curr_version
=
$(
${
bin_dir
}
/taosd
-V
|
head
-1
|
cut
-d
' '
-f
3
)
min_compatible_version
=
$(
${
script_dir
}
/bin/taosd
-V
|
head
-1
|
cut
-d
' '
-f
4
)
min_compatible_version
=
$(
${
script_dir
}
/bin/taosd
-V
|
head
-1
|
cut
-d
' '
-f
5
)
vercomp
$curr_version
$min_compatible_version
case
$?
in
...
...
src/client/src/tscAst.c
浏览文件 @
02e39aab
...
...
@@ -108,12 +108,12 @@ static tSQLSyntaxNode *tSQLSyntaxNodeCreate(SSchema *pSchema, int32_t numOfCols,
return
NULL
;
}
int32_t
i
=
0
;
size_t
nodeSize
=
sizeof
(
tSQLSyntaxNode
);
tSQLSyntaxNode
*
pNode
=
NULL
;
if
(
pToken
->
type
==
TK_ID
||
pToken
->
type
==
TK_TBNAME
)
{
if
(
pToken
->
type
==
TK_ID
)
{
int32_t
i
=
0
;
do
{
size_t
len
=
strlen
(
pSchema
[
i
].
name
);
if
(
strncmp
(
pToken
->
z
,
pSchema
[
i
].
name
,
pToken
->
n
)
==
0
&&
pToken
->
n
==
len
)
break
;
...
...
@@ -268,8 +268,8 @@ static tSQLSyntaxNode *createSyntaxTree(SSchema *pSchema, int32_t numOfCols, cha
}
// get the operator of expr
uint8_t
optr
=
getBinaryExprOptr
(
&
t0
);
if
(
optr
<
=
0
)
{
uint8_t
optr
=
getBinaryExprOptr
(
&
t0
);
if
(
optr
=
=
0
)
{
pError
(
"not support binary operator:%d"
,
t0
.
type
);
tSQLSyntaxNodeDestroy
(
pLeft
,
NULL
);
return
NULL
;
...
...
@@ -323,10 +323,11 @@ static tSQLSyntaxNode *createSyntaxTree(SSchema *pSchema, int32_t numOfCols, cha
pn
->
colId
=
-
1
;
return
pn
;
}
else
{
uint8_t
localOptr
=
getBinaryExprOptr
(
&
t0
);
if
(
localOptr
<
=
0
)
{
uint8_t
localOptr
=
getBinaryExprOptr
(
&
t0
);
if
(
localOptr
=
=
0
)
{
pError
(
"not support binary operator:%d"
,
t0
.
type
);
return
NULL
;
free
(
pBinExpr
)
}
return
parseRemainStr
(
str
,
pBinExpr
,
pSchema
,
localOptr
,
numOfCols
,
i
);
...
...
@@ -418,16 +419,17 @@ void tSQLBinaryExprToString(tSQLBinaryExpr *pExpr, char *dst, int32_t *len) {
if
(
pExpr
==
NULL
)
{
*
dst
=
0
;
*
len
=
0
;
return
;
}
int32_t
lhs
=
tSQLBinaryExprToStringImpl
(
pExpr
->
pLeft
,
dst
,
pExpr
->
pLeft
->
nodeType
);
int32_t
lhs
=
tSQLBinaryExprToStringImpl
(
pExpr
->
pLeft
,
dst
,
pExpr
->
pLeft
->
nodeType
);
dst
+=
lhs
;
*
len
=
lhs
;
char
*
start
=
tSQLOptrToString
(
pExpr
->
nSQLBinaryOptr
,
dst
);
char
*
start
=
tSQLOptrToString
(
pExpr
->
nSQLBinaryOptr
,
dst
);
*
len
+=
(
start
-
dst
);
*
len
+=
tSQLBinaryExprToStringImpl
(
pExpr
->
pRight
,
start
,
pExpr
->
pRight
->
nodeType
);
*
len
+=
tSQLBinaryExprToStringImpl
(
pExpr
->
pRight
,
start
,
pExpr
->
pRight
->
nodeType
);
}
static
void
UNUSED_FUNC
destroySyntaxTree
(
tSQLSyntaxNode
*
pNode
)
{
tSQLSyntaxNodeDestroy
(
pNode
,
NULL
);
}
...
...
@@ -650,7 +652,8 @@ void tSQLListTraverseOnResult(struct tSQLBinaryExpr *pExpr, bool (*fp)(tSkipList
// brutal force search
int64_t
num
=
pResult
->
num
;
for
(
int32_t
i
=
0
,
j
=
0
;
i
<
pResult
->
num
;
++
i
)
{
if
(
fp
==
NULL
||
(
fp
!=
NULL
&&
fp
(
pResult
->
pRes
[
i
],
pExpr
->
info
)
==
true
))
{
//if (fp == NULL || (fp != NULL && fp(pResult->pRes[i], pExpr->info) == true)) {
if
(
fp
==
NULL
||
(
fp
(
pResult
->
pRes
[
i
],
pExpr
->
info
)
==
true
))
{
pResult
->
pRes
[
j
++
]
=
pResult
->
pRes
[
i
];
}
else
{
num
--
;
...
...
src/client/src/tscAsync.c
浏览文件 @
02e39aab
...
...
@@ -157,7 +157,6 @@ static void tscProcessAsyncRetrieveImpl(void *param, TAOS_RES *tres, int numOfRo
SSqlObj
*
pSql
=
(
SSqlObj
*
)
tres
;
if
(
pSql
==
NULL
)
{
// error
tscError
(
"sql object is NULL"
);
tscQueueAsyncError
(
pSql
->
fetchFp
,
param
);
return
;
}
...
...
src/client/src/tscParseInsert.c
浏览文件 @
02e39aab
...
...
@@ -392,7 +392,7 @@ static int32_t tsCheckTimestamp(STableDataBlocks *pDataBlocks, const char *start
}
int
tsParseOneRowData
(
char
**
str
,
STableDataBlocks
*
pDataBlocks
,
SSchema
schema
[],
SParsedDataColInfo
*
spd
,
char
*
error
,
int16_t
timePrec
)
{
int16_t
timePrec
,
int32_t
*
code
,
char
*
tmpTokenBuf
)
{
int32_t
index
=
0
;
bool
isPrevOptr
;
SSQLToken
sToken
=
{
0
};
...
...
@@ -418,6 +418,7 @@ int tsParseOneRowData(char **str, STableDataBlocks *pDataBlocks, SSchema schema[
}
strcpy
(
error
,
"client out of memory"
);
*
code
=
TSDB_CODE_CLI_OUT_OF_MEMORY
;
return
-
1
;
}
...
...
@@ -425,23 +426,42 @@ int tsParseOneRowData(char **str, STableDataBlocks *pDataBlocks, SSchema schema[
(
sToken
.
type
!=
TK_FLOAT
)
&&
(
sToken
.
type
!=
TK_BOOL
)
&&
(
sToken
.
type
!=
TK_NULL
))
||
(
sToken
.
n
==
0
)
||
(
sToken
.
type
==
TK_RP
))
{
tscInvalidSQLErrMsg
(
error
,
"invalid data or symbol"
,
sToken
.
z
);
*
code
=
TSDB_CODE_INVALID_SQL
;
return
-
1
;
}
// Remove quotation marks
if
(
TK_STRING
==
sToken
.
type
)
{
sToken
.
z
++
;
sToken
.
n
-=
2
;
// delete escape character: \\, \', \"
char
delim
=
sToken
.
z
[
0
];
int32_t
cnt
=
0
;
int32_t
j
=
0
;
for
(
int32_t
i
=
1
;
i
<
sToken
.
n
-
1
;
++
i
)
{
if
(
sToken
.
z
[
i
]
==
delim
||
sToken
.
z
[
i
]
==
'\\'
)
{
if
(
sToken
.
z
[
i
+
1
]
==
delim
)
{
cnt
++
;
continue
;
}
}
tmpTokenBuf
[
j
]
=
sToken
.
z
[
i
];
j
++
;
}
tmpTokenBuf
[
j
]
=
0
;
sToken
.
z
=
tmpTokenBuf
;
sToken
.
n
-=
2
+
cnt
;
}
bool
isPrimaryKey
=
(
colIndex
==
PRIMARYKEY_TIMESTAMP_COL_INDEX
);
int32_t
ret
=
tsParseOneColumnData
(
pSchema
,
&
sToken
,
start
,
error
,
str
,
isPrimaryKey
,
timePrec
);
if
(
ret
!=
TSDB_CODE_SUCCESS
)
{
*
code
=
TSDB_CODE_INVALID_SQL
;
return
-
1
;
// NOTE: here 0 mean error!
}
if
(
isPrimaryKey
&&
tsCheckTimestamp
(
pDataBlocks
,
start
)
!=
TSDB_CODE_SUCCESS
)
{
tscInvalidSQLErrMsg
(
error
,
"client time/server time can not be mixed up"
,
sToken
.
z
);
*
code
=
TSDB_CODE_INVALID_TIME_STAMP
;
return
-
1
;
}
}
...
...
@@ -476,7 +496,7 @@ static int32_t rowDataCompar(const void *lhs, const void *rhs) {
}
int
tsParseValues
(
char
**
str
,
STableDataBlocks
*
pDataBlock
,
SMeterMeta
*
pMeterMeta
,
int
maxRows
,
SParsedDataColInfo
*
spd
,
char
*
error
)
{
SParsedDataColInfo
*
spd
,
char
*
error
,
int32_t
*
code
,
char
*
tmpTokenBuf
)
{
int32_t
index
=
0
;
SSQLToken
sToken
;
...
...
@@ -487,6 +507,7 @@ int tsParseValues(char **str, STableDataBlocks *pDataBlock, SMeterMeta *pMeterMe
if
(
spd
->
hasVal
[
0
]
==
false
)
{
strcpy
(
error
,
"primary timestamp column can not be null"
);
*
code
=
TSDB_CODE_INVALID_SQL
;
return
-
1
;
}
...
...
@@ -500,12 +521,13 @@ int tsParseValues(char **str, STableDataBlocks *pDataBlock, SMeterMeta *pMeterMe
int32_t
tSize
=
tscAllocateMemIfNeed
(
pDataBlock
,
pMeterMeta
->
rowSize
);
if
(
0
==
tSize
)
{
strcpy
(
error
,
"client out of memory"
);
*
code
=
TSDB_CODE_CLI_OUT_OF_MEMORY
;
return
-
1
;
}
maxRows
+=
tSize
;
}
int32_t
len
=
tsParseOneRowData
(
str
,
pDataBlock
,
pSchema
,
spd
,
error
,
precision
);
int32_t
len
=
tsParseOneRowData
(
str
,
pDataBlock
,
pSchema
,
spd
,
error
,
precision
,
code
,
tmpTokenBuf
);
if
(
len
<=
0
)
{
// error message has been set in tsParseOneRowData
return
-
1
;
}
...
...
@@ -517,6 +539,7 @@ int tsParseValues(char **str, STableDataBlocks *pDataBlock, SMeterMeta *pMeterMe
*
str
+=
index
;
if
(
sToken
.
n
==
0
||
sToken
.
type
!=
TK_RP
)
{
tscInvalidSQLErrMsg
(
error
,
") expected"
,
*
str
);
*
code
=
TSDB_CODE_INVALID_SQL
;
return
-
1
;
}
...
...
@@ -525,6 +548,7 @@ int tsParseValues(char **str, STableDataBlocks *pDataBlock, SMeterMeta *pMeterMe
if
(
numOfRows
<=
0
)
{
strcpy
(
error
,
"no any data points"
);
*
code
=
TSDB_CODE_INVALID_SQL
;
return
-
1
;
}
else
{
return
numOfRows
;
...
...
@@ -636,10 +660,17 @@ static int32_t doParseInsertStatement(SSqlObj *pSql, void *pTableHashList, char
if
(
0
==
maxNumOfRows
)
{
return
TSDB_CODE_CLI_OUT_OF_MEMORY
;
}
int32_t
numOfRows
=
tsParseValues
(
str
,
dataBuf
,
pMeterMeta
,
maxNumOfRows
,
spd
,
pCmd
->
payload
);
int32_t
code
=
TSDB_CODE_INVALID_SQL
;
char
*
tmpTokenBuf
=
calloc
(
1
,
4096
);
// used for deleting Escape character: \\, \', \"
if
(
NULL
==
tmpTokenBuf
)
{
return
TSDB_CODE_CLI_OUT_OF_MEMORY
;
}
int32_t
numOfRows
=
tsParseValues
(
str
,
dataBuf
,
pMeterMeta
,
maxNumOfRows
,
spd
,
pCmd
->
payload
,
&
code
,
tmpTokenBuf
);
free
(
tmpTokenBuf
);
if
(
numOfRows
<=
0
)
{
return
TSDB_CODE_INVALID_SQL
;
return
code
;
}
for
(
uint32_t
i
=
0
;
i
<
dataBuf
->
numOfParams
;
++
i
)
{
...
...
@@ -1173,7 +1204,7 @@ static int doPackSendDataBlock(SSqlObj *pSql, int32_t numOfRows, STableDataBlock
return
TSDB_CODE_SUCCESS
;
}
static
int
tscInsertDataFromFile
(
SSqlObj
*
pSql
,
FILE
*
fp
)
{
static
int
tscInsertDataFromFile
(
SSqlObj
*
pSql
,
FILE
*
fp
,
char
*
tmpTokenBuf
)
{
size_t
readLen
=
0
;
char
*
line
=
NULL
;
size_t
n
=
0
;
...
...
@@ -1216,10 +1247,10 @@ static int tscInsertDataFromFile(SSqlObj *pSql, FILE *fp) {
maxRows
+=
tSize
;
}
len
=
tsParseOneRowData
(
&
lineptr
,
pTableDataBlock
,
pSchema
,
&
spd
,
pCmd
->
payload
,
pMeterMeta
->
precision
);
len
=
tsParseOneRowData
(
&
lineptr
,
pTableDataBlock
,
pSchema
,
&
spd
,
pCmd
->
payload
,
pMeterMeta
->
precision
,
&
code
,
tmpTokenBuf
);
if
(
len
<=
0
||
pTableDataBlock
->
numOfParams
>
0
)
{
pSql
->
res
.
code
=
TSDB_CODE_INVALID_SQL
;
return
-
1
;
pSql
->
res
.
code
=
code
;
return
(
-
code
)
;
}
pTableDataBlock
->
size
+=
len
;
...
...
@@ -1348,8 +1379,16 @@ void tscProcessMultiVnodesInsertForFile(SSqlObj *pSql) {
tscError
(
"%p get meter meta failed, abort"
,
pSql
);
continue
;
}
char
*
tmpTokenBuf
=
calloc
(
1
,
4096
);
// used for deleting Escape character: \\, \', \"
if
(
NULL
==
tmpTokenBuf
)
{
tscError
(
"%p calloc failed"
,
pSql
);
continue
;
}
int
nrows
=
tscInsertDataFromFile
(
pSql
,
fp
);
int
nrows
=
tscInsertDataFromFile
(
pSql
,
fp
,
tmpTokenBuf
);
free
(
tmpTokenBuf
);
pCmd
->
pDataBlocks
=
tscDestroyBlockArrayList
(
pCmd
->
pDataBlocks
);
if
(
nrows
<
0
)
{
...
...
src/connector/jdbc/readme.md
0 → 100644
浏览文件 @
02e39aab
## TAOS-JDBCDriver 概述
TDengine 为了方便 Java 应用使用,提供了遵循 JDBC 标准(3.0)API 规范的
`taos-jdbcdriver`
实现。目前可以通过
[
Sonatype Repository
][
1
]
搜索并下载。
由于 TDengine 是使用 c 语言开发的,使用 taos-jdbcdriver 驱动包时需要依赖系统对应的本地函数库。
*
libtaos.so
在 linux 系统中成功安装 TDengine 后,依赖的本地函数库 libtaos.so 文件会被自动拷贝至 /usr/lib/libtaos.so,该目录包含在 Linux 自动扫描路径上,无需单独指定。
*
taos.dll
在 windows 系统中安装完客户端之后,驱动包依赖的 taos.dll 文件会自动拷贝到系统默认搜索路径 C:/Windows/System32 下,同样无需要单独指定。
> 注意:在 windows 环境开发时需要安装 TDengine 对应的 windows 版本客户端,由于目前没有提供 Linux 环境单独的客户端,需要安装 TDengine 才能使用。
TDengine 的 JDBC 驱动实现尽可能的与关系型数据库驱动保持一致,但时序空间数据库与关系对象型数据库服务的对象和技术特征的差异导致 taos-jdbcdriver 并未完全实现 JDBC 标准规范。在使用时需要注意以下几点:
*
TDengine 不提供针对单条数据记录的删除和修改的操作,驱动中也没有支持相关方法。
*
由于不支持删除和修改,所以也不支持事务操作。
*
目前不支持表间的 union 操作。
*
目前不支持嵌套查询(nested query),
`对每个 Connection 的实例,至多只能有一个打开的 ResultSet 实例;如果在 ResultSet还没关闭的情况下执行了新的查询,TSDBJDBCDriver 则会自动关闭上一个 ResultSet`
。
## TAOS-JDBCDriver 版本以及支持的 TDengine 版本和 JDK 版本
| taos-jdbcdriver 版本 | TDengine 版本 | JDK 版本 |
| --- | --- | --- |
| 1.0.3 | 1.6.1.x 及以上 | 1.8.x |
| 1.0.2 | 1.6.1.x 及以上 | 1.8.x |
| 1.0.1 | 1.6.1.x 及以上 | 1.8.x |
## TDengine DataType 和 Java DataType
TDengine 目前支持时间戳、数字、字符、布尔类型,与 Java 对应类型转换如下:
| TDengine DataType | Java DataType |
| --- | --- |
| TIMESTAMP | java.sql.Timestamp |
| INT | java.lang.Integer |
| BIGINT | java.lang.Long |
| FLOAT | java.lang.Float |
| DOUBLE | java.lang.Double |
| SMALLINT, TINYINT |java.lang.Short |
| BOOL | java.lang.Boolean |
| BINARY, NCHAR | java.lang.String |
## 如何获取 TAOS-JDBCDriver
### maven 仓库
目前 taos-jdbcdriver 已经发布到
[
Sonatype Repository
][
1
]
仓库,且各大仓库都已同步。
*
[
sonatype
][
8
]
*
[
mvnrepository
][
9
]
*
[
maven.aliyun
][
10
]
maven 项目中使用如下 pom.xml 配置即可:
```
xml
<dependencies>
<dependency>
<groupId>
com.taosdata.jdbc
</groupId>
<artifactId>
taos-jdbcdriver
</artifactId>
<version>
1.0.3
</version>
</dependency>
</dependencies>
```
### 源码编译打包
下载
[
TDengine
][
3
]
源码之后,进入 taos-jdbcdriver 源码目录
`src/connector/jdbc`
执行
`mvn clean package`
即可生成相应 jar 包。
## 使用说明
### 获取连接
如下所示配置即可获取 TDengine Connection:
```
java
Class
.
forName
(
"com.taosdata.jdbc.TSDBDriver"
);
String
jdbcUrl
=
"jdbc:TAOS://127.0.0.1:6030/log?user=root&password=taosdata"
;
Connection
conn
=
DriverManager
.
getConnection
(
jdbcUrl
);
```
> 端口 6030 为默认连接端口,JDBC URL 中的 log 为系统本身的监控数据库。
TDengine 的 JDBC URL 规范格式为:
`jdbc:TSDB://{host_ip}:{port}/[database_name]?[user={user}|&password={password}|&charset={charset}|&cfgdir={config_dir}|&locale={locale}|&timezone={timezone}]`
其中,
`{}`
中的内容必须,
`[]`
中为可选。配置参数说明如下:
*
user:登录 TDengine 用户名,默认值 root。
*
password:用户登录密码,默认值 taosdata。
*
charset:客户端使用的字符集,默认值为系统字符集。
*
cfgdir:客户端配置文件目录路径,Linux OS 上默认值 /etc/taos ,Windows OS 上默认值 C:/TDengine/cfg。
*
locale:客户端语言环境,默认值系统当前 locale。
*
timezone:客户端使用的时区,默认值为系统当前时区。
以上参数可以在 3 处配置,
`优先级由高到低`
分别如下:
1.
JDBC URL 参数
如上所述,可以在 JDBC URL 的参数中指定。
2.
java.sql.DriverManager.getConnection(String jdbcUrl, Properties connProps)
```
java
public
Connection
getConn
()
throws
Exception
{
Class
.
forName
(
"com.taosdata.jdbc.TSDBDriver"
);
String
jdbcUrl
=
"jdbc:TAOS://127.0.0.1:0/log?user=root&password=taosdata"
;
Properties
connProps
=
new
Properties
();
connProps
.
setProperty
(
TSDBDriver
.
PROPERTY_KEY_USER
,
"root"
);
connProps
.
setProperty
(
TSDBDriver
.
PROPERTY_KEY_PASSWORD
,
"taosdata"
);
connProps
.
setProperty
(
TSDBDriver
.
PROPERTY_KEY_CONFIG_DIR
,
"/etc/taos"
);
connProps
.
setProperty
(
TSDBDriver
.
PROPERTY_KEY_CHARSET
,
"UTF-8"
);
connProps
.
setProperty
(
TSDBDriver
.
PROPERTY_KEY_LOCALE
,
"en_US.UTF-8"
);
connProps
.
setProperty
(
TSDBDriver
.
PROPERTY_KEY_TIME_ZONE
,
"UTC-8"
);
Connection
conn
=
DriverManager
.
getConnection
(
jdbcUrl
,
connProps
);
return
conn
;
}
```
3.
客户端配置文件 taos.cfg
linux 系统默认配置文件为 /var/lib/taos/taos.cfg,windows 系统默认配置文件路径为 C:\TDengine\cfg\taos.cfg。
```
properties
# client default username
# defaultUser root
# client default password
# defaultPass taosdata
# default system charset
# charset UTF-8
# system locale
#
locale
en_US.UTF-8
```
> 更多详细配置请参考[客户端配置][13]
### 创建数据库和表
```
java
Statement
stmt
=
conn
.
createStatement
();
// create database
stmt
.
executeUpdate
(
"create database if not exists db"
);
// use database
stmt
.
executeUpdate
(
"use db"
);
// create table
stmt
.
executeUpdate
(
"create table if not exists tb (ts timestamp, temperature int, humidity float)"
);
```
> 注意:如果不使用 `use db` 指定数据库,则后续对表的操作都需要增加数据库名称作为前缀,如 db.tb。
### 插入数据
```
java
// insert data
int
affectedRows
=
stmt
.
executeUpdate
(
"insert into tb values(now, 23, 10.3) (now + 1s, 20, 9.3)"
);
System
.
out
.
println
(
"insert "
+
affectedRows
+
" rows."
);
```
> now 为系统内部函数,默认为服务器当前时间。
> `now + 1s` 代表服务器当前时间往后加 1 秒,数字后面代表时间单位:a(毫秒), s(秒), m(分), h(小时), d(天),w(周), n(月), y(年)。
### 查询数据
```
java
// query data
ResultSet
resultSet
=
stmt
.
executeQuery
(
"select * from tb"
);
Timestamp
ts
=
null
;
int
temperature
=
0
;
float
humidity
=
0
;
while
(
resultSet
.
next
()){
ts
=
resultSet
.
getTimestamp
(
1
);
temperature
=
resultSet
.
getInt
(
2
);
humidity
=
resultSet
.
getFloat
(
"humidity"
);
System
.
out
.
printf
(
"%s, %d, %s\n"
,
ts
,
temperature
,
humidity
);
}
```
> 查询和操作关系型数据库一致,使用下标获取返回字段内容时从 1 开始,建议使用字段名称获取。
### 关闭资源
```
java
resultSet
.
close
();
stmt
.
close
();
conn
.
close
();
```
> `注意务必要将 connection 进行关闭`,否则会出现连接泄露。
## 与连接池使用
**HikariCP**
*
引入相应 HikariCP maven 依赖:
```
xml
<dependency>
<groupId>
com.zaxxer
</groupId>
<artifactId>
HikariCP
</artifactId>
<version>
3.4.1
</version>
</dependency>
```
*
使用示例如下:
```
java
public
static
void
main
(
String
[]
args
)
throws
SQLException
{
HikariConfig
config
=
new
HikariConfig
();
config
.
setJdbcUrl
(
"jdbc:TAOS://127.0.0.1:6030/log"
);
config
.
setUsername
(
"root"
);
config
.
setPassword
(
"taosdata"
);
config
.
setMinimumIdle
(
3
);
//minimum number of idle connection
config
.
setMaximumPoolSize
(
10
);
//maximum number of connection in the pool
config
.
setConnectionTimeout
(
10000
);
//maximum wait milliseconds for get connection from pool
config
.
setIdleTimeout
(
60000
);
// max idle time for recycle idle connection
config
.
setConnectionTestQuery
(
"describe log.dn"
);
//validation query
config
.
setValidationTimeout
(
3000
);
//validation query timeout
HikariDataSource
ds
=
new
HikariDataSource
(
config
);
//create datasource
Connection
connection
=
ds
.
getConnection
();
// get connection
Statement
statement
=
connection
.
createStatement
();
// get statement
//query or insert
// ...
connection
.
close
();
// put back to conneciton pool
}
```
> 通过 HikariDataSource.getConnection() 获取连接后,使用完成后需要调用 close() 方法,实际上它并不会关闭连接,只是放回连接池中。
> 更多 HikariCP 使用问题请查看[官方说明][5]
**Druid**
*
引入相应 Druid maven 依赖:
```
xml
<dependency>
<groupId>
com.alibaba
</groupId>
<artifactId>
druid
</artifactId>
<version>
1.1.20
</version>
</dependency>
```
*
使用示例如下:
```
java
public
static
void
main
(
String
[]
args
)
throws
Exception
{
Properties
properties
=
new
Properties
();
properties
.
put
(
"driverClassName"
,
"com.taosdata.jdbc.TSDBDriver"
);
properties
.
put
(
"url"
,
"jdbc:TAOS://127.0.0.1:6030/log"
);
properties
.
put
(
"username"
,
"root"
);
properties
.
put
(
"password"
,
"taosdata"
);
properties
.
put
(
"maxActive"
,
"10"
);
//maximum number of connection in the pool
properties
.
put
(
"initialSize"
,
"3"
);
//initial number of connection
properties
.
put
(
"maxWait"
,
"10000"
);
//maximum wait milliseconds for get connection from pool
properties
.
put
(
"minIdle"
,
"3"
);
//minimum number of connection in the pool
properties
.
put
(
"timeBetweenEvictionRunsMillis"
,
"3000"
);
// the interval milliseconds to test connection
properties
.
put
(
"minEvictableIdleTimeMillis"
,
"60000"
);
//the minimum milliseconds to keep idle
properties
.
put
(
"maxEvictableIdleTimeMillis"
,
"90000"
);
//the maximum milliseconds to keep idle
properties
.
put
(
"validationQuery"
,
"describe log.dn"
);
//validation query
properties
.
put
(
"testWhileIdle"
,
"true"
);
// test connection while idle
properties
.
put
(
"testOnBorrow"
,
"false"
);
// don't need while testWhileIdle is true
properties
.
put
(
"testOnReturn"
,
"false"
);
// don't need while testWhileIdle is true
//create druid datasource
DataSource
ds
=
DruidDataSourceFactory
.
createDataSource
(
properties
);
Connection
connection
=
ds
.
getConnection
();
// get connection
Statement
statement
=
connection
.
createStatement
();
// get statement
//query or insert
// ...
connection
.
close
();
// put back to conneciton pool
}
```
> 更多 druid 使用问题请查看[官方说明][6]
**注意事项**
*
TDengine
`v1.6.4.1`
版本开始提供了一个专门用于心跳检测的函数
`select server_status()`
,所以在使用连接池时推荐使用
`select server_status()`
进行 Validation Query。
如下所示,
`select server_status()`
执行成功会返回
`1`
。
```
shell
taos>
select
server_status
()
;
server_status
()
|
================
1 |
Query OK, 1 row
(
s
)
in
set
(
0.000141s
)
```
## 与框架使用
*
Spring JdbcTemplate 中使用 taos-jdbcdriver,可参考
[
SpringJdbcTemplate
][
11
]
*
Springboot + Mybatis 中使用,可参考
[
springbootdemo
][
12
]
## 常见问题
*
java.lang.UnsatisfiedLinkError: no taos in java.library.path
**原因**
:程序没有找到依赖的本地函数库 taos。
**解决方法**
:windows 下可以将 C:
\T
Dengine
\d
river
\t
aos.dll 拷贝到 C:
\W
indows
\S
ystem32
\
目录下,linux 下将建立如下软链
` ln -s /usr/local/taos/driver/libtaos.so.x.x.x.x /usr/lib/libtaos.so`
即可。
*
java.lang.UnsatisfiedLinkError: taos.dll Can't load AMD 64 bit on a IA 32-bit platform
**原因**
:目前 TDengine 只支持 64 位 JDK。
**解决方法**
:重新安装 64 位 JDK。
*
其它问题请参考
[
Issues
][
7
]
[
1
]:
https://search.maven.org/artifact/com.taosdata.jdbc/taos-jdbcdriver
[
2
]:
https://mvnrepository.com/artifact/com.taosdata.jdbc/taos-jdbcdriver
[
3
]:
https://github.com/taosdata/TDengine
[
4
]:
https://www.taosdata.com/blog/2019/12/03/jdbcdriver%e6%89%be%e4%b8%8d%e5%88%b0%e5%8a%a8%e6%80%81%e9%93%be%e6%8e%a5%e5%ba%93/
[
5
]:
https://github.com/brettwooldridge/HikariCP
[
6
]:
https://github.com/alibaba/druid
[
7
]:
https://github.com/taosdata/TDengine/issues
[
8
]:
https://search.maven.org/artifact/com.taosdata.jdbc/taos-jdbcdriver
[
9
]:
https://mvnrepository.com/artifact/com.taosdata.jdbc/taos-jdbcdriver
[
10
]:
https://maven.aliyun.com/mvn/search
[
11
]:
https://github.com/taosdata/TDengine/tree/develop/tests/examples/JDBC/SpringJdbcTemplate
[
12
]:
https://github.com/taosdata/TDengine/tree/develop/tests/examples/JDBC/springbootdemo
[
13
]:
https://www.taosdata.com/cn/documentation/administrator/#%E5%AE%A2%E6%88%B7%E7%AB%AF%E9%85%8D%E7%BD%AE
\ No newline at end of file
src/kit/shell/src/shellEngine.c
浏览文件 @
02e39aab
...
...
@@ -151,6 +151,8 @@ void shellReplaceCtrlChar(char *str) {
}
break
;
default:
*
pstr
=
*
str
;
pstr
++
;
break
;
}
ctrlOn
=
false
;
...
...
src/sdb/src/sdbEngine.c
浏览文件 @
02e39aab
...
...
@@ -171,6 +171,7 @@ int sdbInitTableByFile(SSdbTable *pTable) {
void
*
pMetaRow
=
NULL
;
int
total_size
=
0
;
int
real_size
=
0
;
int
maxAutoIndex
=
0
;
oldId
=
pTable
->
id
;
if
(
sdbOpenSdbFile
(
pTable
)
<
0
)
return
-
1
;
...
...
@@ -240,10 +241,18 @@ int sdbInitTableByFile(SSdbTable *pTable) {
rowMeta
.
rowSize
=
rowHead
->
rowSize
;
rowMeta
.
row
=
(
*
(
pTable
->
appTool
))(
SDB_TYPE_DECODE
,
NULL
,
rowHead
->
data
,
rowHead
->
rowSize
,
NULL
);
(
*
sdbAddIndexFp
[
pTable
->
keyType
])(
pTable
->
iHandle
,
rowMeta
.
row
,
&
rowMeta
);
if
(
pTable
->
keyType
==
SDB_KEYTYPE_AUTO
)
pTable
->
autoIndex
++
;
if
(
pTable
->
keyType
==
SDB_KEYTYPE_AUTO
)
{
pTable
->
autoIndex
++
;
maxAutoIndex
=
MAX
(
maxAutoIndex
,
*
(
int32_t
*
)
rowHead
->
data
);
}
pTable
->
numOfRows
++
;
}
}
else
{
// already exists
if
(
pTable
->
keyType
==
SDB_KEYTYPE_AUTO
)
{
pTable
->
autoIndex
++
;
maxAutoIndex
=
MAX
(
maxAutoIndex
,
*
(
int32_t
*
)
rowHead
->
data
);
}
if
(
rowHead
->
id
<
0
)
{
// Delete the object
(
*
sdbDeleteIndexFp
[
pTable
->
keyType
])(
pTable
->
iHandle
,
rowHead
->
data
);
(
*
(
pTable
->
appTool
))(
SDB_TYPE_DESTROY
,
pMetaRow
,
NULL
,
0
,
NULL
);
...
...
@@ -260,6 +269,10 @@ int sdbInitTableByFile(SSdbTable *pTable) {
if
(
pTable
->
id
<
abs
(
rowHead
->
id
))
pTable
->
id
=
abs
(
rowHead
->
id
);
}
if
(
pTable
->
keyType
==
SDB_KEYTYPE_AUTO
)
{
pTable
->
autoIndex
=
maxAutoIndex
;
}
sdbVersion
+=
(
pTable
->
id
-
oldId
);
if
(
numOfDels
>
pTable
->
maxRows
/
4
)
sdbSaveSnapShot
(
pTable
);
...
...
src/system/detail/src/mgmtMeter.c
浏览文件 @
02e39aab
...
...
@@ -233,6 +233,10 @@ void *mgmtMeterActionDelete(void *row, char *str, int size, int *ssize) {
pMeter
=
(
STabObj
*
)
row
;
if
(
mgmtIsNormalMeter
(
pMeter
))
{
if
(
pMeter
->
gid
.
vgId
==
0
)
{
return
NULL
;
}
pVgroup
=
mgmtGetVgroup
(
pMeter
->
gid
.
vgId
);
if
(
pVgroup
==
NULL
)
{
mError
(
"id:%s not in vgroup:%d"
,
pMeter
->
meterId
,
pMeter
->
gid
.
vgId
);
...
...
@@ -426,6 +430,7 @@ void mgmtAddMeterStatisticToAcct(STabObj *pMeter, SAcctObj *pAcct) {
int
mgmtInitMeters
()
{
void
*
pNode
=
NULL
;
void
*
pLastNode
=
NULL
;
SVgObj
*
pVgroup
=
NULL
;
STabObj
*
pMeter
=
NULL
;
STabObj
*
pMetric
=
NULL
;
...
...
@@ -451,21 +456,47 @@ int mgmtInitMeters() {
pNode
=
NULL
;
while
(
1
)
{
pLastNode
=
pNode
;
pNode
=
sdbFetchRow
(
meterSdb
,
pNode
,
(
void
**
)
&
pMeter
);
if
(
pMeter
==
NULL
)
break
;
pDb
=
mgmtGetDbByMeterId
(
pMeter
->
meterId
);
if
(
pDb
==
NULL
)
{
mError
(
"failed to get db: %s"
,
pMeter
->
meterId
);
mError
(
"meter:%s, failed to get db, discard it"
,
pMeter
->
meterId
,
pMeter
->
gid
.
vgId
,
pMeter
->
gid
.
sid
);
pMeter
->
gid
.
vgId
=
0
;
sdbDeleteRow
(
meterSdb
,
pMeter
);
pNode
=
pLastNode
;
continue
;
}
if
(
mgmtIsNormalMeter
(
pMeter
))
{
pVgroup
=
mgmtGetVgroup
(
pMeter
->
gid
.
vgId
);
if
(
pVgroup
==
NULL
||
pVgroup
->
meterList
==
NULL
)
{
mError
(
"failed to get vgroup:%i"
,
pMeter
->
gid
.
vgId
);
if
(
pVgroup
==
NULL
)
{
mError
(
"meter:%s, failed to get vgroup:%d sid:%d, discard it"
,
pMeter
->
meterId
,
pMeter
->
gid
.
vgId
,
pMeter
->
gid
.
sid
);
pMeter
->
gid
.
vgId
=
0
;
sdbDeleteRow
(
meterSdb
,
pMeter
);
pNode
=
pLastNode
;
continue
;
}
if
(
strcmp
(
pVgroup
->
dbName
,
pDb
->
name
)
!=
0
)
{
mError
(
"meter:%s, db:%s not match with vgroup:%d db:%s sid:%d, discard it"
,
pMeter
->
meterId
,
pDb
->
name
,
pMeter
->
gid
.
vgId
,
pVgroup
->
dbName
,
pMeter
->
gid
.
sid
);
pMeter
->
gid
.
vgId
=
0
;
sdbDeleteRow
(
meterSdb
,
pMeter
);
pNode
=
pLastNode
;
continue
;
}
if
(
pVgroup
->
meterList
==
NULL
)
{
mError
(
"meter:%s, vgroup:%d meterlist is null"
,
pMeter
->
meterId
,
pMeter
->
gid
.
vgId
);
pMeter
->
gid
.
vgId
=
0
;
sdbDeleteRow
(
meterSdb
,
pMeter
);
pNode
=
pLastNode
;
continue
;
}
pVgroup
->
meterList
[
pMeter
->
gid
.
sid
]
=
pMeter
;
taosIdPoolMarkStatus
(
pVgroup
->
idPool
,
pMeter
->
gid
.
sid
,
1
);
...
...
src/system/detail/src/vnodeFile.c
浏览文件 @
02e39aab
...
...
@@ -1254,6 +1254,7 @@ int vnodeWriteBlockToFile(SMeterObj *pObj, SCompBlock *pCompBlock, SData *data[]
offset
+=
(
cdata
[
i
]
->
len
+
sizeof
(
TSCKSUM
));
}
else
{
data
[
i
]
->
len
=
pObj
->
schema
[
i
].
bytes
*
points
;
fields
[
i
].
len
=
data
[
i
]
->
len
;
taosCalcChecksumAppend
(
0
,
(
uint8_t
*
)(
data
[
i
]
->
data
),
data
[
i
]
->
len
+
sizeof
(
TSCKSUM
));
offset
+=
(
data
[
i
]
->
len
+
sizeof
(
TSCKSUM
));
...
...
src/util/src/ttimer.c
浏览文件 @
02e39aab
...
...
@@ -254,13 +254,13 @@ static void processExpiredTimer(void* handle, void* arg) {
timer
->
executedBy
=
taosGetPthreadId
();
uint8_t
state
=
atomic_val_compare_exchange_8
(
&
timer
->
state
,
TIMER_STATE_WAITING
,
TIMER_STATE_EXPIRED
);
if
(
state
==
TIMER_STATE_WAITING
)
{
const
char
*
fmt
=
"%s timer[id="
PRIuPTR
", fp=%p, param=%p] execution start."
;
const
char
*
fmt
=
"%s timer[id=
%
"
PRIuPTR
", fp=%p, param=%p] execution start."
;
tmrTrace
(
fmt
,
timer
->
ctrl
->
label
,
timer
->
id
,
timer
->
fp
,
timer
->
param
);
(
*
timer
->
fp
)(
timer
->
param
,
(
tmr_h
)
timer
->
id
);
atomic_store_8
(
&
timer
->
state
,
TIMER_STATE_STOPPED
);
fmt
=
"%s timer[id="
PRIuPTR
", fp=%p, param=%p] execution end."
;
fmt
=
"%s timer[id=
%
"
PRIuPTR
", fp=%p, param=%p] execution end."
;
tmrTrace
(
fmt
,
timer
->
ctrl
->
label
,
timer
->
id
,
timer
->
fp
,
timer
->
param
);
}
removeTimer
(
timer
->
id
);
...
...
@@ -268,7 +268,7 @@ static void processExpiredTimer(void* handle, void* arg) {
}
static
void
addToExpired
(
tmr_obj_t
*
head
)
{
const
char
*
fmt
=
"%s adding expired timer[id="
PRIuPTR
", fp=%p, param=%p] to queue."
;
const
char
*
fmt
=
"%s adding expired timer[id=
%
"
PRIuPTR
", fp=%p, param=%p] to queue."
;
while
(
head
!=
NULL
)
{
uintptr_t
id
=
head
->
id
;
...
...
@@ -282,7 +282,7 @@ static void addToExpired(tmr_obj_t* head) {
schedMsg
.
thandle
=
NULL
;
taosScheduleTask
(
tmrQhandle
,
&
schedMsg
);
tmrTrace
(
"timer[id="
PRIuPTR
"] has been added to queue."
,
id
);
tmrTrace
(
"timer[id=
%
"
PRIuPTR
"] has been added to queue."
,
id
);
head
=
next
;
}
}
...
...
@@ -296,7 +296,7 @@ static uintptr_t doStartTimer(tmr_obj_t* timer, TAOS_TMR_CALLBACK fp, int msecon
timer
->
ctrl
=
ctrl
;
addTimer
(
timer
);
const
char
*
fmt
=
"%s timer[id="
PRIuPTR
", fp=%p, param=%p] started"
;
const
char
*
fmt
=
"%s timer[id=
%
"
PRIuPTR
", fp=%p, param=%p] started"
;
tmrTrace
(
fmt
,
ctrl
->
label
,
timer
->
id
,
timer
->
fp
,
timer
->
param
);
if
(
mseconds
==
0
)
{
...
...
@@ -389,7 +389,7 @@ static bool doStopTimer(tmr_obj_t* timer, uint8_t state) {
// we cannot guarantee the thread safety of the timr in all other cases.
reusable
=
true
;
}
const
char
*
fmt
=
"%s timer[id="
PRIuPTR
", fp=%p, param=%p] is cancelled."
;
const
char
*
fmt
=
"%s timer[id=
%
"
PRIuPTR
", fp=%p, param=%p] is cancelled."
;
tmrTrace
(
fmt
,
timer
->
ctrl
->
label
,
timer
->
id
,
timer
->
fp
,
timer
->
param
);
return
reusable
;
}
...
...
@@ -409,7 +409,7 @@ static bool doStopTimer(tmr_obj_t* timer, uint8_t state) {
// timer callback is executing in another thread, we SHOULD wait it to stop,
// BUT this may result in dead lock if current thread are holding a lock which
// the timer callback need to acquire. so, we HAVE TO return directly.
const
char
*
fmt
=
"%s timer[id="
PRIuPTR
", fp=%p, param=%p] is executing and cannot be stopped."
;
const
char
*
fmt
=
"%s timer[id=
%
"
PRIuPTR
", fp=%p, param=%p] is executing and cannot be stopped."
;
tmrTrace
(
fmt
,
timer
->
ctrl
->
label
,
timer
->
id
,
timer
->
fp
,
timer
->
param
);
return
false
;
}
...
...
@@ -419,7 +419,7 @@ bool taosTmrStop(tmr_h timerId) {
tmr_obj_t
*
timer
=
findTimer
(
id
);
if
(
timer
==
NULL
)
{
tmrTrace
(
"timer[id="
PRIuPTR
"] does not exist"
,
id
);
tmrTrace
(
"timer[id=
%
"
PRIuPTR
"] does not exist"
,
id
);
return
false
;
}
...
...
@@ -446,7 +446,7 @@ bool taosTmrReset(TAOS_TMR_CALLBACK fp, int mseconds, void* param, void* handle,
bool
stopped
=
false
;
tmr_obj_t
*
timer
=
findTimer
(
id
);
if
(
timer
==
NULL
)
{
tmrTrace
(
"%s timer[id="
PRIuPTR
"] does not exist"
,
ctrl
->
label
,
id
);
tmrTrace
(
"%s timer[id=
%
"
PRIuPTR
"] does not exist"
,
ctrl
->
label
,
id
);
}
else
{
uint8_t
state
=
atomic_val_compare_exchange_8
(
&
timer
->
state
,
TIMER_STATE_WAITING
,
TIMER_STATE_CANCELED
);
if
(
!
doStopTimer
(
timer
,
state
))
{
...
...
@@ -461,7 +461,7 @@ bool taosTmrReset(TAOS_TMR_CALLBACK fp, int mseconds, void* param, void* handle,
return
stopped
;
}
tmrTrace
(
"%s timer[id="
PRIuPTR
"] is reused"
,
ctrl
->
label
,
timer
->
id
);
tmrTrace
(
"%s timer[id=
%
"
PRIuPTR
"] is reused"
,
ctrl
->
label
,
timer
->
id
);
// wait until there's no other reference to this timer,
// so that we can reuse this timer safely.
...
...
src/util/src/ttokenizer.c
浏览文件 @
02e39aab
...
...
@@ -418,7 +418,12 @@ uint32_t tSQLGetToken(char* z, uint32_t* tokenType) {
int
delim
=
z
[
0
];
bool
strEnd
=
false
;
for
(
i
=
1
;
z
[
i
];
i
++
)
{
if
(
z
[
i
]
==
delim
)
{
if
(
z
[
i
]
==
'\\'
)
{
i
++
;
continue
;
}
if
(
z
[
i
]
==
delim
)
{
if
(
z
[
i
+
1
]
==
delim
)
{
i
++
;
}
else
{
...
...
@@ -427,6 +432,7 @@ uint32_t tSQLGetToken(char* z, uint32_t* tokenType) {
}
}
}
if
(
z
[
i
])
i
++
;
if
(
strEnd
)
{
...
...
tests/examples/JDBC/readme.md
→
tests/examples/JDBC/
JDBCDemo/
readme.md
浏览文件 @
02e39aab
文件已移动
tests/examples/JDBC/SpringJdbcTemplate/.gitignore
0 → 100644
浏览文件 @
02e39aab
HELP.md
target/
.mvn/
!**/src/main/**
!**/src/test/**
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
### VS Code ###
.vscode/
tests/examples/JDBC/SpringJdbcTemplate/pom.xml
0 → 100644
浏览文件 @
02e39aab
<?xml version="1.0" encoding="UTF-8"?>
<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.0
</modelVersion>
<groupId>
com.taosdata.jdbc
</groupId>
<artifactId>
SpringJdbcTemplate
</artifactId>
<version>
1.0-SNAPSHOT
</version>
<name>
SpringJdbcTemplate
</name>
<url>
http://www.taosdata.com
</url>
<properties>
<project.build.sourceEncoding>
UTF-8
</project.build.sourceEncoding>
<maven.compiler.source>
1.8
</maven.compiler.source>
<maven.compiler.target>
1.8
</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>
org.springframework
</groupId>
<artifactId>
spring-context
</artifactId>
<version>
4.3.2.RELEASE
</version>
</dependency>
<dependency>
<groupId>
org.springframework
</groupId>
<artifactId>
spring-jdbc
</artifactId>
<version>
4.3.2.RELEASE
</version>
</dependency>
<dependency>
<groupId>
junit
</groupId>
<artifactId>
junit
</artifactId>
<version>
4.11
</version>
<scope>
test
</scope>
</dependency>
<dependency>
<groupId>
com.taosdata.jdbc
</groupId>
<artifactId>
taos-jdbcdriver
</artifactId>
<version>
1.0.3
</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>
maven-compiler-plugin
</artifactId>
<version>
3.8.0
</version>
<configuration>
<source>
1.8
</source>
<target>
1.8
</target>
</configuration>
</plugin>
<plugin>
<groupId>
org.apache.maven.plugins
</groupId>
<artifactId>
maven-assembly-plugin
</artifactId>
<version>
3.1.0
</version>
<configuration>
<archive>
<manifest>
<mainClass>
com.taosdata.jdbc.App
</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>
jar-with-dependencies
</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>
make-assembly
</id>
<phase>
package
</phase>
<goals>
<goal>
single
</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
tests/examples/JDBC/SpringJdbcTemplate/readme.md
0 → 100644
浏览文件 @
02e39aab
## TDengine Spring JDBC Template Demo
`Spring JDBC Template`
简化了原生 JDBC Connection 获取释放等操作,使得操作数据库更加方便。
### 配置
修改
`src/main/resources/applicationContext.xml`
文件中 TDengine 的配置信息:
```
xml
<bean
id=
"dataSource"
class=
"org.springframework.jdbc.datasource.DriverManagerDataSource"
>
<property
name=
"driverClassName"
value=
"com.taosdata.jdbc.TSDBDriver"
></property>
<property
name=
"url"
value=
"jdbc:TAOS://127.0.0.1:6030/log"
></property>
<property
name=
"username"
value=
"root"
></property>
<property
name=
"password"
value=
"taosdata"
></property>
</bean>
<bean
id =
"jdbcTemplate"
class=
"org.springframework.jdbc.core.JdbcTemplate"
>
<property
name=
"dataSource"
ref =
"dataSource"
></property>
</bean>
```
### 打包运行
进入
`TDengine/tests/examples/JDBC/SpringJdbcTemplate`
目录下,执行以下命令可以生成可执行 jar 包。
```
shell
mvn clean package
```
打包成功之后,进入
`target/`
目录下,执行以下命令就可运行测试:
```
shell
java
-jar
SpringJdbcTemplate-1.0-SNAPSHOT-jar-with-dependencies.jar
```
\ No newline at end of file
tests/examples/JDBC/SpringJdbcTemplate/src/main/java/com/taosdata/jdbc/App.java
0 → 100644
浏览文件 @
02e39aab
package
com.taosdata.jdbc
;
import
org.springframework.context.ApplicationContext
;
import
org.springframework.context.support.ClassPathXmlApplicationContext
;
import
org.springframework.jdbc.core.JdbcTemplate
;
import
org.springframework.util.CollectionUtils
;
import
java.util.List
;
import
java.util.Map
;
public
class
App
{
public
static
void
main
(
String
[]
args
)
{
ApplicationContext
ctx
=
new
ClassPathXmlApplicationContext
(
"applicationContext.xml"
);
JdbcTemplate
jdbcTemplate
=
(
JdbcTemplate
)
ctx
.
getBean
(
"jdbcTemplate"
);
// create database
jdbcTemplate
.
execute
(
"create database if not exists db "
);
// create table
jdbcTemplate
.
execute
(
"create table if not exists db.tb (ts timestamp, temperature int, humidity float)"
);
String
insertSql
=
"insert into db.tb values(now, 23, 10.3) (now + 1s, 20, 9.3)"
;
// insert rows
int
affectedRows
=
jdbcTemplate
.
update
(
insertSql
);
System
.
out
.
println
(
"insert success "
+
affectedRows
+
" rows."
);
// query for list
List
<
Map
<
String
,
Object
>>
resultList
=
jdbcTemplate
.
queryForList
(
"select * from db.tb"
);
if
(!
CollectionUtils
.
isEmpty
(
resultList
)){
for
(
Map
<
String
,
Object
>
row
:
resultList
){
System
.
out
.
printf
(
"%s, %d, %s\n"
,
row
.
get
(
"ts"
),
row
.
get
(
"temperature"
),
row
.
get
(
"humidity"
));
}
}
}
}
tests/examples/JDBC/SpringJdbcTemplate/src/main/resources/applicationContext.xml
0 → 100644
浏览文件 @
02e39aab
<?xml version="1.0" encoding="utf-8"?>
<beans
xmlns=
"http://www.springframework.org/schema/beans"
xmlns:context=
"http://www.springframework.org/schema/context"
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx=
"http://www.springframework.org/schema/tx"
xsi:schemaLocation=
"
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
"
default-autowire=
"byName"
>
<bean
id=
"dataSource"
class=
"org.springframework.jdbc.datasource.DriverManagerDataSource"
>
<property
name=
"driverClassName"
value=
"com.taosdata.jdbc.TSDBDriver"
></property>
<property
name=
"url"
value=
"jdbc:TAOS://127.0.0.1:6030/log"
></property>
<property
name=
"username"
value=
"root"
></property>
<property
name=
"password"
value=
"taosdata"
></property>
</bean>
<bean
id =
"jdbcTemplate"
class=
"org.springframework.jdbc.core.JdbcTemplate"
>
<property
name=
"dataSource"
ref =
"dataSource"
></property>
</bean>
</beans>
tests/examples/JDBC/SpringJdbcTemplate/src/test/java/com/taosdata/jdbc/AppTest.java
0 → 100644
浏览文件 @
02e39aab
package
com.taosdata.jdbc
;
import
static
org
.
junit
.
Assert
.
assertTrue
;
import
org.junit.Test
;
/**
* Unit test for simple App.
*/
public
class
AppTest
{
/**
* Rigorous Test :-)
*/
@Test
public
void
shouldAnswerWithTrue
()
{
assertTrue
(
true
);
}
}
tests/examples/JDBC/springbootdemo/.gitignore
0 → 100644
浏览文件 @
02e39aab
.mvn/
target/
!**/src/main/**
!**/src/test/**
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
### VS Code ###
.vscode/
tests/examples/JDBC/springbootdemo/.mvn/wrapper/MavenWrapperDownloader.java
0 → 100644
浏览文件 @
02e39aab
/*
* Copyright 2012-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import
java.net.*
;
import
java.io.*
;
import
java.nio.channels.*
;
import
java.util.Properties
;
public
class
MavenWrapperDownloader
{
private
static
final
String
WRAPPER_VERSION
=
"0.5.5"
;
/**
* Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided.
*/
private
static
final
String
DEFAULT_DOWNLOAD_URL
=
"https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/"
+
WRAPPER_VERSION
+
"/maven-wrapper-"
+
WRAPPER_VERSION
+
".jar"
;
/**
* Path to the maven-wrapper.properties file, which might contain a downloadUrl property to
* use instead of the default one.
*/
private
static
final
String
MAVEN_WRAPPER_PROPERTIES_PATH
=
".mvn/wrapper/maven-wrapper.properties"
;
/**
* Path where the maven-wrapper.jar will be saved to.
*/
private
static
final
String
MAVEN_WRAPPER_JAR_PATH
=
".mvn/wrapper/maven-wrapper.jar"
;
/**
* Name of the property which should be used to override the default download url for the wrapper.
*/
private
static
final
String
PROPERTY_NAME_WRAPPER_URL
=
"wrapperUrl"
;
public
static
void
main
(
String
args
[])
{
System
.
out
.
println
(
"- Downloader started"
);
File
baseDirectory
=
new
File
(
args
[
0
]);
System
.
out
.
println
(
"- Using base directory: "
+
baseDirectory
.
getAbsolutePath
());
// If the maven-wrapper.properties exists, read it and check if it contains a custom
// wrapperUrl parameter.
File
mavenWrapperPropertyFile
=
new
File
(
baseDirectory
,
MAVEN_WRAPPER_PROPERTIES_PATH
);
String
url
=
DEFAULT_DOWNLOAD_URL
;
if
(
mavenWrapperPropertyFile
.
exists
())
{
FileInputStream
mavenWrapperPropertyFileInputStream
=
null
;
try
{
mavenWrapperPropertyFileInputStream
=
new
FileInputStream
(
mavenWrapperPropertyFile
);
Properties
mavenWrapperProperties
=
new
Properties
();
mavenWrapperProperties
.
load
(
mavenWrapperPropertyFileInputStream
);
url
=
mavenWrapperProperties
.
getProperty
(
PROPERTY_NAME_WRAPPER_URL
,
url
);
}
catch
(
IOException
e
)
{
System
.
out
.
println
(
"- ERROR loading '"
+
MAVEN_WRAPPER_PROPERTIES_PATH
+
"'"
);
}
finally
{
try
{
if
(
mavenWrapperPropertyFileInputStream
!=
null
)
{
mavenWrapperPropertyFileInputStream
.
close
();
}
}
catch
(
IOException
e
)
{
// Ignore ...
}
}
}
System
.
out
.
println
(
"- Downloading from: "
+
url
);
File
outputFile
=
new
File
(
baseDirectory
.
getAbsolutePath
(),
MAVEN_WRAPPER_JAR_PATH
);
if
(!
outputFile
.
getParentFile
().
exists
())
{
if
(!
outputFile
.
getParentFile
().
mkdirs
())
{
System
.
out
.
println
(
"- ERROR creating output directory '"
+
outputFile
.
getParentFile
().
getAbsolutePath
()
+
"'"
);
}
}
System
.
out
.
println
(
"- Downloading to: "
+
outputFile
.
getAbsolutePath
());
try
{
downloadFileFromURL
(
url
,
outputFile
);
System
.
out
.
println
(
"Done"
);
System
.
exit
(
0
);
}
catch
(
Throwable
e
)
{
System
.
out
.
println
(
"- Error downloading"
);
e
.
printStackTrace
();
System
.
exit
(
1
);
}
}
private
static
void
downloadFileFromURL
(
String
urlString
,
File
destination
)
throws
Exception
{
if
(
System
.
getenv
(
"MVNW_USERNAME"
)
!=
null
&&
System
.
getenv
(
"MVNW_PASSWORD"
)
!=
null
)
{
String
username
=
System
.
getenv
(
"MVNW_USERNAME"
);
char
[]
password
=
System
.
getenv
(
"MVNW_PASSWORD"
).
toCharArray
();
Authenticator
.
setDefault
(
new
Authenticator
()
{
@Override
protected
PasswordAuthentication
getPasswordAuthentication
()
{
return
new
PasswordAuthentication
(
username
,
password
);
}
});
}
URL
website
=
new
URL
(
urlString
);
ReadableByteChannel
rbc
;
rbc
=
Channels
.
newChannel
(
website
.
openStream
());
FileOutputStream
fos
=
new
FileOutputStream
(
destination
);
fos
.
getChannel
().
transferFrom
(
rbc
,
0
,
Long
.
MAX_VALUE
);
fos
.
close
();
rbc
.
close
();
}
}
tests/examples/JDBC/springbootdemo/.mvn/wrapper/maven-wrapper.jar
0 → 100644
浏览文件 @
02e39aab
文件已添加
tests/examples/JDBC/springbootdemo/.mvn/wrapper/maven-wrapper.properties
0 → 100644
浏览文件 @
02e39aab
distributionUrl
=
https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.2/apache-maven-3.6.2-bin.zip
wrapperUrl
=
https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar
tests/examples/JDBC/springbootdemo/mvnw
0 → 100755
浏览文件 @
02e39aab
#!/bin/sh
# ----------------------------------------------------------------------------
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
# ----------------------------------------------------------------------------
# ----------------------------------------------------------------------------
# Maven2 Start Up Batch script
#
# Required ENV vars:
# ------------------
# JAVA_HOME - location of a JDK home dir
#
# Optional ENV vars
# -----------------
# M2_HOME - location of maven2's installed home dir
# MAVEN_OPTS - parameters passed to the Java VM when running Maven
# e.g. to debug Maven itself, use
# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
# ----------------------------------------------------------------------------
if
[
-z
"
$MAVEN_SKIP_RC
"
]
;
then
if
[
-f
/etc/mavenrc
]
;
then
.
/etc/mavenrc
fi
if
[
-f
"
$HOME
/.mavenrc"
]
;
then
.
"
$HOME
/.mavenrc"
fi
fi
# OS specific support. $var _must_ be set to either true or false.
cygwin
=
false
;
darwin
=
false
;
mingw
=
false
case
"
`
uname
`
"
in
CYGWIN
*
)
cygwin
=
true
;;
MINGW
*
)
mingw
=
true
;;
Darwin
*
)
darwin
=
true
# Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
# See https://developer.apple.com/library/mac/qa/qa1170/_index.html
if
[
-z
"
$JAVA_HOME
"
]
;
then
if
[
-x
"/usr/libexec/java_home"
]
;
then
export
JAVA_HOME
=
"
`
/usr/libexec/java_home
`
"
else
export
JAVA_HOME
=
"/Library/Java/Home"
fi
fi
;;
esac
if
[
-z
"
$JAVA_HOME
"
]
;
then
if
[
-r
/etc/gentoo-release
]
;
then
JAVA_HOME
=
`
java-config
--jre-home
`
fi
fi
if
[
-z
"
$M2_HOME
"
]
;
then
## resolve links - $0 may be a link to maven's home
PRG
=
"
$0
"
# need this for relative symlinks
while
[
-h
"
$PRG
"
]
;
do
ls
=
`
ls
-ld
"
$PRG
"
`
link
=
`
expr
"
$ls
"
:
'.*-> \(.*\)$'
`
if
expr
"
$link
"
:
'/.*'
>
/dev/null
;
then
PRG
=
"
$link
"
else
PRG
=
"
`
dirname
"
$PRG
"
`
/
$link
"
fi
done
saveddir
=
`
pwd
`
M2_HOME
=
`
dirname
"
$PRG
"
`
/..
# make it fully qualified
M2_HOME
=
`
cd
"
$M2_HOME
"
&&
pwd
`
cd
"
$saveddir
"
# echo Using m2 at $M2_HOME
fi
# For Cygwin, ensure paths are in UNIX format before anything is touched
if
$cygwin
;
then
[
-n
"
$M2_HOME
"
]
&&
M2_HOME
=
`
cygpath
--unix
"
$M2_HOME
"
`
[
-n
"
$JAVA_HOME
"
]
&&
JAVA_HOME
=
`
cygpath
--unix
"
$JAVA_HOME
"
`
[
-n
"
$CLASSPATH
"
]
&&
CLASSPATH
=
`
cygpath
--path
--unix
"
$CLASSPATH
"
`
fi
# For Mingw, ensure paths are in UNIX format before anything is touched
if
$mingw
;
then
[
-n
"
$M2_HOME
"
]
&&
M2_HOME
=
"
`
(
cd
"
$M2_HOME
"
;
pwd
)
`
"
[
-n
"
$JAVA_HOME
"
]
&&
JAVA_HOME
=
"
`
(
cd
"
$JAVA_HOME
"
;
pwd
)
`
"
fi
if
[
-z
"
$JAVA_HOME
"
]
;
then
javaExecutable
=
"
`
which javac
`
"
if
[
-n
"
$javaExecutable
"
]
&&
!
[
"
`
expr
\"
$javaExecutable
\"
:
'\([^ ]*\)'
`
"
=
"no"
]
;
then
# readlink(1) is not available as standard on Solaris 10.
readLink
=
`
which
readlink
`
if
[
!
`
expr
"
$readLink
"
:
'\([^ ]*\)'
`
=
"no"
]
;
then
if
$darwin
;
then
javaHome
=
"
`
dirname
\"
$javaExecutable
\"
`
"
javaExecutable
=
"
`
cd
\"
$javaHome
\"
&&
pwd
-P
`
/javac"
else
javaExecutable
=
"
`
readlink
-f
\"
$javaExecutable
\"
`
"
fi
javaHome
=
"
`
dirname
\"
$javaExecutable
\"
`
"
javaHome
=
`
expr
"
$javaHome
"
:
'\(.*\)/bin'
`
JAVA_HOME
=
"
$javaHome
"
export
JAVA_HOME
fi
fi
fi
if
[
-z
"
$JAVACMD
"
]
;
then
if
[
-n
"
$JAVA_HOME
"
]
;
then
if
[
-x
"
$JAVA_HOME
/jre/sh/java"
]
;
then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD
=
"
$JAVA_HOME
/jre/sh/java"
else
JAVACMD
=
"
$JAVA_HOME
/bin/java"
fi
else
JAVACMD
=
"
`
which java
`
"
fi
fi
if
[
!
-x
"
$JAVACMD
"
]
;
then
echo
"Error: JAVA_HOME is not defined correctly."
>
&2
echo
" We cannot execute
$JAVACMD
"
>
&2
exit
1
fi
if
[
-z
"
$JAVA_HOME
"
]
;
then
echo
"Warning: JAVA_HOME environment variable is not set."
fi
CLASSWORLDS_LAUNCHER
=
org.codehaus.plexus.classworlds.launcher.Launcher
# traverses directory structure from process work directory to filesystem root
# first directory with .mvn subdirectory is considered project base directory
find_maven_basedir
()
{
if
[
-z
"
$1
"
]
then
echo
"Path not specified to find_maven_basedir"
return
1
fi
basedir
=
"
$1
"
wdir
=
"
$1
"
while
[
"
$wdir
"
!=
'/'
]
;
do
if
[
-d
"
$wdir
"
/.mvn
]
;
then
basedir
=
$wdir
break
fi
# workaround for JBEAP-8937 (on Solaris 10/Sparc)
if
[
-d
"
${
wdir
}
"
]
;
then
wdir
=
`
cd
"
$wdir
/.."
;
pwd
`
fi
# end of workaround
done
echo
"
${
basedir
}
"
}
# concatenates all lines of a file
concat_lines
()
{
if
[
-f
"
$1
"
]
;
then
echo
"
$(
tr
-s
'\n'
' '
<
"
$1
"
)
"
fi
}
BASE_DIR
=
`
find_maven_basedir
"
$(
pwd
)
"
`
if
[
-z
"
$BASE_DIR
"
]
;
then
exit
1
;
fi
##########################################################################################
# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
# This allows using the maven wrapper in projects that prohibit checking in binary data.
##########################################################################################
if
[
-r
"
$BASE_DIR
/.mvn/wrapper/maven-wrapper.jar"
]
;
then
if
[
"
$MVNW_VERBOSE
"
=
true
]
;
then
echo
"Found .mvn/wrapper/maven-wrapper.jar"
fi
else
if
[
"
$MVNW_VERBOSE
"
=
true
]
;
then
echo
"Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
fi
if
[
-n
"
$MVNW_REPOURL
"
]
;
then
jarUrl
=
"
$MVNW_REPOURL
/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar"
else
jarUrl
=
"https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar"
fi
while
IFS
=
"="
read
key value
;
do
case
"
$key
"
in
(
wrapperUrl
)
jarUrl
=
"
$value
"
;
break
;;
esac
done
<
"
$BASE_DIR
/.mvn/wrapper/maven-wrapper.properties"
if
[
"
$MVNW_VERBOSE
"
=
true
]
;
then
echo
"Downloading from:
$jarUrl
"
fi
wrapperJarPath
=
"
$BASE_DIR
/.mvn/wrapper/maven-wrapper.jar"
if
$cygwin
;
then
wrapperJarPath
=
`
cygpath
--path
--windows
"
$wrapperJarPath
"
`
fi
if
command
-v
wget
>
/dev/null
;
then
if
[
"
$MVNW_VERBOSE
"
=
true
]
;
then
echo
"Found wget ... using wget"
fi
if
[
-z
"
$MVNW_USERNAME
"
]
||
[
-z
"
$MVNW_PASSWORD
"
]
;
then
wget
"
$jarUrl
"
-O
"
$wrapperJarPath
"
else
wget
--http-user
=
$MVNW_USERNAME
--http-password
=
$MVNW_PASSWORD
"
$jarUrl
"
-O
"
$wrapperJarPath
"
fi
elif
command
-v
curl
>
/dev/null
;
then
if
[
"
$MVNW_VERBOSE
"
=
true
]
;
then
echo
"Found curl ... using curl"
fi
if
[
-z
"
$MVNW_USERNAME
"
]
||
[
-z
"
$MVNW_PASSWORD
"
]
;
then
curl
-o
"
$wrapperJarPath
"
"
$jarUrl
"
-f
else
curl
--user
$MVNW_USERNAME
:
$MVNW_PASSWORD
-o
"
$wrapperJarPath
"
"
$jarUrl
"
-f
fi
else
if
[
"
$MVNW_VERBOSE
"
=
true
]
;
then
echo
"Falling back to using Java to download"
fi
javaClass
=
"
$BASE_DIR
/.mvn/wrapper/MavenWrapperDownloader.java"
# For Cygwin, switch paths to Windows format before running javac
if
$cygwin
;
then
javaClass
=
`
cygpath
--path
--windows
"
$javaClass
"
`
fi
if
[
-e
"
$javaClass
"
]
;
then
if
[
!
-e
"
$BASE_DIR
/.mvn/wrapper/MavenWrapperDownloader.class"
]
;
then
if
[
"
$MVNW_VERBOSE
"
=
true
]
;
then
echo
" - Compiling MavenWrapperDownloader.java ..."
fi
# Compiling the Java class
(
"
$JAVA_HOME
/bin/javac"
"
$javaClass
"
)
fi
if
[
-e
"
$BASE_DIR
/.mvn/wrapper/MavenWrapperDownloader.class"
]
;
then
# Running the downloader
if
[
"
$MVNW_VERBOSE
"
=
true
]
;
then
echo
" - Running MavenWrapperDownloader.java ..."
fi
(
"
$JAVA_HOME
/bin/java"
-cp
.mvn/wrapper MavenWrapperDownloader
"
$MAVEN_PROJECTBASEDIR
"
)
fi
fi
fi
fi
##########################################################################################
# End of extension
##########################################################################################
export
MAVEN_PROJECTBASEDIR
=
${
MAVEN_BASEDIR
:-
"
$BASE_DIR
"
}
if
[
"
$MVNW_VERBOSE
"
=
true
]
;
then
echo
$MAVEN_PROJECTBASEDIR
fi
MAVEN_OPTS
=
"
$(
concat_lines
"
$MAVEN_PROJECTBASEDIR
/.mvn/jvm.config"
)
$MAVEN_OPTS
"
# For Cygwin, switch paths to Windows format before running java
if
$cygwin
;
then
[
-n
"
$M2_HOME
"
]
&&
M2_HOME
=
`
cygpath
--path
--windows
"
$M2_HOME
"
`
[
-n
"
$JAVA_HOME
"
]
&&
JAVA_HOME
=
`
cygpath
--path
--windows
"
$JAVA_HOME
"
`
[
-n
"
$CLASSPATH
"
]
&&
CLASSPATH
=
`
cygpath
--path
--windows
"
$CLASSPATH
"
`
[
-n
"
$MAVEN_PROJECTBASEDIR
"
]
&&
MAVEN_PROJECTBASEDIR
=
`
cygpath
--path
--windows
"
$MAVEN_PROJECTBASEDIR
"
`
fi
# Provide a "standardized" way to retrieve the CLI args that will
# work with both Windows and non-Windows executions.
MAVEN_CMD_LINE_ARGS
=
"
$MAVEN_CONFIG
$@
"
export
MAVEN_CMD_LINE_ARGS
WRAPPER_LAUNCHER
=
org.apache.maven.wrapper.MavenWrapperMain
exec
"
$JAVACMD
"
\
$MAVEN_OPTS
\
-classpath
"
$MAVEN_PROJECTBASEDIR
/.mvn/wrapper/maven-wrapper.jar"
\
"-Dmaven.home=
${
M2_HOME
}
"
"-Dmaven.multiModuleProjectDirectory=
${
MAVEN_PROJECTBASEDIR
}
"
\
${
WRAPPER_LAUNCHER
}
$MAVEN_CONFIG
"
$@
"
tests/examples/JDBC/springbootdemo/mvnw.cmd
0 → 100644
浏览文件 @
02e39aab
@REM ----------------------------------------------------------------------------
@REM Licensed to the Apache Software Foundation (ASF) under one
@REM or more contributor license agreements. See the NOTICE file
@REM distributed with this work for additional information
@REM regarding copyright ownership. The ASF licenses this file
@REM to you under the Apache License, Version 2.0 (the
@REM "License"); you may not use this file except in compliance
@REM with the License. You may obtain a copy of the License at
@REM
@REM https://www.apache.org/licenses/LICENSE-2.0
@REM
@REM Unless required by applicable law or agreed to in writing,
@REM software distributed under the License is distributed on an
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@REM KIND, either express or implied. See the License for the
@REM specific language governing permissions and limitations
@REM under the License.
@REM ----------------------------------------------------------------------------
@REM ----------------------------------------------------------------------------
@REM Maven2 Start Up Batch script
@REM
@REM Required ENV vars:
@REM JAVA_HOME - location of a JDK home dir
@REM
@REM Optional ENV vars
@REM M2_HOME - location of maven2's installed home dir
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
@REM e.g. to debug Maven itself, use
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
@REM ----------------------------------------------------------------------------
@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
@echo
off
@REM set title of command window
title
%
0
@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
@if
"
%MAVEN_BATCH_ECHO%
"
==
"on"
echo
%MAVEN_BATCH_ECHO%
@REM set %HOME% to equivalent of $HOME
if
"
%HOME%
"
==
""
(
set
"HOME=
%HOMEDRIVE%%
HOMEPATH
%
"
)
@REM Execute a user defined script before this one
if
not
"
%MAVEN_SKIP_RC%
"
==
""
goto
skipRcPre
@REM check for pre script, once with legacy .bat ending and once with .cmd ending
if
exist
"
%HOME%
\mavenrc_pre.bat"
call
"
%HOME%
\mavenrc_pre.bat"
if
exist
"
%HOME%
\mavenrc_pre.cmd"
call
"
%HOME%
\mavenrc_pre.cmd"
:skipRcPre
@setlocal
set
ERROR_CODE
=
0
@REM To isolate internal variables from possible post scripts, we use another setlocal
@setlocal
@REM ==== START VALIDATION ====
if
not
"
%JAVA_HOME%
"
==
""
goto
OkJHome
echo
.
echo
Error
:
JAVA_HOME
not
found
in
your
environment
.
>&
2
echo
Please
set
the
JAVA_HOME
variable
in
your
environment
to
match
the
>&
2
echo
location
of
your
Java
installation
.
>&
2
echo
.
goto
error
:OkJHome
if
exist
"
%JAVA_HOME%
\bin\java.exe"
goto
init
echo
.
echo
Error
:
JAVA_HOME
is
set
to
an
invalid
directory
.
>&
2
echo
JAVA_HOME
=
"
%JAVA_HOME%
"
>&
2
echo
Please
set
the
JAVA_HOME
variable
in
your
environment
to
match
the
>&
2
echo
location
of
your
Java
installation
.
>&
2
echo
.
goto
error
@REM ==== END VALIDATION ====
:init
@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
@REM Fallback to current working directory if not found.
set
MAVEN_PROJECTBASEDIR
=
%MAVEN_BASEDIR%
IF
NOT
"
%MAVEN_PROJECTBASEDIR%
"
==
""
goto
endDetectBaseDir
set
EXEC_DIR
=
%CD%
set
WDIR
=
%EXEC_DIR%
:findBaseDir
IF
EXIST
"
%WDIR%
"
\.mvn
goto
baseDirFound
cd
..
IF
"
%WDIR%
"
==
"
%CD%
"
goto
baseDirNotFound
set
WDIR
=
%CD%
goto
findBaseDir
:baseDirFound
set
MAVEN_PROJECTBASEDIR
=
%WDIR%
cd
"
%EXEC_DIR%
"
goto
endDetectBaseDir
:baseDirNotFound
set
MAVEN_PROJECTBASEDIR
=
%EXEC_DIR%
cd
"
%EXEC_DIR%
"
:endDetectBaseDir
IF
NOT
EXIST
"
%MAVEN_PROJECTBASEDIR%
\.mvn\jvm.config"
goto
endReadAdditionalConfig
@setlocal
EnableExtensions
EnableDelayedExpansion
for
/F
"usebackq delims="
%%a
in
(
"
%MAVEN_PROJECTBASEDIR%
\.mvn\jvm.config"
)
do
set
JVM_CONFIG_MAVEN_PROPS
=
!JVM_CONFIG_MAVEN_PROPS!
%%a
@endlocal
&
set
JVM_CONFIG_MAVEN_PROPS
=
%JVM_CONFIG_MAVEN_PROPS%
:endReadAdditionalConfig
SET
MAVEN_JAVA_EXE
=
"
%JAVA_HOME%
\bin\java.exe"
set
WRAPPER_JAR
=
"
%MAVEN_PROJECTBASEDIR%
\.mvn\wrapper\maven-wrapper.jar"
set
WRAPPER_LAUNCHER
=
org
.apache.maven.wrapper.MavenWrapperMain
set
DOWNLOAD_URL
=
"https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar"
FOR
/F
"tokens=1,2 delims=="
%%A
IN
(
"
%MAVEN_PROJECTBASEDIR%
\.mvn\wrapper\maven-wrapper.properties"
)
DO
(
IF
"
%%A
"
==
"wrapperUrl"
SET
DOWNLOAD_URL
=
%%B
)
@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
if
exist
%WRAPPER_JAR%
(
if
"
%MVNW_VERBOSE%
"
==
"true"
(
echo
Found
%WRAPPER_JAR%
)
)
else
(
if
not
"
%MVNW_REPOURL%
"
==
""
(
SET
DOWNLOAD_URL
=
"
%MVNW_REPOURL%
/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar"
)
if
"
%MVNW_VERBOSE%
"
==
"true"
(
echo
Couldn
't find
%WRAPPER_JAR%
, downloading it ...
echo Downloading from:
%DOWNLOAD_URL%
)
powershell -Command "&{"
^
"$webclient = new-object System.Net.WebClient;"
^
"if (-not ([string]::IsNullOrEmpty('
%MVNW_USERNAME%
') -and [string]::IsNullOrEmpty('
%MVNW_PASSWORD%
'))) {"
^
"$webclient.Credentials = new-object System.Net.NetworkCredential('
%MVNW_USERNAME%
', '
%MVNW_PASSWORD%
');"
^
"}"
^
"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('
%DOWNLOAD_URL%
', '
%WRAPPER_JAR%
')"
^
"}"
if "
%MVNW_VERBOSE%
" == "true" (
echo Finished downloading
%WRAPPER_JAR%
)
)
@REM End of extension
@REM Provide a "standardized" way to retrieve the CLI args that will
@REM work with both Windows and non-Windows executions.
set MAVEN_CMD_LINE_ARGS=
%
*
%MAVEN_JAVA_EXE%
%JVM_CONFIG_MAVEN_PROPS%
%MAVEN_OPTS%
%MAVEN_DEBUG_OPTS%
-classpath
%WRAPPER_JAR%
"-Dmaven.multiModuleProjectDirectory=
%MAVEN_PROJECTBASEDIR%
"
%WRAPPER_LAUNCHER%
%MAVEN_CONFIG%
%
*
if ERRORLEVEL 1 goto error
goto end
:error
set ERROR_CODE=1
:end
@endlocal & set ERROR_CODE=
%ERROR_CODE%
if not "
%MAVEN_SKIP_RC%
" == "" goto skipRcPost
@REM check for post script, once with legacy .bat ending and once with .cmd ending
if exist "
%HOME%
\mavenrc_post.bat" call "
%HOME%
\mavenrc_post.bat"
if exist "
%HOME%
\mavenrc_post.cmd" call "
%HOME%
\mavenrc_post.cmd"
:skipRcPost
@REM pause the script if MAVEN_BATCH_PAUSE is set to '
on
'
if "
%MAVEN_BATCH_PAUSE%
" == "on" pause
if "
%MAVEN_TERMINATE_CMD%
" == "on" exit
%ERROR_CODE%
exit /B
%ERROR_CODE%
tests/examples/JDBC/springbootdemo/pom.xml
0 → 100644
浏览文件 @
02e39aab
<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd"
>
<modelVersion>
4.0.0
</modelVersion>
<parent>
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-starter-parent
</artifactId>
<version>
2.2.1.RELEASE
</version>
<relativePath/>
<!-- lookup parent from repository -->
</parent>
<groupId>
com.taosdata.jdbc
</groupId>
<artifactId>
springbootdemo
</artifactId>
<version>
0.0.1-SNAPSHOT
</version>
<name>
springbootdemo
</name>
<description>
Demo project for using tdengine with Spring Boot
</description>
<properties>
<java.version>
1.8
</java.version>
</properties>
<dependencies>
<dependency>
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-starter-data-jdbc
</artifactId>
</dependency>
<dependency>
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-starter-thymeleaf
</artifactId>
</dependency>
<dependency>
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-starter-web
</artifactId>
</dependency>
<dependency>
<groupId>
org.mybatis.spring.boot
</groupId>
<artifactId>
mybatis-spring-boot-starter
</artifactId>
<version>
2.1.1
</version>
</dependency>
<dependency>
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-devtools
</artifactId>
<scope>
runtime
</scope>
<optional>
true
</optional>
</dependency>
<dependency>
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-configuration-processor
</artifactId>
<optional>
true
</optional>
</dependency>
<dependency>
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-starter-test
</artifactId>
<scope>
test
</scope>
<exclusions>
<exclusion>
<groupId>
org.junit.vintage
</groupId>
<artifactId>
junit-vintage-engine
</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>
com.taosdata.jdbc
</groupId>
<artifactId>
taos-jdbcdriver
</artifactId>
<version>
1.0.3
</version>
</dependency>
<dependency>
<groupId>
com.alibaba
</groupId>
<artifactId>
druid-spring-boot-starter
</artifactId>
<version>
1.1.17
</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-maven-plugin
</artifactId>
</plugin>
</plugins>
</build>
</project>
tests/examples/JDBC/springbootdemo/readme.md
0 → 100644
浏览文件 @
02e39aab
## TDengine SpringBoot + Mybatis Demo
### 配置 application.properties
```
properties
# datasource config
spring.datasource.driver-class-name
=
com.taosdata.jdbc.TSDBDriver
spring.datasource.url
=
jdbc:TAOS://127.0.0.1:6030/log
spring.datasource.username
=
root
spring.datasource.password
=
taosdata
spring.datasource.druid.initial-size
=
5
spring.datasource.druid.min-idle
=
5
spring.datasource.druid.max-active
=
5
# max wait time for get connection, ms
spring.datasource.druid.max-wait
=
60000
spring.datasource.druid.validation-query
=
describe log.dn
spring.datasource.druid.validation-query-timeout
=
5000
spring.datasource.druid.test-on-borrow
=
false
spring.datasource.druid.test-on-return
=
false
spring.datasource.druid.test-while-idle
=
true
spring.datasource.druid.time-between-eviction-runs-millis
=
60000
spring.datasource.druid.min-evictable-idle-time-millis
=
600000
spring.datasource.druid.max-evictable-idle-time-millis
=
900000
# mybatis
mybatis.mapper-locations
=
classpath:mapper/*.xml
# log
logging.level.com.taosdata.jdbc.springbootdemo.dao
=
debug
```
### 主要功能
*
创建数据库和表
```
xml
<!-- weatherMapper.xml -->
<update
id=
"createDB"
>
create database if not exists test;
</update>
<update
id=
"createTable"
>
create table if not exists test.weather(ts timestamp, temperature int, humidity float);
</update>
```
*
插入单条记录
```
xml
<!-- weatherMapper.xml -->
<insert
id=
"insert"
parameterType=
"com.taosdata.jdbc.springbootdemo.domain.Weather"
>
insert into test.weather (ts, temperature, humidity) values (now, #{temperature,jdbcType=INTEGER}, #{humidity,jdbcType=FLOAT})
</insert>
```
*
插入多条记录
```
xml
<!-- weatherMapper.xml -->
<insert
id=
"batchInsert"
parameterType=
"java.util.List"
>
insert into test.weather (ts, temperature, humidity) values
<foreach
separator=
" "
collection=
"list"
item=
"weather"
index=
"index"
>
(now + #{index}a, #{weather.temperature}, #{weather.humidity})
</foreach>
</insert>
```
*
分页查询
```
xml
<!-- weatherMapper.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper
namespace=
"com.taosdata.jdbc.springbootdemo.dao.WeatherMapper"
>
<resultMap
id=
"BaseResultMap"
type=
"com.taosdata.jdbc.springbootdemo.domain.Weather"
>
<id
column=
"ts"
jdbcType=
"TIMESTAMP"
property=
"ts"
/>
<result
column=
"temperature"
jdbcType=
"INTEGER"
property=
"temperature"
/>
<result
column=
"humidity"
jdbcType=
"FLOAT"
property=
"humidity"
/>
</resultMap>
<sql
id=
"Base_Column_List"
>
ts, temperature, humidity
</sql>
<select
id=
"select"
resultMap=
"BaseResultMap"
>
select
<include
refid=
"Base_Column_List"
/>
from test.weather
order by ts desc
<if
test=
"limit != null"
>
limit #{limit,jdbcType=BIGINT}
</if>
<if
test=
"offset != null"
>
offset #{offset,jdbcType=BIGINT}
</if>
</select>
</mapper>
```
tests/examples/JDBC/springbootdemo/src/main/java/com/taosdata/jdbc/springbootdemo/SpringbootdemoApplication.java
0 → 100644
浏览文件 @
02e39aab
package
com.taosdata.jdbc.springbootdemo
;
import
org.mybatis.spring.annotation.MapperScan
;
import
org.springframework.boot.SpringApplication
;
import
org.springframework.boot.autoconfigure.SpringBootApplication
;
@MapperScan
(
basePackages
=
{
"com.taosdata.jdbc.springbootdemo.dao"
})
@SpringBootApplication
public
class
SpringbootdemoApplication
{
public
static
void
main
(
String
[]
args
)
{
SpringApplication
.
run
(
SpringbootdemoApplication
.
class
,
args
);
}
}
tests/examples/JDBC/springbootdemo/src/main/java/com/taosdata/jdbc/springbootdemo/controller/WeatherController.java
0 → 100644
浏览文件 @
02e39aab
package
com.taosdata.jdbc.springbootdemo.controller
;
import
com.taosdata.jdbc.springbootdemo.domain.Weather
;
import
com.taosdata.jdbc.springbootdemo.service.WeatherService
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.web.bind.annotation.*
;
import
java.util.List
;
@RequestMapping
(
"/weather"
)
@RestController
public
class
WeatherController
{
@Autowired
private
WeatherService
weatherService
;
/**
* create database and table
* @return
*/
@GetMapping
(
"/init"
)
public
boolean
init
(){
return
weatherService
.
init
();
}
/**
* Pagination Query
* @param limit
* @param offset
* @return
*/
@GetMapping
(
"/{limit}/{offset}"
)
public
List
<
Weather
>
queryWeather
(
@PathVariable
Long
limit
,
@PathVariable
Long
offset
){
return
weatherService
.
query
(
limit
,
offset
);
}
/**
* upload single weather info
* @param temperature
* @param humidity
* @return
*/
@PostMapping
(
"/{temperature}/{humidity}"
)
public
int
saveWeather
(
@PathVariable
int
temperature
,
@PathVariable
float
humidity
){
return
weatherService
.
save
(
temperature
,
humidity
);
}
/**
* upload multi weather info
* @param weatherList
* @return
*/
@PostMapping
(
"/batch"
)
public
int
batchSaveWeather
(
@RequestBody
List
<
Weather
>
weatherList
){
return
weatherService
.
save
(
weatherList
);
}
}
tests/examples/JDBC/springbootdemo/src/main/java/com/taosdata/jdbc/springbootdemo/dao/WeatherMapper.java
0 → 100644
浏览文件 @
02e39aab
package
com.taosdata.jdbc.springbootdemo.dao
;
import
com.taosdata.jdbc.springbootdemo.domain.Weather
;
import
org.apache.ibatis.annotations.Param
;
import
java.util.List
;
public
interface
WeatherMapper
{
int
insert
(
Weather
weather
);
int
batchInsert
(
List
<
Weather
>
weatherList
);
List
<
Weather
>
select
(
@Param
(
"limit"
)
Long
limit
,
@Param
(
"offset"
)
Long
offset
);
void
createDB
();
void
createTable
();
}
tests/examples/JDBC/springbootdemo/src/main/java/com/taosdata/jdbc/springbootdemo/domain/Weather.java
0 → 100644
浏览文件 @
02e39aab
package
com.taosdata.jdbc.springbootdemo.domain
;
import
java.sql.Timestamp
;
public
class
Weather
{
private
Timestamp
ts
;
private
int
temperature
;
private
float
humidity
;
public
Timestamp
getTs
()
{
return
ts
;
}
public
void
setTs
(
Timestamp
ts
)
{
this
.
ts
=
ts
;
}
public
int
getTemperature
()
{
return
temperature
;
}
public
void
setTemperature
(
int
temperature
)
{
this
.
temperature
=
temperature
;
}
public
float
getHumidity
()
{
return
humidity
;
}
public
void
setHumidity
(
float
humidity
)
{
this
.
humidity
=
humidity
;
}
}
tests/examples/JDBC/springbootdemo/src/main/java/com/taosdata/jdbc/springbootdemo/service/WeatherService.java
0 → 100644
浏览文件 @
02e39aab
package
com.taosdata.jdbc.springbootdemo.service
;
import
com.taosdata.jdbc.springbootdemo.dao.WeatherMapper
;
import
com.taosdata.jdbc.springbootdemo.domain.Weather
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Service
;
import
java.util.List
;
@Service
public
class
WeatherService
{
@Autowired
private
WeatherMapper
weatherMapper
;
public
boolean
init
()
{
weatherMapper
.
createDB
();
weatherMapper
.
createTable
();
return
true
;
}
public
List
<
Weather
>
query
(
Long
limit
,
Long
offset
)
{
return
weatherMapper
.
select
(
limit
,
offset
);
}
public
int
save
(
int
temperature
,
float
humidity
)
{
Weather
weather
=
new
Weather
();
weather
.
setTemperature
(
temperature
);
weather
.
setHumidity
(
humidity
);
return
weatherMapper
.
insert
(
weather
);
}
public
int
save
(
List
<
Weather
>
weatherList
)
{
return
weatherMapper
.
batchInsert
(
weatherList
);
}
}
tests/examples/JDBC/springbootdemo/src/main/resources/application.properties
0 → 100644
浏览文件 @
02e39aab
# datasource config
spring.datasource.driver-class-name
=
com.taosdata.jdbc.TSDBDriver
spring.datasource.url
=
jdbc:TAOS://127.0.0.1:6030/log
spring.datasource.username
=
root
spring.datasource.password
=
taosdata
spring.datasource.druid.initial-size
=
5
spring.datasource.druid.min-idle
=
5
spring.datasource.druid.max-active
=
5
# max wait time for get connection, ms
spring.datasource.druid.max-wait
=
60000
spring.datasource.druid.validation-query
=
describe log.dn
spring.datasource.druid.validation-query-timeout
=
5000
spring.datasource.druid.test-on-borrow
=
false
spring.datasource.druid.test-on-return
=
false
spring.datasource.druid.test-while-idle
=
true
spring.datasource.druid.time-between-eviction-runs-millis
=
60000
spring.datasource.druid.min-evictable-idle-time-millis
=
600000
spring.datasource.druid.max-evictable-idle-time-millis
=
900000
#mybatis
mybatis.mapper-locations
=
classpath:mapper/*.xml
logging.level.com.taosdata.jdbc.springbootdemo.dao
=
debug
\ No newline at end of file
tests/examples/JDBC/springbootdemo/src/main/resources/mapper/WeatherMapper.xml
0 → 100644
浏览文件 @
02e39aab
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper
namespace=
"com.taosdata.jdbc.springbootdemo.dao.WeatherMapper"
>
<resultMap
id=
"BaseResultMap"
type=
"com.taosdata.jdbc.springbootdemo.domain.Weather"
>
<id
column=
"ts"
jdbcType=
"TIMESTAMP"
property=
"ts"
/>
<result
column=
"temperature"
jdbcType=
"INTEGER"
property=
"temperature"
/>
<result
column=
"humidity"
jdbcType=
"FLOAT"
property=
"humidity"
/>
</resultMap>
<update
id=
"createDB"
>
create database if not exists test;
</update>
<update
id=
"createTable"
>
create table if not exists test.weather(ts timestamp, temperature int, humidity float);
</update>
<sql
id=
"Base_Column_List"
>
ts, temperature, humidity
</sql>
<select
id=
"select"
resultMap=
"BaseResultMap"
>
select
<include
refid=
"Base_Column_List"
/>
from test.weather
order by ts desc
<if
test=
"limit != null"
>
limit #{limit,jdbcType=BIGINT}
</if>
<if
test=
"offset != null"
>
offset #{offset,jdbcType=BIGINT}
</if>
</select>
<insert
id=
"insert"
parameterType=
"com.taosdata.jdbc.springbootdemo.domain.Weather"
>
insert into test.weather (ts, temperature, humidity) values (now, #{temperature,jdbcType=INTEGER}, #{humidity,jdbcType=FLOAT})
</insert>
<insert
id=
"batchInsert"
parameterType=
"java.util.List"
>
insert into test.weather (ts, temperature, humidity) values
<foreach
separator=
" "
collection=
"list"
item=
"weather"
index=
"index"
>
(now + #{index}a, #{weather.temperature}, #{weather.humidity})
</foreach>
</insert>
</mapper>
\ No newline at end of file
tests/examples/JDBC/springbootdemo/src/test/java/com/taosdata/jdbc/springbootdemo/SpringbootdemoApplicationTests.java
0 → 100644
浏览文件 @
02e39aab
package
com.taosdata.jdbc.springbootdemo
;
import
org.junit.jupiter.api.Test
;
import
org.springframework.boot.test.context.SpringBootTest
;
@SpringBootTest
class
SpringbootdemoApplicationTests
{
@Test
void
contextLoads
()
{
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录