diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index 35215e3..855b203 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -4,12 +4,31 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -24,6 +43,7 @@
+
@@ -32,6 +52,7 @@
+
@@ -53,6 +74,17 @@
+
+
+
+
+
true
diff --git a/go.mod b/go.mod
index cf681ef..3964690 100644
--- a/go.mod
+++ b/go.mod
@@ -9,6 +9,12 @@ require (
github.com/go-sql-driver/mysql v1.9.0 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/gorilla/websocket v1.4.2 // indirect
+ github.com/jinzhu/inflection v1.0.0 // indirect
+ github.com/jinzhu/now v1.1.5 // indirect
+ github.com/shopspring/decimal v1.4.0 // indirect
golang.org/x/net v0.0.0-20200425230154-ff2c4b7c35a0 // indirect
- golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
+ golang.org/x/sync v0.11.0 // indirect
+ golang.org/x/text v0.22.0 // indirect
+ gorm.io/driver/mysql v1.5.7 // indirect
+ gorm.io/gorm v1.25.12 // indirect
)
diff --git a/go.sum b/go.sum
index 155c3bf..da905e4 100644
--- a/go.sum
+++ b/go.sum
@@ -2,17 +2,33 @@ filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
github.com/eclipse/paho.mqtt.golang v1.4.2 h1:66wOzfUHSSI1zamx7jR6yMEI5EuHnT1G6rNA5PM12m4=
github.com/eclipse/paho.mqtt.golang v1.4.2/go.mod h1:JGt0RsEwEX+Xa/agj90YJ9d9DH2b7upDZMK9HRbFvCA=
+github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
github.com/go-sql-driver/mysql v1.9.0 h1:Y0zIbQXhQKmQgTp44Y1dp3wTXcn804QoTptLZT1vtvo=
github.com/go-sql-driver/mysql v1.9.0/go.mod h1:pDetrLJeA3oMujJuvXc8RJoasr589B6A9fwzD3QMrqw=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
+github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
+github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
+github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
+github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
+github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k=
+github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/net v0.0.0-20200425230154-ff2c4b7c35a0 h1:Jcxah/M+oLZ/R4/z5RzfPzGbPXnVDPkEDtf2JnuxN+U=
golang.org/x/net v0.0.0-20200425230154-ff2c4b7c35a0/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
+golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
+golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
+gorm.io/driver/mysql v1.5.7 h1:MndhOPYOfEp2rHKgkZIhJ16eVUIRf2HmzgoPmh7FCWo=
+gorm.io/driver/mysql v1.5.7/go.mod h1:sEtPWMiqiN1N1cMXoXmBbd8C6/l+TESwriotuRRpkDM=
+gorm.io/gorm v1.25.7/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
+gorm.io/gorm v1.25.12 h1:I0u8i2hWQItBq1WfE0o2+WuL9+8L21K9e2HHSTE/0f8=
+gorm.io/gorm v1.25.12/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ=
diff --git a/install_go.sh b/install_go.sh
index 607bec2..7373be1 100755
--- a/install_go.sh
+++ b/install_go.sh
@@ -1,4 +1,196 @@
+#mysql driver
go get -u github.com/go-sql-driver/mysql
-go get github.com/google/uuid
\ No newline at end of file
+#uuid
+go get github.com/google/uuid
+#gorm
+go get -u gorm.io/gorm
+#gorm mysql driver
+go get -u gorm.io/driver/mysql
+#获取随机数
+go get -u github.com/shopspring/decimal
+
+
+
+#GORM 使用指南
+#https://blog.csdn.net/qq_21484461/article/details/138588619
+#gorm github
+#https://github.com/go-gorm/gorm?tab=readme-ov-file
+#gorm 使用文档
+#https://gorm.io/zh_CN/docs/index.html
+
+
+#1. 介绍
+#GORM(Go Object Relational Mapper)是一个用于 Go 语言的 ORM 库,
+#它允许开发者通过面向对象的方式操作数据库,而不必直接编写 SQL 查询语句。
+#GORM 提供了简单易用的 API,使得在 Go 项目中进行数据库操作变得更加高效和便捷。
+#它的设计理念是将数据库表映射为 Go 的结构体(Struct),并通过方法调用来实现对数据的增删改查等操作,
+#从而降低了与数据库交互的复杂性。
+
+#1.2 GORM 的历史和背景
+#GORM 最初由 Jinzhu(原名:Liao Xingchang) 在 2013 年创建,并于同年开源发布在 GitHub 上。起初,GORM 是为了解决 Go 语言中缺乏成熟 ORM 库的问题而诞生的。随着 Go 语言的流行和生态系统的不断发展,GORM 逐渐成为了 Go 社区中最受欢迎的 ORM 库之一。
+#
+#经过多年的发展,GORM 不断完善和更新,增加了许多功能和优化,同时也受到了全球范围内开发者的广泛关注和使用。截至目前,GORM 的 GitHub 仓库已经获得了数万颗星星,并且被众多知名的开源项目和商业项目所采用和推荐。
+#
+#1.3 为什么选择 GORM?
+#选择 GORM 作为数据库操作工具的原因有以下几点:
+#
+#简单易用:GORM 提供了简洁的 API,使得开发者能够用最少的代码完成数据库操作,降低了学习成本和开发成本。
+#
+#功能丰富:GORM 支持丰富的数据库操作功能,包括基本的 CRUD 操作、事务管理、关联查询等,满足了大部分应用场景的需求。
+#
+#灵活性:GORM 提供了丰富的配置选项和扩展接口,可以灵活地适应不同的项目需求和数据库类型。
+#
+#社区支持:作为一个活跃的开源项目,GORM 拥有庞大的社区支持和活跃的开发团队,能够及时解决问题并提供技术支持。
+#
+#性能优化:GORM 在设计和实现上对性能进行了优化,同时提供了一些性能调优的建议和工具,可以帮助开发者提升应用程序的性能表现。
+#
+#生态完善:GORM 作为一个成熟的 ORM 库,已经在 Go 生态系统中建立了良好的地位,与其他常用的库和框架(如 Gin、Echo 等)集成良好,能够为开发者提供更加完整的解决方案。
+#
+#综上所述,GORM 是一个功能强大、易于使用且受到广泛认可的 ORM 库,适用于各种规模的 Go 项目,并且能够帮助开发者提高开发效率和代码质量。
+
+
+#2. 安装与配置
+#2.1 安装 GORM
+#安装 GORM 可以通过 Go 的包管理工具 go get 来完成。假设你已经安装了 Go 环境,执行以下命令即可安装 GORM:
+#
+#go get -u github.com/go-gorm/gorm
+#1
+#这条命令会将 GORM 库下载并安装到你的 $GOPATH 下的 src 目录中。
+
+#2.2 配置数据库连接
+#在使用 GORM 之前,你需要配置数据库连接信息,包括数据库类型、连接地址、用户名、密码等。GORM 支持多种数据库,常用的包括 MySQL、PostgreSQL、SQLite、SQL Server 等。
+#
+#以下是一个示例配置 MySQL 数据库连接的代码:
+
+#import (
+# "gorm.io/driver/mysql"
+# "gorm.io/gorm"
+#)
+#
+#func main() {
+# dsn := "user:password@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local"
+# db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
+# if err != nil {
+# panic("failed to connect database")
+# }
+#
+# // 在这里使用 db 进行数据库操作
+#}
+#
+#其中,dsn 是数据源名称,包含了数据库的连接信息,格式为 "用户名:密码@tcp(数据库地址:端口号)/数据库名称?参数"。具体的参数说明如下:
+#
+#charset=utf8mb4:设置字符集为 UTF-8。
+#parseTime=True:自动解析数据库中的时间字段为 Go 的时间类型。
+#loc=Local:设置时区为本地时区。
+#你需要将示例代码中的 user、password、dbname 替换为你自己的数据库用户名、密码和数据库名称,并根据需要修改数据库地址和端口号。
+
+#2.3 初始化 GORM
+#在连接数据库之后,你需要初始化 GORM 的数据库连接,以便后续进行数据库操作。通常情况下,你只需要在程序启动时进行一次初始化操作即可。
+#
+#以下是初始化 GORM 的示例代码:
+#
+#import (
+# "gorm.io/gorm"
+# "gorm.io/driver/mysql"
+#)
+#
+#var DB *gorm.DB
+#
+#func InitDB() {
+# dsn := "user:password@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local"
+# db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
+# if err != nil {
+# panic("failed to connect database")
+# }
+#
+# DB = db
+#}
+#
+#在这个示例中,我们将初始化操作封装在了一个名为 InitDB() 的函数中,
+#并将初始化后的数据库连接赋值给了全局变量 DB,以便在程序的其他地方进行使用。
+#你可以根据自己的项目需求,将初始化操作放在适当的位置,并根据需要进行调整。
+
+#3. 模型定义
+#在 GORM 中,模型定义是指将数据库表映射为 Go 的结构体(Struct),通过结构体的字段来表示数据库表的字段,
+#并使用 GORM 提供的标签来指定字段的属性和约束。
+#同时,通过在结构体之间建立关联关系,可以实现数据库表之间的关联查询和操作。
+#
+#3.1 创建模型结构体
+#下面是一个示例,展示了如何使用 GORM 创建一个简单的模型结构体:
+#
+#import "gorm.io/gorm"
+#
+#type User struct {
+# gorm.Model // 内置模型结构体,包含 ID、CreatedAt、UpdatedAt、DeletedAt 字段
+#
+# Name string
+# Age int
+# Email string `gorm:"unique"` // 使用标签指定字段属性,这里表示 Email 字段在数据库中是唯一的
+# Address string
+#}
+#
+#
+#在这个示例中,我们创建了一个名为 User 的结构体,用于表示数据库中的用户表。
+#User 结构体包含了 gorm.Model 结构体,这是 GORM 提供的一个内置模型结构体,
+#包含了一些常用的字段,如 ID、CreatedAt、UpdatedAt、DeletedAt,
+#用于记录记录的主键、创建时间、更新时间和软删除状态。
+#
+#除了内置模型字段外,我们还定义了 Name、Age、Email 和 Address 字段,
+#分别表示用户的姓名、年龄、邮箱和地址。这些字段与数据库表的字段一一对应,用于存储用户的信息。
+#
+#3.2 模型字段标签解析
+#在模型定义中,我们可以通过在字段上添加标签来指定字段的属性和约束。常用的标签包括:
+#
+#gorm:"column:column_name":指定字段在数据库中的列名。
+#gorm:"primaryKey":指定字段为主键。
+#gorm:"autoIncrement":指定字段为自增长。
+#gorm:"unique":指定字段在数据库中唯一。
+#gorm:"not null":指定字段不能为空。
+#gorm:"default:value":指定字段的默认值。
+#gorm:"size:length":指定字段的长度。
+#gorm:"index":指定字段创建索引。
+#下面是一个示例,展示了如何在模型字段上添加标签:
+#
+#type Product struct {
+# ID uint `gorm:"primaryKey;autoIncrement"`
+# Name string `gorm:"size:255;not null"`
+# Price float64
+# Category string `gorm:"index"`
+#}
+#
+#在这个示例中,我们定义了一个名为 Product 的结构体,用于表示数据库中的产品表。
+#Product 结构体包含了 ID、Name、Price 和 Category 字段,
+#分别表示产品的编号、名称、价格和类别。其中,ID 字段通过 primaryKey 和 autoIncrement
+#标签指定为主键并自增长,Name 字段通过 size 和 not null 标签指定了字段的长度和不能为空,
+#Category 字段通过 index 标签为字段创建了索引。
+
+
+#3.3 模型关联关系
+#在 GORM 中,可以通过在模型结构体中建立字段关联来表示数据库表之间的关联关系,常见的关联关系包括一对一、一对多和多对多。以下是一个示例,展示了如何在模型中定义关联关系:
+#
+#type Order struct {
+# ID uint
+# OrderNumber string
+# TotalAmount float64
+# UserID uint // 外键
+#
+# User User `gorm:"foreignKey:UserID"` // 一对一关联,通过 UserID 外键关联到 User 结构体
+#}
+#
+#type User struct {
+# ID uint
+# Name string
+# Email string
+# Order Order // 一对一关联,一个用户对应一个订单
+#}
+#
+#在这个示例中,我们定义了两个结构体 Order 和 User,分别表示数据库中的订单表和用户表。
+#在 Order 结构体中,我们使用了 UserID 字段作为外键,
+#关联到了 User 结构体,通过 gorm:"foreignKey:UserID" 标签指定了外键关联的字段。
+#在 User 结构体中,我们定义了一个名为 Order 的字段,用于表示与用户关联的订单信息。
+#这样,我们就建立了订单表和用户表之间的一对一关联关系。
+#
+#除了一对一关联关系外,GORM 还支持一对多和多对多等其他类型的关联关系,
+#开发者可以根据实际需求选择合适的关联关系来设计模型。
diff --git a/main.go b/main.go
index 1251a98..82300dd 100644
--- a/main.go
+++ b/main.go
@@ -15,16 +15,16 @@ import (
"time"
)
-func getMySqlDB() (*sql.DB, error){
+func getMySqlDB() (*sql.DB, error) {
dsn := "root:Skyinno251,@tcp(47.242.184.139:3306)/appserver?charset=utf8mb4&parseTime=True&loc=Local"
db, err := sql.Open("mysql", dsn)
if err != nil {
log.Fatal(err)
- return nil,err
+ return nil, err
}
- db.SetConnMaxLifetime(time.Minute * 5) // 连接最大生命周期
- db.SetMaxOpenConns(50) // 最大连接数
- db.SetMaxIdleConns(10) // 最大空闲连接数
+ db.SetConnMaxLifetime(time.Minute * 5) // 连接最大生命周期
+ db.SetMaxOpenConns(50) // 最大连接数
+ db.SetMaxIdleConns(10) // 最大空闲连接数
//defer mydb.Close()
@@ -33,7 +33,7 @@ func getMySqlDB() (*sql.DB, error){
// 处理连接失败的情况。例如,打印错误信息并退出程序。
log.Println("47.242.184.139:3306连接失败")
fmt.Println("Connection failed:", err)
- return nil,err
+ return nil, err
} else {
log.Println("47.242.184.139:3306连接成功")
fmt.Println("Connected successfully")
@@ -42,7 +42,7 @@ func getMySqlDB() (*sql.DB, error){
//如果遇到任何问题,检查你的DSN是否正确,以及MySQL服务器是否正在运行并允许连接。
//确保你的防火墙设置允许你的应用程序访问MySQL端口(默认是3306)。
//如果你使用的是远程数据库,确保网络设置允许你从当前位置访问数据库服务器。
- return db,nil
+ return db, nil
}
}
@@ -66,12 +66,10 @@ func moreDBConnect() {
//fmt.Println("Connected to databases:", db1.Name, "and", db2.Name)
}
-
-
func queryOneDataByMySql(db *sql.DB) {
//DB.QueryRow 用于查询单行数据,返回的是一个单独的 Row 对象。和 Query 不同,它只返回一行结果,适合用于查询根据条件唯一的数据:
var temperature models.Temperature
- err := db.QueryRow("SELECT id,create_date,data_date,data_hour,data_minute,humidity,location_desc,temperature,topic FROM temperature order by id desc limit 0,?",1).Scan(&temperature.Id, &temperature.CreateDate, &temperature.DataDate, &temperature.DataHour, &temperature.DataMinute, &temperature.Humidity, &temperature.LocationDesc, &temperature.Temperature, &temperature.Topic)
+ err := db.QueryRow("SELECT id,create_date,data_date,data_hour,data_minute,humidity,location_desc,temperature,topic FROM temperature order by id desc limit 0,?", 1).Scan(&temperature.Id, &temperature.CreateDate, &temperature.DataDate, &temperature.DataHour, &temperature.DataMinute, &temperature.Humidity, &temperature.LocationDesc, &temperature.Temperature, &temperature.Topic)
if err != nil {
fmt.Println("QueryRow failed:", err)
return
@@ -82,12 +80,12 @@ func queryOneDataByMySql(db *sql.DB) {
func queryMoreDataByMySql(db *sql.DB) {
//DB.QueryRow 用于查询单行数据,返回的是一个单独的 Row 对象。和 Query 不同,它只返回一行结果,适合用于查询根据条件唯一的数据:
- rows, err := db.Query("SELECT id,create_date,data_date,data_hour,data_minute,humidity,location_desc,temperature,topic FROM temperature WHERE id > ? and id < ?", 0,30)
+ rows, err := db.Query("SELECT id,create_date,data_date,data_hour,data_minute,humidity,location_desc,temperature,topic FROM temperature WHERE id > ? and id < ?", 0, 30)
if err != nil {
fmt.Println("Query failed:", err)
return
}
- defer rows.Close() // 确保在使用完毕后关闭资源
+ defer rows.Close() // 确保在使用完毕后关闭资源
items := make([]models.Temperature, 0)
for rows.Next() {
@@ -101,8 +99,8 @@ func queryMoreDataByMySql(db *sql.DB) {
}
}
-//插入单条数据
-func insertDataByMySql(db *sql.DB,temperature *models.Temperature) {
+// 插入单条数据
+func insertDataByMySql(db *sql.DB, temperature *models.Temperature) {
//插入操作:
stmt, err := db.Prepare("INSERT INTO temperature(create_date,data_date,data_hour,data_minute,humidity,location_desc,temperature,topic) VALUES(?, ?,?, ?,?, ?,?, ?)")
if err != nil {
@@ -118,8 +116,8 @@ func insertDataByMySql(db *sql.DB,temperature *models.Temperature) {
fmt.Printf("Inserted Temperature with ID: %d\n", lastID)
}
-//事务处理:保证数据一致性
-func insertMoreDataByMySql(db *sql.DB,temperature *models.Temperature) {
+// 事务处理:保证数据一致性
+func insertMoreDataByMySql(db *sql.DB, temperature *models.Temperature) {
tx, err := db.Begin()
if err != nil {
fmt.Println("Begin transaction failed:", err)
@@ -127,11 +125,11 @@ func insertMoreDataByMySql(db *sql.DB,temperature *models.Temperature) {
}
_, err = tx.Exec("UPDATE users SET age = ? WHERE id = ?", 35, 1)
if err != nil {
- tx.Rollback() // 如果发生错误,回滚事务
+ tx.Rollback() // 如果发生错误,回滚事务
fmt.Println("Exec failed:", err)
return
}
- err = tx.Commit() // 提交事务
+ err = tx.Commit() // 提交事务
if err != nil {
fmt.Println("Commit failed:", err)
return
@@ -139,7 +137,6 @@ func insertMoreDataByMySql(db *sql.DB,temperature *models.Temperature) {
fmt.Println("Transaction committed successfully")
}
-
func dbTest() {
// 初始化数据库连接
DB, err := sql.Open("mysql", "root:123456@tcp(127.0.0.1:3306)/test")
@@ -180,7 +177,6 @@ func dbTest() {
stmt.Exec(1)
}
-
func timing(client mqtt.Client) {
//定时器,10秒钟执行一次
ticker := time.NewTicker(5 * time.Second)
@@ -192,11 +188,11 @@ func timing(client mqtt.Client) {
} else {
fmt.Println("client has connect")
//moreDBConnect()
- db, err := getMySqlDB()
- if err == nil {
- queryOneDataByMySql(db)
- //mydb.Close()
- }
+ //db, err := getMySqlDB()
+ //if err == nil {
+ // queryOneDataByMySql(db)
+ // //mydb.Close()
+ //}
}
}
}
@@ -204,8 +200,8 @@ func timing(client mqtt.Client) {
var messagePubHandler mqtt.MessageHandler = func(client mqtt.Client, msg mqtt.Message) {
fmt.Printf("Received message: %s from topic: %s\n", msg.Payload(), msg.Topic())
- message := fmt.Sprintf("%s",msg.Payload())
- topic := fmt.Sprintf("%s",msg.Topic())
+ message := fmt.Sprintf("%s", msg.Payload())
+ topic := fmt.Sprintf("%s", msg.Topic())
fmt.Println(message)
result := strings.Split(message, " ")
fmt.Println(result[0])
@@ -213,29 +209,59 @@ var messagePubHandler mqtt.MessageHandler = func(client mqtt.Client, msg mqtt.Me
now := time.Now()
temperature := new(models.Temperature)
- temperature.CreateDate=now
- temperature.DataDate=now.Format("2006-01-02")
- temperature.DataHour=now.Format("2006-01-02 15")
- temperature.DataMinute=now.Format("2006-01-02 15:04")
- temperature.Humidity=result[0]
- temperature.Temperature=result[1]
- temperature.Topic=topic
-
- if topic=="WifiSHT/7C87CE9CA4E6/SHT20" {
- temperature.LocationDesc="广东省珠海市高新区唐家湾镇东岸村水风三街28号501"
+ temperature.CreateDate = now
+ temperature.DataDate = now.Format("2006-01-02")
+ temperature.DataHour = now.Format("2006-01-02 15")
+ temperature.DataMinute = now.Format("2006-01-02 15:04")
+ temperature.Humidity = result[0]
+ temperature.Temperature = result[1]
+ temperature.Topic = topic
+
+ if topic == "WifiSHT/7C87CE9CA4E6/SHT20" {
+ temperature.LocationDesc = "广东省珠海市高新区唐家湾镇东岸村水风三街28号501"
}
- if topic=="WifiSHT/7C87CE9F5CBF/SHT20" {
- temperature.LocationDesc="广东省珠海市金湾区三灶镇百川路1号1栋1单元1508房"
+ if topic == "WifiSHT/7C87CE9F5CBF/SHT20" {
+ temperature.LocationDesc = "广东省珠海市金湾区三灶镇百川路1号1栋1单元1508房"
}
- if topic=="WifiSHT/4CEBD686B6AA/SHT20" {
- temperature.LocationDesc="广西壮族自治区崇左市天等县天等镇荣华村弄在屯113号"
+ if topic == "WifiSHT/4CEBD686B6AA/SHT20" {
+ temperature.LocationDesc = "广西壮族自治区崇左市天等县天等镇荣华村弄在屯113号"
}
+ fmt.Println("测温传感器地点:", temperature.LocationDesc)
+
+ //db, err := getMySqlDB()
+ //if err == nil {
+ // insertDataByMySql(db,temperature)
+ // //mydb.Close()
+ //}
+
+ models.SaveTemperature(temperature)
+
+ //uuid := uuid.New()
+ //models.SaveProduct()
+ //models.SaveUser(uuid.String())
+ //models.SaveOrder()
+
+ //var users []models.User
+ //var orders []models.Order
+ //var user models.User
+ //mydb.DB.Where("name = ?", "wenfei").First(&user)
+ //fmt.Println(user)
+
+ // 查询多条记录
+ //mydb.DB.Find(&users) // 查询所有产品信息
+ //mydb.DB.Order("id desc").Limit(2).Offset(0).Find(&users) // 按价格降序排序,取前 10 条记录
+ //fmt.Println("users:", users)
+
+ // 查询多条记录
+ //mydb.DB.Find(&users) // 查询所有产品信息
+ //mydb.DB.Where("id > ? and id < ?", 60,65).Find(&orders)
+ //fmt.Println("orders:", orders)
+
+ // 原生 SQL 查询
+ //var products []models.Product
+ //mydb.DB.Raw("SELECT * FROM product WHERE price > ?", 1000).Scan(&products) // 查询价格大于 1000 的产品信息
+ //fmt.Println("Products:", products)
- db, err := getMySqlDB()
- if err == nil {
- insertDataByMySql(db,temperature)
- //mydb.Close()
- }
}
var connectHandler mqtt.OnConnectHandler = func(client mqtt.Client) {
@@ -255,7 +281,7 @@ func sub(client mqtt.Client) {
func subTemperature(client mqtt.Client) {
topic := "WifiSHT/+/SHT20"
- token := client.Subscribe(topic, 1, nil)
+ token := client.Subscribe(topic, 2, nil)
token.Wait()
fmt.Printf("Subscribed to topic: %s", topic)
}
@@ -271,9 +297,6 @@ func publish(client mqtt.Client) {
}
}
-
-
-
func main() {
uuid := uuid.New()
diff --git a/models/Order.go b/models/Order.go
new file mode 100644
index 0000000..7395c74
--- /dev/null
+++ b/models/Order.go
@@ -0,0 +1,38 @@
+package models
+
+import (
+ "fmt"
+ "github.com/google/uuid"
+ "go_mqtt/mydb"
+)
+
+type Order struct {
+ ID uint
+ OrderNumber string
+ TotalAmount float64
+ UserID uint // 外键
+
+ //User User `gorm:"foreignKey:UserID"` // 一对一关联,通过 UserID 外键关联到 User 结构体
+}
+
+func init() {
+ fmt.Println("Order init()")
+ mydb.DB.AutoMigrate(&Order{})
+}
+
+// TableName 会将 Product 的表名重写为 `product`
+func (Order) TableName() string {
+ return "order"
+}
+
+func SaveOrder() {
+ uuid := uuid.New()
+ // 创建记录
+ order := Order{OrderNumber: uuid.String(), TotalAmount: 1999.9, UserID: 1}
+ result := mydb.DB.Create(&order)
+ if result.Error != nil {
+ fmt.Println("Failed to create order:", result.Error)
+ } else {
+ fmt.Println("order created successfully!")
+ }
+}
diff --git a/models/Product.go b/models/Product.go
new file mode 100644
index 0000000..94004fb
--- /dev/null
+++ b/models/Product.go
@@ -0,0 +1,45 @@
+package models
+
+import (
+ "fmt"
+ "go_mqtt/mydb"
+ "go_mqtt/utils"
+)
+
+//gorm:"column:column_name":指定字段在数据库中的列名。
+//gorm:"primaryKey":指定字段为主键。
+//gorm:"autoIncrement":指定字段为自增长。
+//gorm:"unique":指定字段在数据库中唯一。
+//gorm:"not null":指定字段不能为空。
+//gorm:"default:value":指定字段的默认值。
+//gorm:"size:length":指定字段的长度。
+//gorm:"index":指定字段创建索引。
+
+type Product struct {
+ ID uint `gorm:"primaryKey;autoIncrement"`
+ Name string `gorm:"size:255;not null"`
+ Price float64
+ Category string `gorm:"index"`
+}
+
+func init() {
+ fmt.Println("Product init()")
+ mydb.DB.AutoMigrate(&Product{})
+}
+
+// TableName 会将 Product 的表名重写为 `product`
+func (Product) TableName() string {
+ return "product"
+}
+
+func SaveProduct() {
+ price := utils.GetRandomFloat64(100, 2000)
+ // 创建记录
+ product := Product{Name: "Laptop", Price: price}
+ result := mydb.DB.Create(&product)
+ if result.Error != nil {
+ fmt.Println("Failed to create product:", result.Error)
+ } else {
+ fmt.Println("Product created successfully!")
+ }
+}
diff --git a/models/Temperature.go b/models/Temperature.go
index 24518e8..e4d99c7 100644
--- a/models/Temperature.go
+++ b/models/Temperature.go
@@ -1,15 +1,38 @@
package models
-import "time"
+import (
+ "fmt"
+ "go_mqtt/mydb"
+ "time"
+)
type Temperature struct {
Id int64
CreateDate time.Time
- DataDate string
- DataHour string
- DataMinute string
- Humidity string
- LocationDesc string
- Temperature string
- Topic string
+ DataDate string `gorm:"size:20"`
+ DataHour string `gorm:"size:20"`
+ DataMinute string `gorm:"size:20"`
+ Humidity string `gorm:"size:10"`
+ LocationDesc string `gorm:"size:80"`
+ Temperature string `gorm:"size:10"`
+ Topic string `gorm:"size:60"`
+}
+
+func init() {
+ fmt.Println("Temperature init()")
+ mydb.DB.AutoMigrate(&Temperature{})
+}
+
+// TableName 会将 User 的表名重写为 `user`
+func (Temperature) TableName() string {
+ return "temperature"
+}
+
+func SaveTemperature(temperature *Temperature) {
+ result := mydb.DB.Create(&temperature)
+ if result.Error != nil {
+ fmt.Println("Failed to create Temperature:", result.Error)
+ } else {
+ fmt.Println("Temperature created successfully!")
+ }
}
diff --git a/models/User.go b/models/User.go
new file mode 100644
index 0000000..661686e
--- /dev/null
+++ b/models/User.go
@@ -0,0 +1,47 @@
+package models
+
+import (
+ "fmt"
+ "go_mqtt/mydb"
+ "gorm.io/gorm"
+)
+
+//gorm:"column:column_name":指定字段在数据库中的列名。
+//gorm:"primaryKey":指定字段为主键。
+//gorm:"autoIncrement":指定字段为自增长。
+//gorm:"unique":指定字段在数据库中唯一。
+//gorm:"not null":指定字段不能为空。
+//gorm:"default:value":指定字段的默认值。
+//gorm:"size:length":指定字段的长度。
+//gorm:"index":指定字段创建索引。
+
+type User struct {
+ gorm.Model // 内置模型结构体,包含 ID、CreatedAt、UpdatedAt、DeletedAt 字段
+
+ Name string
+ Age int
+ Email string `gorm:"unique"` // 使用标签指定字段属性,这里表示 Email 字段在数据库中是唯一的
+ Address string
+ Order Order // 一对一关联,一个用户对应一个订单
+}
+
+func init() {
+ fmt.Println("User init()")
+ mydb.DB.AutoMigrate(&User{})
+}
+
+// TableName 会将 User 的表名重写为 `user`
+func (User) TableName() string {
+ return "user"
+}
+
+func SaveUser(uuid string) {
+ // 创建记录
+ product := User{Name: "Wenfei", Age: 20, Email: uuid, Address: "天等县弄在屯"}
+ result := mydb.DB.Create(&product)
+ if result.Error != nil {
+ fmt.Println("Failed to create product:", result.Error)
+ } else {
+ fmt.Println("User created successfully!")
+ }
+}
diff --git a/mydb/initialize.go b/mydb/initialize.go
new file mode 100644
index 0000000..e30f7a7
--- /dev/null
+++ b/mydb/initialize.go
@@ -0,0 +1,58 @@
+package mydb
+
+import (
+ "fmt"
+ "gorm.io/driver/mysql"
+ "gorm.io/gorm"
+ "log"
+ "time"
+)
+
+func init() {
+ fmt.Println("mydb init()")
+ initDatabase()
+}
+
+var DB *gorm.DB
+
+func initDatabase() {
+
+ //dsn := "root:Skyinno251,@tcp(192.168.2.18:3306)/gorm?charset=utf8mb4&parseTime=True&loc=Local"
+ dsn := "root:Skyinno251,@tcp(47.242.184.139:3306)/appserver?charset=utf8mb4&parseTime=True&loc=Local"
+
+ db, err := gorm.Open(mysql.New(mysql.Config{
+ DSN: dsn, // DSN data source name
+ DefaultStringSize: 255, // string 类型字段的默认长度
+ DisableDatetimePrecision: true, // 禁用 datetime 精度,MySQL 5.6 之前的数据库不支持
+ DontSupportRenameIndex: true, // 重命名索引时采用删除并新建的方式,MySQL 5.7 之前的数据库和 MariaDB 不支持重命名索引
+ DontSupportRenameColumn: true, // 用 `change` 重命名列,MySQL 8 之前的数据库和 MariaDB 不支持重命名列
+ SkipInitializeWithVersion: false, // 根据当前 MySQL 版本自动配置
+ }), &gorm.Config{})
+
+ //db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
+ if err != nil {
+ fmt.Println("failed to connect database")
+ }
+
+ // 获取通用数据库对象 sql.DB ,然后使用其提供的功能
+ sqlDB, errDB := db.DB()
+ if errDB != nil {
+ return
+ }
+
+ // SetMaxIdleConns 用于设置连接池中空闲连接的最大数量。
+ sqlDB.SetMaxIdleConns(10)
+ // SetMaxOpenConns 设置打开数据库连接的最大数量。
+ sqlDB.SetMaxOpenConns(50)
+ // SetConnMaxLifetime 设置了连接可复用的最大时间。
+ sqlDB.SetConnMaxLifetime(time.Minute * 5) // 连接最大生命周期
+
+ err = sqlDB.Ping() // 检查连接是否成功建立。如果失败,则返回错误。
+ if err != nil {
+ // 处理连接失败的情况。例如,打印错误信息并退出程序。
+ log.Println("192.168.2.18:3306连接失败")
+ fmt.Println("Connection failed:", err)
+ return
+ }
+ DB = db
+}
diff --git a/utils/RandomNumber.go b/utils/RandomNumber.go
new file mode 100644
index 0000000..0887930
--- /dev/null
+++ b/utils/RandomNumber.go
@@ -0,0 +1,81 @@
+package utils
+
+import (
+ "fmt"
+ "github.com/shopspring/decimal"
+ "math"
+ "math/rand"
+ "testing"
+ "time"
+)
+
+func init() {
+ // 初始化rand模块的Seed,要不然所有的随机值会一样~
+ rand.Seed(time.Now().UnixNano())
+}
+
+// 获取随机float64 保留2位小数 Notice 不四舍五入
+func GetRandomFloat64(min, max float64) float64 {
+ min, max = math.Abs(min), math.Abs(max)
+ min, max = GetMinFloat64WHW(min, max), GetMaxFloat64WHW(min, max)
+ // 到这里确保 max>=min 并且二者一定是正数
+ ret := GetMinFloat64WHW(min, max) + rand.Float64()*(max-min)
+ // 不四舍五入
+ ret, _ = decimal.NewFromFloat(ret).RoundFloor(2).Float64()
+ if ret > max {
+ ret = max
+ }
+ if ret < min {
+ ret = min
+ }
+ return ret
+}
+
+func GetMaxFloat64WHW(min, max float64) float64 {
+ if min >= max {
+ return min
+ }
+ return max
+}
+
+func GetMinFloat64WHW(min, max float64) float64 {
+ if min <= max {
+ return min
+ }
+ return max
+}
+
+func TestRandFloat64222(t *testing.T) {
+
+ fmt.Println(GetRandomFloat64(1, 2))
+ fmt.Println(GetRandomFloat64(-1.2233, 2.123))
+ fmt.Println(GetRandomFloat64(3.2, 2))
+ fmt.Println(GetRandomFloat64(0.01, 0.1))
+ fmt.Println(GetRandomFloat64(-0.01, 0.1))
+
+}
+
+// 随机数
+// 生成min与max之间的整数(包含)
+func GenRandomInt(min, max int) int {
+ if min == max {
+ return min
+ }
+ // 为了保险取两个值之间大的那个作为max
+ randNum := rand.Intn(GetMaxInt(min, max)-min) + min
+ return randNum
+}
+
+func GetMaxInt(min, max int) int {
+ if max >= min {
+ return max
+ }
+ return min
+}
+
+func GetMinInt(min, max int) int {
+ if min <= max {
+ return min
+ }
+ return max
+}