乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      Go組件學(xué)習(xí)——gorm四步帶你搞定DB增刪改查

       F2967527 2019-08-08

      1、簡(jiǎn)介

      ORM

        Object-Relationl Mapping, 它的作用是映射數(shù)據(jù)庫和對(duì)象之間的關(guān)系,方便我們?cè)趯?shí)現(xiàn)數(shù)據(jù)庫操作的時(shí)候不用去寫復(fù)雜的sql語句,把對(duì)數(shù)據(jù)庫的操作上升到對(duì)于對(duì)象的操作。

      gorm

        gorm就是基于Go語言實(shí)現(xiàn)的ORM庫。

        類似于Java生態(tài)里大家聽到過的Mybatis、Hibernate、SpringData等。

      Github

        https://github.com/jinzhu/gorm

      官方文檔

        https:///

      2、如何使用Gorm

        只要四步就能上手gorm,可以盡情的沉浸在毫無技術(shù)含量的CRUD世界。

      2.1 下載gorm庫

        下載gorm庫

      go get -u github.com/jinzhu/gorm

        這是比較原始的方式,現(xiàn)在有了go mod,我們可以更方便的配置,甚至不用配置。

        寫好代碼,在文件下執(zhí)行g(shù)o build,go.mod會(huì)自動(dòng)添加對(duì)于gorm的依賴包

      github.com/jinzhu/gorm v1.9.10

        當(dāng)然,也可以手動(dòng)添加這個(gè)依賴。

        具體參見go-demo項(xiàng)目(https://github.com/DMinerJackie/go-demo)

      2.2 創(chuàng)建DB連接

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

      package mainimport ( 'github.com/jinzhu/gorm' _ 'github.com/jinzhu/gorm/dialects/mysql')func main() {var err error db, connErr := gorm.Open('mysql', 'root:rootroot@/dqm?charset=utf8&parseTime=True&loc=Local')if connErr != nil {panic('failed to connect database')} defer db.Close() db.SingularTable(true)}

        gorm支持很多數(shù)據(jù)源包括PostgreSQL、MySQL等。

        這里連接的是MySQL,所以需要引用'github.com/jinzhu/gorm/dialects/mysql'驅(qū)動(dòng)。

        通過上面聲明,已經(jīng)獲取數(shù)據(jù)庫的連接。

        db.SingularTable(true)這句的作用后面會(huì)提到。

      2.3 創(chuàng)建映射表結(jié)構(gòu)的struct

        定義數(shù)據(jù)庫表結(jié)構(gòu)對(duì)應(yīng)的struct

        比如這里我們要操作的是表test表,表結(jié)構(gòu)如下

      CREATE TABLE `test` (  `id` bigint(20) NOT NULL,  `name` varchar(5) DEFAULT NULL,  `age` int(11) DEFAULT NULL,  PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci

        于是我們對(duì)應(yīng)可以定義struct結(jié)構(gòu)如下

      type Test struct { ID int64 `gorm:'type:bigint(20);column:id;primary_key'` Name string `gorm:'type:varchar(5);column:name'` Age int `gorm:'type:int(11);column:age'`}

        每個(gè)字段后面的gorm是結(jié)構(gòu)標(biāo)記,可以用于聲明對(duì)應(yīng)數(shù)據(jù)庫字段的屬性。

        比如ID后面的約束為該字段為bigint(20)類型,對(duì)應(yīng)列表為id,且該字段為主鍵。

        除此以外,還有更加豐富的標(biāo)簽定義參見官方文檔:http:///zh_CN/docs/models.html

      2.4 CRUD

        有了前面三步的鋪墊,下面就可以執(zhí)行真正寫數(shù)據(jù)庫操作了。

      比如'增'

      test := &Test{	ID:3,	Name:'jackie',	Age:18,}db.Create(test)

        比如'刪'

      test := &Test{ ID:3, Name:'jackie', Age:18,}db.Delete(test)

      比如'改'

      test := &Test{	ID:   3,	Name: 'hello',	Age:  18,}db.Model(&test).Update('name', 'world')

        比如'查'

      var testResult Testdb.Where('name = ?', 'hello').First(&testResult)fmt.Println('result: ', testResult)

      如果只是想做個(gè)純粹的CRUDer,掌握上面四步就算是會(huì)用gorm了。

      如果還想來點(diǎn)花式的,更深入的,繼續(xù)往下看~~~

      3、表名和結(jié)構(gòu)體如何映射

        從上面四步,我們只看到在創(chuàng)建DB鏈接的時(shí)候,提供的信息僅僅到數(shù)據(jù)庫,那么gorm是如何做到將表結(jié)構(gòu)和你定義的struct映射起來的呢?

        有三種方式可以實(shí)現(xiàn),如果以下三種方式都沒有實(shí)現(xiàn),如果你是創(chuàng)建表,則gorm默認(rèn)會(huì)在你定義的struct名后面加上”s“,比如上面就會(huì)創(chuàng)建tests表。

      3.1 db.SingularTable(true)

        通過db.SingularTable(true),gorm會(huì)在創(chuàng)建表的時(shí)候去掉”s“的后綴

      3.2 實(shí)現(xiàn)TableName方法

      func (Test) TableName() string {return 'test'}

        TableName方法定義在scope.go的tabler接口中

      type tabler interface {TableName() string}

      3.3 通過Table API聲明

      db.Table('test').Where('name = ?', 'hello').First(&testResult)

      在CRUD前,指明需要操作的表名也是OK的。

      4、其他花式操作

      下面花式API操作使用表dqm_user_role,對(duì)應(yīng)struct如下

      type DqmUserRole struct { ID int64 `gorm:'column:id;primary_key' json:'id'` UserId string `gorm:'column:user_id' json:'user_id'` RoleId string `gorm:'column:role_id' json:'role_id'` CreatedAt time.Time `gorm:'column:created_at' json:'created_at'` UpdatedAt time.Time `gorm:'column:updated_at' json:'updated_at'`}

      表中初始數(shù)據(jù)如下

      以下API均親測(cè)可用

      First

      var dqmUserRole DqmUserRole// 按照主鍵順序的第一條記錄db.First(&dqmUserRole)fmt.Println('roleId: ', dqmUserRole.RoleId)

      Last

      var dqmUserRole1 DqmUserRole// 按照主鍵順序的最后一條記錄db.Last(&dqmUserRole1)fmt.Println('roleId: ', dqmUserRole1.RoleId)

      Find

      var dqmUserRoels []DqmUserRole// 所有記錄db.Find(&dqmUserRoels)fmt.Println('dqmUserRoles: ', dqmUserRoels)

      Where

      var dqmUserRole3 DqmUserRole// 根據(jù)條件查詢得到滿足條件的第一條記錄db.Where('role_id = ?', '2').First(&dqmUserRole3)fmt.Println('where roleId: ', dqmUserRole3.RoleId)var dqmUserRoles4 []DqmUserRole// 根據(jù)條件查詢得到滿足條件的所有記錄db.Where('user_id = ?', '1').Find(&dqmUserRoles4)fmt.Println('where dqmUserRoles: ', dqmUserRoles4)var dqmUserRole5 []DqmUserRole// like模糊查詢db.Where('role_id like ?', '%2').Find(&dqmUserRole5)fmt.Println('where dqmUserRoles: ', dqmUserRole5)var dqmUserRole6 []DqmUserRoledb.Where('updated_at > ?', '2019-02-08 18:08:27').Find(&dqmUserRole6)fmt.Println('where dqmUserRoles: ', dqmUserRole6)var dqmUserRole7 DqmUserRole// struct結(jié)構(gòu)查詢條件db.Where(&DqmUserRole{RoleId: '1,2', UserId: '1'}).First(&dqmUserRole7)fmt.Println('where dqmUserRole: ', dqmUserRole7)var dqmUserRole8 DqmUserRole// map結(jié)構(gòu)查詢條件db.Where(map[string]interface{}{'role_id': '1,2', 'user_id': '1'}).Find(&dqmUserRole8)fmt.Println('where dqmUserRole: ', dqmUserRole8)

      Not

      var dqmUserRole9 DqmUserRoledb.Not([]int64{1}).First(&dqmUserRole9)fmt.Println('not dqmUserRole: ', dqmUserRole9)

      Or

      var dqmUserRole10 []DqmUserRoledb.Where(&DqmUserRole{RoleId: '1,2'}).Or(map[string]interface{}{'user_id': '2'}).Find(&dqmUserRole10)fmt.Println('or dqmUserRoles: ', dqmUserRole10)

      FirstOrInit和Attrs

      var dqmUserRole11 DqmUserRole// 查不到該條記錄,則使用attrs值替換db.Where('user_id = ?', '0').Attrs('role_id', '12').FirstOrInit(&dqmUserRole11)fmt.Println('after FirstOrInit: ', dqmUserRole11)var dqmUserRole12 DqmUserRole// 查到記錄,則使用數(shù)據(jù)庫中的值db.Where('user_id = ?', '1').Attrs('role_id', '2').FirstOrInit(&dqmUserRole12)fmt.Println('after FirstOrInit: ', dqmUserRole12)

      FirstOrInit和Assign

      var dqmUserRole13 DqmUserRole// 不管是否找到對(duì)應(yīng)記錄,使用Assign值替代查詢到的值db.Where('role_id = ?', '1,2').Assign(DqmUserRole{UserId: '15'}).FirstOrInit(&dqmUserRole13)fmt.Println('assign dqmUserRole: ', dqmUserRole13)

      FirstOrCreate

      var dqmUserRole14 DqmUserRole// 如果記錄存在則返回結(jié)果,如果不存在則創(chuàng)建db.Where(&DqmUserRole{UserId: '3', RoleId: '3'}).FirstOrCreate(&dqmUserRole14)fmt.Println('firstOrCreate dqmUserRole: ', dqmUserRole14)

      Order

      var dqmUserRole16 []DqmUserRoledb.Order('user_id desc').Find(&dqmUserRole16) // 注意這里的order要在find前面,否則不生效fmt.Println('order dqmUserRoles: ', dqmUserRole16)

      Limit和Offset

      var dqmUserRole18 []DqmUserRoledb.Limit(10).Offset(2).Find(&dqmUserRole18) // 如果只有offset沒有l(wèi)imit則不會(huì)生效fmt.Println('offset dqmUserRoles: ', dqmUserRole18)

      Scan

      type Result struct { Id int64 }var results []Resultdb.Select('id').Where('user_id in (?)', []string{'1', '2'}).Find(&dqmUserRole20).Scan(&results)fmt.Println('ids: ', results)

      支持執(zhí)行原生sql

      var dqmUserRole24 []DqmUserRoledb.Exec('select * from dqm_user_role').Find(&dqmUserRole24)fmt.Println('sql dqmUserRole: ', dqmUserRole24)

      事務(wù)

      tx := db.Begin()defer func() {if r := recover(); r != nil { tx.Rollback()}if err != nil { tx.Rollback()} else { tx.Commit()}}()if err = tx.Create(&DqmUserRole{UserId: '8', RoleId: '8'}).Error; err != nil { //tx.Rollback()//return}if err = tx.Create(&DqmUserRole{UserId: '9', RoleId: '9'}).Error; err != nil {//tx.Rollback()//return}

      錯(cuò)誤處理

      var dqmUserRole25 DqmUserRoleerr = db.Where('role_id = ?', 54321).First(&dqmUserRole25).Errorif err == gorm.ErrRecordNotFound {  fmt.Println('ErrRecordNotFound, record not found')} else {  fmt.Println('err: ', err)}fmt.Println('err dqmUserRole: ', dqmUserRole25)

      5、總結(jié)

      gorm作為一款orm庫,幾乎滿足了一個(gè)CRUDer的一切想象。實(shí)現(xiàn)靈活,花樣繁多。

      有了gorm,就不需要再在代碼中維護(hù)sql語句了。

      后面有時(shí)間會(huì)再看看gorm的實(shí)現(xiàn),作為國人開源的第一個(gè)orm庫,目前star已經(jīng)超過15k,值得深入學(xué)習(xí)下。

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多