golang简单强大的SQL数据库操作插件库KSQL的使用
Golang简单强大的SQL数据库操作插件库KSQL的使用
KSQL是一个为Golang设计的简单而强大的SQL数据库操作库,旨在提供易于使用且功能丰富的API来与SQL数据库交互。
主要特点
- 每个操作只返回一次错误,便于错误处理
- 提供日常操作的辅助函数:Insert、Patch和Delete
- 通用且强大的查询和扫描数据到结构体的功能
- 基于成熟的库如
database/sql
和pgx
构建 - 支持
sql.Scanner
和sql.Valuer
接口 - 支持
pgx
的特殊类型(使用kpgx
时)
快速入门示例
package main
import (
"context"
"errors"
"fmt"
"log"
"github.com/vingarcia/ksql"
"github.com/vingarcia/ksql/adapters/kpgx"
)
var UsersTable = ksql.NewTable("users", "user_id")
type User struct {
ID int `ksql:"user_id"`
Name string `ksql:"name"`
Type string `ksql:"type"`
Posts []Post
}
// Post与User是多对一关系
var PostsTable = ksql.NewTable("posts", "post_id")
type Post struct {
ID int `ksql:"post_id"`
UserID int `ksql:"user_id"`
Title string `ksql:"title"`
Text string `ksql:"text"`
}
// Address与User是一对一关系
var AddressesTable = ksql.NewTable("addresses", "id")
type Address struct {
ID int `ksql:"id"`
UserID int `ksql:"user_id"`
FullAddr string `ksql:"full_addr"`
}
func main() {
ctx := context.Background()
dbURL, closeDB := startExampleDB(ctx)
defer closeDB()
db, err := kpgx.New(ctx, dbURL, ksql.Config{})
if err != nil {
log.Fatalf("unable connect to database: %s", err)
}
defer db.Close()
// 查询部分属性可以使用自定义结构体
var count []struct {
Count int `ksql:"count"`
Type string `ksql:"type"`
}
err = db.Query(ctx, &count, "SELECT type, count(*) as count FROM users GROUP BY type")
if err != nil {
log.Fatalf("unable to query users: %s", err)
}
fmt.Println("number of users by type:", count)
// 从数据库加载实体时,如果省略SELECT部分,KSQL会自动构建
var adminUsers []User
err = db.Query(ctx, &adminUsers, "FROM users WHERE type = $1", "admin")
if err != nil {
log.Fatalf("unable to query admin users: %s", err)
}
fmt.Println("admin users:", adminUsers)
// 加载用户及其帖子的好方法
var user User
err = errors.Join(
db.QueryOne(ctx, &user, "FROM users WHERE user_id = $1", 42),
db.Query(ctx, &user.Posts, "FROM posts WHERE user_id = $1", user.ID),
)
if err != nil {
log.Fatalf("unable to query users: %s", err)
}
fmt.Println("user with posts:", user)
// 从连接表中检索数据
var rows []struct {
OneUser User `tablename:"users"`
OneAddress Address `tablename:"addr"`
}
err = db.Query(ctx, &rows,
`FROM users
JOIN addresses addr
ON users.user_id = addr.user_id`,
)
if err != nil {
log.Fatalf("unable to query users: %s", err)
}
fmt.Println("rows of joined tables:", rows)
}
CRUD操作示例
package main
import (
"context"
"fmt"
"time"
"github.com/vingarcia/ksql"
"github.com/vingarcia/ksql/adapters/ksqlite3"
"github.com/vingarcia/ksql/nullable"
)
type User struct {
ID int `ksql:"id"`
Name string `ksql:"name"`
Age int `ksql:"age"`
// json修饰符会将地址以JSON格式保存到数据库
Address Address `ksql:"address,json"`
// timeNowUTC修饰符会在保存前将此字段设置为time.Now().UTC()
UpdatedAt time.Time `ksql:"updated_at,timeNowUTC"`
// timeNowUTC/skipUpdates修饰符只在首次创建时设置此字段为time.Now().UTC()
// 在更新时忽略它
CreatedAt time.Time `ksql:"created_at,timeNowUTC/skipUpdates"`
}
type PartialUpdateUser struct {
ID int `ksql:"id"`
Name *string `ksql:"name"`
Age *int `ksql:"age"`
Address *Address `ksql:"address,json"`
}
type Address struct {
State string `json:"state"`
City string `json:"city"`
}
// UsersTable告诉KSQL表名和主键列名默认为"id"
var UsersTable = ksql.NewTable("users")
func main() {
ctx := context.Background()
// 使用sqlite3
db, err := ksqlite3.New(ctx, "/tmp/hello.sqlite", ksql.Config{
MaxOpenConns: 1,
})
if err != nil {
panic(err.Error())
}
defer db.Close()
// 创建表
_, err = db.Exec(ctx, `CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY,
age INTEGER,
name TEXT,
address BLOB,
created_at DATETIME,
updated_at DATETIME
)`)
if err != nil {
panic(err.Error())
}
// 插入记录
var alison = User{
Name: "Alison",
Age: 22,
Address: Address{
State: "MG",
},
}
err = db.Insert(ctx, UsersTable, &alison)
if err != nil {
panic(err.Error())
}
fmt.Println("Alison ID:", alison.ID)
// 删除记录
err = db.Delete(ctx, UsersTable, alison.ID)
if err != nil {
panic(err.Error())
}
// 查询单条记录
var cris User
err = db.QueryOne(ctx, &cris, "FROM users WHERE name = ? ORDER BY id", "Cristina")
if err != nil {
panic(err.Error())
}
// 更新记录
cris.Name = "Cris"
err = db.Patch(ctx, UsersTable, cris)
// 部分更新技术1
err = db.Patch(ctx, UsersTable, struct {
ID int `ksql:"id"`
Age int `ksql:"age"`
}{ID: cris.ID, Age: 28})
if err != nil {
panic(err.Error())
}
// 部分更新技术2
err = db.Patch(ctx, UsersTable, PartialUpdateUser{
ID: cris.ID,
Age: nullable.Int(28), // 只是一个int指针,如果为null则不会更新
})
if err != nil {
panic(err.Error())
}
// 查询多条记录
var users []User
err = db.Query(ctx, &users, "FROM users LIMIT 10")
if err != nil {
panic(err.Error())
}
// 事务处理
err = db.Transaction(ctx, func(db ksql.Provider) error {
var cris2 User
err = db.QueryOne(ctx, &cris2, "FROM users WHERE id = ?", cris.ID)
if err != nil {
return err
}
err = db.Patch(ctx, UsersTable, PartialUpdateUser{
ID: cris2.ID,
Age: nullable.Int(29),
})
if err != nil {
panic(err.Error())
}
return nil
})
if err != nil {
panic(err.Error())
}
}
支持的适配器
KSQL支持多种数据库适配器:
-
Postgres (使用pgx v4):
go get github.com/vingarcia/ksql/adapters/kpgx
-
Postgres (使用pgx v5):
go get github.com/vingarcia/ksql/adapters/kpgx5
-
MySQL:
go get github.com/vingarcia/ksql/adapters/kmysql
-
SQLServer:
go get github.com/vingarcia/ksql/adapters/ksqlserver
-
SQLite3 (基于CGO):
go get github.com/vingarcia/ksql/adapters/ksqlite3
-
SQLite (无CGO):
go get github.com/vingarcia/ksql/adapters/modernc-ksqlite
KSQL提供了简单而强大的API来操作SQL数据库,通过结构体标签和辅助方法简化了常见的数据库操作,同时保持了良好的性能。
更多关于golang简单强大的SQL数据库操作插件库KSQL的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于golang简单强大的SQL数据库操作插件库KSQL的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
KSQL: Golang简单强大的SQL数据库操作库
KSQL是一个轻量级但功能强大的Golang SQL数据库操作库,它提供了简单易用的API来执行常见的数据库操作。下面我将介绍KSQL的主要特性和使用方法。
KSQL主要特性
- 简单易用的API设计
- 支持多种数据库(MySQL, PostgreSQL, SQLite等)
- 自动映射结构体和数据库表
- 支持事务操作
- 内置SQL注入防护
- 支持链式调用
安装KSQL
go get github.com/vingarcia/ksql
基本使用方法
1. 初始化数据库连接
package main
import (
"database/sql"
"fmt"
"log"
"github.com/vingarcia/ksql"
_ "github.com/go-sql-driver/mysql"
)
func main() {
// 使用标准库的sql.Open创建连接
db, err := sql.Open("mysql", "user:password@tcp(127.0.0.1:3306)/dbname")
if err != nil {
log.Fatal(err)
}
defer db.Close()
// 创建KSQL适配器
adapter := ksql.NewAdapter(db, ksql.Config{
TableName: "users", // 默认表名
})
// 使用KSQL进行操作...
}
2. 定义模型结构体
type User struct {
ID int `ksql:"id"`
Name string `ksql:"name"`
Email string `ksql:"email"`
CreatedAt string `ksql:"created_at"`
}
3. CRUD操作示例
插入数据
user := User{
Name: "张三",
Email: "zhangsan@example.com",
}
// 插入并返回ID
id, err := adapter.Insert(ksql.InsertOpts{
TableName: "users",
Record: &user,
})
if err != nil {
log.Fatal(err)
}
fmt.Printf("插入成功,ID: %d\n", id)
查询单个记录
var user User
err := adapter.QueryOne(ksql.QueryOneOpts{
TableName: "users",
Record: &user,
Where: ksql.Where("id = ?", 1),
})
if err != nil {
log.Fatal(err)
}
fmt.Printf("查询结果: %+v\n", user)
查询多个记录
var users []User
err := adapter.Query(ksql.QueryOpts{
TableName: "users",
Records: &users,
Where: ksql.Where("name LIKE ?", "%张%"),
Limit: 10,
})
if err != nil {
log.Fatal(err)
}
for _, user := range users {
fmt.Printf("用户: %+v\n", user)
}
更新数据
user := User{
ID: 1,
Name: "张三(更新)",
Email: "newemail@example.com",
}
rowsAffected, err := adapter.Update(ksql.UpdateOpts{
TableName: "users",
Record: &user,
})
if err != nil {
log.Fatal(err)
}
fmt.Printf("更新了 %d 行\n", rowsAffected)
删除数据
rowsAffected, err := adapter.Delete(ksql.DeleteOpts{
TableName: "users",
Where: ksql.Where("id = ?", 1),
})
if err != nil {
log.Fatal(err)
}
fmt.Printf("删除了 %d 行\n", rowsAffected)
4. 事务处理
err := adapter.Transaction(func(tx *ksql.Adapter) error {
// 在事务中执行多个操作
_, err := tx.Insert(ksql.InsertOpts{
TableName: "users",
Record: &User{
Name: "李四",
Email: "lisi@example.com",
},
})
if err != nil {
return err
}
_, err = tx.Update(ksql.UpdateOpts{
TableName: "users",
Record: &User{
ID: 2,
Name: "王五(更新)",
Email: "wangwu@example.com",
},
})
return err
})
if err != nil {
log.Fatal("事务执行失败:", err)
}
5. 高级查询
// 使用Join查询
var result []struct {
User User `ksql:"users"`
Order Order `ksql:"orders"`
}
err := adapter.Query(ksql.QueryOpts{
TableName: "users",
Records: &result,
Join: "LEFT JOIN orders ON users.id = orders.user_id",
Where: ksql.Where("users.id > ?", 10),
})
if err != nil {
log.Fatal(err)
}
// 使用Count统计
count, err := adapter.Count(ksql.CountOpts{
TableName: "users",
Where: ksql.Where("name LIKE ?", "%张%"),
})
if err != nil {
log.Fatal(err)
}
fmt.Printf("共有 %d 个姓张的用户\n", count)
总结
KSQL提供了简单而强大的API来操作SQL数据库,它的主要优点包括:
- 简洁的API设计,减少了样板代码
- 自动映射结构体和数据库表
- 内置安全防护
- 支持事务处理
- 良好的错误处理
对于需要轻量级ORM但又不想使用复杂框架的Golang项目,KSQL是一个很好的选择。它既保留了SQL的灵活性,又提供了ORM的便利性。
更多高级用法和详细文档可以参考KSQL的GitHub仓库:https://github.com/vingarcia/ksql