database/sql
是go语言内置数据库引擎,使用sql查询数据库,配置datasource后使用其数据库操作方法对数据库操作,如下:
package main
import (
"database/sql"
"fmt"
_ "github.com/Masterminds/squirrel"
_ "github.com/go-sql-driver/mysql"
)
func main() {
datasource := "root:root@tcp(192.168.42.128:3306)/test"
sqlDB, err := sql.Open("mysql", datasource)
if err != nil {
panic(err)
}
defer sqlDB.Close()
r := sqlDB.QueryRow("select * from user")
type User struct {
Id int
Account string
Password string
}
var user User
err = r.Scan(&user.Id, &user.Account, &user.Password)
if err != nil {
panic(err)
}
fmt.Println(user)
//squirrel.Select("")
}
除了原生的方法外许多orm框架也是对sql进行了封装,如gorm,xorm等。使用原生database/sql
就需要编写sql语句。
database/sql
方法传入的是sql的字符串,再使用squirrel
生成sql。
squirrel
是一个sql生成工具,能够帮助开发者快速构建sql,避免拼接原生sql,原生sql语句一般是很长的,特别是多表联查的时候。squirrel
能够避免直接拼接太长SQL的过程,简化书写。
github地址
首先介绍squirrel
的四大结构体
SelectBuilder
UpdateBuilder
InsertBuilder
DeleteBuilder
这些结构体都没有成员变量,都是用来实实现具体方法构造SQL的,其归属其类型都是builder.Builder
。
但是由于不用DDL,DML的区别,这些结构体也会实现不同的方法,例如
select * from `user` where `id` = 1 inner join order on `user.orderid` = `order.id`
update `user` set `password` = 123456
delete from `user` where `id` = 1
insert into `user` (....) values (....)
在上述CURD中,不同的语句具有不同的关键字,这是四大结构体就会实现具体的方法,返回特定sql构造结构体。
那么就可以使用squirrel
构造sql了,显然方法参数是sql的变量。
s, i, err := squirrel.Select("*").From("user").ToSql()
if err != nil {
panic(err)
}
fmt.Println(s)
fmt.Print(i)
可以看到ToSql
方法返回三个参数,分别是sql语句和参数为切片类型,代码所示没有传入参数因此未一个空切片。
ub := squirrel.Update("user").Set("password", 12345678).Where("id", 1)
s, i, _ := ub.ToSql()
fmt.Printf("sql = %s,elem = %v\n", s, i)
ub1 := squirrel.Update("user").Set("password = ?", 12345678).Where("id = ?", 1)
s1, i1, _ := ub1.ToSql()
fmt.Printf("sql = %s,elem = %v\n", s1, i1)
s2, i2, _ := squirrel.Delete("user").Where("id = ?", 1).ToSql()
fmt.Printf("sql = %s,elem = %v\n", s2, i2)
通过上面的测试可以发现set
关键字后面只能是=
因此会自动拼接,where
后面不一定是=
所以不会自动拼接。
数据库操作的关键是条件查询,对于where关键字来说是传入变量最多的,通过上述案例可以知道如下的传参方式:
s, i, err := squirrel.Select("*").From("user").Where("id = ? and name = ? and password = ?", 1, "xiaoux", "12345678").ToSql()
fmt.Printf("%s,%v,%v\n", s, i, err)
这样依旧可以传参成功但是并没有简便多少,另外squirrel还提供squirrel.Eq
来传参
s2, i2, err2 := squirrel.Select("*").From("user").Where(squirrel.Eq{"id": 1, "name": "xiaoxu", "password": "123456"}).ToSql()
fmt.Printf("%s,%v,%v\n", s2, i2, err2)
和前一个生成sql一样,但是却更具有可观性。squirrel不支持结构体作为参数,只支持string和map两种类型。
s, i, err := squirrel.Select("user.id", "user.name", "order.id", "order.name").From("user").Where("user.orderid = order.id").Join("order").ToSql()
fmt.Println(s, i, err)
Squirrel 本身并不是一个直接用于执行数据库查询的库。它是一个 SQL 查询构建器,旨在简化动态生成和构造复杂 SQL 查询语句的过程。
使用 Squirrel,你可以通过链式调用方法来构建 SQL 查询,包括选择要返回的列、指定表名、添加条件、排序、限制结果等。但是,要执行实际的数据库查询,你还需要借助一个具体的数据库驱动程序或 ORM 库。
在 Go 语言中,database/sql 包提供了与数据库交互的通用接口,而各种数据库驱动程序(如 MySQL、PostgreSQL、SQLite 等)则实现了这个接口。你可以结合使用 Squirrel 和适当的数据库驱动程序来执行查询。当然也可以是其他数据库驱动程序。
总结而言,Squirrel 可以辅助你构建复杂的 SQL 查询语句,但要执行实际的数据库查询,你需要结合具体的数据库驱动程序或 ORM 库来完成。