Heim  >  Artikel  >  Datenbank  >  So verbinden Sie Golang mit der MySQL-Datenbank

So verbinden Sie Golang mit der MySQL-Datenbank

王林
王林nach vorne
2023-05-26 11:05:511341Durchsuche

golang operation mysql

Installation

go get "github.com/go-sql-driver/mysql"
go get "github.com/jmoiron/sqlx"

Datenbank verbinden

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

Verbindung 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()
}

Handle-Typen

SQLX-Design und Datenbank-/SQL-Nutzung sind gleich. Enthält 4 Haupthandle-Typen:

  • sqlx.DB – stellt ähnlich wie sql.DB die Datenbank dar.

  • sqlx.Tx – Ähnlich wie sql.Tx stellt es Dinge dar.

  • sqlx.Stmt – Ähnlich wie sql.Stmt stellt es eine vorbereitete Anweisung dar.

  • sqlx.NamedStmt – stellt eine vorbereitete Anweisung dar (unterstützt benannte Parameter)

Alle Handlertypen sind kompatibel mit „database/sql“ bedeutet, dass Sie sqlx.DB.Query direkt durch „sql.DB.Query“ ersetzen können. Dadurch lässt sich sqlx einfach zu vorhandenen Datenbankprojekten hinzufügen.

Darüber hinaus verfügt sqlx auch über zwei Cursortypen:

  • sqlx.Rows – Ähnlich wie sql.Rows gibt Queryx zurück.

  • sqlx.Row – Ähnlich wie sql.Row gibt QueryRowx zurück.

Im Vergleich zur Datenbank/SQL-Methode gibt es eine neue Syntax, was bedeutet, dass die erhaltenen Daten direkt in eine Struktur umgewandelt werden können.

  • Get(dest interface{}, …) error

  • Select(dest interface{}, …) Fehler

Tabelle erstellen

Alle folgenden Beispiele haben die folgende Tabellenstruktur als Grundlage für die Operation.

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

Exec verwendet

Exec und MustExec nehmen eine Verbindung aus dem Verbindungspool heraus und führen dann den entsprechenden Abfragevorgang aus. Für Treiber, die die Ad-hoc-Abfrageausführung nicht unterstützen, wird hinter der Operationsausführung eine vorbereitete Anweisung erstellt. Diese Verbindung wird an den Verbindungspool zurückgegeben, bevor das Ergebnis zurückgegeben wird.

Es ist zu beachten, dass verschiedene Datenbanktypen unterschiedliche Platzhalter verwenden. als Platzhaltersymbol.

  • MySQL verwendet?

  • PostgreSQL verwendet 1,1,2 usw.

  • SQLite verwendet? Oder $1

  • Oracle-Verwendung: Name

Exec, um dieses Beispiel hinzuzufügen oder zu löschen

# 🎜🎜# Die Abfragesyntax mit Query wird später erwähnt Die Datenbank wurde deklariert und ihre Deklaration befindet sich in der Datenbank. Wir können sie im Voraus deklarieren, damit sie an anderer Stelle wiederverwendet werden kann.

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

Natürlich stellt sqlx auch Preparex() für die Erweiterung bereit, das direkt für die Strukturkonvertierung verwendet werden kann

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)

Query

row results by using Zu erhaltende Datenbankzeilen in /sql. Die Abfrage gibt ein sql.Rows-Objekt und ein Fehlerobjekt zurück.

Wenn Sie es verwenden, sollten Sie Zeilen als Cursor und nicht als Ergebnisreihe behandeln. Obwohl die Methoden des datenbankgesteuerten Cachings unterschiedlich sind, wird jedes Mal eine Ergebnisspalte durch Next()-Iteration abgerufen. Wenn die Abfrageergebnisse sehr groß sind, kann die Speichernutzung mithilfe von Scan() effektiv begrenzt werden von SQL-Ergebnissen zum Mitnehmen. Wenn Sie nicht alle Zeilenergebnisse durchlaufen, rufen Sie unbedingt rows.Close() auf, bevor Sie die Verbindung an den Verbindungspool zurückgeben.

Der von Query zurückgegebene Fehler kann auftreten, wenn der Server die Abfrage vorbereitet, oder er kann auftreten, wenn die Abfrageanweisung ausgeführt wird. Selbst wenn die Datenbank beispielsweise zehnmal versucht, eine verfügbare Verbindung zu finden oder zu erstellen, ist es möglich, dass eine fehlerhafte Verbindung aus dem Verbindungspool abgerufen wird. Normalerweise entstehen Fehler hauptsächlich durch Fehler in SQL-Anweisungen, ähnliche Matching-Fehler und Fehler in Domänennamen oder Tabellennamen.

In den meisten Fällen erstellt Rows.Scan() eine Kopie der vom Treiber erhaltenen Daten, unabhängig davon, wie der Treiber den Cache verwendet. Der spezielle Typ sql.RawBytes kann verwendet werden, um aus den vom Treiber zurückgegebenen Daten ein Zero-Copy-Slice-Byte abzurufen. Beim nächsten Aufruf von Next ist der Wert ungültig, da der Speicher, auf den er verweist, vom Treiber mit anderen Daten überschrieben wurde.

Die von Query verwendete Verbindung wird freigegeben, nachdem alle Zeilen durch Next() durchlaufen wurden oder nachdem rows.Close() aufgerufen wurde.

Beispiel:

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

Queryx

Queryx verhält sich sehr ähnlich wie Query, gibt jedoch ein sqlx.Rows-Objekt zurück und unterstützt erweitertes Scanverhalten in Strukturen umgewandelt werden.

Beispiel:

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

QueryRow und QueryRowx

Sowohl QueryRow als auch QueryRowx beziehen ein Datenelement aus der Datenbank, aber QueryRowx stellt eine Scan-Erweiterung bereit kann direkt verwendet werden Konvertieren Sie das Ergebnis in eine 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()  {
    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

Get and Select (sehr häufig verwendet)

Get and Select ist eine sehr zeitsparende Erweiterung, die das Ergebnis direkt der Struktur zuordnen kann und StructScan intern kapselt . Transformation. Verwenden Sie die Get-Methode, um ein einzelnes Ergebnis zu erhalten, und verwenden Sie dann die Scan-Methode sowie die Select-Methode, um Ergebnisausschnitte zu erhalten.

Beispiel:

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}

Transaktionen

Transaktionsvorgänge werden durch drei Methoden implementiert:

Begin( ): Offene Transaktion

Commit(): Transaktion senden (SQL ausführen)

Rollback(): Rollback

Nutzungsprozess: #🎜🎜 #

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

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

为了维持一个持续的连接状态,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")
    }

}

连接池设置

当连接池中没有可用空闲连接时,连接池会自动创建连接,并且其增长是无限制的。最大连接数可以通过调用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)

}

案例使用

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)
}

Das obige ist der detaillierte Inhalt vonSo verbinden Sie Golang mit der MySQL-Datenbank. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:yisu.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen