Bagaimana untuk menyambung golang ke pangkalan data mysql

王林
Lepaskan: 2023-05-26 11:05:51
ke hadapan
1353 orang telah melayarinya

golang operation mysql

Pemasangan

go get "github.com/go-sql-driver/mysql"
go get "github.com/jmoiron/sqlx"
Salin selepas log masuk

Sambung ke pangkalan data

var Db *sqlx.DB
db, err := sqlx.Open("mysql","username:password@tcp(ip:port)/database?charset=utf8")
Db = db
Salin selepas log masuk

Sambung 2

package main
import (
	"database/sql"
	"fmt"
	_ "github.com/go-sql-driver/mysql"
)
var db *sql.DB  //全局对象db

func initDB() (err error) {
  db, err = sql.Open("mysql","root:admin123@tcp(127.0.0.1:3306)/dududu?charset=utf8")
  if err!=nil{
    return err
  }
  err = db.Ping()  //校验数据库连接
  if err!=nil{
    return err
  }
  return nil
}

type beautiful struct {
	spu_id string
	title string
	price string
}

func queryRowDemo()  {
	sqlStr :="select spu_id,title,price from dududu_shops where id = ?"
	var u beautiful
	err:=db.QueryRow(sqlStr,101).Scan(&u.spu_id,&u.title,&u.price)
	if err!=nil{
		fmt.Println("2",err)
	}
	fmt.Println(u)
}


func main()  {
	err:=initDB()
	if err!=nil{
		fmt.Println("1",err)
		return
	}
	queryRowDemo()
}
Salin selepas log masuk

Jenis Pengendalian

Reka bentuk sqlx dan kaedah penggunaan pangkalan data/sql adalah sama. Mengandungi 4 jenis pemegang utama:

  • sqlx.DB - serupa dengan sql.DB, mewakili pangkalan data.

  • sqlx.Tx - serupa dengan sql.Tx, mewakili sesuatu.

  • sqlx.Stmt - Sama seperti sql.Stmt, ia mewakili pernyataan yang disediakan.

  • sqlx.NamedStmt - mewakili pernyataan yang disediakan (menyokong parameter bernama)

Semua jenis pengendali menyediakan keserasian dengan pangkalan data/sql, Ini bermakna apabila anda memanggil sqlx.DB.Query, anda boleh menggantikannya secara langsung dengan sql.DB.Query Ini menjadikan sqlx mudah untuk ditambahkan pada projek pangkalan data sedia ada.

Selain itu, sqlx mempunyai dua jenis kursor:

  • sqlx.Rows - Sama seperti sql.Rows, Queryx kembali.

  • sqlx.Row - Sama seperti sql.Row, QueryRowx kembali.

Berbanding dengan kaedah pangkalan data/sql, terdapat sintaks baru, yang bermaksud bahawa data yang diperolehi boleh terus ditukar kepada struktur.

  • Dapatkan(antara muka akhir{}, …) ralat

  • Ralat pilih(antara muka akhir{}, …)

Mencipta jadual

Semua contoh berikut menggunakan struktur jadual berikut sebagai asas untuk operasi.

CREATE TABLE `userinfo` (
    `uid` INT(10) NOT NULL AUTO_INCREMENT,
    `username` VARCHAR(64)  DEFAULT NULL,
    `password` VARCHAR(32)  DEFAULT NULL,
    `department` VARCHAR(64)  DEFAULT NULL,
    `email` varchar(64) DEFAULT NULL,
    PRIMARY KEY (`uid`)
)ENGINE=InnoDB DEFAULT CHARSET=utf8
Salin selepas log masuk

Exec menggunakan

Exec dan MustExec untuk mengeluarkan sambungan daripada kumpulan sambungan dan kemudian melaksanakan operasi pertanyaan yang sepadan. Untuk pemandu yang tidak menyokong pelaksanaan pertanyaan ad-hoc, pernyataan yang disediakan dibuat di sebalik pelaksanaan operasi. Sambungan ini akan dikembalikan ke kolam sambungan sebelum hasilnya dikembalikan.

Perlu diingatkan bahawa jenis pangkalan data yang berbeza menggunakan ruang letak yang berbeza Apakah yang digunakan oleh mysql? sebagai simbol pemegang tempat.

  • MySQL digunakan?

  • PostgreSQL menggunakan 1,1,2 dsb.

  • SQLite menggunakan? Atau $1

  • Oracle Use: name

Exec untuk menambah atau memadam contoh ini

Sintaks pertanyaan menggunakan Query akan disebut nanti

package main

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

var Db *sqlx.DB

func init()  {
    db, err := sqlx.Open("mysql", "stu:1234qwer@tcp(10.0.0.241:3307)/test?charset=utf8")
    if err != nil {
        fmt.Println("open mysql failed,", err)
        return
    }
    Db = db
}

func main()  {
    result, err := Db.Exec("INSERT INTO userinfo (username, password, department,email) VALUES (?, ?, ?,?)","wd","123","it","wd@163.com")
    if err != nil{
        fmt.Println("insert failed,error: ", err)
        return
    }
    id,_ := result.LastInsertId()
    fmt.Println("insert id is :",id)
    _, err1 := Db.Exec("update userinfo set username = ? where uid = ?","jack",1)
    if err1 != nil{
        fmt.Println("update failed error:",err1)
    } else {
        fmt.Println("update success!")
    }
    _, err2 := Db.Exec("delete from userinfo where uid = ? ", 1)
    if err2 != nil{
        fmt.Println("delete error:",err2)
    }else{
        fmt.Println("delete success")
    }

}
//insert id is : 1
//update success!
//delete success
Salin selepas log masuk

sql Prepared Statements

Bagi kebanyakan pangkalan data, apabila pertanyaan dilaksanakan, pernyataan di dalam pangkalan data pernyataan sql telah pun diisytiharkan, dan pernyataannya berada dalam pangkalan data, kami boleh mengisytiharkan ia lebih awal daripada masa untuk digunakan semula di tempat lain.

stmt, err := db.Prepare(`SELECT * FROM place WHERE telcode=?`)
row = stmt.QueryRow(65)
 
tx, err := db.Begin()
txStmt, err := tx.Prepare(`SELECT * FROM place WHERE telcode=?`)
row = txStmt.QueryRow(852)
Salin selepas log masuk

Sudah tentu sqlx juga menyediakan Preparex() untuk pengembangan, yang boleh digunakan terus untuk penukaran struktur

stmt, err := db.Preparex(`SELECT * FROM place WHERE telcode=?`)
var p Place
err = stmt.Get(&p, 852)
Salin selepas log masuk

Query

hasil baris diperoleh dengan menggunakan Rows dalam pangkalan data/ sql Dapatkan. Pertanyaan mengembalikan objek sql.Rows dan objek ralat.

Apabila menggunakannya, Rows harus dianggap sebagai kursor dan bukannya satu siri hasil. Walaupun kaedah caching dipacu pangkalan data adalah berbeza, satu lajur hasil diperoleh setiap kali melalui lelaran Next() Apabila hasil pertanyaan adalah sangat besar, penggunaan memori boleh dihadkan dengan berkesan untuk memetakan setiap lajur daripada hasil SQL untuk pergi jenis data bahasa seperti rentetan, []bait, dsb. Jika anda tidak mengulangi semua hasil baris, pastikan anda memanggil rows.Close() sebelum mengembalikan sambungan ke kolam sambungan.

Ralat yang dikembalikan oleh Pertanyaan mungkin berlaku apabila pelayan menyediakan pertanyaan, atau ia mungkin berlaku apabila pernyataan pertanyaan dilaksanakan. Sebagai contoh, walaupun pangkalan data cuba 10 kali untuk mencari atau mencipta sambungan yang tersedia, adalah mungkin untuk mendapatkan sambungan yang buruk daripada kumpulan sambungan. Biasanya, ralat terutamanya berpunca daripada ralat dalam pernyataan SQL, ralat padanan serupa dan ralat dalam nama domain atau nama jadual.

Dalam kebanyakan kes, Rows.Scan() akan membuat salinan data yang diperoleh daripada pemandu, tanpa mengira cara pemandu menggunakan cache. Jenis sql.RawBytes khas boleh digunakan untuk mendapatkan bait hirisan salinan sifar daripada data yang dikembalikan oleh pemandu. Kali seterusnya Next dipanggil, nilai akan menjadi tidak sah kerana memori yang ditunjuknya telah ditimpa oleh pemacu dengan data lain.

Sambungan yang digunakan oleh Query dikeluarkan selepas semua baris dilalui melalui Next() atau selepas baris.Close() dipanggil.

Contoh:

package main

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

var Db *sqlx.DB

func init()  {
    db, err := sqlx.Open("mysql", "stu:1234qwer@tcp(10.0.0.241:3307)/test?charset=utf8")
    if err != nil {
        fmt.Println("open mysql failed,", err)
        return
    }
    Db = db
}

func main()  {
    rows, err := Db.Query("SELECT username,password,email FROM userinfo")
    if err != nil{
        fmt.Println("query failed,error: ", err)
        return
    }
    for rows.Next() {  //循环结果
        var username,password,email string
        err = rows.Scan(&username, &password, &email)
        println(username,password,email)
    }
    
}
//wd 123 wd@163.com
//jack 1222 jack@165.com
Salin selepas log masuk

Queryx

Queryx berkelakuan sangat serupa dengan Query, tetapi mengembalikan objek sqlx.Rows, menyokong gelagat imbasan lanjutan dan boleh menstrukturkan penukaran badan data .

Contoh:

package main

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

var Db *sqlx.DB

type stu struct {
    Username string   `db:"username"`
    Password string      `db:"password"`
    Department string  `db:"department"`
    Email string        `db:"email"`
}

func init()  {
    db, err := sqlx.Open("mysql", "stu:1234qwer@tcp(10.0.0.241:3307)/test?charset=utf8")
    if err != nil {
        fmt.Println("open mysql failed,", err)
        return
    }
    Db = db
}

func main()  {
    rows, err := Db.Queryx("SELECT username,password,email FROM userinfo")
    if err != nil{
        fmt.Println("Qeryx failed,error: ", err)
        return
    }
    for rows.Next() {  //循环结果
        var stu1 stu
        err = rows.StructScan(&stu1)// 转换为结构体
        fmt.Println("stuct data:",stu1.Username,stu1.Password)
    }
}
//stuct data: wd 123
//stuct data: jack 1222
Salin selepas log masuk

QueryRow dan QueryRowx

QueryRow dan QueryRowx kedua-duanya memperoleh sekeping data daripada pangkalan data, tetapi QueryRowx menyediakan sambungan imbasan yang boleh menukar hasil secara terus kepada sebuah struktur.

package main

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

var Db *sqlx.DB

type stu struct {
    Username string   `db:"username"`
    Password string      `db:"password"`
    Department string  `db:"department"`
    Email string        `db:"email"`
}

func init()  {
    db, err := sqlx.Open("mysql", "stu:1234qwer@tcp(10.0.0.241:3307)/test?charset=utf8")
    if err != nil {
        fmt.Println("open mysql failed,", err)
        return
    }
    Db = db
}

func main()  {
    row := Db.QueryRow("SELECT username,password,email FROM userinfo where uid = ?",1) // QueryRow返回错误,错误通过Scan返回
    var username,password,email string
    err :=row.Scan(&username,&password,&email)
    if err != nil{
        fmt.Println(err)
    }
    fmt.Printf("this is QueryRow res:[%s:%s:%s]\n",username,password,email)
    var s stu
    err1 := Db.QueryRowx("SELECT username,password,email FROM userinfo where uid = ?",2).StructScan(&s)
    if err1 != nil{
        fmt.Println("QueryRowx error :",err1)
    }else {
        fmt.Printf("this is QueryRowx res:%v",s)
    }
}
//this is QueryRow res:[wd:123:wd@163.com]
//this is QueryRowx res:{jack 1222  jack@165.com}
Salin selepas log masuk

Dapatkan dan Pilih (sangat biasa digunakan)

Dapatkan dan Pilih ialah sambungan yang sangat menjimatkan masa yang boleh memberikan hasil secara langsung kepada struktur, dan ia merangkumi StructScan secara dalaman untuk penukaran. Gunakan kaedah Dapatkan untuk mendapatkan hasil tunggal dan kemudian gunakan kaedah Imbas, dan gunakan kaedah Pilih untuk mendapatkan kepingan hasil.

Contoh:

package main

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

var Db *sqlx.DB

type stu struct {
    Username string   `db:"username"`
    Password string      `db:"password"`
    Department string  `db:"department"`
    Email string        `db:"email"`
}

func init()  {
    db, err := sqlx.Open("mysql", "stu:1234qwer@tcp(10.0.0.241:3307)/test?charset=utf8")
    if err != nil {
        fmt.Println("open mysql failed,", err)
        return
    }
    Db = db
}

func main()  {
    var stus []stu
    err := Db.Select(&stus,"SELECT username,password,email FROM userinfo")
    if err != nil{
        fmt.Println("Select error",err)
    }
    fmt.Printf("this is Select res:%v\n",stus)
    var s stu
    err1 := Db.Get(&s,"SELECT username,password,email FROM userinfo where uid = ?",2)
    if err1 != nil{
        fmt.Println("GET error :",err1)
    }else {
        fmt.Printf("this is GET res:%v",s)
    }
}
//this is Select res:[{wd 123  wd@163.com} {jack 1222  jack@165.com}]
//this is GET res:{jack 1222  jack@165.com}
Salin selepas log masuk

Transaksi

Operasi transaksi dilaksanakan melalui tiga kaedah:

Begin(): Mulakan transaksi

Komit (): Hantar transaksi (laksana sql)

Rollback(): Rollback

Proses penggunaan:

tx, err := db.Begin()
err = tx.Exec(...)
err = tx.Commit()

//或者使用sqlx扩展的事务
tx := db.MustBegin()
tx.MustExec(...)
err = tx.Commit()
Salin selepas log masuk

为了维持一个持续的连接状态,Tx对象必须绑定和控制单个连接。在整个生命周期期间,一个Tx将保持连接,直到调用commit或Rollback()方法将其释放。必须非常谨慎地调用这些函数,否则连接将一直被占用,直到被垃圾回收。

使用示例:

package main

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

var Db *sqlx.DB

func init()  {
    db, err := sqlx.Open("mysql", "stu:1234qwer@tcp(10.0.0.241:3307)/test?charset=utf8")
    if err != nil {
        fmt.Println("open mysql failed,", err)
        return
    }
    Db = db
}

func main()  {
    tx, err := Db.Beginx()
    _, err = tx.Exec("insert into userinfo(username,password) values(?,?)", "Rose","2223")
    if err != nil {
        tx.Rollback()
    }
    _, err = tx.Exec("insert into userinfo(username,password) values(?,?)", "Mick",222)
    if err != nil {
        fmt.Println("exec sql error:",err)
        tx.Rollback()
    }
    err = tx.Commit()
    if err != nil {
        fmt.Println("commit error")
    }

}
Salin selepas log masuk

连接池设置

当连接池中没有可用空闲连接时,连接池会自动创建连接,并且其增长是无限制的。最大连接数可以通过调用DB.SetMaxOpenConns来设置。未使用的连接标记为空闲,如果不需要则关闭。为了减少连接的开启和关闭次数,可以利用DB.SetMaxIdleConns方法来设定最大的空闲连接数。

注意:该设置方法golang版本至少为1.2

  • DB.SetMaxIdleConns(n int) 设置最大空闲连接数

  • DB.SetMaxOpenConns(n int) 设置最大打开的连接数

  • DB.SetConnMaxIdleTime(time.Second*10) 间隔时间

示例:

package main

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

var Db *sqlx.DB

func init()  {
    db, err := sqlx.Open("mysql", "stu:1234qwer@tcp(10.0.0.241:3307)/test?charset=utf8")
    if err != nil {
        fmt.Println("open mysql failed,", err)
        return
    }
    Db = db
    Db.SetMaxOpenConns(30)
    Db.SetMaxIdleConns(15)

}
Salin selepas log masuk

案例使用

var Db *sqlx.DB
db, err := sqlx.Open("mysql","root:admin123@tcp(127.0.0.1:3306)/dududu?charset=utf8")
Db = db

rows, err := Db.Query("SELECT spu_id,title,price FROM dududu_shops")

if err != nil{
  fmt.Println("query failed,error: ", err)
  return
}
for rows.Next() {  //循环结果
  var spu_id,title,price string
  err = rows.Scan(&spu_id, &title, &price)
  println(spu_id,title,price)
}
Salin selepas log masuk

Atas ialah kandungan terperinci Bagaimana untuk menyambung golang ke pangkalan data mysql. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Label berkaitan:
sumber:yisu.com
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan