最新文章专题视频专题问答1问答10问答100问答1000问答2000关键字专题1关键字专题50关键字专题500关键字专题1500TAG最新视频文章推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37视频文章20视频文章30视频文章40视频文章50视频文章60 视频文章70视频文章80视频文章90视频文章100视频文章120视频文章140 视频2关键字专题关键字专题tag2tag3文章专题文章专题2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章专题3
问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501
当前位置: 首页 - 科技 - 知识百科 - 正文

Golang操作数据库

来源:懂视网 责编:小采 时间:2020-11-09 08:13:38
文档

Golang操作数据库

Golang操作数据库:基本概念 Open() – creates a DB Close() - closes the DB Query() - 查询 QueryRow() -查询行 Exec() -执行操作,update,insert,delete Row - A row is not a hash map, but an abstraction of a cu
推荐度:
导读Golang操作数据库:基本概念 Open() – creates a DB Close() - closes the DB Query() - 查询 QueryRow() -查询行 Exec() -执行操作,update,insert,delete Row - A row is not a hash map, but an abstraction of a cu

基本概念 Open() – creates a DB Close() - closes the DB Query() - 查询 QueryRow() -查询行 Exec() -执行操作,update,insert,delete Row - A row is not a hash map, but an abstraction of a cursor Next() Scan() 注意: DB并不是指的一个connectio

基本概念

  • Open() – creates a DB
  • Close() - closes the DB
  • Query() - 查询
  • QueryRow() -查询行
  • Exec() -执行操作,update,insert,delete
  • Row - A row is not a hash map, but an abstraction of a cursor
  • Next()
  • Scan()
  • 注意:DB并不是指的一个connection

    连接到数据库

    我们以mysql为例,使用github.com/go-sql-driver/mysql,首先我们需要导入我们需要的包

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

    注意我们导入github.com/go-sql-driver/mysql 前面用了一个"",操作其实是引入该包,而不直接使用包里面的函数,而是调用了该包里面的init函数,import的时候其实是执行了该包里面的init函数,初始化了里面的变量,_操作只是说该包引入了,我只初始化里面的 init函数和一些变量,但是往往这些init函数里面是注册自己包里面的引擎,让外部可以方便的使用,就很多实现database/sql的包,在 init函数里面都是调用了sql.Register(name string, driver driver.Driver)注册自己,然后外部就可以使用了。
    我们用Open()函数来打开一个database handle

    db, err := sql.Open("mysql", "user:password@tcp(ip:port)/database")
    

    写一个完整的:

    import (
    	"database/sql"
    	_ "github.com/go-sql-driver/mysql"
    	"log"
    )
    func main() {
     db, err := sql.Open("mysql", "user:password@tcp(ip:port)/database")
     if err != nil {
     log.Println(err)
     }
     
     //在这里进行一些数据库操作
     
     defer db.Close()
    }

    我们在执行Open函数的时候,并不会去获得数据库连接有效性,当执行数据库操作的时候才会去连接,当我们需要在Open之后就知道连接的有效性的时候,可以通过Ping()来进行

    err = db.Ping()
    if err != nil {
     log.Println(err)
    }

    我们通常习惯使用Close来关闭数据库连接,但是sql.DB是被设计成长期有效的类型,我们不应该频繁的Open和Close,相反,我们应该建立一个sql.DB,在程序需要进行数据库操作的时候一直使用它,不要在一个方法里面进行Open和Close,应该把sql.DB作为参数传递给方法

    进行数据库操作

    增删改操作

    Exec()方法一般用于增删改操作,这里以增加为例:

    stmt, err := db.Prepare("insert into user(name,age)values(?,?)")
    if err != nil {
     log.Println(err)
    }
    
    rs, err := stmt.Exec("go-test", 12)
    if err != nil {
     log.Println(err)
    }
    //我们可以获得插入的id
    id, err := rs.LastInsertId()
    //可以获得影响行数
    affect, err := rs.RowsAffected()

    查询操作

    一般的查询

     var name string
    	var age int
    	rows, err := db.Query("select name,age from user where id = ? ", 1)
    	if err != nil {
    	fmt.Println(err)
    	}
    	defer rows.Close()
    
    	for rows.Next() {
    	err := rows.Scan(&name, &age)
    	if err != nil {
    	fmt.Println(err)
    	}
    	}
    
    	err = rows.Err()
    	if err != nil {
    	fmt.Println(err)
    	}
    
    	fmt.Println("name:", url, "age:", description)
    

    我们应该养成关闭rows的习惯,在任何时候,都不要忘记rows.Close().哪怕这个rows在确实循环完之后,已经自动关闭掉了,我们定义rows.Close()也是对我们没有坏处的,因为我们无法保证,rows是否会正常的循环完。

    查询单条记录,

    我们使用db.QueryRow()

     var name string
     err = db.QueryRow("select name from user where id = ?", 222).Scan(&name)

    没有结果的时候会返回err

    处理空值

    我们用一个name字段为空的记录来举例

    var name NullString
    err := db.QueryRow("SELECT name FROM names WHERE id = ?", id).Scan(&name)
    ...
    if name.Valid {
     // use name.String
    } else {
     // value is NULL
    }

    在这种情况下我们通常使用NullString,但是有时候我们并不关心值是不是Null,我们只需要吧他当一个空字符串来对待就行。这时候我们可以使用[]byte(null byte[]可以转化为空string) 或者 sql.RawBytes,

    var col1, col2 []byte
    
    for rows.Next() {
     // Scan the value to []byte
     err = rows.Scan(&col1, &col2)
    
     if err != nil {
     panic(err.Error()) // Just for example purpose. You should use proper error handling instead of panic
     }
    
     // Use the string value
     fmt.Println(string(col1), string(col2))
    }

    使用*sql.RawBytes

    package main
    
    import (
     "database/sql"
     "fmt"
     _ "github.com/go-sql-driver/mysql"
    )
    
    func main() {
     // Open database connection
     db, err := sql.Open("mysql", "user:password@/dbname")
     if err != nil {
     panic(err.Error()) // Just for example purpose. You should use proper error handling instead of panic
     }
     defer db.Close()
    
     // Execute the query
     rows, err := db.Query("SELECT * FROM table")
     if err != nil {
     panic(err.Error()) // proper error handling instead of panic in your app
     }
    
     // Get column names
     columns, err := rows.Columns()
     if err != nil {
     panic(err.Error()) // proper error handling instead of panic in your app
     }
    
     // Make a slice for the values
     values := make([]sql.RawBytes, len(columns))
    
     // rows.Scan wants '[]interface{}' as an argument, so we must copy the
     // references into such a slice
     // See http://code.google.com/p/go-wiki/wiki/InterfaceSlice for details
     scanArgs := make([]interface{}, len(values))
     for i := range values {
     scanArgs[i] = &values[i]
     }
    
     // Fetch rows
     for rows.Next() {
     // get RawBytes from data
     err = rows.Scan(scanArgs...)
     if err != nil {
     panic(err.Error()) // proper error handling instead of panic in your app
     }
    
     // Now do something with the data.
     // Here we just print each column as a string.
     var value string
     for i, col := range values {
     // Here we can check if the value is nil (NULL value)
     if col == nil {
     value = "NULL"
     } else {
     value = string(col)
     }
     fmt.Println(columns[i], ": ", value)
     }
     fmt.Println("-----------------------------------")
     }
     if err = rows.Err(); err != nil {
     panic(err.Error()) // proper error handling instead of panic in your app
     }
    }

    事务

    使用db.Begin()来开启一个事务, 通过Commit()和Rollback()方法来关闭。

     tx := db.Begin()
    	tx.Rollback()
    	tx.Commit()

    Exec, Query, QueryRow and Prepare 方法已经全部可以在tx上面使用。使用方法和在*sql.DB是一样的,事务必须以Commit()或者Rollback()结束

    The Connection Pool

    在database/sql中有一个很基本的连接池,你并没有多大的控制权,仅仅可以设置SetMaxIdleConns和SetMaxOpenConns,也就是最大空闲连接和最大连接数。

    	db.SetMaxIdleConns(n)
    	db.SetMaxOpenConns(n)

    声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

    文档

    Golang操作数据库

    Golang操作数据库:基本概念 Open() – creates a DB Close() - closes the DB Query() - 查询 QueryRow() -查询行 Exec() -执行操作,update,insert,delete Row - A row is not a hash map, but an abstraction of a cu
    推荐度:
    标签: 操作 数据库 create
    • 热门焦点

    最新推荐

    猜你喜欢

    热门推荐

    专题
    Top