Go   发布时间:2019-10-06  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了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 cursor
  • Next()
  • Scan()

注意:@H_874_29@DB并不是指的一个connection

连接到数据库

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

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

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

db@H_874_29@,@H_874_29@ err @H_874_29@:=@H_874_29@ sql@H_874_29@.@H_874_29@Open@H_874_29@(@H_874_29@"mysql"@H_874_29@ @H_874_29@"user:password@tcp(ip:port)/database"@H_874_29@ 写一个完整的:

"log"@H_874_29@)@H_874_29@
func main@H_874_29@()@H_874_29@{@H_874_29@
    db@H_874_29@
    @H_874_29@if@H_874_29@!=@H_874_29@ @H_874_29@nil@H_874_29@
        log@H_874_29@Println@H_874_29@err@H_874_29@
    @H_874_29@}@H_874_29@
    @H_874_29@//在这里进行一些数据库操作@H_874_29@
    defer db@H_874_29@Close@H_874_29@}@H_874_29@

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

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

进行数据库操作

增删改操作

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

stmt@H_874_29@Prepare@H_874_29@"insert into user(name,agE)values(?,?)"@H_874_29@
rs@H_874_29@ stmt@H_874_29@Exec@H_874_29@"go-test"@H_874_29@ @H_874_29@12@H_874_29@
@H_874_29@//我们可以获得插入的id@H_874_29@
id@H_874_29@ rs@H_874_29@LasTinsertId@H_874_29@//可以获得影响行数@H_874_29@
affect@H_874_29@RowsAffected@H_874_29@()@H_874_29@

查询操作

一般的查询

    @H_874_29@var@H_874_29@ name @H_874_29@String@H_874_29@
	@H_874_29@ age @H_874_29@int@H_874_29@
	rows@H_874_29@Query@H_874_29@"SELEct name,age from user where id = ? "@H_874_29@1@H_874_29@
		fmt@H_874_29@
	@H_874_29@
	defer rows@H_874_29@for@H_874_29@ rows@H_874_29@Next@H_874_29@
		err @H_874_29@Scan@H_874_29@(&@H_874_29@name@H_874_29@&@H_874_29@age@H_874_29@
		@H_874_29@
			fmt@H_874_29@
		@H_874_29@
	err @H_874_29@Err@H_874_29@
	fmt@H_874_29@"name:"@H_874_29@ url@H_874_29@"age:"@H_874_29@ description@H_874_29@ 我们应该养成关闭rows的习惯,在任何时候,都不要忘记rows.Close().哪怕这个rows在确实循环完之后,已经自动关闭掉了,我们定义rows.Close()也是对我们没有坏处的,因为我们无法保证,rows是否会正常的循环完。

查询单条记录,

我们使用db.QueryRow()

    err @H_874_29@QueryRow@H_874_29@"SELEct name from user where id = ?"@H_874_29@222@H_874_29@).@H_874_29@ 没有结果的时候会返回err

处理空值

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

 name @H_874_29@NullString@H_874_29@
err @H_874_29@"SELECT name FROM names WHERE id = ?"@H_874_29@ id@H_874_29@...@H_874_29@ name@H_874_29@Valid@H_874_29@
        @H_874_29@// use name.String@H_874_29@else@H_874_29@// value is NULL@H_874_29@ 在这种情况下我们通常使用NullString,但是有时候我们并不关心值是不是Null,我们只需要吧他当一个空字符串来对待就行。这时候我们可以使用[]byte(null byte[]可以转化为空String) 或者@H_874_29@sql.RawBytes,

 col1@H_874_29@ col2 @H_874_29@[]@H_874_29@byte@H_874_29@// Scan the value to []byte@H_874_29@col1@H_874_29@col2@H_874_29@
        panic@H_874_29@Error@H_874_29@())@H_874_29@ @H_874_29@// Just for example purpose. You should use proper error handling instead of panic@H_874_29@// Use the String value@H_874_29@
    fmt@H_874_29@(@H_874_29@String@H_874_29@),0)">))@H_874_29@ 使用*sql.RawBytes

package@H_874_29@ main
@H_874_29@
    @H_874_29@"fmt"@H_874_29@
    _ @H_874_29@// Open database connection@H_874_29@"user:password@/dbname"@H_874_29@  @H_874_29@// Execute the query@H_874_29@
    rows@H_874_29@"SELECT * FROM table"@H_874_29@// proper error handling instead of panic in your app@H_874_29@// Get column names@H_874_29@
    columns@H_874_29@columns@H_874_29@// Make a slice for the values@H_874_29@
    values @H_874_29@ make@H_874_29@([]@H_874_29@sql@H_874_29@RawBytes@H_874_29@ len@H_874_29@columns@H_874_29@// rows.Scan wants '[]interface{}' as an argument,so we must copy the@H_874_29@// references into such a slice@H_874_29@// See http://code.google.com/p/go-wiki/wiki/InterfaceSlice for details@H_874_29@
    scanArgs @H_874_29@([]@H_874_29@interface@H_874_29@{},0)">values@H_874_29@ i @H_874_29@ range values @H_874_29@
        scanArgs@H_874_29@[@H_874_29@i@H_874_29@]@H_874_29@// Fetch rows@H_874_29@// get RawBytes from data@H_874_29@
        err @H_874_29@scanArgs@H_874_29@...)@H_874_29@
        @H_874_29@
            panic@H_874_29@
        @H_874_29@// Now do something with the data.@H_874_29@// Here we just print each column as a String.@H_874_29@ value @H_874_29@ i@H_874_29@ col @H_874_29@
            @H_874_29@// Here we can check if the value is nil (NULL value)@H_874_29@
            @H_874_29@==@H_874_29@
                value @H_874_29@"NULL"@H_874_29@
            @H_874_29@col@H_874_29@
            fmt@H_874_29@],255)">": "@H_874_29@ value@H_874_29@
        fmt@H_874_29@"-----------------------------------"@H_874_29@();@H_874_29@}@H_874_29@

事务

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

    tx @H_874_29@Begin@H_874_29@
	tx@H_874_29@RollBACk@H_874_29@Commit@H_874_29@()@H_874_29@

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

The Connection Pool

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

	db@H_874_29@SetMaxIdleConns@H_874_29@n@H_874_29@
	db@H_874_29@SetMaxOpenConns@H_874_29@)@H_874_29@

大佬总结

以上是大佬教程为你收集整理的golang-数据库详解全部内容,希望文章能够帮你解决golang-数据库详解所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。