Go之資料庫操作

MClink發表於2020-12-31

1.MySQL 驅動

Go中支援MySQL的驅動目前比較多,有如下幾種,有些是支援database/sql標準,而有些是採用了自己的 實現介面,常用的有如下幾種:

  • https://github.com/go-sql-driver/mysql 支援database/sql,全部採用go寫。
  • https://github.com/ziutek/mymysql 支援database/sql,也支援自定義的介面,全部採用go寫。
  • https://github.com/Philio/GoMySQL 不支援database/sql,自定義介面,全部採用go寫。

使用例項:

package main

import (
	"database/sql"
	"fmt"
	_ "github.com/go-sql-driver/mysql"
)

func  main()  {
	db, err := sql.Open("mysql", "root:@tcp(localhost:3306)/learn?charset=utf8")
	checker(err)

	// 插入資料
	stmt, err := db.Prepare("insert userinfo set username=?, departname=?, created=?")
	checker(err)

	res, err := stmt.Exec("mclink", "研發部門", "2020-01-01")
	checker(err)

	id, err := res.LastInsertId()
	checker(err)

	fmt.Println(id)
	
    //刪除資料
	stmt, err = db.Prepare("delete from userinfo where uid=?")
	checker(err)

	res, err = stmt.Exec(id)

	affect, err = res.RowsAffected()
	checker(err)

	fmt.Println(affect)
}

func checker(err error) {
	if err != nil {
		fmt.Println(err)
	}
}


sql.Open()函式用來開啟一個註冊過的資料庫驅動,go-sql-driver中註冊了mysql這個資料庫驅動,第二個 引數是DSN(Data Source Name),它是go-sql-driver定義的一些資料庫連結和配置資訊。它支援如下格 式:

  user@unix(/path/to/socket)/dbname?charset=utf8
  user:password@tcp(localhost:5555)/dbname?charset=utf8
  user:password@/dbname
  user:password@tcp([de:ad:be:ef::ca:fe]:80)/dbname

db.Prepare()函式用來返回準備要執行的sql操作,然後返回準備完畢的執行狀態。 db.Query()函式用來直接執行Sql返回Rows結果。 stmt.Exec()函式用來執行stmt準備好的SQL語句 我們可以看到我們傳入的引數都是=?對應的資料,這樣做的方式可以一定程度上防止SQL隱碼攻擊。

2.使用 beedb 庫進行 MySQL orm 開發

2.1 orm 的插入資料操作

package main

import (
	"database/sql"
	"github.com/astaxie/beedb"
	_ "github.com/go-sql-driver/mysql"
	"time"
)

// 表結構定義
type UserInfo struct {
	Uid int `PK`
	Username string
	Departname string
	Created time.Time
}

func main()  {
    // 開啟連線
	db, err := sql .Open("mysql", "root:@tcp(localhost:3306)/learn?charset=utf8")
	checker(err)
    //建立例項
	orm := beedb.New(db, "mysql")

	// 插入資料
	var saveone UserInfo
	saveone.Username = "mclink2"
	saveone.Departname = "yanfa"
	saveone.Created = time.Now()
	_ = orm.Save(&saveone)


	// Map 插入資料
	add := make(map[string]interface{})
	add["username"] = "aaa"
	add["departname"] = "aaa"
	add["created"] = time.Now()
	_, _ = orm.SetTable("userinfo").Insert(add)

	// 插入多條資料
	addSlice := make([]map[string]interface{}, 0)
	add1 := make(map[string]interface{})
	add2 := make(map[string]interface{})

	add1["username"] = "www"
	add1["deparetname"] = "www"
	add1["created"] = time.Now()
	add2["username"] = "jjj"
	add2["departname"] = "jjj"
	add2["created"] = time.Now()

	addSlice =  append(addSlice, add1, add2)

	_, _ = orm.SetTable("userinfo").InsertBatch(addSlice)
}

2.2 更新資料

    //更新資料
	saveone.Username = "update-name"
	saveone.Departname = "udpate-departname"
	saveone.Created = time.Now()
	_ = orm.Save(&saveone) //saveone有了主鍵值,則為更新操作
	
    
	add3 := make(map[string]interface{})
	add3["Username"] = "udpate2-name"
	add3["Departname"] = "update3-departname"
	_, _ = orm.SetTable("userinfo").SetPK("uid").Where(2).Update(add3) 
  • SetPK:顯式的告訴ORM,資料庫表 userinfo 的主鍵是 uid 。
  • Where:用來設定條件,支援多個引數,第一個引數如果為整數,相當於呼叫了Where(“主鍵=?”,值)。
  • Updata函式接收map型別的資料,執行更新資料。

2.3 查詢資料

	// 查詢資料
	var user2 UserInfo
	_ = orm.Where("uid=?", 3).Find(&user2)
	// 等效於
	_ = orm.Where(3).Find(&user2)

	var user3 UserInfo
	_ = orm.Where("name=? and age <?", "mclink", 3).Find(&user3)
	//獲取多條記錄
	var users []UserInfo
	_ = orm.OrderBy("id").Where("id>?", 1).FindAll(&users)
	//獲取指定欄位的資料
	a, _ := orm.SetTable("userinfo").SetPK("uid").Where(2).Select("uid,username").FindMap()
	fmt.Println(a)
	
	
	// 關聯查詢
	b, _ := orm.Join("LEFT", "userdetail", "userinfo.uid=userdeatail.uid").FindMap()
	fmt.Println(b)

2.4 刪除資料

	// 刪除單條資料
	_, _ = orm.Delete(&saveone)
	_, _ = orm.Where("uid = ?", 2).DeleteRow()

	// 刪除多條資料
	_, _ = orm.DeleteAll(&addSlice)

3.使用 Redis 操作

package main

import (
	"fmt"
	"github.com/astaxie/goredis"
)
func main()  {
	var client goredis.Client
	client.Addr = "127.0.0.1:6379"

	_ = client.Set("a", []byte("hello"))
	val, _ := client.Get("a")

	fmt.Println(string(val))
}

相關文章