目錄
golang操作mysql
安裝
連接資料庫
處理類型(Handle Types)
建表
Exec使用
#Exec增刪該範例
sql預聲明(Prepared Statements)
Query
Queryx
QueryRow和QueryRowx
Get 和Select(非常常用)
交易(Transactions)
连接池设置
案例使用
首頁 資料庫 mysql教程 golang怎麼連接mysql資料庫

golang怎麼連接mysql資料庫

May 26, 2023 am 11:05 AM
mysql golang

golang操作mysql

安裝

go get "github.com/go-sql-driver/mysql"
go get "github.com/jmoiron/sqlx"
登入後複製

連接資料庫

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

連接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 Types)

sqlx設計和database/sql使用方法是一樣的。包含有4個主要的handle types:

  • sqlx.DB - 和sql.DB相似,表示資料庫。

  • sqlx.Tx - 和sql.Tx相似,表示事物。

  • sqlx.Stmt - 和sql.Stmt相似,表示prepared statement。

  • sqlx.NamedStmt - 表示prepared statement(支援named parameters)

所有的handler types都提供了對database/sql的相容,意味著當你呼叫sqlx.DB.Query時,可以直接替換為sql.DB.Query.這就使得sqlx可以很容易的加入到已有的資料庫項目中。

此外,sqlx還有兩個cursor類型:

  • sqlx.Rows - 和sql.Rows類似,Queryx回傳。

  • sqlx.Row - 和sql.Row類似,QueryRowx回傳。

比起database/sql方法也多了新語法,也就是實作將要取得的資料直接轉換結構體實作。

  • Get(dest interface{}, …) error

  • Select(dest interface{}, …) error

建表

以下所有範例均已以下表格結構作為操作基礎。

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使用

Exec和MustExec會從連接池中取出一個連接,然後執行對應的查詢操作。對於不支援ad-hoc query execution的驅動,在操作執行的背後會建立一個prepared statement。在結果回傳前這個connection會回到連線池。

要注意的是不同的資料庫類型所使用的佔位符不同,mysql採用?作為佔位符號。

  • MySQL 使用?

  • PostgreSQL 使用1,1,2等

  • #SQLite 使用?或$1

  • Oracle 使用:name

#Exec增刪該範例

查詢語法使用Query後續會提到

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
登入後複製

sql預聲明(Prepared Statements)

對於大部分的資料庫來說,當一個query執行的時候,在sql語句資料庫內部宣告已經宣告過了,其宣告是在資料庫中,我們可以提前進行聲明,以便在其他地方重複使用。

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)
登入後複製

當然sqlx也提供了Preparex()進行擴展,可直接用於結構體轉換

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

Query

row結果透過使用database/sql中的Rows來獲取。 Query回傳一個sql.Rows物件和一個error物件。

在使用的時候應該吧Rows當成一個遊標而不是一連串的結果。儘管資料庫驅動快取的方法不一樣,透過Next()迭代每次取得一列結果,對於查詢結果非常巨大的情況下,可以有效的限制記憶體的使用,Scan()利用reflect把sql每一列結果對應到go語言的資料型態如string,[]byte等。如果你沒有遍歷完全部的rows結果,一定要記得在把connection回到連線池之前呼叫rows.Close()。

Query回傳的error有可能是在server準備查詢的時候發生的,也有可能是在執行查詢語句的時候發生的。舉個例子,即使在資料庫嘗試10次發現或建立可用的連線時,也有可能從連線池中取得到一個糟糕的連線。通常,錯誤主要源自於SQL語句的錯誤、類似符合的錯誤和網域名稱或表名的錯誤。

在大多數情況下,無論驅動程式如何使用緩存,Rows.Scan()都會將從驅動器取得的資料複製一份。特殊類型sql.RawBytes可以用來從驅動回傳的資料總取得一個zero-copy的slice byte。在下一次呼叫 Next 時,該值將失效,因為它所指向的記憶體已被驅動程式重寫為其他資料。

Query使用的connection在所有的rows通過Next()遍歷完後或呼叫rows.Close()後釋放。

範例:

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
登入後複製

Queryx

Queryx和Query行為很相似,不過傳回一個sqlx.Rows對象,支援擴充的scan行為,同時可將對資料進行結構體轉換。

範例:

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
登入後複製

QueryRow和QueryRowx

#QueryRow和QueryRowx都是從資料庫中取得一條數據,但是QueryRowx提供scan擴展,可直接將結果轉換為結構體。

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}
登入後複製

Get 和Select(非常常用)

Get和Select是一個非常省時的擴展,可直接將結果賦值給結構體,其內部封裝了StructScan進行轉換。使用Get方法來取得單一結果後再使用Scan方法,使用Select方法則可取得結果切片。

範例:

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}
登入後複製

交易(Transactions)

交易操作是透過三個方法實作:

Begin():開啟交易

Commit():提交交易(執行sql)

Rollback():回溯

#使用流程:

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)
}
登入後複製

以上是golang怎麼連接mysql資料庫的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

MySQL的位置:數據庫和編程 MySQL的位置:數據庫和編程 Apr 13, 2025 am 12:18 AM

MySQL在數據庫和編程中的地位非常重要,它是一個開源的關係型數據庫管理系統,廣泛應用於各種應用場景。 1)MySQL提供高效的數據存儲、組織和檢索功能,支持Web、移動和企業級系統。 2)它使用客戶端-服務器架構,支持多種存儲引擎和索引優化。 3)基本用法包括創建表和插入數據,高級用法涉及多表JOIN和復雜查詢。 4)常見問題如SQL語法錯誤和性能問題可以通過EXPLAIN命令和慢查詢日誌調試。 5)性能優化方法包括合理使用索引、優化查詢和使用緩存,最佳實踐包括使用事務和PreparedStatemen

apache怎麼連接數據庫 apache怎麼連接數據庫 Apr 13, 2025 pm 01:03 PM

Apache 連接數據庫需要以下步驟:安裝數據庫驅動程序。配置 web.xml 文件以創建連接池。創建 JDBC 數據源,指定連接設置。從 Java 代碼中使用 JDBC API 訪問數據庫,包括獲取連接、創建語句、綁定參數、執行查詢或更新以及處理結果。

docker怎麼啟動mysql docker怎麼啟動mysql Apr 15, 2025 pm 12:09 PM

在 Docker 中啟動 MySQL 的過程包含以下步驟:拉取 MySQL 鏡像創建並啟動容器,設置根用戶密碼並映射端口驗證連接創建數據庫和用戶授予對數據庫的所有權限

MySQL的角色:Web應用程序中的數據庫 MySQL的角色:Web應用程序中的數據庫 Apr 17, 2025 am 12:23 AM

MySQL在Web應用中的主要作用是存儲和管理數據。 1.MySQL高效處理用戶信息、產品目錄和交易記錄等數據。 2.通過SQL查詢,開發者能從數據庫提取信息生成動態內容。 3.MySQL基於客戶端-服務器模型工作,確保查詢速度可接受。

laravel入門實例 laravel入門實例 Apr 18, 2025 pm 12:45 PM

Laravel 是一款 PHP 框架,用於輕鬆構建 Web 應用程序。它提供一系列強大的功能,包括:安裝: 使用 Composer 全局安裝 Laravel CLI,並在項目目錄中創建應用程序。路由: 在 routes/web.php 中定義 URL 和處理函數之間的關係。視圖: 在 resources/views 中創建視圖以呈現應用程序的界面。數據庫集成: 提供與 MySQL 等數據庫的開箱即用集成,並使用遷移來創建和修改表。模型和控制器: 模型表示數據庫實體,控制器處理 HTTP 請求。

centos7如何安裝mysql centos7如何安裝mysql Apr 14, 2025 pm 08:30 PM

優雅安裝 MySQL 的關鍵在於添加 MySQL 官方倉庫。具體步驟如下:下載 MySQL 官方 GPG 密鑰,防止釣魚攻擊。添加 MySQL 倉庫文件:rpm -Uvh https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm更新 yum 倉庫緩存:yum update安裝 MySQL:yum install mysql-server啟動 MySQL 服務:systemctl start mysqld設置開機自啟動

centos安裝mysql centos安裝mysql Apr 14, 2025 pm 08:09 PM

在 CentOS 上安裝 MySQL 涉及以下步驟:添加合適的 MySQL yum 源。執行 yum install mysql-server 命令以安裝 MySQL 服務器。使用 mysql_secure_installation 命令進行安全設置,例如設置 root 用戶密碼。根據需要自定義 MySQL 配置文件。調整 MySQL 參數和優化數據庫以提升性能。

解決數據庫連接問題:使用minii/db庫的實際案例 解決數據庫連接問題:使用minii/db庫的實際案例 Apr 18, 2025 am 07:09 AM

在開發一個小型應用時,我遇到了一個棘手的問題:需要快速集成一個輕量級的數據庫操作庫。嘗試了多個庫後,我發現它們要么功能過多,要么兼容性不佳。最終,我找到了minii/db,這是一個基於Yii2的簡化版本,完美地解決了我的問題。

See all articles