<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Go 數(shù)據(jù)存儲篇(七):GORM 使用入門

          共 4386字,需瀏覽 9分鐘

           ·

          2020-10-06 06:29


          1、ORM 與 GORM

          我們已經(jīng)成功存儲數(shù)據(jù)到數(shù)據(jù)表,但是所有操作都要自行編寫代碼,很多編程語言和框架會引入 ORM 來解決模型類與數(shù)據(jù)表記錄的映射關(guān)系,ORM 架起了 SQL 語句和應(yīng)用程序之間的橋梁,將模型類和數(shù)據(jù)表映射起來,將模型類字段和數(shù)據(jù)表字段建立關(guān)聯(lián)。

          典型的 ORM 庫比如 Java 中的 Hibernate、Ruby 中的 ActiveRecord、以及 Laravel 中的 Eloquent。

          在 Go 語言中,也有這樣的 ORM 庫,最流行的當(dāng)屬 GORM。

          GORM 是一個適用于 Go 語言的 ORM 庫,遵循 ActiveRecord 模式進(jìn)行設(shè)計(jì)。

          注:ORM 有兩種實(shí)現(xiàn)方式 —— ActiveRecord 和 DataMapper,關(guān)于兩者之間的區(qū)別可以參考這篇教程:https://xueyuanjun.com/post/966.html。

          GORM 的功能非常強(qiáng)大,除了基本的基于模型類對數(shù)據(jù)表進(jìn)行增刪改查之外,還支持定義關(guān)聯(lián)關(guān)系、執(zhí)行數(shù)據(jù)表遷移、查詢鏈以及很多其他高級特性,并且支持在特定事件發(fā)生時(比如插入、更新、刪除)觸發(fā)指定的回調(diào)函數(shù)(類似 Laravel 框架的模型事件)。

          下面我們來簡單演示下如何基于 GORM 進(jìn)行增刪改查和關(guān)聯(lián)查詢。

          2、GORM 使用示例

          使用之前需要先安裝 GORM:

          go?get?github.com/jinzhu/gorm

          然后我們編寫一段示例代碼:

          package?main

          import?(
          ????"fmt"
          ????"github.com/jinzhu/gorm"
          ????_?"github.com/jinzhu/gorm/dialects/mysql"
          ????"time"
          )

          type?Post?struct?{
          ????Id?int
          ????Title?string
          ????Content?string
          ????Author?string?`sql:"not?null"`
          ????CreatedAt?time.Time
          ????Comments?[]Comment
          }

          type?Comment?struct?{
          ????Id?int
          ????Content?string
          ????Author?string?`sql:"not?null"`
          ????PostId?int?`sql:"index"`
          ????CreatedAt?time.Time
          }

          var?DbConn?*gorm.DB

          func?init()??{
          ????var?err?error
          ????DbConn,?err?=?gorm.Open("mysql",?"root:root@/test_db?charset=utf8mb4&parseTime=true")
          ????if?err?!=?nil?{
          ????????panic(err)
          ????}
          ????DbConn.AutoMigrate(&Post{},?&Comment{})
          }

          func?main()??{
          ????post?:=?Post{Title:?"GORM?示例教程",?Content:?"基于?GORM?進(jìn)行數(shù)據(jù)庫增刪改查",?Author:?"學(xué)院君"}

          ????//?通過?GORM?插入文章記錄
          ????DbConn.Create(&post)
          ????fmt.Println(post)

          ????//?通過關(guān)聯(lián)關(guān)系新增評論并將其附加到對應(yīng)的文章記錄
          ????comment?:=?Comment{Content:?"Test?Comment",?Author:?"學(xué)院君小號"}
          ????DbConn.Model(&post).Association("Comments").Append(comment)

          ????//?查詢文章記錄
          ????var?gormPost?Post
          ????DbConn.Where("author?=??",?"學(xué)院君").First(&gormPost)

          ????//?查詢包含評論數(shù)據(jù)的文章記錄
          ????var?comments?[]Comment
          ????DbConn.Model(&gormPost).Related(&comments)
          ????fmt.Println(comments[0])
          }

          由于 GORM 會根據(jù)模型類結(jié)構(gòu)體聲明自動創(chuàng)建對應(yīng)的數(shù)據(jù)表,所以我們可以刪除 test_db 數(shù)據(jù)庫中的 postscomments 表,然后運(yùn)行這段代碼看看結(jié)果是否符合預(yù)期:

          可以看到,數(shù)據(jù)表的插入和關(guān)聯(lián)查詢結(jié)果都是正常的。下面我們簡單分析下這段示例代碼。

          3、GORM 運(yùn)行原理

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

          由于 GORM 也實(shí)現(xiàn)了 database/sql 接口,所以建立數(shù)據(jù)庫連接和之前使用 go-sql-driver/mysql 包類似,只是調(diào)用方法改成了 gorm.Open

          DbConn,?err?=?gorm.Open("mysql",?"root:root@/test_db?charset=utf8mb4&parseTime=true")

          參數(shù)和之前完全一樣,引入的驅(qū)動包調(diào)整為 jinzhu/gorm 即可:

          "github.com/jinzhu/gorm"
          _?"github.com/jinzhu/gorm/dialects/mysql"

          注:更多關(guān)于 GORM 數(shù)據(jù)庫連接配置的細(xì)節(jié),請參考 GORM 官方文檔(https://gorm.io/zh_CN/docs/)。

          數(shù)據(jù)表自動遷移

          和使用 go-sql-driver/mysql 包不同的是,這次我們不再需要手動創(chuàng)建數(shù)據(jù)表,因?yàn)?GORM 提供了數(shù)據(jù)表自動遷移功能:

          DbConn.AutoMigrate(&Post{},?&Comment{})

          通過 AutoMigrate 方法傳入要遷移的模型類實(shí)例即可,GORM 會自動創(chuàng)建對應(yīng)的數(shù)據(jù)表,表名規(guī)則是模型類名小寫的復(fù)數(shù)形式。

          模型類定義

          接下來,我們看下模型類的定義:

          type?Post?struct?{
          ????Id?int
          ????Title?string
          ????Content?string
          ????Author?string?`sql:"not?null"`
          ????CreatedAt?time.Time
          ????Comments?[]Comment
          }

          type?Comment?struct?{
          ????Id?int
          ????Content?string
          ????Author?string?`sql:"not?null"`
          ????PostId?int?`sql:"index"`
          ????CreatedAt?time.Time
          }

          這里定義了兩個模型類,PostComment,分別對應(yīng)數(shù)據(jù)表 postscomments,并且在 Post 中通過如下方式定義了 PostComment 之間的一對多關(guān)聯(lián):

          Comments?[]Comment

          這里我們沒有用結(jié)構(gòu)體標(biāo)簽指定關(guān)聯(lián)外鍵(GORM 支持通過結(jié)構(gòu)體標(biāo)簽設(shè)置數(shù)據(jù)表字段屬性),GORM 底層會自動維護(hù)這個關(guān)聯(lián),默認(rèn)規(guī)則是在 Comment 中的 PostId 字段(即當(dāng)前模型類名加上主鍵 ID 后綴)。

          但是還是有一些字段設(shè)置了結(jié)構(gòu)體標(biāo)簽,這是為了給該字段添加額外的數(shù)據(jù)表字段約束,比如索引、是否允許為空等:

          Author?string?`sql:"not?null"`
          PostId?int?`sql:"index"`

          注:更多模型類定義的細(xì)節(jié)和結(jié)構(gòu)體標(biāo)簽設(shè)置,請參考 GORM 官方文檔。

          增刪改查

          我們繼續(xù)來看增刪改查和關(guān)聯(lián)模型的操作,在 GORM 中,我們總算不用維護(hù) SQL 語句了,所有的增刪改查操作都可以通過 GORM 庫提供的方法來實(shí)現(xiàn),比如要創(chuàng)建一條記錄可以這么做:

          post?:=?Post{Title:?"GORM?示例教程",?Content:?"基于?GORM?進(jìn)行數(shù)據(jù)庫增刪改查",?Author:?"學(xué)院君"}
          DbConn.Create(&post)

          模型類中的 IdCreatedAt 字段系統(tǒng)會自動維護(hù),不需要顯示設(shè)置。

          注:如果要實(shí)現(xiàn)修改、刪除和查詢操作,請參考 GORM 官方文檔 CRUD 接口部分,這些也都有相應(yīng)的內(nèi)置方法。

          關(guān)聯(lián)查詢

          如果要在上述模型實(shí)例上創(chuàng)建與之關(guān)聯(lián)的評論,可以這么做:

          comment?:=?Comment{Content:?"Test?Comment",?Author:?"學(xué)院君小號"}
          DbConn.Model(&post).Association("Comments").Append(comment)

          最后要查詢包含關(guān)聯(lián)評論記錄的主題,可以這么做:

          var?gormPost?Post
          DbConn.Where("author?=??",?"學(xué)院君").First(&gormPost)

          var?comments?[]Comment
          DbConn.Model(&gormPost).Related(&comments)

          注:更多關(guān)聯(lián)查詢和操作的使用,請參考 GORM 官方文檔的關(guān)聯(lián)部分。

          4、小結(jié)

          可以看到,引入 GROM 之后,我們不再需要手動編寫復(fù)雜的 SQL 語句,只需要借助 GORM 提供的方法就可以非常便捷地完成數(shù)據(jù)庫交互,這極大簡化了我們?nèi)粘i_發(fā)的代碼編寫和維護(hù)成本,也降低了安全風(fēng)險(xiǎn),所有的 SQL 語句都由 GORM 底層去構(gòu)建并執(zhí)行,它會將上層模型實(shí)例的增刪改查、關(guān)聯(lián)操作方法執(zhí)行轉(zhuǎn)化為相應(yīng)的 SQL 語句去執(zhí)行,這也是 ORM 的設(shè)計(jì)初衷。

          以上只是 GORM 的簡單示例,完整功能請閱讀官方文檔(https://gorm.io/zh_CN/docs/),需要指出的是 GORM 的作者是中國人,所以中文文檔支持非常友好。

          關(guān)于 Go 語言的數(shù)據(jù)庫操作部分,我們就簡單介紹到這里,到目前為止,還并沒有看到 Go 語言相對于 PHP 開發(fā) Web 應(yīng)用的任何優(yōu)勢,接下來,我們來看看 Go 語言 Web 編程的重頭戲 —— 并發(fā)編程,這也是 Go 語言本身的優(yōu)勢所在。

          (全文完)


          推薦閱讀


          福利

          我為大家整理了一份從入門到進(jìn)階的Go學(xué)習(xí)資料禮包(下圖只是部分),同時還包含學(xué)習(xí)建議:入門看什么,進(jìn)階看什么。

          關(guān)注公眾號 「polarisxu」,回復(fù)?ebook?獲??;還可以回復(fù)「進(jìn)群」,和數(shù)萬 Gopher 交流學(xué)習(xí)。



          瀏覽 73
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  免费在线观看一区 | 青青草操逼网 | 一级a一级a爱片免费免免高潮按摩 | 青青草a 人人操人 | 免费成人一级片 |