日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

golang xorm mysql_golang 之xorm

發布時間:2024/3/24 数据库 54 豆豆
生活随笔 收集整理的這篇文章主要介紹了 golang xorm mysql_golang 之xorm 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

xorm

xorm是一個簡單而強大的ORM庫。

安裝

go get -u github.com/go-xorm/xorm

驅動支持

Mysql: github.com/go-sql-driver/mysql

MyMysql: github.com/ziutek/mymysql

Postgres: github.com/lib/pq

Tidb: github.com/pingcap/tidb

SQLite: github.com/mattn/go-sqlite3

MsSql: github.com/denisenkom/go-mssqldb

MsSql: github.com/lunny/godbc

Oracle: github.com/mattn/go-oci8 (試驗性支持)

創建orm引擎

一個xorm可同時存在orm引擎,一個Orm引擎稱為Engine,一個Engine一般只對應一個數據庫。Engine通過調用xorm.NewEngine生成,如:

package main

import (

"github.com/go-xorm/xorm"

_ "github.com/go-sql-driver/mysql"

)

func main() {

engine, err := xorm.NewEngine("mysql", "root:passwd@tcp(127.0.0.1:3306)/dabase_name?timeout=3s&parseTime=true&loc=Local&charset=utf8")

if err !=nil{

return

}

engine.Ping() // 可以判斷是否能連接

defer engine.Close() // 退出后關閉

}

定義表結構體

表名映射一般有三種方式,且都按優先級高低

表名的優先級順序如下:

engine.Table() 指定的臨時表名優先級最高

TableName() string 其次

Mapper 自動映射的表名優先級最后

字段名的優先級順序如下:

結構體tag指定的字段名優先級較高

Mapper 自動映射的表名優先級較低

Column屬性定義,首先定義一個結構體如

type User struct {

Id int64

Name string `xorm:"varchar(25) notnull unique 'usr_name'"`

Balance float64

Version int `xorm:"version"` // 樂觀鎖

}

具體tag詳情如下。且字段名根據不同數據庫區分大小寫

Tag說明

name

當前field對應的字段的名稱,可選,如不寫,則自動根據field名字和轉換規則命名,如與其它關鍵字沖突,請使用單引號括起來。

pk

是否是Primary Key,如果在一個struct中有多個字段都使用了此標記,則這多個字段構成了復合主鍵,單主鍵當前支持int32,int,int64,uint32,uint,uint64,string這7種Go的數據類型,復合主鍵支持這7種Go的數據類型的組合。

當前支持30多種字段類型,詳情參見本文最后一個表格

字段類型

autoincr

是否是自增

[not ]null 或 notnull

是否可以為空

unique或unique(uniquename)

是否是唯一,如不加括號則該字段不允許重復;如加上括號,則括號中為聯合唯一索引的名字,此時如果有另外一個或多個字段和本unique的uniquename相同,則這些uniquename相同的字段組成聯合唯一索引

index或index(indexname)

是否是索引,如不加括號則該字段自身為索引,如加上括號,則括號中為聯合索引的名字,此時如果有另外一個或多個字段和本index的indexname相同,則這些indexname相同的字段組成聯合索引

extends

應用于一個匿名成員結構體或者非匿名成員結構體之上,表示此結構體的所有成員也映射到數據庫中,extends可加載無限級

-

這個Field將不進行字段映射

->

這個Field將只寫入到數據庫而不從數據庫讀取

這個Field將只從數據庫讀取,而不寫入到數據庫

created

這個Field將在Insert時自動賦值為當前時間

updated

這個Field將在Insert或Update時自動賦值為當前時間

deleted

這個Field將在Delete時設置為當前時間,并且當前記錄不刪除

version

這個Field將會在insert時默認為1,每次更新自動加1

default 0或default(0)

設置默認值,緊跟的內容如果是Varchar等需要加上單引號

json

表示內容將先轉成Json格式,然后存儲到數據庫中,數據庫中的字段類型可以為Text或者二進制

需要注意的幾點

如果field名稱為ID,且類型為int64,并且 沒有定義tag,則會被xorm視為主鍵,且擁有自增屬性。如果要用其它名字為主鍵,需對應tag加上 xorm:"pk"

string類型默認為varchar(255)

支持type MyString string 等自定義的field。支持Slice, Map,等field成員。這些成員默認存儲為Text類型。并且擁有Json格式來序列化和反序列化。

實現Conversion接口的類型或者結構體,將根據接口的轉換方式在類型和數據庫記錄之間進行相互轉換。

type Conversion interface {

FromDB([]byte) error

ToDB() ([]byte, error)

}

表結構常用操作

獲取數據庫信息

DBMetas(): xorm支持獲取表結構信息。通過調用engine.DBMetas()獲取表,字段,索引信息

TableInfo(): 根據傳入的結構體指針及對應的Tag,提取出模型對應的表結構信息。

表操作

CreateTables(): 創建表engine.CreateTables() 參數為一個或多個空的對應Struct的指針。可用方法有Charset()和StoreEngine()。

IsTableEmpty(): 判斷是否為空。參數和CreateTables()相同。

IsTableExist():判斷是否存在

DropTables(): 刪除表engine.DropTables().參數為一個或多個空的對應Struct的指針或者表的名字。如果為string傳入,則只刪除對應的表,如果傳入的為Struct,則刪除表的同時還會刪除對應的索引。

創建索引和唯一索引

CreateIndexes: 根據struct中的Tag來創建索引

CreateUniques: 根據struct中的tag來創建唯一索引

同步數據庫結構到 mysql中

Sync

自動檢測和創建表,這個檢測是根據表的名字

自動檢測和新增表中的字段,這個檢測是根據字段名

自動檢測和創建索引和唯一索引,這個檢測是根據索引的一個或多個字段名,而不根據索引名稱

err := engine.Sync(new(User), new(Group))

// 其中User ,Group為要創建的兩個表對應的struct

Sync2, 對Sync進行改進,推薦使用Sync2

自動檢測和創建表,這個檢測是根據表的名字

自動檢測和新增表中的字段,這個檢測是根據字段名,同時對表中多余的字段給出警告信息

自動檢測,創建和刪除索引和唯一索引,這個檢測是根據索引的一個或多個字段名,而不根據索引名稱。因此這里需要注意,如果在一個有大量數據的表中引入新的索引,數據庫可能需要一定的時間來建立索引。

自動轉換varchar字段類型到text字段類型,自動警告其它字段類型在模型和數據庫之間不一致的情況。

自動警告字段的默認值,是否為空信息在模型和數據庫之間不匹配的情況

以上信息需要將engine.ShowWarn設置為true才會顯示。調用方法

err := engine.Sync2(new(User), new(Group))

導入導出SQL腳本

dump

engine.DumpAll(w io.Writer)

engine.DumpAllFile(fpath string)

Import

engine.Import(r io.Reader)

或者

engine.ImportFile(fpath string)

插入數據操作(表結構參照上面User表)

ORM插入一條數據

user := new(User)

user.Name = "myname"

affected, err := engine.Insert(user)

// INSERT INTO user (name) values (?)

插入同一個表的多條數據

users := make([]User, 1)

users[0].Name = "name0"

users[0].ID = "0"

...

affected, err := engine.Insert(&users)

指針Slice插入多條記錄

users := make([]*User, 1)

users[0] = new(User)

users[0].Name = "name0"

users[0].ID = "0"

...

affected, err := engine.Insert(&users)

不同表的一條記錄

user := new(User)

user.Name = "myname"

question := new(Question)

question.Content = "whywhywhwy?"

affected, err := engine.Insert(user, question)

不同表的多條記錄

users := make([]User, 1)

users[0].Name = "name0"

...

questions := make([]Question, 1)

questions[0].Content = "whywhywhwy?"

affected, err := engine.Insert(&users, &questions)

使用SQL插入數據

sql ="insert into config(key,value) values (?, ?)"

res, err := engine.Exec(sql, "OSCHINA", "OSCHINA")

或者

sql_2 := "insert into config(key,value) values (?, ?)"

affected, err := engine.Sql(sql_4, "OSCHINA", "OSCHINA").Execute()

或者

//SqlMap中key為 "sql_i_1" 配置的Sql語句為:insert into config(key,value) values (?, ?)

sql_i_1 := "sql_i_1"

affected, err := engine.SqlMapClient(sql_i_1, "config_1", "1").Execute()

或者

sql_i_3 := "insert.example.stpl"

paramMap_i_t := map[string]interface{}{"key": "config_3", "value": "3"}

affected, err := engine.SqlTemplateClient(sql_i_3, &paramMap_i_t).Execute()

查詢操作

ORM常用查詢

注意下面出現的 & +表結構體

設置別名

engine.Alias("o").Where("o.name = ?", name).Get(&order)

條件查找

engine.Where(...).And(...).Get(&order)

某個字段排序

// 正序

engine.Asc("id").Find(&orders)

//倒序

engine.Asc("id").Desc("time").Find(&orders)

主鍵查找

var user User

engine.Id(1).Get(&user)

// SELECT * FROM user Where id = 1

// 或者復合主鍵

engine.Id(core.PK{1, "name"}).Get(&user)

// SELECT * FROM user Where id =1 AND name= 'name'

select, in, cols

engine.Select("a.*, (select name from b limit 1) as name").Find(&beans)

engine.Select("a.*, (select name from b limit 1) as name").Get(&bean)

// in

engine.In("cloumn", 1, 2, 3).Find()

engine.In("column", []int{1, 2, 3}).Find()

// cols

engine.Cols("age", "name").Get(&usr)

// SELECT age, name FROM user limit 1

engine.Cols("age", "name").Find(&users)

// SELECT age, name FROM user

engine.Cols("age", "name").Update(&user)

// UPDATE user SET age=? AND name=?

GET方法,查詢到的數據會賦給結構體

has, err := engine.Get(&user)

// SELECT * FROM user LIMIT 1

has, err := engine.Where("name = ?", name).Desc("id").Get(&user)

// SELECT * FROM user WHERE name = ? ORDER BY id DESC LIMIT 1

var name string

has, err := engine.Where("id = ?", id).Cols("name").Get(&name)

// SELECT name FROM user WHERE id = ?

var id int64

has, err := engine.Where("name = ?", name).Cols("id").Get(&id)

// SELECT id FROM user WHERE name = ?

var valuesMap = make(map[string]string)

has, err := engine.Where("id = ?", id).Get(&valuesMap)

// SELECT * FROM user WHERE id = ?

var valuesSlice = make([]interface{}, len(cols))

has, err := engine.Where("id = ?", id).Cols(cols...).Get(&valuesSlice)

// SELECT col1, col2, col3 FROM user WHERE id = ?

或者

user := new(User)

has, err := engine.Where("name=?", "xlw").Get(user)

子查詢

var student []Student

err = db.Table("student").Select("id ,name").Where("id in (?)", db.Table("studentinfo").Select("id").Where("status = ?", 2).QueryExpr()).Find(&student)

//SELECT id ,name FROM `student` WHERE (id in (SELECT id FROM `studentinfo` WHERE (status = 2)))

SQL操作返回格式json or xml

var users []User

results,err := engine.Where("id=?", 6).Search(&users).Xml() //返回查詢結果的xml字符串

results,err := engine.Where("id=?", 6).Search(&users).Json() //返回查詢結果的json字符串

更新操作

update方法

user := new(User)

user.Name = "myname"

affected, err := engine.Id(id).Update(user)

指定更新值

affected, err := engine.Id(id).Cols("age").Update(&user)

// 或

affected, err := engine.Table(new(User)).Id(id).Update(map[string]interface{}{"age":0})

更新時間,可以在字段名后添加 update如下

type User struct {

Id int64

Name string

UpdatedAt time.Time `xorm:"updated"`

}

刪除操作

delete方法

user := new(User)

affected, err := engine.Id(id).Delete(user)

//Delete的返回值第一個參數為刪除的記錄數,第二個參數為錯誤。

xorm還提供了軟刪除,如下設置

type User struct {

Id int64

Name string

DeletedAt time.Time `xorm:"deleted"`

}

如果設置軟刪除,那么永久刪除或者獲取使用Unscoped

var user User

engine.Id(1).Unscoped().Get(&user)

// 此時將可以獲得記錄

engine.Id(1).Unscoped().Delete(&user)

// 此時將可以真正的刪除記錄

創建數據庫組

xorm提供了可以連接多個數據庫。如下

package main

import (

"github.com/go-xorm/xorm"

_ "github.com/go-sql-driver/mysql"

)

func main() {

conns := []string{

"mysql", "root:passwd@tcp(127.0.0.1:3306)/dabase_name?timeout=3s&parseTime=true&loc=Local&charset=utf8",

"mysql", "root:passwd@tcp(127.0.0.1:3306)/dabase_name?timeout=3s&parseTime=true&loc=Local&charset=utf8",

"mysql", "root:passwd@tcp(127.0.0.1:3306)/dabase_name?timeout=3s&parseTime=true&loc=Local&charset=utf8",

}

engine, err := xorm.NewEngineGroup("mysql", conns)

if err !=nil{

return

}

engine.Ping() // 可以判斷是否能連接

defer engine.Close() // 退出后關閉

}

連接池

engine內部支持連接池接口和對應的函數。

如果需要設置連接池的空閑數大小,可以使用engine.SetMaxIdleConns()來實現。

如果需要設置最大打開連接數,則可以使用engine.SetMaxOpenConns()來實現。

詳細查詢操作可參照github,鏈接? https://github.com/go-xorm/xorm/

總結

以上是生活随笔為你收集整理的golang xorm mysql_golang 之xorm的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。