基本概念 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,首先我们需要导入我们需要的包
<code>import ( "database/sql" _ "github.com/go-sql-driver/mysql" )</code>
注意我们导入github.com/go-sql-driver/mysql 前面用了一个"",操作其实是引入该包,而不直接使用包里面的函数,而是调用了该包里面的init函数,import的时候其实是执行了该包里面的init函数,初始化了里面的变量,_操作只是说该包引入了,我只初始化里面的 init函数和一些变量,但是往往这些init函数里面是注册自己包里面的引擎,让外部可以方便的使用,就很多实现database/sql的包,在 init函数里面都是调用了sql.Register(name string, driver driver.Driver)注册自己,然后外部就可以使用了。
我们用Open()函数来打开一个database handle
<code>db, err := sql.Open("mysql", "user:password@tcp(ip:port)/database") </code>
写一个完整的:
<code>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() }</code>
我们在执行Open函数的时候,并不会去获得数据库连接有效性,当执行数据库操作的时候才会去连接,当我们需要在Open之后就知道连接的有效性的时候,可以通过Ping()来进行
<code>err = db.Ping() if err != nil { log.Println(err) }</code>
我们通常习惯使用Close来关闭数据库连接,但是sql.DB是被设计成长期有效的类型,我们不应该频繁的Open和Close,相反,我们应该建立一个sql.DB,在程序需要进行数据库操作的时候一直使用它,不要在一个方法里面进行Open和Close,应该把sql.DB作为参数传递给方法
进行数据库操作
增删改操作
Exec()方法一般用于增删改操作,这里以增加为例:
<code>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()</code>
查询操作
一般的查询
<code> 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) </code>
我们应该养成关闭rows的习惯,在任何时候,都不要忘记rows.Close().哪怕这个rows在确实循环完之后,已经自动关闭掉了,我们定义rows.Close()也是对我们没有坏处的,因为我们无法保证,rows是否会正常的循环完。
查询单条记录,
我们使用db.QueryRow()
<code> var name string err = db.QueryRow("select name from user where id = ?", 222).Scan(&name)</code>
没有结果的时候会返回err
处理空值
我们用一个name字段为空的记录来举例
<code>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 }</code>
在这种情况下我们通常使用NullString,但是有时候我们并不关心值是不是Null,我们只需要吧他当一个空字符串来对待就行。这时候我们可以使用[]byte(null byte[]可以转化为空string) 或者 sql.RawBytes,
<code>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)) }</code>
使用*sql.RawBytes
<code>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 } }</code>
事务
使用db.Begin()来开启一个事务, 通过Commit()和Rollback()方法来关闭。
<code> tx := db.Begin() tx.Rollback() tx.Commit()</code>
Exec, Query, QueryRow and Prepare 方法已经全部可以在tx上面使用。使用方法和在*sql.DB是一样的,事务必须以Commit()或者Rollback()结束
The Connection Pool
在database/sql中有一个很基本的连接池,你并没有多大的控制权,仅仅可以设置SetMaxIdleConns和SetMaxOpenConns,也就是最大空闲连接和最大连接数。
<code> db.SetMaxIdleConns(n) db.SetMaxOpenConns(n)</code>

MySQL和SQLite的主要区别在于设计理念和使用场景:1.MySQL适用于大型应用和企业级解决方案,支持高性能和高并发;2.SQLite适合移动应用和桌面软件,轻量级且易于嵌入。

MySQL中的索引是数据库表中一列或多列的有序结构,用于加速数据检索。1)索引通过减少扫描数据量提升查询速度。2)B-Tree索引利用平衡树结构,适合范围查询和排序。3)创建索引使用CREATEINDEX语句,如CREATEINDEXidx_customer_idONorders(customer_id)。4)复合索引可优化多列查询,如CREATEINDEXidx_customer_orderONorders(customer_id,order_date)。5)使用EXPLAIN分析查询计划,避

在MySQL中使用事务可以确保数据一致性。1)通过STARTTRANSACTION开始事务,执行SQL操作后用COMMIT提交或ROLLBACK回滚。2)使用SAVEPOINT可以设置保存点,允许部分回滚。3)性能优化建议包括缩短事务时间、避免大规模查询和合理使用隔离级别。

选择PostgreSQL而非MySQL的场景包括:1)需要复杂查询和高级SQL功能,2)要求严格的数据完整性和ACID遵从性,3)需要高级空间功能,4)处理大数据集时需要高性能。PostgreSQL在这些方面表现出色,适合需要复杂数据处理和高数据完整性的项目。

MySQL数据库的安全可以通过以下措施实现:1.用户权限管理:通过CREATEUSER和GRANT命令严格控制访问权限。2.加密传输:配置SSL/TLS确保数据传输安全。3.数据库备份和恢复:使用mysqldump或mysqlpump定期备份数据。4.高级安全策略:使用防火墙限制访问,并启用审计日志记录操作。5.性能优化与最佳实践:通过索引和查询优化以及定期维护兼顾安全和性能。

如何有效监控MySQL性能?使用mysqladmin、SHOWGLOBALSTATUS、PerconaMonitoringandManagement(PMM)和MySQLEnterpriseMonitor等工具。1.使用mysqladmin查看连接数。2.用SHOWGLOBALSTATUS查看查询数。3.PMM提供详细性能数据和图形化界面。4.MySQLEnterpriseMonitor提供丰富的监控功能和报警机制。

MySQL和SQLServer的区别在于:1)MySQL是开源的,适用于Web和嵌入式系统,2)SQLServer是微软的商业产品,适用于企业级应用。两者在存储引擎、性能优化和应用场景上有显着差异,选择时需考虑项目规模和未来扩展性。

在需要高可用性、高级安全性和良好集成性的企业级应用场景下,应选择SQLServer而不是MySQL。1)SQLServer提供企业级功能,如高可用性和高级安全性。2)它与微软生态系统如VisualStudio和PowerBI紧密集成。3)SQLServer在性能优化方面表现出色,支持内存优化表和列存储索引。


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

SublimeText3 英文版
推荐:为Win版本,支持代码提示!

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

mPDF
mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),

禅工作室 13.0.1
功能强大的PHP集成开发环境