栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Go语言

【数据库】原生 go 执行的基本 sql 语句

Go语言 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【数据库】原生 go 执行的基本 sql 语句

提示

建议你先看这篇文章《【数据库】原生 go 与 MySql 的基本示例》,熟悉基本的 go 如何连接 MySql,及一些基本的配置,同时我也会使用该篇文章中已经创建好的数据库和数据表。

环境配置
  1. go1.17
  2. MySql8.0
基本数据库/表内容
  1. 已经存在的一个数据库:bookInfo
  2. 已经存在的一个数据表:books
插入,删除和更新操作

在 database/sql 这个官方包中提供了 Exec 和 ExecContext (该方法提供了 context.Context 用于上下文的选择,可以取消正在进行的操作)两个方法用于执行基本的插入,删除和更新操作,官方文档中将其视为“不返回数据的”操作。

关于 Exec 的插入示例

func addBook(book Book) (int64, error) {
	// 注意,这里使用的查询语句是 MySql 的,不同的数据库在执行 Exec 时,内部查询语句可能不一样
	res, err := db.Exec("insert into books (title, author, price) values (?, ?, ?)", book.Title, book.Author, book.Price)
	if err != nil {
		return 0, fmt.Errorf("新增书籍 %s 出错,错误为 %v", book.Title, err)
	}

	// LastInsertId 返回插入数据的 id 值
	id, err := res.LastInsertId()
	if err != nil {
		return 0, fmt.Errorf("返回 id 出错,错误为 %v", err)
	}
	return id, nil
}
查询

在 database/sql 这个官方包中提供了 Query,QueryContext(可以取消正在执行的操作),QueryRow(一般用于查询 id,因为 id 是唯一的) 和 QueryRowContext(同样可以取消正在执行的操作) 两个方法用于执行基本的查询。

  1. 请求到的数据可以通过 Scan 方法将其读取到你的变量中。
  2. 对于多行数据,可以用 Next 方法进行遍历。

查询多行返回数据:通过 Query 来查询一个作者下的多个书籍信息

func findBooksByAuthor(name string) ([]Book, error) {
	// 书籍结构体
	// 包含了 ID,Title,Author,Price 字段
	var books []Book

	rows, err := db.Query("SELECt * FROM books WHERe author = ?", name)
	if err != nil {
		return nil, fmt.Errorf("查询作者 %q 时出错:%v", name, err)
	}

	defer rows.Close()

	// 循环遍历这个连接
	for rows.Next() {
		var book Book
		// Scan 将当前行中所有数据复制到对应的数据结构中
		err := rows.Scan(&book.ID, &book.Title, &book.Author, &book.Price)
		if err != nil {
			return nil, fmt.Errorf("遍历作者书籍 %q 时出错:%v", name, err)
		}

		// 将一行书籍信息添加至书籍切片中
		books = append(books, book)
	}

	// Err 返回迭代期间遇到的错误
	if err := rows.Err(); err != nil {
		return nil, fmt.Errorf("遍历作者书籍 %q 时出错:%v", name, err)
	}
	return books, nil
}

查询单行返回数据:通过 QueryRow 来查询一个 id 对应的书籍信息。

func findBookById(id int64) (Book, error) {
	var book Book

	// QueryRow 只会返回一行数据
	row := db.QueryRow("SELECt * FROM books WHERe id = ?", id)

	// Scan 将当前行中所有数据复制到对应的数据结构中
	err := row.Scan(&book.ID, &book.Title, &book.Author, &book.Price)
	if err == sql.ErrNoRows {
		return book, fmt.Errorf("没有 ID 为 %d 对应的书籍,错误是:%v", id, err)
	}

	return book, nil
}

【注】QueryRow 本身不返回任何错误,Scan 会返回错误,其中和返回数据相关的错误只有一个,就是sql.ErrNoRows表示没有查询到信息

复用数据库操作语句

如果你存在多处复用相同的数据库操作语句,不妨使用 sql.Stmt来实现。

func preParedStatement(id int) Book {
	// 准备预制语句
	stmt, err := db.Prepare("select * from books where id =?")
	if err != nil {
		log.Fatal("db.Prepare", err)
	}

	var book Book
	// 通过提供 id 来满足占位符 ? 需要的数据
	err = stmt.QueryRow(id).Scan(&book.ID, &book.Title, &book.Author, &book.Price)
	if err != nil {
		if err == sql.ErrNoRows {
			log.Fatal("stmt.QueryRow(id).Scan", err)
		}
		return book
	}
	return book
}

在 main.go 中我们可以得到结果

	// 预制语句
	book := preParedStatement(2)
	fmt.Println(book) // {2 鹿川有许多粪 李沧东 58}
参考

Executing SQL statements that don’t return data
Querying for data
Using prepared statements

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/944882.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号