数据库改用orm框架 gorm

master
hwf452 9 months ago
parent e85a4ca4c0
commit 919cce7fa2

@ -4,12 +4,31 @@
<option name="autoReloadType" value="ALL" /> <option name="autoReloadType" value="ALL" />
</component> </component>
<component name="ChangeListManager"> <component name="ChangeListManager">
<list default="true" id="9f8c3ce4-c378-4191-b7a4-3d5acbc0ebbc" name="Changes" comment="" /> <list default="true" id="9f8c3ce4-c378-4191-b7a4-3d5acbc0ebbc" name="Changes" comment="">
<change afterPath="$PROJECT_DIR$/models/Order.go" afterDir="false" />
<change afterPath="$PROJECT_DIR$/models/Product.go" afterDir="false" />
<change afterPath="$PROJECT_DIR$/models/User.go" afterDir="false" />
<change afterPath="$PROJECT_DIR$/mydb/initialize.go" afterDir="false" />
<change afterPath="$PROJECT_DIR$/utils/RandomNumber.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/go.mod" beforeDir="false" afterPath="$PROJECT_DIR$/go.mod" afterDir="false" />
<change beforePath="$PROJECT_DIR$/go.sum" beforeDir="false" afterPath="$PROJECT_DIR$/go.sum" afterDir="false" />
<change beforePath="$PROJECT_DIR$/install_go.sh" beforeDir="false" afterPath="$PROJECT_DIR$/install_go.sh" afterDir="false" />
<change beforePath="$PROJECT_DIR$/main.go" beforeDir="false" afterPath="$PROJECT_DIR$/main.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/models/Temperature.go" beforeDir="false" afterPath="$PROJECT_DIR$/models/Temperature.go" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" /> <option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" /> <option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" /> <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" /> <option name="LAST_RESOLUTION" value="IGNORE" />
</component> </component>
<component name="FileTemplateManagerImpl">
<option name="RECENT_TEMPLATES">
<list>
<option value="Go File" />
</list>
</option>
</component>
<component name="GOROOT" url="file://$USER_HOME$/sdk_go/go1.21.3" /> <component name="GOROOT" url="file://$USER_HOME$/sdk_go/go1.21.3" />
<component name="Git.Settings"> <component name="Git.Settings">
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" /> <option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
@ -24,6 +43,7 @@
<option name="showLibraryContents" value="true" /> <option name="showLibraryContents" value="true" />
</component> </component>
<component name="PropertiesComponent"> <component name="PropertiesComponent">
<property name="DefaultGoTemplateProperty" value="Go File" />
<property name="RunOnceActivity.OpenProjectViewOnStart" value="true" /> <property name="RunOnceActivity.OpenProjectViewOnStart" value="true" />
<property name="RunOnceActivity.ShowReadmeOnStart" value="true" /> <property name="RunOnceActivity.ShowReadmeOnStart" value="true" />
<property name="WebServerToolWindowFactoryState" value="false" /> <property name="WebServerToolWindowFactoryState" value="false" />
@ -32,6 +52,7 @@
<property name="go.modules.go.list.on.any.changes.was.set" value="true" /> <property name="go.modules.go.list.on.any.changes.was.set" value="true" />
<property name="go.sdk.automatically.set" value="true" /> <property name="go.sdk.automatically.set" value="true" />
<property name="last_opened_file_path" value="$USER_HOME$" /> <property name="last_opened_file_path" value="$USER_HOME$" />
<property name="settings.editor.selected.configurable" value="go.sdk" />
</component> </component>
<component name="RunManager"> <component name="RunManager">
<configuration name="go build main.go" type="GoApplicationRunConfiguration" factoryName="Go Application" temporary="true" nameIsGenerated="true"> <configuration name="go build main.go" type="GoApplicationRunConfiguration" factoryName="Go Application" temporary="true" nameIsGenerated="true">
@ -53,6 +74,17 @@
<component name="TypeScriptGeneratedFilesManager"> <component name="TypeScriptGeneratedFilesManager">
<option name="version" value="3" /> <option name="version" value="3" />
</component> </component>
<component name="Vcs.Log.Tabs.Properties">
<option name="TAB_STATES">
<map>
<entry key="MAIN">
<value>
<State />
</value>
</entry>
</map>
</option>
</component>
<component name="VgoProject"> <component name="VgoProject">
<integration-enabled>true</integration-enabled> <integration-enabled>true</integration-enabled>
</component> </component>

@ -9,6 +9,12 @@ require (
github.com/go-sql-driver/mysql v1.9.0 // indirect github.com/go-sql-driver/mysql v1.9.0 // indirect
github.com/google/uuid v1.6.0 // indirect github.com/google/uuid v1.6.0 // indirect
github.com/gorilla/websocket v1.4.2 // 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/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
) )

@ -2,17 +2,33 @@ filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= 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 h1:66wOzfUHSSI1zamx7jR6yMEI5EuHnT1G6rNA5PM12m4=
github.com/eclipse/paho.mqtt.golang v1.4.2/go.mod h1:JGt0RsEwEX+Xa/agj90YJ9d9DH2b7upDZMK9HRbFvCA= 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 h1:Y0zIbQXhQKmQgTp44Y1dp3wTXcn804QoTptLZT1vtvo=
github.com/go-sql-driver/mysql v1.9.0/go.mod h1:pDetrLJeA3oMujJuvXc8RJoasr589B6A9fwzD3QMrqw= 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 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 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 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= 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/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 h1:Jcxah/M+oLZ/R4/z5RzfPzGbPXnVDPkEDtf2JnuxN+U=
golang.org/x/net v0.0.0-20200425230154-ff2c4b7c35a0/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= 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 h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 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-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 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.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=

@ -1,4 +1,196 @@
#mysql driver
go get -u github.com/go-sql-driver/mysql go get -u github.com/go-sql-driver/mysql
#uuid
go get github.com/google/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. 介绍
#GORMGo 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 还支持一对多和多对多等其他类型的关联关系,
#开发者可以根据实际需求选择合适的关联关系来设计模型。

@ -15,12 +15,12 @@ import (
"time" "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" dsn := "root:Skyinno251,@tcp(47.242.184.139:3306)/appserver?charset=utf8mb4&parseTime=True&loc=Local"
db, err := sql.Open("mysql", dsn) db, err := sql.Open("mysql", dsn)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
return nil,err return nil, err
} }
db.SetConnMaxLifetime(time.Minute * 5) // 连接最大生命周期 db.SetConnMaxLifetime(time.Minute * 5) // 连接最大生命周期
db.SetMaxOpenConns(50) // 最大连接数 db.SetMaxOpenConns(50) // 最大连接数
@ -33,7 +33,7 @@ func getMySqlDB() (*sql.DB, error){
// 处理连接失败的情况。例如,打印错误信息并退出程序。 // 处理连接失败的情况。例如,打印错误信息并退出程序。
log.Println("47.242.184.139:3306连接失败") log.Println("47.242.184.139:3306连接失败")
fmt.Println("Connection failed:", err) fmt.Println("Connection failed:", err)
return nil,err return nil, err
} else { } else {
log.Println("47.242.184.139:3306连接成功") log.Println("47.242.184.139:3306连接成功")
fmt.Println("Connected successfully") fmt.Println("Connected successfully")
@ -42,7 +42,7 @@ func getMySqlDB() (*sql.DB, error){
//如果遇到任何问题检查你的DSN是否正确以及MySQL服务器是否正在运行并允许连接。 //如果遇到任何问题检查你的DSN是否正确以及MySQL服务器是否正在运行并允许连接。
//确保你的防火墙设置允许你的应用程序访问MySQL端口默认是3306 //确保你的防火墙设置允许你的应用程序访问MySQL端口默认是3306
//如果你使用的是远程数据库,确保网络设置允许你从当前位置访问数据库服务器。 //如果你使用的是远程数据库,确保网络设置允许你从当前位置访问数据库服务器。
return db,nil return db, nil
} }
} }
@ -66,12 +66,10 @@ func moreDBConnect() {
//fmt.Println("Connected to databases:", db1.Name, "and", db2.Name) //fmt.Println("Connected to databases:", db1.Name, "and", db2.Name)
} }
func queryOneDataByMySql(db *sql.DB) { func queryOneDataByMySql(db *sql.DB) {
//DB.QueryRow 用于查询单行数据,返回的是一个单独的 Row 对象。和 Query 不同,它只返回一行结果,适合用于查询根据条件唯一的数据: //DB.QueryRow 用于查询单行数据,返回的是一个单独的 Row 对象。和 Query 不同,它只返回一行结果,适合用于查询根据条件唯一的数据:
var temperature models.Temperature 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 { if err != nil {
fmt.Println("QueryRow failed:", err) fmt.Println("QueryRow failed:", err)
return return
@ -82,7 +80,7 @@ func queryOneDataByMySql(db *sql.DB) {
func queryMoreDataByMySql(db *sql.DB) { func queryMoreDataByMySql(db *sql.DB) {
//DB.QueryRow 用于查询单行数据,返回的是一个单独的 Row 对象。和 Query 不同,它只返回一行结果,适合用于查询根据条件唯一的数据: //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 { if err != nil {
fmt.Println("Query failed:", err) fmt.Println("Query failed:", err)
return return
@ -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(?, ?,?, ?,?, ?,?, ?)") stmt, err := db.Prepare("INSERT INTO temperature(create_date,data_date,data_hour,data_minute,humidity,location_desc,temperature,topic) VALUES(?, ?,?, ?,?, ?,?, ?)")
if err != nil { if err != nil {
@ -118,8 +116,8 @@ func insertDataByMySql(db *sql.DB,temperature *models.Temperature) {
fmt.Printf("Inserted Temperature with ID: %d\n", lastID) 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() tx, err := db.Begin()
if err != nil { if err != nil {
fmt.Println("Begin transaction failed:", err) fmt.Println("Begin transaction failed:", err)
@ -139,7 +137,6 @@ func insertMoreDataByMySql(db *sql.DB,temperature *models.Temperature) {
fmt.Println("Transaction committed successfully") fmt.Println("Transaction committed successfully")
} }
func dbTest() { func dbTest() {
// 初始化数据库连接 // 初始化数据库连接
DB, err := sql.Open("mysql", "root:123456@tcp(127.0.0.1:3306)/test") DB, err := sql.Open("mysql", "root:123456@tcp(127.0.0.1:3306)/test")
@ -180,7 +177,6 @@ func dbTest() {
stmt.Exec(1) stmt.Exec(1)
} }
func timing(client mqtt.Client) { func timing(client mqtt.Client) {
//定时器10秒钟执行一次 //定时器10秒钟执行一次
ticker := time.NewTicker(5 * time.Second) ticker := time.NewTicker(5 * time.Second)
@ -192,11 +188,11 @@ func timing(client mqtt.Client) {
} else { } else {
fmt.Println("client has connect") fmt.Println("client has connect")
//moreDBConnect() //moreDBConnect()
db, err := getMySqlDB() //db, err := getMySqlDB()
if err == nil { //if err == nil {
queryOneDataByMySql(db) // queryOneDataByMySql(db)
//mydb.Close() // //mydb.Close()
} //}
} }
} }
} }
@ -204,8 +200,8 @@ func timing(client mqtt.Client) {
var messagePubHandler mqtt.MessageHandler = func(client mqtt.Client, msg mqtt.Message) { var messagePubHandler mqtt.MessageHandler = func(client mqtt.Client, msg mqtt.Message) {
fmt.Printf("Received message: %s from topic: %s\n", msg.Payload(), msg.Topic()) fmt.Printf("Received message: %s from topic: %s\n", msg.Payload(), msg.Topic())
message := fmt.Sprintf("%s",msg.Payload()) message := fmt.Sprintf("%s", msg.Payload())
topic := fmt.Sprintf("%s",msg.Topic()) topic := fmt.Sprintf("%s", msg.Topic())
fmt.Println(message) fmt.Println(message)
result := strings.Split(message, " ") result := strings.Split(message, " ")
fmt.Println(result[0]) fmt.Println(result[0])
@ -213,29 +209,59 @@ var messagePubHandler mqtt.MessageHandler = func(client mqtt.Client, msg mqtt.Me
now := time.Now() now := time.Now()
temperature := new(models.Temperature) temperature := new(models.Temperature)
temperature.CreateDate=now temperature.CreateDate = now
temperature.DataDate=now.Format("2006-01-02") temperature.DataDate = now.Format("2006-01-02")
temperature.DataHour=now.Format("2006-01-02 15") temperature.DataHour = now.Format("2006-01-02 15")
temperature.DataMinute=now.Format("2006-01-02 15:04") temperature.DataMinute = now.Format("2006-01-02 15:04")
temperature.Humidity=result[0] temperature.Humidity = result[0]
temperature.Temperature=result[1] temperature.Temperature = result[1]
temperature.Topic=topic temperature.Topic = topic
if topic=="WifiSHT/7C87CE9CA4E6/SHT20" { if topic == "WifiSHT/7C87CE9CA4E6/SHT20" {
temperature.LocationDesc="广东省珠海市高新区唐家湾镇东岸村水风三街28号501" temperature.LocationDesc = "广东省珠海市高新区唐家湾镇东岸村水风三街28号501"
} }
if topic=="WifiSHT/7C87CE9F5CBF/SHT20" { if topic == "WifiSHT/7C87CE9F5CBF/SHT20" {
temperature.LocationDesc="广东省珠海市金湾区三灶镇百川路1号1栋1单元1508房" temperature.LocationDesc = "广东省珠海市金湾区三灶镇百川路1号1栋1单元1508房"
} }
if topic=="WifiSHT/4CEBD686B6AA/SHT20" { if topic == "WifiSHT/4CEBD686B6AA/SHT20" {
temperature.LocationDesc="广西壮族自治区崇左市天等县天等镇荣华村弄在屯113号" 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) { var connectHandler mqtt.OnConnectHandler = func(client mqtt.Client) {
@ -255,7 +281,7 @@ func sub(client mqtt.Client) {
func subTemperature(client mqtt.Client) { func subTemperature(client mqtt.Client) {
topic := "WifiSHT/+/SHT20" topic := "WifiSHT/+/SHT20"
token := client.Subscribe(topic, 1, nil) token := client.Subscribe(topic, 2, nil)
token.Wait() token.Wait()
fmt.Printf("Subscribed to topic: %s", topic) fmt.Printf("Subscribed to topic: %s", topic)
} }
@ -271,9 +297,6 @@ func publish(client mqtt.Client) {
} }
} }
func main() { func main() {
uuid := uuid.New() uuid := uuid.New()

@ -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!")
}
}

@ -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!")
}
}

@ -1,15 +1,38 @@
package models package models
import "time" import (
"fmt"
"go_mqtt/mydb"
"time"
)
type Temperature struct { type Temperature struct {
Id int64 Id int64
CreateDate time.Time CreateDate time.Time
DataDate string DataDate string `gorm:"size:20"`
DataHour string DataHour string `gorm:"size:20"`
DataMinute string DataMinute string `gorm:"size:20"`
Humidity string Humidity string `gorm:"size:10"`
LocationDesc string LocationDesc string `gorm:"size:80"`
Temperature string Temperature string `gorm:"size:10"`
Topic string 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!")
}
} }

@ -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!")
}
}

@ -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
}

@ -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
}
Loading…
Cancel
Save