日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
創(chuàng)新互聯(lián)GoFrame教程:GoFrame 模型關(guān)聯(lián)-ScanList

?gf?的?ORM?沒有采用其他?ORM?常見的?BelongsTo?, ?HasOne?, ?HasMany?, ?ManyToMany?這樣的模型關(guān)聯(lián)設(shè)計(jì),這樣的關(guān)聯(lián)關(guān)系維護(hù)較繁瑣,例如外鍵約束、額外的標(biāo)簽備注等,對(duì)開發(fā)者有一定的心智負(fù)擔(dān)。因此?gf?框架不傾向于通過(guò)向模型結(jié)構(gòu)體中注入過(guò)多復(fù)雜的標(biāo)簽內(nèi)容、關(guān)聯(lián)屬性或方法,并一如既往地嘗試著簡(jiǎn)化設(shè)計(jì),目標(biāo)是使得模型關(guān)聯(lián)查詢盡可能得易于理解、使用便捷。

創(chuàng)新互聯(lián)公司堅(jiān)持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:做網(wǎng)站、成都網(wǎng)站制作、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿足客戶于互聯(lián)網(wǎng)時(shí)代的高州網(wǎng)站設(shè)計(jì)、移動(dòng)媒體設(shè)計(jì)的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!

接下來(lái)關(guān)于?gf ORM?提供的模型關(guān)聯(lián)實(shí)現(xiàn),從?GF v1.13.6?版本開始提供,目前屬于實(shí)驗(yàn)性特性。

那么我們就使用一個(gè)例子來(lái)介紹?gf ORM?提供的模型關(guān)聯(lián)吧。

數(shù)據(jù)結(jié)構(gòu)

為簡(jiǎn)化示例,我們這里設(shè)計(jì)得表都盡可能簡(jiǎn)單,每張表僅包含3-4個(gè)字段,方便闡述關(guān)聯(lián)關(guān)系即可。

# 用戶表
CREATE TABLE `user` (
  uid int(10) unsigned NOT NULL AUTO_INCREMENT,
  name varchar(45) NOT NULL,
  PRIMARY KEY (uid)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

# 用戶詳情
CREATE TABLE `user_detail` (
  uid  int(10) unsigned NOT NULL AUTO_INCREMENT,
  address varchar(45) NOT NULL,
  PRIMARY KEY (uid)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

# 用戶學(xué)分
CREATE TABLE `user_scores` (
  id int(10) unsigned NOT NULL AUTO_INCREMENT,
  uid int(10) unsigned NOT NULL,
  score int(10) unsigned NOT NULL,
  course varchar(45) NOT NULL,
  PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

數(shù)據(jù)模型

根據(jù)表定義,我們可以得知:

  1. 用戶表與用戶詳情是?1:1?關(guān)系。
  2. 用戶表與用戶學(xué)分是?1:N?關(guān)系。
  3. 這里并沒有演示?N:N?的關(guān)系,因?yàn)橄啾容^于?1:N?的查詢只是多了一次關(guān)聯(lián)、或者一次查詢,最終處理方式和?1:N?類似。

那么GOlang的模型可定義如下:

// 用戶表
type EntityUser struct {
    Uid  int    `orm:"uid"`
    Name string `orm:"name"`
}
// 用戶詳情
type EntityUserDetail struct {
    Uid     int    `orm:"uid"`
    Address string `orm:"address"`
}
// 用戶學(xué)分
type EntityUserScores struct {
    Id     int    `orm:"id"`
    Uid    int    `orm:"uid"`
    Score  int    `orm:"score"`
    Course string `orm:"course"`
}
// 組合模型,用戶信息
type Entity struct {
    User       *EntityUser
    UserDetail *EntityUserDetail
    UserScores []*EntityUserScores
}

其中,?EntityUser?, ?EntityUserDetail?, ?EntityUserScores?分別對(duì)應(yīng)的是用戶表、用戶詳情、用戶學(xué)分?jǐn)?shù)據(jù)表的數(shù)據(jù)模型。?Entity?是一個(gè)組合模型,對(duì)應(yīng)的是一個(gè)用戶的所有詳細(xì)信息。

數(shù)據(jù)寫入

寫入數(shù)據(jù)時(shí)涉及到簡(jiǎn)單的數(shù)據(jù)庫(kù)事務(wù)即可。

err := db.Transaction(func(tx *gdb.TX) error {
    r, err := tx.Table("user").Save(EntityUser{
        Name: "john",
    })
    if err != nil {
        return err
    }
    uid, err := r.LastInsertId()
    if err != nil {
        return err
    }
    _, err = tx.Table("user_detail").Save(EntityUserDetail{
        Uid:     int(uid),
        Address: "Beijing DongZhiMen #66",
    })
    if err != nil {
        return err
    }
    _, err = tx.Table("user_scores").Save(g.Slice{
        EntityUserScores{Uid: int(uid), Score: 100, Course: "math"},
        EntityUserScores{Uid: int(uid), Score: 99, Course: "physics"},
    })
    return err
})

數(shù)據(jù)查詢

單條數(shù)據(jù)記錄

查詢單條模型數(shù)據(jù)比較簡(jiǎn)單,直接使用?Scan?方法即可,該方法會(huì)自動(dòng)識(shí)別綁定查詢結(jié)果到單個(gè)對(duì)象屬性還是數(shù)組對(duì)象屬性中。例如:

// 定義用戶列表
var user Entity
// 查詢用戶基礎(chǔ)數(shù)據(jù)
// SELECT * FROM `user` WHERE `name`='john'
err := db.Table("user").Scan(&user.User, "name", "john")
if err != nil {
    return err
}
// 查詢用戶詳情數(shù)據(jù)
// SELECT * FROM `user_detail` WHERE `uid`=1
err := db.Table("user_detail").Scan(&user.UserDetail, "uid", user.User.Uid)
// 查詢用戶學(xué)分?jǐn)?shù)據(jù)
// SELECT * FROM `user_scores` WHERE `uid`=1
err := db.Table("user_scores").Scan(&user.UserScores, "uid", user.User.Uid)

多條數(shù)據(jù)記錄

查詢多條數(shù)據(jù)記錄并綁定數(shù)據(jù)到數(shù)據(jù)模型數(shù)組中,需要使用到?ScanList?方法,該方法會(huì)需要用戶指定結(jié)果字段與模型屬性的關(guān)系,隨后底層會(huì)遍歷數(shù)組并自動(dòng)執(zhí)行數(shù)據(jù)綁定。例如:

// 定義用戶列表
var users []Entity
// 查詢用戶基礎(chǔ)數(shù)據(jù)
// SELECT * FROM `user`
err := db.Table("user").ScanList(&users, "User")
// 查詢用戶詳情數(shù)據(jù)
// SELECT * FROM `user_detail` WHERE `uid` IN(1,2)
err := db.Table("user_detail").
       Where("uid", gdb.ListItemValuesUnique(users, "User", "Uid")).
       ScanList(&users, "UserDetail", "User", "uid:Uid")
// 查詢用戶學(xué)分?jǐn)?shù)據(jù)
// SELECT * FROM `user_scores` WHERE `uid` IN(1,2)
err := db.Table("user_scores").
       Where("uid", gdb.ListItemValuesUnique(users, "User", "Uid")).
       ScanList(&users, "UserScores", "User", "uid:Uid")

這其中涉及到兩個(gè)比較重要的方法:

1. ?ScanList?

方法定義:

// ScanList converts  to struct slice which contains other complex struct attributes.
// Note that the parameter  should be type of *[]struct/*[]*struct.
// Usage example:
//
// type Entity struct {
// 	   User       *EntityUser
// 	   UserDetail *EntityUserDetail
//	   UserScores []*EntityUserScores
// }
// var users []*Entity
// or
// var users []Entity
//
// ScanList(&users, "User")
// ScanList(&users, "UserDetail", "User", "uid:Uid")
// ScanList(&users, "UserScores", "User", "uid:Uid")
// The parameters "User"/"UserDetail"/"UserScores" in the example codes specify the target attribute struct
// that current result will be bound to.
// The "uid" in the example codes is the table field name of the result, and the "Uid" is the relational
// struct attribute name. It automatically calculates the HasOne/HasMany relationship with given 
// parameter.
// See the example or unit testing cases for clear understanding for this function.
func (m *Model) ScanList(listPointer interface{}, attributeName string, relation ...string) (err error)

該方法用于將查詢到的數(shù)組數(shù)據(jù)綁定到指定的列表上,例如:

  • ?ScanList(&users, "User")?:表示將查詢到的用戶信息數(shù)組數(shù)據(jù)綁定到?users?列表中每一項(xiàng)的?User?屬性上。
  • ?ScanList(&users, "UserDetail", "User", "uid:Uid")?:表示將查詢到用戶詳情數(shù)組數(shù)據(jù)綁定到?users?列表中每一項(xiàng)的?UserDetail?屬性上,并且和另一個(gè)?User?對(duì)象屬性通過(guò)?uid:Uid?的字段:屬性關(guān)聯(lián),內(nèi)部將會(huì)根據(jù)這一關(guān)聯(lián)關(guān)系自動(dòng)進(jìn)行數(shù)據(jù)綁定。其中?uid:Uid?前面的?uid?表示查詢結(jié)果字段中的?uid?字段,后面的?Uid?表示目標(biāo)關(guān)聯(lián)對(duì)象中的?Uid?屬性。
  • ?ScanList(&users, "UserScores", "User", "uid:Uid")?:表示將查詢到用戶詳情數(shù)組數(shù)據(jù)綁定到?users?列表中每一項(xiàng)的?UserScores?屬性上,并且和另一個(gè)?User?對(duì)象屬性通過(guò)?uid:Uid?的字段:屬性關(guān)聯(lián),內(nèi)部將會(huì)根據(jù)這一關(guān)聯(lián)關(guān)系自動(dòng)進(jìn)行數(shù)據(jù)綁定。由于?UserScores?是一個(gè)數(shù)組類型?[]*EntityUserScores?,因此該方法內(nèi)部可以自動(dòng)識(shí)別到?User?到?UserScores?其實(shí)是?1:N?的關(guān)系,自動(dòng)完成數(shù)據(jù)綁定。

需要提醒的是,如果關(guān)聯(lián)數(shù)據(jù)中對(duì)應(yīng)的關(guān)聯(lián)屬性數(shù)據(jù)不存在,那么該屬性不會(huì)被初始化并將保持?nil?。

2. ?ListItemValues/ListItemValuesUnique?

方法定義:

// ListItemValues retrieves and returns the elements of all item struct/map with key .
// Note that the parameter  should be type of slice which contains elements of map or struct,
// or else it returns an empty slice.
//
// The parameter  supports types like:
// []map[string]interface{}
// []map[string]sub-map
// []struct
// []struct:sub-struct
// Note that the sub-map/sub-struct makes sense only if the optional parameter  is given.
func ListItemValues(list interface{}, key interface{}, subKey ...interface{}) (values []interface{})  

// ListItemValuesUnique retrieves and returns the unique elements of all struct/map with key .
// Note that the parameter  should be type of slice which contains elements of map or struct,
// or else it returns an empty slice.
// See gutil.ListItemValuesUnique.
func ListItemValuesUnique(list interface{}, key string, subKey ...interface{}) []interface{}

?ListItemValuesUnique?與?ListItemValues?方法的區(qū)別在于過(guò)濾重復(fù)的返回值,保證返回的列表數(shù)據(jù)中不帶有重復(fù)值。這兩個(gè)方法都會(huì)在當(dāng)給定的列表中包含?struct/map?數(shù)據(jù)項(xiàng)時(shí),用于獲取指定屬性/鍵名的數(shù)據(jù)值,構(gòu)造成數(shù)組?[]interface{}?返回。示例:

  • ?gdb.ListItemValuesUnique(users, "Uid")?用于獲取?users?數(shù)組中,每一個(gè)?Uid?屬性,構(gòu)造成?[]interface{}?數(shù)組返回。這里以便根據(jù)?uid?構(gòu)造成?SELECT...IN...?查詢。
  • ?gdb.ListItemValuesUnique(users, "User", "Uid")?用于獲取?users?數(shù)組中,每一個(gè)?User?屬性項(xiàng)中的?Uid?屬性,構(gòu)造成?[]interface{}?數(shù)組返回。這里以便根據(jù)?uid?構(gòu)造成?SELECT...IN...?查詢。

分享題目:創(chuàng)新互聯(lián)GoFrame教程:GoFrame 模型關(guān)聯(lián)-ScanList
鏈接URL:http://www.5511xx.com/article/djsgici.html