本文介绍: Scan() 方法负责结果的列映射到相应的变量,并在需要触发底层查询执行。在调用 Scan() 之前,QueryRow() 不会执行实际的查询执行一次查询返回多行结果(即Rows),一般用于执行select命令。包提供了保证SQL或类SQL数据库的泛用接口常用数据库驱动有。获取最后插入的 ID,通常在表中一个自增主键使用获取影响行数,即更新操作实际影响的行数。,而是返回一个实现了 Row 接口的非空值。,它将用于保存数据库连接实例。将当前行的数据扫描到相应的变量中。

go语言
database/sql包提供了保证SQL或类SQL数据库的泛用接口常用数据库驱动
github.com/go-sql-driver/mysql

初始化连接

以下代码定义一个全局变量 db,它将用于保存数据库连接实例然后定义initDB 函数负责初始化数据库连接。它使用给定连接字符串创建个数据库连接实例然后通过 Ping 方法检查是否能够成功连接数据库。在这里CheckError 函数用于检查处理每个步骤可能发生的错误

package main

import (
	"database/sql"
	"fmt"
	_ "github.com/go-sql-driver/mysql"
)

var db *sql.DB

func CheckError(err error, arg string) {
	if err != nil {
		fmt.Printf("%s err:%v", arg, err)
	}
}

func initDB() (err error) {
	dsn := "root:123456@tcp(127.0.0.1:3306)/users"
	db, err = sql.Open("mysql", dsn)
	CheckError(err, "Open")
	err = db.Ping()
	CheckError(err, "ping")
	return nil
}

func main() {
	err := initDB()
	CheckError(err, "init db")
	defer db.Close()
}

查询数据

定义一个struct存储查询数据

type userData struct {
	id       int
	age      int
	name     string
}

单行查询

在 Go 语言中,db.QueryRow() 用于执行一次查询期望返回最多一行结果。如果没有找到结果,它不会返回 nil,而是返回一个实现了 Row 接口的非空值

调用 QueryRow() 后,通常会使用 Scan() 方法从结果中提取数据。Scan() 方法负责将结果的列映射到相应的变量,并在需要时触发底层查询执行。在调用 Scan() 之前,QueryRow() 不会执行实际的查询。

// 单行查询db.QueryRow()执行一次查询,并期望返回最多一行结果(即Row
func queryRowDemo() {
	sqlStr := "select id,name,age from user where id=?"
	var u userData
	// 非常重要:确保QueryRow之后调用Scan方法,否则持有的数据库链接不会被释放
	err := db.QueryRow(sqlStr, 1).Scan(&u.id, &u.name, &u.age)
	CheckError(err, "scan")
	fmt.Printf("id:%d,name:%s,username:%s", u.id, u.name, u.age)
}

多行查询

多行查询db.Query()执行一次查询,返回多行结果(即Rows),一般用于执行select命令

func queryMultiRowDemo() {
	sqlStr := "select id,name,age from user where id>?"
	rows, err := db.Query(sqlStr, 0)
	CheckError(err, "query")
	defer rows.Close()

	// 循环读取结果集中的数据
	for rows.Next() {
		var u userData
		err := rows.Scan(&u.id, &u.name, &u.age)
		CheckError(err, "rows scan")
		fmt.Printf("id:%d,name:%s,age:%dn", u.id, u.name, u.age)
	}
}

以上代码使用 rows.Next() 遍历结果集中的每一行然后使用 rows.Scan当前行的数据扫描到相应的变量中。

插入数据

插入更新删除操作都使用Exec方法。

func InsertRowDemo() {
	sqlStr := "insert into user(name,age) values (?,?)"
	ret, err := db.Exec(sqlStr, "王五", 18)
	CheckError(err, "insert")
	theID, err := ret.LastInsertId()
	CheckError(err, "LastInsertId")
	fmt.Println("insert success,the id is", theID)
}

使用 ret.LastInsertId() 获取最后插入的 ID,通常在表中有一个自增主键时使用。

更新数据

这里user 表中 id 为 5 的行的 age 列更新为 100。并使用 ret.RowsAffected() 获取受影响的行数,即更新操作实际影响的行数。

func UpdateRowDemo() {
	sqlStr := "update user set age=? where id=?"
	ret, err := db.Exec(sqlStr, 100, 5)
	CheckError(err, "update")
	n, err := ret.RowsAffected() // 操作影响的行数
	CheckError(err, "RowsAffected")
	fmt.Printf("update success, affected rows:%dn", n)
}

删除数据

func DeleteRowDemo() {
	sqlStr := "delete from user where id=?"
	ret, err := db.Exec(sqlStr, 5)
	CheckError(err, "delete")
	n, err := ret.RowsAffected()
	CheckError(err, "RowsAffected")
	fmt.Printf("delete success,affected rows:%dn", n)
}

编译

编译执行过程

  1. 把SQL语句分成两部分命令部分与数据部分
  2. 先把命令部分发送给MySQL服务端,MySQL服务端进行SQL预处理
  3. 然后把数据部分发送给MySQL服务端,MySQL服务端对SQL语句进行占位替换
  4. MySQL服务端执行完整的SQL语句并将结果返回给客户端

Golang通过database/sql使用下面的Prepare方法来实现处理操作

func (db *DB) Prepare(query string) (*Stmt, error)

查询数据

func PrepareQueryDemo() {
	Sqlstr := "select id,name,age from user where id > ?"
	stmt, err := db.Prepare(Sqlstr)
	CheckError(err, "Prepare stmt")
	defer stmt.Close()
	rows, err := stmt.Query(0)
	CheckError(err, "Query")
	defer rows.Close()
	for rows.Next() {
		var u userData
		err := rows.Scan(&u.id, &u.name, &u.age)
		CheckError(err, "rows scan")
		fmt.Printf("id:%d,name:%s,age:%dn", u.id, u.name, u.age)
	}
}

插入数据

func InsertQueryDemo() {
	Sqlstr := "insert into user(name,age) values(?,?)"
	stmt, err := db.Prepare(Sqlstr)
	CheckError(err, "stmt")
	defer stmt.Close()
	_, err = stmt.Exec("wangdong", 20)
	CheckError(err, "insert")
	fmt.Println("insert success")
}

更新删除操作类似插入操作

原文地址:https://blog.csdn.net/weixin_46270220/article/details/134739541

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_49946.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注