自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Go 語言使用 XORM 操作 MySQL 的陷阱

數(shù)據(jù)庫 MySQL
本文我們介紹了使用 XORM 操作 MySQL 時,新手讀者朋友們可能會遇到的陷阱,希望可以給大家?guī)硪恍椭?/div>

01 介紹

在 Go 語言開發(fā)中,大家為了方便,通常會選擇使用 ORM 操作數(shù)據(jù)庫,比如使用 XORM 或 GORM 操作 MySQL。

雖然使用 ORM 操作 MySQL 比直接使用標(biāo)準(zhǔn)庫 `sql`[1] 和三方 MySQL 數(shù)據(jù)庫驅(qū)動包[2]操作 MySQL 更加方便,但是也會遇到一些陷阱。

本文我們來介紹一下使用 XORM[3] 操作 MySQL 可能會遇到的陷阱。

02 使用 XORM 操作 MySQL 的陷阱

類型零值

在 Golang 中,每個數(shù)據(jù)類型都有各自的類型零值,比如 int 的零值是 0,string 的零值是 ''等。

示例代碼:

package main

import (
 "fmt"
 _ "github.com/go-sql-driver/mysql"
 "xorm.io/xorm"
)

func main() {
 // 創(chuàng)建 Engine
 engine, err := xorm.NewEngine("mysql", "root:root@/example?charset=utf8")
 defer func() {
  err = engine.Close()
  if err != nil {
   fmt.Printf("engine close err=%v\n", err)
   return
  }
 }()
 if err != nil {
  fmt.Printf("init xorm engine fail, err=%v\n", err)
  return
 }

 // 更新數(shù)據(jù)
 example := &Example{
  Title: "go",
  View:  0,
 }
 condi := &Example{
  Id: 2,
 }
 affected, err := engine.Update(example, condi)
 if err != nil {
  fmt.Printf("Update err=%v\n", err)
  return
 }
 fmt.Printf("affected=%d\n", affected)
}

type Example struct {
 Id      int    `json:"id" form:"id"`
 Title   string `json:"title" form:"title"`
 View    int    `json:"view" form:"view"`
 Created int    `json:"created" form:"created" xorm:"created"`
 Updated int    `json:"updated" form:"updated" xorm:"updated"`
}

閱讀上面這段代碼,我們可以發(fā)現(xiàn)示例代碼中將 id=2 的數(shù)據(jù) view 字段更新為 0,因為 0 是 int 的類型零值,XORM 的 Update 方法會自動忽略類型零值,所以該數(shù)據(jù) view 字段的值沒有更改。

但是,在實際項目開發(fā)中,我們可能需要將某個字段的值更新為該字段類型的類型零值,此時我們該怎么操作呢?

affected, err := engine.Cols("title", "view").Update(example, condi)

我們可以使用 Cols() 方法,指定需要更新的字段,這樣即便需要更新字段的值是該字段類型的類型零值,也可以正常更改。

提示:建議在設(shè)計數(shù)據(jù)庫表時,字段的值盡量使用非類型零值。

自增 id

在插入數(shù)據(jù)時,我們可能需要返回自增 id,我們先看一段代碼:

// 插入數(shù)據(jù)
example := &Example{
  Title: "PHP",
  View:  90,
}
affected, err := engine.Insert(example)
if err != nil {
  fmt.Printf("Insert err=%v\n", err)
  return
}
fmt.Printf("affected=%v\n", affected)

閱讀上面這段代碼,我們插入一條數(shù)據(jù),返回結(jié)果是影響行數(shù)和錯誤信息,而不是直接返回該條數(shù)據(jù)的自增 id。

可能有些讀者朋友們會接著使用查詢方法,查詢最新一條數(shù)據(jù)的 id,在并發(fā)請求數(shù)低的場景中,該方法是可以查到新插入數(shù)據(jù)的自增 id。

但是在并發(fā)請求數(shù)高的場景中,該方法查到的最新一條數(shù)據(jù)的 id,未必是我們剛插入的數(shù)據(jù)的自增 id。

id := example.Id
fmt.Printf("affected=%v || id=%d\n", affected, id)

閱讀上面這段代碼,我們想要獲取新插入數(shù)據(jù)的自增 id,直接 example.Id 即可獲取,但是前提條件是結(jié)構(gòu)體中,id 字段使用 xorm:"autoincr" 標(biāo)簽。

更新 created 字段

我們在結(jié)構(gòu)體中,使用標(biāo)簽 xorm:created 和 xorm:updated 即可自動插入當(dāng)前時間。

但是,使用 xorm:created 標(biāo)簽的字段,只有在第一次插入數(shù)據(jù)時寫入當(dāng)前時間,此后將不再會更改;使用 xorm:updated 標(biāo)簽的字段,在第一次插入數(shù)據(jù)時寫入當(dāng)前時間,此后每次 Update 操作,時間都會更改。

如果我們的業(yè)務(wù)需求是需要更改使用 xorm:created 標(biāo)簽的字段,可以做到嗎?

// 更改數(shù)據(jù)
example := &Example{
  Title: "JavaScript",
  View:  98,
}

condi := &Example{
  Id: 2,
}

affected, err := engine.Update(example, condi)
if err != nil {
  fmt.Printf("Update err=%v\n", err)
  return
}
fmt.Printf("affected=%d\n", affected)

閱讀上面這段代碼,我們發(fā)現(xiàn)執(zhí)行 Update 方法之后,使用 xorm:updated 標(biāo)簽的字段的值被更改,而使用 xorm:created 標(biāo)簽的字段的值沒被更改。

我們換一種更新數(shù)據(jù)的方式,代碼如下:

// 更改數(shù)據(jù)
sql := "UPDATE example SET title=?, view=?, created=? WHERE id=?"
res, err := engine.Exec(sql, "Python", 60, time.Now().Unix(), 2)
if err != nil {
  fmt.Printf("Update err=%v\n", err)
  return
}
affected, err := res.RowsAffected()
if err != nil {
  fmt.Printf("RowsAffected err=%v\n", err)
  return
}
fmt.Printf("affected=%d\n", affected)

閱讀上面這段代碼,我們可以發(fā)現(xiàn)使用 Exec 方法執(zhí)行原生 SQL 可以滿足我們的需求。

03 總結(jié)

本文我們介紹了使用 XORM 操作 MySQL 時,新手讀者朋友們可能會遇到的陷阱,希望可以給大家?guī)硪恍椭?/p>

讀者朋友們在使用 XORM 或 GORM 操作 MySQL 時,還遇到過哪些陷阱,歡迎讀者朋友們在留言區(qū)分享。

責(zé)任編輯:武曉燕 來源: Golang語言開發(fā)棧
相關(guān)推薦

2021-10-26 10:51:30

GoxormMySQL

2023-06-26 00:03:55

Go語言類型

2021-07-08 23:53:44

Go語言拷貝

2024-01-07 23:11:16

defer?Go語言

2020-07-02 16:20:36

MySQLCURD數(shù)據(jù)庫

2024-01-07 19:54:51

2021-01-23 12:47:19

MySQL數(shù)據(jù)庫Go語言

2021-01-27 10:01:46

MySQL數(shù)據(jù)庫SQLX

2024-03-25 07:22:50

GolangMySQL數(shù)據(jù)庫

2024-12-30 00:38:23

Go語言微服務(wù)

2023-01-31 08:48:49

Go語言文件

2024-05-10 08:36:40

Go語言對象

2022-06-05 23:30:25

AES加密算法

2024-10-28 00:40:49

Go語法版本

2012-10-08 09:25:59

GoGo語言開發(fā)語言

2018-03-12 22:13:46

GO語言編程軟件

2024-09-13 09:58:54

MarotoGo語言

2022-08-08 06:50:06

Go語言閉包

2014-04-09 09:32:24

Go并發(fā)

2015-01-21 15:40:44

GoRuby
點贊
收藏

51CTO技術(shù)棧公眾號