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

posted @ 2021-03-15 10:32  tianzhh_lynn  阅读(111)  评论(0编辑  收藏  举报