您好,欢迎访问一九零五行业门户网

golang怎么连接mysql数据库

golang操作mysql安装go get "github.com/go-sql-driver/mysql"go get "github.com/jmoiron/sqlx"
连接数据库var db *sqlx.dbdb, err := sqlx.open("mysql","username:password@tcp(ip:port)/database?charset=utf8")db = db
连接2
package mainimport ( "database/sql" "fmt" _ "github.com/go-sql-driver/mysql")var db *sql.db //全局对象dbfunc 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 mainimport ( _ "github.com/go-sql-driver/mysql" "github.com/jmoiron/sqlx" "fmt")var db *sqlx.dbfunc 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 placeerr = stmt.get(&p, 852)
queryrow结果通过使用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 mainimport ( _ "github.com/go-sql-driver/mysql" "github.com/jmoiron/sqlx" "fmt")var db *sqlx.dbfunc 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
queryxqueryx和query行为很相似,不过返回一个sqlx.rows对象,支持扩展的scan行为,同时可将对数据进行结构体转换。
示例:
package mainimport ( _ "github.com/go-sql-driver/mysql" "github.com/jmoiron/sqlx" "fmt")var db *sqlx.dbtype 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和queryrowxqueryrow和queryrowx都是从数据库中获取一条数据,但是queryrowx提供scan扩展,可直接将结果转换为结构体。
package mainimport ( _ "github.com/go-sql-driver/mysql" "github.com/jmoiron/sqlx" "fmt")var db *sqlx.dbtype 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 mainimport ( _ "github.com/go-sql-driver/mysql" "github.com/jmoiron/sqlx" "fmt")var db *sqlx.dbtype 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 mainimport ( _ "github.com/go-sql-driver/mysql" "github.com/jmoiron/sqlx" "fmt")var db *sqlx.dbfunc 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 mainimport ( _ "github.com/go-sql-driver/mysql" "github.com/jmoiron/sqlx" "fmt")var db *sqlx.dbfunc 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.dbdb, err := sqlx.open("mysql","root:admin123@tcp(127.0.0.1:3306)/dududu?charset=utf8")db = dbrows, 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数据库的详细内容。
其它类似信息

推荐信息