GORM の簡単な紹介
GORM は Golang 用の ORM フレームワークです。
簡単に言えば、GORM はインスタンス オブジェクトの構文を通じてリレーショナル データベースの操作を完了するテクノロジーです。
「Object-Relational Mapping」(オブジェクト/リレーショナル マッピング)の略称です。
ORM フレームワークを使用すると、データベースをより便利に操作できるようになります。
GORM で正式にサポートされているデータベースの種類は次のとおりです。
MISQL、PostgreSQL、SQlite、SQL Server
実際のプロジェクトでデータベースモデルを定義する場合は、以下の点に注意してください。
1. 構造体の名前は最初の文字が大文字で、データベース テーブルの名前に対応している必要があります。
例: テーブル名はユーザー構造です。
名前はUser、テーブル名はarticle_cate、構造名はArticleCateとして定義されます。
2. 構造内のフィールド名の最初の文字は大文字にし、データベース テーブル内のフィールドに 1 対 1 で対応する必要があります。
例: 以下の構造内の ID はデータベース内の ID に対応します。
ユーザー名はデータベース内のユーザー名に対応します。
年齢はデータベース内の年齢に対応します。
電子メールはデータベース内の電子メールに対応します。
AddTime はデータベースの add_time フィールドに対応します。
3. デフォルトでは、テーブル名は構造名の複数形です。
構造名が User として定義されている場合、
このモデルがデフォルトで users テーブル上で動作することを示します。
データベース内のテーブルのクエリを実装する
モジュール\connectMySQL.go
package modules
import (
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
var DB *gorm.DB
var err error
func init() {
// 请替换为你的实际数据库信息
// parseTime=True 和 loc=Local 确保时间类型能正确解析
// zhangsan123 是数据库密码,根据实际情况修改
// school 是数据库名称,根据实际情况修改
dsn := "root:zhangsan123@tcp(127.0.0.1:3306)/school?charset=utf8mb4&parseTime=True&loc=Local"
DB, err = gorm.Open(mysql.Open(dsn), &gorm.Config{})
if err != nil {
panic("failed to connect database: " + err.Error())
}
}
docs/connecting_to_the_database.html
インポートしてインストールする
ドキュメント/
go get -u gorm.io/gorm
go get -u gorm.io/driver/sqlite

そして実行します
go mod tidy

モジュール\class.go
package modules
type Class struct {
ID int
Name string
Email string
Score int
}
func (Class) TableName() string {
return "class"
}
このクラス構造内のデータは、データベース内の構造データと一致している必要があります。
踏み込みやすい罠
フィールド名は大文字である必要があります (エクスポート)。id int GORM はそのような小文字のフィールドを直接無視し、列の作成もスキャンも行いません。正しくするために、現在はすべて大文字を使用しています。
GORMにおけるこの構造体の正式名称はmodelです。
「Goコード⇄データベーステーブル」間のマッピング規約です。
これがないと、GORM はどのテーブルをチェックする必要があるのか、テーブルにどの列があるのか、各列の型が何であるのかがわかりません。
この構造には 3 つの特定の機能があります。
-
テーブル構造を説明します。 2. GORM にデータの読み取りと書き込みの方法を知らせます。 3. ビジネスコードにタイプセーフキャリアを与える
-
テーブル構造の説明
type Class struct {
ID int // → 列 id,int
Name string // → 列 name,varchar
Email string // → 列 email
Score int // → 列 score
}
各フィールドは MySQL の列に対応します。
GORM はデフォルトでフィールド名を小文字または Snake_case に変換します (ID →id 、UserName →user_name )。
-
GORM にデータの読み取りと書き込みの方法を知らせる
modules.DB.First(&class)データベースレコードの行を Go 変数に「変換」できる理由は次のとおりです。
この構造体のフィールド情報はリフレクションを通じて読み取られます。
同様に、Save(&class)これらのフィールドを反復処理すると、UPDATE ... SET name=?, email=?, score=?。 -
ビジネスコードにタイプセーフキャリアを与える
タイプ的には、class.Name = "周末3"コンパイル時にチェックできます。
と置き換えますmap[string]interface{}制約はありません。フィールド名が正しく書かれていない場合、実行時まで爆発しません。

メイン.ゴー
package main
import (
"gin-quickstart/modules"
"gin-quickstart/routers"
"github.com/gin-contrib/sessions"
"github.com/gin-contrib/sessions/cookie"
"github.com/gin-gonic/gin"
)
// "gin-quickstart/routers" 表示引入 routers 包(也就是引入我们创建的路由文件夹),用于注册路由
func main() {
// 创建一个默认的路由引擎
r := gin.Default()
// 配置session中间件,基于cookie存储引擎
store := cookie.NewStore([]byte("miYao"))
r.Use(sessions.Sessions("mysession", store))
// 允许跨域中间件(注意:必须写在路由注册【之前】才对已注册路由生效)
r.Use(func(c *gin.Context) {
c.Header("Access-Control-Allow-Origin", "*") // 允许所有来源(学习阶段够用)
c.Header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
c.Header("Access-Control-Allow-Headers", "Content-Type")
// 浏览器发复杂请求前会先发 OPTIONS 预检,直接放行
if c.Request.Method == "OPTIONS" {
c.AbortWithStatus(204)
return
}
c.Next()
})
// 注册用户路由,routers表示的是路由包,
// UserRouters表示的是路由函数(也就是这个包中user.go文件中的函数)
routers.UserRouters(r)
r.GET("/session/set", func(c *gin.Context) {
session := sessions.Default(c)
// 设置session
session.Set("sessionID", "zs20161016")
// 保存session,这一步是必须的哈
session.Save()
c.JSON(200, gin.H{
"msg": "hello gin",
})
})
r.GET("/session/get", func(c *gin.Context) {
session := sessions.Default(c)
// 获取session:Get 只返回一个值,取不到时返回 nil
sessionID := session.Get("sessionID")
c.JSON(200, gin.H{
// 转换为字符串类型
"msg": "sessionID: " + sessionID.(string),
})
})
// 查询
r.GET("/class", func(c *gin.Context) {
classList := []modules.Class{}
modules.DB.Find(&classList)
c.JSON(200, gin.H{
"msg": "获取班级列表成功",
"list": classList,
})
})
// 启动服务,端口为8080,当然你也可以更改的哈
r.Run(":8087")
}

追加機能を実装する
package main
import (
"gin-quickstart/modules"
"gin-quickstart/routers"
"github.com/gin-contrib/sessions"
"github.com/gin-contrib/sessions/cookie"
"github.com/gin-gonic/gin"
)
// "gin-quickstart/routers" 表示引入 routers 包(也就是引入我们创建的路由文件夹),用于注册路由
func main() {
// 创建一个默认的路由引擎
r := gin.Default()
// 配置session中间件,基于cookie存储引擎
store := cookie.NewStore([]byte("miYao"))
r.Use(sessions.Sessions("mysession", store))
// 允许跨域中间件(注意:必须写在路由注册【之前】才对已注册路由生效)
r.Use(func(c *gin.Context) {
c.Header("Access-Control-Allow-Origin", "*") // 允许所有来源(学习阶段够用)
c.Header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
c.Header("Access-Control-Allow-Headers", "Content-Type")
// 浏览器发复杂请求前会先发 OPTIONS 预检,直接放行
if c.Request.Method == "OPTIONS" {
c.AbortWithStatus(204)
return
}
c.Next()
})
// 注册用户路由,routers表示的是路由包,
// UserRouters表示的是路由函数(也就是这个包中user.go文件中的函数)
routers.UserRouters(r)
r.GET("/session/set", func(c *gin.Context) {
session := sessions.Default(c)
// 设置session
session.Set("sessionID", "zs20161016")
// 保存session,这一步是必须的哈
session.Save()
c.JSON(200, gin.H{
"msg": "hello gin",
})
})
r.GET("/session/get", func(c *gin.Context) {
session := sessions.Default(c)
// 获取session:Get 只返回一个值,取不到时返回 nil
sessionID := session.Get("sessionID")
c.JSON(200, gin.H{
// 转换为字符串类型
"msg": "sessionID: " + sessionID.(string),
})
})
r.GET("/addClass", func(c *gin.Context) {
// 不需要制定id,因为id会自动新增的
class := modules.Class{
Name: "周末",
Email: "123456@163.com",
Score: 33,
}
modules.DB.Create(&class)
c.JSON(200, gin.H{
"msg": "添加班级成功",
})
})
// 启动服务,端口为8080,当然你也可以更改的哈
r.Run(":8087")
}


ID が 6 のデータをクエリします
r.GET("/getId", func(c *gin.Context) {
// 查询id等于6的数据
class := modules.Class{ID: 6}
modules.DB.Find(&class)
c.JSON(200, gin.H{
"msg": "查询更改",
"class": class,
})
})

データを更新する
r.GET("/update", func(c *gin.Context) {
// 查询id等于6的数据
class := modules.Class{ID: 6}
modules.DB.Find(&class)
// 修改班级名称为周末2
class.Name = "周末2"
// 修改班级成绩为34
class.Score = 34
modules.DB.Save(&class)
c.JSON(200, gin.H{
"msg": "查询更改",
"class": class,
})
})

更新する別の方法
r.GET("/update", func(c *gin.Context) {
// 更新id等于6的数据
class := modules.Class{}
modules.DB.Where("id = ?", 6).First(&class)
// 修改班级名称为周末3
class.Name = "周末3"
// 修改班级成绩为34
class.Score = 34
modules.DB.Save(&class)
c.JSON(200, gin.H{
"msg": "更新班级成功",
"class": class,
})
})

ID が 6 のデータを削除します
r.GET("/delete", func(c *gin.Context) {
// 删除id等于6的数据
class := modules.Class{ID: 6}
modules.DB.Delete(&class)
c.JSON(200, gin.H{
"msg": "删除成功",
})
})

ユーザー名の削除は週末です
r.GET("/delete", func(c *gin.Context) {
// 删除用户名称是 周末 的用户
class := modules.Class{}
modules.DB.Where("name = ?", "周末").Delete(&class)
c.JSON(200, gin.H{
"msg": "删除成功",
})
})