1.はじめに
蛇
オブジェクトRelationlマッピングは、その役割は、オブジェクトのデータベース操作の操作に上昇し、複雑なSQL文を記述する必要はありませんデータベース操作の実現に私たちを助けるために、データベースとオブジェクトの間のマッピングです。
ブルー
GORMはORMライブラリ囲碁言語をベースにしています。
誰もがそうでMyBatisのは、Hibernate、SpringDataとを聞いたJavaエコシステムに似ています。
Githubの
https://github.com/jinzhu/gorm
公式ドキュメント
https://gorm.io/
ゴームを使用する方法2、
わずか4ステップは、GORMを始めるために、あなたは何の技術的な内容が存在しない世界に浸漬CRUDを楽しむことができます。
2.1のダウンロードGORMライブラリ
ライブラリGORMをダウンロード
GET -u github.com/jinzhu/gorm行きます
これはかなり原始的な方法ですが、今はより簡単にしても設定せずに、設定することができ、MOD行くしています。
実行時のコードを記述したファイルをビルドして行く、自動的に依存関係をGORMに追加go.mod
github.com/jinzhu/gormのv1.9.10
もちろん、あなたも手動でこの依存関係を追加することができます。
参照し、具体的に行って、デモ・プロジェクト(https://github.com/DMinerJackie/go-demo)
2.2 DB接続の作成
データベース接続を確立します
パッケージメイン インポート( "github.com/jinzhu/gorm" _ "github.com/jinzhu/gorm/dialects/mysql" ) FUNCメイン(){ VARのERR誤差 DB、connErr:= gorm.Open( "MySQLの"、 "ルート:?rootroot @ / DQMのcharset = UTF8&parseTime =真&LOC =ローカル") の場合connErr = nilの{! パニックが("データベースを接続に失敗しました") } db.Closeを延期() db.SingularTable(真) }
GORMはそうではPostgreSQL、MySQLとを含む多くのデータソースをサポートしています。
ここでの接続は、MySQLであるので、あなたは「github.com/jinzhu/gorm/dialects/mysql」ドライブを参照する必要があります。
上記の文を通じ、それはデータベースへの接続を取得する必要があります。
db.SingularTable(真の)アクション句は、後述します。
2.3マッピングテーブル構造の構造体を作成します
データベーステーブル定義された構造体の構造に対応
たとえば、次のようにここでは、テーブルテストテーブルを操作したい、テーブル構造があります
表`test`(CREATE ` id` BIGINT(20)NOT NULL、 `NAME`のVARCHAR(5)デフォルトNULL、 ` age`はint(11)は、デフォルトのNULL、 PRIMARY KEY( `id`) )ENGINE = InnoDBのデフォルトの文字セットを= utf8mb4 COLLATE = utf8mb4_0900_ai_ci
だから我々は、対応する構造体の構造を定義することができ、次のようです
型テスト構造体{ GORM `のInt64 ID: "タイプ:BIGINT(20);カラム:ID; PRIMARY_KEY"` 名文字列`GORM: "タイプ:VARCHAR(5);カラム:名称"` 年齢INT `GORM:"タイプ: INT(11);カラム:年齢"` }
各フィールドマーカーGORM構造た後、データベース・フィールドの対応する属性を宣言するために使用することができます。
IDフィールドが制約さBIGINT(20)タイプの後ろに、例えば、対応するリストは、ID、主キーフィールドです。
ます。http://gorm.io/zh_CN/docs/models.html加えて、より豊かなタグの定義があり、公式ドキュメントを参照してください
2.4 CRUD
寝具の前で三の段階で、我々は実際にデータベース操作を記述する準備が整いました。
例えば、「増加」
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 Test db.Where("name = ?", "hello").First(&testResult) fmt.Println("result: ", testResult)
如果只是想做个纯粹的CRUDer,掌握上面四步就算是会用gorm了。
如果还想来点花式的,更深入的,继续往下看~~~
3、表名和结构体如何映射
从上面四步,我们只看到在创建DB链接的时候,提供的信息仅仅到数据库,那么gorm是如何做到将表结构和你定义的struct映射起来的呢?
有三种方式可以实现,如果以下三种方式都没有实现,如果你是创建表,则gorm默认会在你定义的struct名后面加上”s“,比如上面就会创建tests表。
3.1 db.SingularTable(true)
通过db.SingularTable(true),gorm会在创建表的时候去掉”s“的后缀
3.2 实现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,对应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"` }
表中初始数据如下
以下API均亲测可用
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 // 根据条件查询得到满足条件的第一条记录 db.Where("role_id = ?", "2").First(&dqmUserRole3) fmt.Println("where roleId: ", dqmUserRole3.RoleId) var dqmUserRoles4 []DqmUserRole // 根据条件查询得到满足条件的所有记录 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 []DqmUserRole db.Where("updated_at > ?", "2019-02-08 18:08:27").Find(&dqmUserRole6) fmt.Println("where dqmUserRoles: ", dqmUserRole6) var dqmUserRole7 DqmUserRole // struct结构查询条件 db.Where(&DqmUserRole{RoleId: "1,2", UserId: "1"}).First(&dqmUserRole7) fmt.Println("where dqmUserRole: ", dqmUserRole7) var dqmUserRole8 DqmUserRole // map结构查询条件 db.Where(map[string]interface{}{"role_id": "1,2", "user_id": "1"}).Find(&dqmUserRole8) fmt.Println("where dqmUserRole: ", dqmUserRole8)
Not
var dqmUserRole9 DqmUserRole db.Not([]int64{1}).First(&dqmUserRole9) fmt.Println("not dqmUserRole: ", dqmUserRole9)
Or
var dqmUserRole10 []DqmUserRole db.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 // 查到记录,则使用数据库中的值 db.Where("user_id = ?", "1").Attrs("role_id", "2").FirstOrInit(&dqmUserRole12) fmt.Println("after FirstOrInit: ", dqmUserRole12)
FirstOrInit和Assign
var dqmUserRole13 DqmUserRole // 不管是否找到对应记录,使用Assign值替代查询到的值 db.Where("role_id = ?", "1,2").Assign(DqmUserRole{UserId: "15"}).FirstOrInit(&dqmUserRole13) fmt.Println("assign dqmUserRole: ", dqmUserRole13)
FirstOrCreate
var dqmUserRole14 DqmUserRole // 如果记录存在则返回结果,如果不存在则创建 db.Where(&DqmUserRole{UserId: "3", RoleId: "3"}).FirstOrCreate(&dqmUserRole14) fmt.Println("firstOrCreate dqmUserRole: ", dqmUserRole14)
Order
var dqmUserRole16 []DqmUserRole db.Order("user_id desc").Find(&dqmUserRole16) // 注意这里的order要在find前面,否则不生效 fmt.Println("order dqmUserRoles: ", dqmUserRole16)
Limit和Offset
var dqmUserRole18 []DqmUserRole db.Limit(10).Offset(2).Find(&dqmUserRole18) // 如果只有offset没有limit则不会生效 fmt.Println("offset dqmUserRoles: ", dqmUserRole18)
Scan
type Result struct { Id int64 } var results []Result db.Select("id").Where("user_id in (?)", []string{"1", "2"}).Find(&dqmUserRole20).Scan(&results) fmt.Println("ids: ", results)
支持执行原生sql
var dqmUserRole24 []DqmUserRole db.Exec("select * from dqm_user_role").Find(&dqmUserRole24) fmt.Println("sql dqmUserRole: ", dqmUserRole24)
事务
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 }
错误处理
var dqmUserRole25 DqmUserRole err = db.Where("role_id = ?", 54321).First(&dqmUserRole25).Error if err == gorm.ErrRecordNotFound { fmt.Println("ErrRecordNotFound, record not found") } else { fmt.Println("err: ", err) } fmt.Println("err dqmUserRole: ", dqmUserRole25)
5、总结
gorm作为一款orm库,几乎满足了一个CRUDer的一切想象。实现灵活,花样繁多。
有了gorm,就不需要再在代码中维护sql语句了。
后面有时间会再看看gorm的实现,作为国人开源的第一个orm库,目前star已经超过15k,值得深入学习下。
如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!如果您想持续关注我的文章,请扫描二维码,关注JackieZheng的微信公众号,我会将我的文章推送给您,并和您一起分享我日常阅读过的优质文章。