首页 > 编程知识 正文

golang数据分析库,数据库查询库的所有数据

时间:2023-05-06 08:54:59 阅读:274950 作者:3801

database/sql包

golang封装了database/sql标准库,它提供了用于处理sql相关的操作的接口。而接口的实现则交给了数据库驱动

好处在于写代码逻辑的时候,不用考虑后端的具体数据库,即使迁移数据库类型的时候,也只需要迁移相应的驱动即可,而不用修改代码使用数据库时,除了database/sql包本身,必须要引入想使用的特定数据库驱动

sql.Open()不建立与数据库的任何连接,也不会验证驱动连接参数。相反,它只是准备数据库抽象以供以后使用

首次真正的连接数据库将在第一次需要时惰性建立如果你想立即检查数据库是否可用(例如,检查是否可以建立网络连接并登陆),请使用db.Ping()来执行此操作

sql.DB对象被设计为长连接

不要经常Open()和Close()数据库对象 否则会遇到诸如重复使用和连接共享不足,耗尽可用的网络资源以及由于TIME_WAIT中剩余大量TCP连接而导致的零星故障的状态 应该在需要是把sql.DB对象作为参数,或赋值给全局变量

rows.Close()是一种无害的操作,如果它已经关闭,所以你可以多次调用它

请注意首先检查错误,如果没有错误再调用rows.Close(),否则会导致运行时的panic延迟语句在函数退出之前不会执行,所以长时间运行的函数不应该使用它 不要在循环中用defer推迟

Query将返回一个sql.Rows,它保持数据库连接,直到sql.Rows关闭

如果rows.Next()循环不是由于查询完毕而自动退出的(例如遇到error),连接不会释放 正常退出会自动关闭连接垃圾回收器最终会关闭底层的net.Conn,但这可能需要很长时间 如果你只想执行一个语句并检查是否有错误,但忽略结果(例如DELETE等),应该使用db.Exec()而不是db.Query()

来自rows.Err()的错误可能是rows.Next()循环中各种错误的结果

例如循环可能会由于查询时间过长等原因提前退出,这种情况在Next内是不会有错误的,也不会自动回收连接

对于QueryRow(),有一个特殊的错误常量,称为sql.ErrNoRows,当结果为空时,它将从QueryRow()返回

这在大多数情况下需要作为特殊情况来处理空的结果通常不被应用程序代码认为是错误的,如果不检查错误是不是这个特殊常量,那么会导致你意想不到的应用程序代码错误 var name stringerr = db.QueryRow("select name from users where id = ?", 1).Scan(&name)if err != nil { if err == sql.ErrNoRows { // there were no rows, but otherwise no error occurred } else { log.Fatal(err) }} 如果你不知道查询将返回多少列,则可以使用Columns()来查询列名称列表。你可以检查此列表的长度以查看有多少列,并且可以将切片传递给具有正确数值的Scan() 对于不定字段查询,我们可以定义一个map的key和value用来表示数据库一条记录的row的值。通过rows.Columns得到的col作为map的key值如果你不知道这些列或者它们的类型,你应该使用sql.RawBytes cols, err := rows.Columns()if err != nil{ log.Fatalln(err)}vals := make([][]byte, len(cols))scans := make([]interface{}, len(cols))for i := range vals{ scans[i] = &vals[i]}var results []map[string]stringfor rows.Next(){ err = rows.Scan(scans...) if err != nil{ log.Fatalln(err) } row := make(map[string]string) for k, v := range vals{ key := cols[k] row[key] = string(v) } results = append(results, row)} 不必检查或者尝试处理连接失败的情况 单纯的小猫咪进行数据库操作的时候,如果连接失败了,database/sql会自动尝试重连10次仍然无法重连的情况下会自动从连接池再获取一个或者新建另外一个 连接池配置 db.SetMaxOpenConns(n int) 设置打开数据库的最大连接数 包含正在使用的连接和连接池的连接如果你的函数调用需要申请一个连接,并且连接池已经没有了连接或者连接数达到了最大连接数。此时的函数调用将会被block,直到有可用的连接才会返回设置这个值可以避免并发太高导致连接mysql出现too many connections的错误该函数的默认设置是0,表示无限制 db.SetMaxIdleConns(n int)设置连接池中的保持连接的最大连接数 默认也是0,表示连接池不会保持释放会连接池中的连接的连接状态:即当连接释放回到连接池的时候,连接将会被关闭 这会导致连接再连接池中频繁的关闭和创建 db.maxLifeTime(t time.Duration) 设置连接被复用的最大时间 注意并不是连接空闲时间,而是从连接建立到这个时间点就会被强制回收,从而保证连接活性MySQL 侧会强制 kill 掉长时间空闲的连接(8h) Query方法原理 步骤 从连接池中请求一个连接执行查询的sql语句将数据库连接的所属权传递给Result结果集 Query返回的结果集是sql.Rows类型。它有一个Next方法,可以迭代数据库的游标,进而获取每一行的数据rows.Next方法设计用来迭代 当它迭代到最后一行数据之后,会触发一个io.EOF的信号,即引发一个错误,同时go会自动调用rows.Close方法释放连接,然后返回false。此时循环将会结束退出 Scan函数会帮我们自动推断除数据字段匹配目标变量 比如有个数据库字段的类型是VARCHAR,而他的值是一个数字串,例如"1"。如果我们定义目标变量是string,则scan赋值后目标变量是数字string如果声明的目标变量是一个数字类型,那么scan会自动调用strconv.ParseInt()或者strconv.ParseInt()方法将字段转换成和声明的目标变量一致的类型当然如果有些字段无法转换成功,则会返回错误。因此在调用scan后都需要检查错误 GORM 支持的数据库 MySQL, PostgreSQL,Sqlite3为了处理time.Time,连接MySQL时需要包括parseTime作为参数 db, err := gorm.Open("mysql","user:password@/dbname?charset=utf8&parseTime=True&loc=Local") 默认映射 表名是结构体名称的复数形式 通过给结构体添加TableName() string方法自定义表名 列名是字段名的蛇形小写 可以通过结构体tag重设: gorm:"column:<new name>" 字段ID为默认主键 使用结构体tag重设:gorm:"primary_key" gorm的使用方式是链式操作,很多函数都返回*DB这个结构 参考 简书-mysql笔记1(后面还有234)Go database/sql文档GORM中文文档

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。