一.database/sql 原生方法
1.需要引入包:
import ( "database/sql" //原生sql库 _ "github.com/go-sql-driver/mysql" //导入第三方mysql驱动 )
导入MySQL驱动之前,需要将驱动下载回来
go get -u github.com/go-sql-driver/mysql (确保已经安装了git)
2.连接MySQL数据库
func main() { dbcon := "user:password@tcp(127.0.0.1:3306)/dbname" //Open函数不会校验该数据库连接字符串是否正确,只校验引入的数据库是否配置正确,只有在执行sql的时候才首次校验(懒惰校验) //所以如果想马上校验,可使用 db.Ping() 方法进行校验 db,err := sql.Open("mysql",dbcon) if err != nil{ fmt.Println(err) return } err := db.Ping() if err != nil{ fmt.Println(err) return } db.SetMaxOpenConns(100) //设置最大连接数 db.SetMaxIdleConns(10) //设置默认连接数 //defer db.Close()关闭数据库连接 }
3.执行 SQL
sql := "select id from test where id>?" //? 为要输入的参数值,虽然也可以直接拼接字符串,但是会有SQL注入风险 //查询单行 rows,err := db.QueryRow(sql,param) //param 的值对应 SQL 语句上的 ? ,多个参数则需要对应顺序进行传参 //查询多行 rows,err := db.Query(sql,param) //遍历 rows 数据 for rows.Next(){ id := 0 err := rows.Scan(id) //需要映射的字段变量,查询出来的数据会传到改变量中 if err != nil{ } } //关闭 rows defer func(){ if rows != nil{ rows.Close() } }() (当 rows 使用完,需要进行关闭处理,否则会占用数据库连接数,影响程序性能) //插入,更新,删除 result,err := db.Exec(sql,param) result.LastInsertId() //返回出入数据后的主键Id值 result.RowsAffected() //返回执行SQL后,影响的数据行数
4.MySQL预处理
所谓预处理,是指将 SQL语句 和 SQL参数 分开发送到 MySQL,而不是在客户端中,把完整的 SQL语句 发送到 MySQL 进行处理
这样的好处是:
1.当同一条 SQL 反复执行,性能会很高
2.避免 SQL 注入
//查询 stmt := db.Prepare(sql) rows,err := stmt.Query(param) //插入,更新,删除 stmt := db.Prepare(sql) result,err := stmt.Exec(param) 剩下操作同非预处理一样,最后需要关闭 rows 和 stmt
5.事务
应用场景主要是 完整的更新多个表或者多行数据,保证多个 SQL 执行后数据的一致性
特性:
原子性(要么全部执行成功,要么全部失败)
隔离性(多个事务执行互不影响)
持久性(当事务执行成功后又恰好数据库宕机,当数据库恢复的时候,事务处理的的数据结果还会在不会丢失)
//启动一个事务 conn,err := db.Begin() //回滚一个事务(事务过程中,当发生错误时候,需执行回滚) _,err := conn.Exec(sql,param) if err != nil{ conn.RollBack() } //提交一个事务 conn.Comit()
二.sqlx 方法
sqlx 比原生库优势的地方在于
1.无需手动关闭数据库连接,可避免超过最大连接数导致程序异常
2.查询 sql 执行完成后返回数据结果集,无需再分开字段将参数一个个传入进行映射返回,只需传入一个实体对象即可,也无需再循环 rows 去获取数据,使用上更加简单
1.需要导入
import ( _ "github.com/go-sql-driver/mysql" //导入第三方mysql驱动 "github.com/jmoiron/sqlx" //第三方sql库 )
2.连接MySQL数据库
func main() { dbcon := "user:password@tcp(127.0.0.1:3306)/dbname" //Open函数不会校验该数据库连接字符串是否正确,只校验引入的数据库是否配置正确,只有在执行sql的时候才校验 db,err := sqlx.Open("mysql",dbcon) if err != nil{ fmt.Println(err) return } defer db.Close() }
3.执行 SQL
sql := "select id from test where id>?" //? 为要输入的参数值,虽然也可以直接拼接字符串,但是会有SQL注入风险 //查询单行 Entity为定义好的实体对象(stuct类型),param 的值对应 SQL 语句上的 ? ,多个参数则需要对应顺序进行传参 err := db.Get(&Entity,sql,param) //查询多行 err := db.Select(&[]Entity,sql,param) 其他操作如 增删改 和 事务 就和原生的语法基本一致