go 操作mysql
02 go 操作mysql
1 介绍和基本应用
- 下载mysql驱动
$ go get -u github.com/go-sql-driver/mysql
- 初始化连接
package main
package settings
import (
"database/sql" // 只提供泛接口,没有驱动
_ "github.com/go-sql-driver/mysql" // mysql驱动
)
func main() {
var DB *sql.DB
dsn := "root:12345678@tcp(127.0.0.1:3306)/sql_test"
DB, _ = sql.Open("mysql", dsn) // 检查参数格式
DB.Ping() // 连接数据库
DB.SetMaxIdleConns(10) // 设置连接个数,默认不限制
defer DB.Close() // 最后关闭数据库
}
2 数据库操作CRUD
- 准备
创建数据,创建表
$ create database sql_test;
$ use sql_test;
$ CREATE TABLE `user` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(128) DEFAULT '',
`age` INT(11) DEFAULT '0',
`message` VARCHAR(128) DEFAULT '',
PRIMARY KEY(`id`)
)ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;
01 查询
- 单条查询
为了方便操作数据库数据,自定义结构体,与表结构字段一致
type user struct {
id int
age int
name string
message string
}
查询
DB.QueryRow
package main
package settings
import (
"database/sql"
_ "github.com/go-sql-driver/mysql"
)
func main() {
var DB *sql.DB
dsn := "root:12345678@tcp(127.0.0.1:3306)/sql_test"
DB, _ = sql.Open("mysql", dsn)
DB.Ping()
DB.SetMaxIdleConns(10)
defer DB.Close()
sqlStr := "select * from user where id=?" // 几个问号,QueryRow后边跟几个参数
var u user
DB.QueryRow(sqlStr, 1000).Scan(&u.id, &u.name, &u.age, &u.message)
fmt.Println(u.name, u.age, u.id, u.message)
}
注意:
DB.QueryRow(a, b)
:b参数个数是a中问号的个数
- 多条查询
DB.Query
package main
package settings
import (
"database/sql"
_ "github.com/go-sql-driver/mysql"
)
func main() {
var DB *sql.DB
dsn := "root:12345678@tcp(127.0.0.1:3306)/sql_test"
DB, _ = sql.Open("mysql", dsn)
DB.Ping()
DB.SetMaxIdleConns(10)
defer DB.Close()
sqlStr := "select * from user"
rows, _:= DB.Query(sqlStr) // 如果sqlStr中有?那么后边可以跟参数
for rows.Next(){ // 有几条数据循环几次
var u user
rows.Scan(&u.id, &u.name, &u.age, &u.message)
fmt.Println(u.message)
}
}
02 新增
DB.Exec()
package main
package settings
import (
"database/sql"
_ "github.com/go-sql-driver/mysql"
)
func main() {
var DB *sql.DB
dsn := "root:12345678@tcp(127.0.0.1:3306)/sql_test"
DB, _ = sql.Open("mysql", dsn)
DB.Ping()
DB.SetMaxIdleConns(10)
defer DB.Close()
sqlStr := "insert into user (name, age, message) values (?,?,?)"
DB.Exec(sqlStr, "tianzh", 18, "tianzh is 18") // 有几个问号,跟几个参数
fmt.Println("ok")
}
03 修改
DB.Exec()
package main
package settings
import (
"database/sql"
_ "github.com/go-sql-driver/mysql"
)
func main() {
var DB *sql.DB
dsn := "root:12345678@tcp(127.0.0.1:3306)/sql_test"
DB, _ = sql.Open("mysql", dsn)
DB.Ping()
DB.SetMaxIdleConns(10)
defer DB.Close()
sqlStr := "update user set name=? where id=?"
DB.Exec(sqlStr, "tianzh", 1) // 有几个问号,跟几个参数
fmt.Println("ok")
}
04 删除
DB.Exec()
package main
package settings
import (
"database/sql"
_ "github.com/go-sql-driver/mysql"
)
func main() {
var DB *sql.DB
dsn := "root:12345678@tcp(127.0.0.1:3306)/sql_test"
DB, _ = sql.Open("mysql", dsn)
DB.Ping()
DB.SetMaxIdleConns(10)
defer DB.Close()
sqlStr := "delete from user where id = ?"
DB.Exec(sqlStr, 1) // 有几个问号,跟几个参数
fmt.Println("ok")
}
3 mysql预处理
一般情况下用这种方法,效率更优化
先将sql语句发送给mysql服务端,返回一个准备好的状态用于之后的命令。可以同时执行多个命令
Prepare
方法
package main
package settings
import (
"database/sql"
_ "github.com/go-sql-driver/mysql"
)
func main() {
var DB *sql.DB
dsn := "root:12345678@tcp(127.0.0.1:3306)/sql_test"
DB, _ = sql.Open("mysql", dsn)
DB.Ping()
DB.SetMaxIdleConns(10)
sqlStr := "select * from user where id=?"
var u user
PreBd := DB.Prepare(sqlStr) // 把sql语句传到mysql服务端
PreBd.QueryRow(1).Scan(&u.id, &u.name, &u.age, &u.message) // 直接传递?需要的参数
fmt.Println(u.message)
defer PreDb.Close()
fmt.Println(u.name, u.age, u.id, u.message)
}
4 sql注入问题
任何情况下,我们不要自己拼接sql语句,用sql自己的占位符。
mysql的占位符是:?
5 实现事物
mysql中只有innodb引擎才有事物。
事物是最小的不可再分的工作单元
- 事物相关方法
开始事物:DB.Begin
提交事物:DB.Commit
回滚事物:DB.rollback