Go的databasesql体验

Go的database/sql体验篇

Go官方提供了database/sql接口用于数据库交互,但其实database/sql库只是提供了一套接口和规范,比如大家熟悉的SQL预处理、连接池、数据绑定、事务、错误处理等。本篇为实际操作篇

简单来说这个包提供了sql的泛用接口,使用时还要注入一个数据库驱动

导入driver

import (
	"database/sql"			//官方sql包
	_ "github.com/go-sql-driver/mysql"		//一个driver的驱动
)

这里_表示只调用mysql包中的init函数,不使用这个包里的变量和函数。

连接数据库

db, err := sql.Open("mysql",
		"username:password@tcp(127.0.0.1:3306)/test_db")
	if err != nil {
		log.Fatal(err)
	}
	defer db.Close()

这里sql.Open第一个参数就是上面传进来的driver的名字,第二个参数分别是用户名、密码、数据库地址:端口号、对应具体的数据库

查询一条/多条数据

用Query先试试

var (
		id   int
		name string
	)
	//rows, err := db.Query("select id,name from user where id = ?", 1)
	rows, err := db.Query("select id, name from user")
	if err != nil {
		log.Fatal(err)
	}
	defer rows.Close()

	fmt.Println("rows: ", rows)

	for rows.Next() {
		err := rows.Scan(&id, &name)
		if err != nil {
			log.Fatal(err)
		}
		//log.Println(id, name)
		fmt.Printf("id:%d ,name: %s \n", id, name)
	}
	err = rows.Err()
	if err != nil {
		log.Fatal(err)
	}

不管是一条还是多条查询都一样,拿个for循环来接收结果就行

image-20220104144433370

image-20220104144541283

插入一条数据

在mybatis里我们也有PreparedStatements的说法,用于执行insert、update、delete的操作,在这也差不多

这里嫌麻烦先把checkErr抽出来了

func checkErr(err error) {
	if err != nil {
		log.Fatal(err)
	}
}

插入部分

func insertDB() {
	db, err := sql.Open("mysql",
		"username:password@tcp(127.0.0.1:3306)/test_db")
	if err != nil {
		log.Fatal(err)
	}
	defer db.Close()

	stmt, err := db.Prepare("INSERT INTO user(id, name, pwd, perms) VALUES(?, ?, ?, ?)")
	checkErr(err)
	res, err := stmt.Exec(12, "Marks", "666555", "")
	checkErr(err)
	fmt.Println(res.LastInsertId())
	//lastId, err := res.LastInsertId()
	//checkErr(err)
	//rowCnt, err := res.RowsAffected()
	//checkErr(err)
	//log.Printf("ID = %d, affected = %d\n", lastId, rowCnt)
}

运行

GIF 2022-1-4 14-57-25

当然也可以直接插入,不用PreparedStatements方式

func insertDirect() {
	db, err := sql.Open("mysql",
		"username:password@tcp(127.0.0.1:3306)/test_db")
	if err != nil {
		log.Fatal(err)
	}
	defer db.Close()
	
	sql := "INSERT INTO user(id, name, pwd) VALUES(?, ?, ?)"
	res, err := db.Exec(sql, 13, "Jobs", "444555")
	checkErr(err)
	fmt.Println(res.LastInsertId())
}

一样

GIF 2022-1-4 15-01-39

删除数据

func deleteDB() {
	db, err := sql.Open("mysql",
		"username:password@tcp(127.0.0.1:3306)/test_db")
	if err != nil {
		log.Fatal(err)
	}
	defer db.Close()

	sql := "DELETE FROM user where id=?"
	res, err := db.Exec(sql, 12)
	checkErr(err)
	fmt.Println(res.RowsAffected())
}

更新数据

func updateDB() {
	db, err := sql.Open("mysql",
		"username:password@tcp(127.0.0.1:3306)/test_db")
	if err != nil {
		log.Fatal(err)
	}
	defer db.Close()

	sql := "UPDATE user SET name=? WHERE id=?"
	stmt, err := db.Prepare(sql)
	checkErr(err)
	defer stmt.Close()
	result, err := stmt.Exec("Marksss", 12)
	checkErr(err)
	fmt.Println(result.RowsAffected())
}

修改成功没问题

image-20220104150543743

事务支持

完成一系列的操作可以用事务的格式

func transDB() {
	db, err := sql.Open("mysql",
		"username:password@tcp(127.0.0.1:3306)/test_db")
	if err != nil {
		log.Fatal(err)
	}
	defer db.Close()

	tx, err := db.Begin()
	checkErr(err)
	_, err = tx.Exec("UPDATE user SET pwd = ? WHERE id = ?", "888999", 10)
	checkTxErr(err, tx)
	_, err = tx.Exec("UPDATE user SET pwd = ? WHERE id = ?", "888999", 11)
	checkTxErr(err, tx)
	err = tx.Commit()
	checkTxErr(err, tx)
}


func checkTxErr(err error, tx *sql.Tx) {
	if err != nil {
		log.Println(err)
		err = tx.Rollback()
		checkErr(err)
	}
}

运行也没啥问题,如果报错则会回滚

GIF 2022-1-4 15-16-46

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

上上签i

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值