最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Go ORM的封裝解決方式詳解

 更新時(shí)間:2023年01月13日 09:46:38   作者:Afu  
這篇文章主要為大家介紹了Go ORM的封裝解決方式詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

背景

去年慢慢開(kāi)始接觸了Go語(yǔ)言,也在公司寫(xiě)了幾個(gè)Go的生產(chǎn)項(xiàng)目。我是從Java轉(zhuǎn)過(guò)來(lái)的。(其實(shí)也不算轉(zhuǎn),公司用啥,我用啥)在這個(gè)過(guò)程中,老是想用Java的思維寫(xiě)Go,在開(kāi)始的一兩個(gè)月,那是邊寫(xiě)邊吐槽。

丑陋的錯(cuò)誤處理,沒(méi)有流式處理,還竟然沒(méi)有泛型,框架生態(tài)鏈不成熟,沒(méi)有一家獨(dú)大的類(lèi)似Spring的框架。(其實(shí)現(xiàn)在寫(xiě)了快一年的Go,Go還是挺香的,哈哈)

今天,我來(lái)聊一下,我在我在寫(xiě)Go過(guò)程中用的最多orm框架gorm。

Java的orm

寫(xiě)過(guò)Java的基本都知道Mybatis,Mybatis-plus。

在Mybatis-plus中操作單表非常方便,通過(guò)QueryWrapper,對(duì)于單表的操作非常的絲滑,沒(méi)有任何的思維負(fù)擔(dān)。

類(lèi)似下面這樣:

        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(User::getUsername,"zhangsan").eq(User::getAge,18);
        userMapper.selectList(queryWrapper);

Go的orm

這里的條件查詢(xún)都需要開(kāi)發(fā)手動(dòng)來(lái)拼接字符串,如果項(xiàng)目比較大的話(huà),就會(huì)看到漫天飛的SQL字段,維護(hù)起來(lái)非常麻煩。

  var users []*User
  sqlResult := db.Where("username = ? and age = ?", "zhangsan", 18).Find(&users)

解決方式

寫(xiě)了一段時(shí)間的Go之后,實(shí)在不想每次都寫(xiě)這些字符串拼接了,于是我給gorm封裝了一個(gè)gorm-plus。

這里我使用到了go 1.18的泛型。泛型出了這么久,也該使用上了。

其實(shí)就是把Mybatis-plus的那套語(yǔ)法借鑒了一下。(好吧,就是抄他的)

Mybatis-plus對(duì)于單表操作提供了非常多的CRUD操作。

我給gorm-plus 也提供了類(lèi)似的操作

下面是具體用法

下載:

go get github.com/acmestack/gorm-plus

初始化sql

DROP TABLE IF EXISTS `users`;
CREATE TABLE `users`  (
                          `id` int(0) NOT NULL AUTO_INCREMENT,
                          `username` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
                          `password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
                          `age` int(0) NULL DEFAULT NULL,
                          `phone` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
                          `score` int(0) NULL DEFAULT NULL,
                          `address` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
                          `dept` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
                          `created_at` datetime(0) NULL DEFAULT NULL,
                          `updated_at` datetime(0) NULL DEFAULT NULL,
                          PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
SET FOREIGN_KEY_CHECKS = 1;

連接數(shù)據(jù)庫(kù)

var GormDb *gorm.DB
func init() {
  dsn := "root:123456@tcp(127.0.0.1:3306)/test?charset=utf8mb4&parseTime=True&loc=Local"
  var err error
  GormDb, err = gorm.Open(mysql.Open(dsn), &gorm.Config{
    Logger: logger.Default.LogMode(logger.Info),
  })
  if err != nil {
    log.Fatalln(err)
  }
  gplus.Init(GormDb)
}

插入語(yǔ)句

  user := &User{Username: "zhangsan", Password: "123456", Age: 18, Score: 100, Dept: "A部門(mén)"}
  result := gplus.Insert(user)
  fmt.Println(result.RowsAffected)

查詢(xún)語(yǔ)句

根據(jù)id查詢(xún):

注意這里需要傳入泛型User

  user, resultDb := gplus.SelectById[User](1)
  fmt.Println(user, resultDb.RowsAffected)

根據(jù)ids查詢(xún):

  var ids = []int{1,2}
  users, resultDb := gplus.SelectByIds[User](ids)
  fmt.Println(users, resultDb.RowsAffected)

條件查詢(xún):

  q := gplus.NewQuery[User]()
  q.Eq("username", "zhangsan").Eq("age",18)
  users, resultDb := gplus.SelectList(q)
  fmt.Println(users,resultDb.RowsAffected)

對(duì)比一下Mybatis-plus寫(xiě)法基本一致了。

        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(User::getUsername,"zhangsan").eq(User::getAge,18);
        userMapper.selectList(queryWrapper);

更多操作請(qǐng)查看:

github.com/acmestack/g…

gplus工具

其實(shí)上面的寫(xiě)法還是需要寫(xiě)數(shù)據(jù)庫(kù)的字段名,如果數(shù)據(jù)庫(kù)的字段名很多,我們很容易寫(xiě)錯(cuò),導(dǎo)致不必要的bug 產(chǎn)生。

一旦名稱(chēng)長(zhǎng),非常容易誤寫(xiě),而且如果有字段名稱(chēng)修改的話(huà),還需要全局搜索一個(gè)個(gè)地修改,比較麻煩。

Go沒(méi)有提供類(lèi)似Java的lambad表達(dá)式或者C#中 nameof 方式直接獲取某個(gè)對(duì)象的字段名稱(chēng)的操作,但是我們可以通過(guò)生成代碼的方式生成字段名。

所有就有了gplus,它作用就是自動(dòng)識(shí)別結(jié)構(gòu)體,把結(jié)構(gòu)體的字段名生成出來(lái)。

下載使用:

go install github.com/acmestack/gorm-plus/cmd/gplus@latest

通過(guò) gplus gen paths=路徑,gplus 會(huì)自動(dòng)識(shí)別帶有// +gplus:column=true注釋的結(jié)構(gòu)體,給這個(gè)結(jié)構(gòu)體生成字段。

gplus 會(huì)在輸入的路徑下面生成 zz_gen.column.go文件。

例如:

在example目錄下創(chuàng)建了了一個(gè)users.go 目錄,執(zhí)行 gplus gen paths=./eample

users.go

// +gplus:column=true
type User struct {
  ID        int64
  Username  string `gorm:"column:username"`
  Password  string
  Address   string
  Age       int
  Phone     string
  Score     int
  Dept      string
  CreatedAt time.Time
  UpdatedAt time.Time
}

zz_gen.column.go (自動(dòng)生成的)

var UserColumn = struct {
  ID        string
  Username  string
  Password  string
  Address   string
  Age       string
  Phone     string
  Score     string
  Dept      string
  CreatedAt string
  UpdatedAt string
}{
  ID:        "id",
  Username:  "username",
  Password:  "password",
  Address:   "address",
  Age:       "age",
  Phone:     "phone",
  Score:     "score",
  Dept:      "dept",
  CreatedAt: "created_at",
  UpdatedAt: "updated_at",
}

其實(shí)你自己也可以手寫(xiě)這個(gè)文件,只不過(guò)通過(guò)工具生成更加方便而已。

有了這個(gè)文件,我們的查詢(xún)就變成這樣:

  q := gplus.NewQuery[User]()
  q.Eq(UserColumn.Username, "zhangsan").Eq(UserColumn.Age,18)
  users, resultDb := gplus.SelectList(q)
  fmt.Println(users,resultDb.RowsAffected)

這樣維護(hù)起來(lái)就非常方便了。

最后

更多的用法請(qǐng)查看github地址:https://github.com/acmestack/gorm-plus

以上就是Go ORM的封裝解決方式詳解的詳細(xì)內(nèi)容,更多關(guān)于Go ORM封裝的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Golang繼承模擬實(shí)例詳解

    Golang繼承模擬實(shí)例詳解

    這篇文章主要介紹了Golang繼承模擬方法,結(jié)合實(shí)例形式分析了Go語(yǔ)言實(shí)現(xiàn)繼承的原理與相關(guān)操作技巧,需要的朋友可以參考下
    2016-07-07
  • golang API開(kāi)發(fā)過(guò)程的中的自動(dòng)重啟方式(基于gin框架)

    golang API開(kāi)發(fā)過(guò)程的中的自動(dòng)重啟方式(基于gin框架)

    這篇文章主要介紹了golang API開(kāi)發(fā)過(guò)程的中的自動(dòng)重啟方式(基于gin框架),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-12-12
  • golang image圖片處理示例

    golang image圖片處理示例

    這篇文章主要介紹了golang image圖片處理的方法,結(jié)合實(shí)例形式分析了Go語(yǔ)言針對(duì)圖片的打開(kāi)、讀取、轉(zhuǎn)換等相關(guān)操作技巧,需要的朋友可以參考下
    2016-07-07
  • Go數(shù)據(jù)庫(kù)遷移的實(shí)現(xiàn)步驟

    Go數(shù)據(jù)庫(kù)遷移的實(shí)現(xiàn)步驟

    本文主要介紹了Go數(shù)據(jù)庫(kù)遷移的實(shí)現(xiàn)步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-07-07
  • Go語(yǔ)言omitempty選項(xiàng)的實(shí)現(xiàn)

    Go語(yǔ)言omitempty選項(xiàng)的實(shí)現(xiàn)

    本文主要介紹了Go語(yǔ)言omitempty選項(xiàng)的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • Go channel發(fā)送方和接收方如何相互阻塞等待源碼解讀

    Go channel發(fā)送方和接收方如何相互阻塞等待源碼解讀

    這篇文章主要為大家介紹了Go channel發(fā)送方和接收方如何相互阻塞等待源碼解讀,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-12-12
  • 詳解Go語(yǔ)言如何對(duì)數(shù)據(jù)庫(kù)進(jìn)行CRUD操作

    詳解Go語(yǔ)言如何對(duì)數(shù)據(jù)庫(kù)進(jìn)行CRUD操作

    在這篇文章中,主要帶大家來(lái)學(xué)習(xí)一下在Go語(yǔ)言中如何對(duì)數(shù)據(jù)庫(kù)進(jìn)行CRUD操作,從而探討一下Go的接口編程,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-05-05
  • Go語(yǔ)言的IO庫(kù)那么多糾結(jié)該如何選擇

    Go語(yǔ)言的IO庫(kù)那么多糾結(jié)該如何選擇

    在Go語(yǔ)言中涉及 I/O 操作的內(nèi)置庫(kù)有很多種,比如: io 庫(kù), os 庫(kù), ioutil 庫(kù), bufio 庫(kù), bytes 庫(kù), strings 庫(kù)等等。擁有這么多內(nèi)置庫(kù)是好事,但是具體到涉及 I/O 的場(chǎng)景我們應(yīng)該選擇哪個(gè)庫(kù)呢,帶著這個(gè)問(wèn)題一起通過(guò)本文學(xué)習(xí)下吧
    2021-06-06
  • golang struct擴(kuò)展函數(shù)參數(shù)命名警告解決方法

    golang struct擴(kuò)展函數(shù)參數(shù)命名警告解決方法

    今天在使用VSCode編寫(xiě)golang代碼時(shí),定義一個(gè)struct,擴(kuò)展幾個(gè)方法,需要的朋友可以參考下
    2017-02-02
  • golang接口IP限流,IP黑名單,IP白名單的實(shí)例

    golang接口IP限流,IP黑名單,IP白名單的實(shí)例

    這篇文章主要介紹了golang接口IP限流,IP黑名單,IP白名單的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-12-12

最新評(píng)論

惠来县| 香格里拉县| 屏南县| 云浮市| 黄龙县| 兴安县| 略阳县| 景谷| 交城县| 清远市| 太原市| 兴文县| 秀山| 鸡东县| 咸丰县| 阿坝县| 泗阳县| 青州市| 长汀县| 海南省| 得荣县| 临高县| 乌审旗| 于田县| 三都| 施甸县| 济宁市| 上栗县| 宜兴市| 闽清县| 杭锦后旗| 宁德市| 平陆县| 达尔| 怀化市| 齐齐哈尔市| 白沙| 岳池县| 定边县| 河池市| 额济纳旗|