GoLang—MySQL数据库操作

柔情只为你懂 2024-04-18 22:20 130阅读 0赞

Go标准库中没有数据库驱动,如果实现数据库连接与操作,参见获取第三方的数据库驱动。本文以MySQL为例,我们使用go-sql-driver实现数据库的连接和操作,首先在CMD窗口下安装驱动go-sql-driver,指令如下。

  1. go get github.com/go-sql-driver/mysql

数据库驱动安装成功后,在GoLand(ide)中使用go-sql-driver实现数据库的连接和操作,实现方式首先连接MySQL的某个数据库,生成数据库对象db,然后使用数据库对象db对数据表实现怎删改查操作。

数据查询

go-sql-driver提供2种数据查询方式:Query和QueryRow。Query是查询多行数据,也可以查询单行数据,适用范围较广;QueryRow只能查询单行数据,该对象能调用的方法较少,局限性较大。不管Query或QueryRow,两者只查询数据表的数据,如果想将数据表的字段与数据一一对应,需要我们编写函数方法实现,废话不多说,直接看代码。

  1. package main
  2. import (
  3. "database/sql"
  4. "encoding/json"
  5. "fmt"
  6. _ "github.com/go-sql-driver/mysql"
  7. )
  8. func GetAll(rows *sql.Rows) []map[string]string {
  9. // 判断传入的查询结果是否为nil
  10. if rows == nil {
  11. return nil
  12. }
  13. // 定义返回值的数据类型(定义为数组,元素类型为映射,映射的数据为字符串类型)
  14. var result []map[string]string
  15. // 获取查询结果rows的列名(即字段名)
  16. cols, _ := rows.Columns()
  17. // 定义数组byte
  18. rawResult := make([][]byte, len(cols))
  19. // 定义数组dest
  20. dest := make([]interface{}, len(cols))
  21. // 将byte数组的内存地址对应分配给dest
  22. for i, _ := range rawResult {
  23. dest[i] = &rawResult[i]
  24. }
  25. // 遍历每行数据
  26. for rows.Next() {
  27. // 将每行的数据分别存入数组dest
  28. // 由于数组dest和数组byte的内存地址是相同的
  29. // 因此两个数组的数据也是相同,只不过两个数组的每个元素的数据格式不同
  30. rows.Scan(dest...)
  31. // 根据列的个数定义相应的映射对象sresult
  32. sresult := make(map[string]string, len(cols))
  33. // 将当前数据写入映射对象sresult
  34. for i, raw := range rawResult {
  35. if raw == nil {
  36. sresult[cols[i]] = ""
  37. } else {
  38. sresult[cols[i]] = string(raw)
  39. }
  40. }
  41. // 将数据写入数组result
  42. result = append(result, sresult)
  43. }
  44. // 将数组result作为返回值
  45. return result
  46. }
  47. func main(){
  48. // 连接MySQL数据库
  49. db, _ := sql.Open("mysql", "root:1234@tcp(127.0.0.1:3306)/music_db?charset=utf8")
  50. // 查询方式一,先使用Prepare再使用Query或QueryRow
  51. p , _ := db.Prepare("select * from index_song")
  52. rows, _ := p.Query()
  53. // 查询方式二,直接使用Query或QueryRow
  54. //rows, _ := db.Query("select * from index_song")
  55. s2 := GetAll(rows)
  56. for _, v := range s2{
  57. // 将映射对象转化JSON数据
  58. mjson, _ :=json.Marshal(v)
  59. mString :=string(mjson)
  60. fmt.Println(mString)
  61. }
  62. // 查询方式三,查询单条数据
  63. // 适合单条数据的某些字段,如果查询全部字段,建议使用Query
  64. row := db.QueryRow("select name,album from index_song where id=1")
  65. var name,album string
  66. row.Scan(&name,&album)
  67. fmt.Println(name,album)
  68. }

上述代码中,涉及了两个Go的基础语法,下划线(_)和三个点(…),本文不再详细讲述语法知识,读者可以点击相关链接查看。
函数方法GetAll是将Query查询对象rows作为函数参数,函数返回值result为数组类型,数组元素的数据类型为映射对象。函数首先从查询对象rows获取数据表的字段名,生成对象cols,将对象cols的字段名作为返回值result的映射对象的key,而数据表的数据作为映射对象的value。具体的实现过程不过多讲述,详细可看代码注释。

数据增改删

数据的增改删操作主要由Exec方法实现,实现方法较为简单,直接看到代码即可理解

  1. package main
  2. import (
  3. "database/sql"
  4. "fmt"
  5. _ "github.com/go-sql-driver/mysql"
  6. )
  7. func main(){
  8. // 连接MySQL数据库
  9. db, _ := sql.Open("mysql", "root:1234@tcp(127.0.0.1:3306)/music_db?charset=utf8")
  10. // 新增数据
  11. ret, _ := db.Exec("insert into index_label(id,name) values(15,'测试测试')")
  12. // LastInsertId是获取数据新增后的ID
  13. insID, _ := ret.LastInsertId()
  14. fmt.Println(insID)
  15. // 修改数据
  16. ret2, _ := db.Exec("update index_label set name= 'GOGO' where id = ?", 15)
  17. // RowsAffected是获取已被修改的数据总数
  18. aff_nums, _ := ret2.RowsAffected()
  19. fmt.Println(aff_nums)
  20. // 删除数据
  21. ret3, _ := db.Exec("delete from index_label where id = ?",15)
  22. delNums, _ := ret3.RowsAffected()
  23. fmt.Println(delNums)
  24. }

事务

事务由Begin函数方法实现,只需在数据库连接对象调用Begin函数方法即可,然后由Begin函数方法生成的对象执行数据操作即可,可以根据执行结果判断当前事务是否执行或回滚,详细代码如下。

  1. package main
  2. import (
  3. "database/sql"
  4. "fmt"
  5. _ "github.com/go-sql-driver/mysql"
  6. )
  7. func main(){
  8. // 连接MySQL数据库
  9. db, _ := sql.Open("mysql", "root:1234@tcp(127.0.0.1:3306)/music_db?charset=utf8")
  10. //开启事务
  11. tx, _ := db.Begin()
  12. //id为1的price+1,id为2的price-1
  13. ret4, _ := tx.Exec("update index_label set name = '测试事务1' where id = ?", 10)
  14. ret5, _ := tx.Exec("update index_label set name = '测试事务2' where id = ?", 2)
  15. //如果id不存在,受影响行数则为0
  16. //接收影响行数,为0则失败
  17. updNums1, _ := ret4.RowsAffected()
  18. updNums2, _ := ret5.RowsAffected()
  19. if updNums1 > 0 && updNums2 > 0 { //只有两条更新同时成功,那么才提交
  20. tx.Commit() //提交事务
  21. fmt.Println("Success")
  22. } else { //否则回滚
  23. tx.Rollback() //回退事务
  24. fmt.Println("Fail")
  25. }
  26. }

综合上述,本博文讲述了如何使用go-sql-driver实现数据库MySQL数据库操作,下一节将讲述如何使用ORM框架实现数据库操作。

发表评论

表情:
评论列表 (有 0 条评论,130人围观)

还没有评论,来说两句吧...

相关阅读

    相关 数据库操作

    连接数据库 要访问数据库,首先要加载数据库的驱动程序,然后每次访问时创建一个Connection对象,接着执行SQL语句,最后在完成数据库操作后销毁前面创建的Connec

    相关 数据库操作

    数据库操作 1.数据库修改字段属性 如将user\_table表中的user\_name字段长度修改为varchar(100). (1)mysql中修改语句