記事ディレクトリ
モデル定義と Gorm の初期化については、以前の記事https://mingvvv.blog.csdn.net/article/details/129026914を参照してください。
まず接続プールを初期化します
db := cus_orm.MysqlConnection()
単一レコードを追加する
モデルオブジェクトを直接追加する
Debug() を使用して SQL ステートメントを出力すると、開発中に観察しやすくなります。
user := &model.User{
Name: "姓名",
}
// 添加一条
if err := db.Debug().Create(user).Error; err != nil {
fmt.Println(err)
return
}
-------------------------------------------
INSERT INTO `user` (`name`,`infant_name`,`age`,`user_desc`,`json_field`,`create_time`,`update_time`) VALUES ('姓名','',18,'这是一条默认描述',NULL,'2023-03-01 15:24:56','2023-03-01 15:24:56')
ここのオブジェクトでは、Nameにのみ値を割り当てますが、次の理由により、他のフィールドにも実際に実行されるSQL の値が含まれます。
デフォルト値の割り当て方法 1: gorm label
デフォルト値の割り当て方法2: setフックメソッド(Hooks)
次のメソッドを構造に追加します。
モデル オブジェクトが作成されると、これら 4 つのメソッドが順番に呼び出され、実行シーケンスは
BeforeSave => BeforeCreate => AfterCreate => AfterSave となる
ため、これらのメソッドでオブジェクトに対していくつかの操作を実行できます。次のように、CreateTime、UpdateTime、および UserDesc に単純な割り当てが行われます。
... ...
func (u *User) BeforeCreate(tx *gorm.DB) (err error) {
u.CreateTime = time.Unix(time.Now().Unix(), 0) //初始化创建时间
u.UpdateTime = time.Unix(time.Now().Unix(), 0) //初始化修改时间
u.UserDesc = "这是一条默认描述"
fmt.Println("BeforeCreate -- Auto Setting")
return
}
... ...
指定したフィールドを挿入します
db.Debug().Select("Name").Create(&user)
db.Debug().Select("Name","UserDesc").Create(&user)
---------------------------
INSERT INTO `user` (`name`) VALUES ('姓名')
INSERT INTO `user` (`name`,`user_desc`) VALUES ('姓名','这是一条默认描述')
挿入時に一部のフィールドを無視する
更新時間を無視する
db.Debug().Omit("UpdateTime").Create(&user)
----------------------------------------------
INSERT INTO `user` (`name`,`infant_name`,`age`,`user_desc`,`json_field`,`create_time`,`id`) VALUES ('姓名','',18,'这是一条默认描述',NULL,'2023-03-01 15:50:59',539)
挿入時にフックメソッドは禁止されています
場合によっては、保存時のデータの前処理に Dog メソッドが必要ない場合があるため、フック メソッドを無効にしてSession(&gorm.Session{SkipHooks: true})
を使用する必要があります。上記のフック メソッドが実行されないことがわかります。
import "gorm.io/gorm"
db.Debug().Omit("UpdateTime").Session(&gorm.Session{
SkipHooks: true}).Create(&user)
-------------------------------------------
INSERT INTO `user` (`name`,`infant_name`,`age`,`user_desc`,`json_field`,`create_time`,`update_time`) VALUES ('姓名','',18,'',NULL,'0000-00-00 00:00:00','0000-00-00 00:00:00')
複数のレコードを追加する
オブジェクトリストごとに挿入
CreateInBatches(&users, 100) 100 は、毎回挿入される最大行数を意味します。リスト内のオブジェクトの数がこの値より大きい場合、バッチごとに最大 100 行で挿入されます。
users := []model.User{
{
Name: "测试goper111",
},
{
Name: "测试goper222",
},
{
Name: "测试goper333",
},
}
db.Debug().CreateInBatches(&users, 100)
--------------------------------------------------------------------
INSERT INTO `user` (`name`,`infant_name`,`age`,`user_desc`,`json_field`,`create_time`,`update_time`) VALUES
('测试goper111','',18,'这是一条默认描述',NULL,'2023-03-01 16:04:18','2023-03-01 16:04:18'),
('测试goper222','',18,'这是一条默认描述',NULL,'2023-03-01 16:04:18','2023-03-01 16:04:18'),
('测试goper333','',18,'这是一条默认描述',NULL,'2023-03-01 16:04:18','2023-03-01 16:04:18')
辞書のリストによる挿入
db.Model(&model.User{
}).Debug().Create([]map[string]interface{
}{
{
"Name": "姓名1", "Age": 18},
{
"Name": "姓名2", "Age": 20},
})
-------------------
INSERT INTO `user` (`age`,`name`) VALUES
(18,'姓名1'),
(20,'姓名2')
辞書での SQL 組み込み関数の使用
使用句.Expr{SQL: "組み込み関数"、Vars: []インターフェイス{}{パラメータ オブジェクト}}
import "gorm.io/gorm/clause"
db.Model(&model.User{
}).Debug().Create([]map[string]interface{
}{
{
"Name": clause.Expr{
SQL: "Concat(?,?)", Vars: []interface{
}{
"姓名", "拼接"}}, "Age": 18},
})
----------------------------------------
INSERT INTO `user` (`age`,`name`) VALUES (18,Concat('姓名','拼接'))
組み込み関数を利用する方法もありますが、事前にデータ型をカスタマイズする必要があり面倒です。
実装プロセスは次のアドレスを参照できます
https://gorm.io/docs/data_types.html#GormValuerInterface
連想挿入
User 構造では、最後の 2 つのフィールドは他の 2 つのテーブルに関連しています。
挿入するオブジェクト内のこれら 2 つの要素が null 値ではない場合、これら 2 つの構造に対応するテーブルにもデータが挿入されます。上の赤いボックスでは、外部キー関係を定式化していることに注意してください。つまり、2 つのテーブルの user_id がユーザー テーブルの外部キーであるため、挿入時に 2 つのテーブルの user_id がユーザー テーブルの ID として自動的に割り当てられます
。
user2 := &model.User{
Name: "姓名",
UserRole: model.UserRole{
RoleId: 1,
},
UserExtend: model.UserExtend{
Gender: 1,
},
}
db.Debug().Create(&user2)
--------------------------------------------
INSERT INTO `user_role` (`user_id`,`role_id`) VALUES (546,1) ON DUPLICATE KEY UPDATE `user_id`=VALUES(`user_id`)
INSERT INTO `user_extend` (`user_id`,`gender`) VALUES (546,1) ON DUPLICATE KEY UPDATE `user_id`=VALUES(`user_id`)
INSERT INTO `user` (`name`,`infant_name`,`age`,`user_desc`,`json_field`,`create_time`,`update_time`) VALUES ('姓名','',18,'这是一条默认描述',NULL,'2023-03-01 16:22:25','2023-03-01 16:22:25')
挿入のリンクを解除する
関連挿入を指定しない
以下は、user_role テーブルの関連する挿入をキャンセルします。
user2 := &model.User{
Name: "姓名",
UserRole: model.UserRole{
RoleId: 1,
},
UserExtend: model.UserExtend{
Gender: 1,
},
}
db.Debug().Omit("UserRole").Create(&user2)
-----------------------------------------
INSERT INTO `user_extend` (`user_id`,`gender`) VALUES (547,1) ON DUPLICATE KEY UPDATE `user_id`=VALUES(`user_id`)
INSERT INTO `user` (`name`,`infant_name`,`age`,`user_desc`,`json_field`,`create_time`,`update_time`) VALUES ('姓名','',18,'这是一条默认描述',NULL,'2023-03-01 16:29:09','2023-03-01 16:29:09')
関連するすべての挿入をキャンセルします
import "gorm.io/gorm/clause"
user2 := &model.User{
Name: "姓名",
UserRole: model.UserRole{
RoleId: 1,
},
UserExtend: model.UserExtend{
Gender: 1,
},
}
db.Debug().Omit(clause.Associations).Create(&user2)
-----------------------------------------
INSERT INTO `user` (`name`,`infant_name`,`age`,`user_desc`,`json_field`,`create_time`,`update_time`) VALUES ('姓名','',18,'这是一条默认描述',NULL,'2023-03-01 16:29:09','2023-03-01 16:29:09')
対立
テーブルを作成するとき、いくつかの一意のインデックスを作成しますが、そのようなインデックスに対応する列では、テーブル内で重複したデータが許可されません。
重複したデータを挿入すると、挿入時にエラーが報告されます。この場合、これらの競合を無視するか、挿入操作を変更操作に変えることができます。
競合を無視する
競合が発生した場合は、id を id に変更します。これは本質的に何もしないのと同じです。
user := &model.User{
Id: 521,
Name: "姓名",
JsonField: map[string]string{
"test": "test"},
}
db.Debug().Clauses(clause.OnConflict{
DoNothing: true}).Create(&user)
--------------------------------------------------
INSERT INTO `user` (`name`,`infant_name`,`age`,`user_desc`,`json_field`,`create_time`,`update_time`,`id`)
VALUES ('姓名','',18,'这是一条默认描述','{
"test":"test"}','2023-03-01 16:55:24','2023-03-01 16:55:24',521)
ON DUPLICATE KEY UPDATE `id`=`id`
行レコードを変更するには競合があります
競合が発生した場合は、フィールドを新しい値に変更します。
user := &model.User{
Id: 521,
Name: "姓名",
JsonField: map[string]string{
"test": "test"},
}
db.Debug().Clauses(clause.OnConflict{
UpdateAll: true}).Create(&user)
---------------------------------------
INSERT INTO `user` (`name`,`infant_name`,`age`,`user_desc`,`json_field`,`create_time`,`update_time`,`id`)
VALUES ('姓名','',18,'这是一条默认描述','{
"test":"test"}','2023-03-01 17:20:13','2023-03-01 17:20:13',521)
ON DUPLICATE KEY UPDATE `name`=VALUES(`name`),`infant_name`=VALUES(`infant_name`),`age`=VALUES(`age`),`user_desc`=VALUES(`user_desc`),`json_field`=VALUES(`json_field`),`create_time`=VALUES(`create_time`),`update_time`=VALUES(`update_time`)
競合が発生した場合は、指定されたフィールドを新しい値に変更します
db.Debug().Clauses(clause.OnConflict{
DoUpdates: clause.AssignmentColumns([]string{
"json_field", "name"}),
}).Create(&user)
---------------------------------------
INSERT INTO `user` (`name`,`infant_name`,`age`,`user_desc`,`json_field`,`create_time`,`update_time`,`id`)
VALUES ('姓名','',18,'这是一条默认描述','{
"test":"test"}','2023-03-01 17:17:35','2023-03-01 17:17:35',521)
ON DUPLICATE KEY UPDATE `user_desc`=VALUES(`user_desc`),`name`=VALUES(`name`)
競合が発生した場合は、指定されたフィールドの内容を変更します
db.Debug().Clauses(clause.OnConflict{
DoUpdates: clause.Assignments(map[string]interface{
}{
"user_desc": "冲突后做了修改"}),
}).Create(&user)
--------------------------------------------------
INSERT INTO `user` (`name`,`infant_name`,`age`,`user_desc`,`json_field`,`create_time`,`update_time`,`id`)
VALUES ('姓名','',18,'这是一条默认描述','{"test":"test"}','2023-03-01 16:51:45','2023-03-01 16:51:45',521)
ON DUPLICATE KEY UPDATE `user_desc`='冲突后做了修改'
組み込み関数を使用する
db.Debug().Clauses(clause.OnConflict{
DoUpdates: clause.Assignments(map[string]interface{
}{
"user_desc": gorm.Expr("Concat('测试', '拼接')")}),
}).Create(&user)
--------------------------------------------------
INSERT INTO `user` (`name`,`infant_name`,`age`,`user_desc`,`json_field`,`create_time`,`update_time`,`id`)
VALUES ('姓名','',18,'这是一条默认描述','{"test":"test"}','2023-03-01 17:15:17','2023-03-01 17:15:17',521)
ON DUPLICATE KEY UPDATE `user_desc`=Concat('测试', '拼接')