本文档帮助你快速上手 daog,从环境准备到完成第一个 CRUD 示例。
- Go 1.18+ (需要泛型支持)
- MySQL 5.7+
go get github.com/rolandhe/daoggo install github.com/rolandhe/compilex@latest验证安装:
compilex -h创建 schema.sql 文件:
CREATE TABLE `user_info` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
`name` varchar(64) NOT NULL COMMENT '用户名',
`email` varchar(128) NOT NULL COMMENT '邮箱',
`age` int NOT NULL DEFAULT 0 COMMENT '年龄',
`status` tinyint NOT NULL DEFAULT 1 COMMENT '状态:1-正常 0-禁用',
`created_at` datetime NOT NULL COMMENT '创建时间',
`updated_at` datetime NOT NULL COMMENT '更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_email` (`email`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户信息表';compilex -i="schema.sql" -pkg dal -o ./dal参数说明:
-i: 输入的 SQL 文件路径-pkg: 生成代码的包名-o: 输出目录
执行后会生成两个文件:
UserInfo.go(不可修改):
package dal
import (
"github.com/rolandhe/daog"
"github.com/rolandhe/daog/ttypes"
)
// 字段名常量
var UserInfoFields = struct {
Id string
Name string
Email string
Age string
Status string
CreatedAt string
UpdatedAt string
}{
"id",
"name",
"email",
"age",
"status",
"created_at",
"updated_at",
}
// 表元数据
var UserInfoMeta = &daog.TableMeta[UserInfo]{
Table: "user_info",
Columns: []string{"id", "name", "email", "age", "status", "created_at", "updated_at"},
AutoColumn: "id",
LookupFieldFunc: func(columnName string, ins *UserInfo, point bool) any {
// 字段映射逻辑...
},
}
// QuickDao 实例
var UserInfoDao daog.QuickDao[UserInfo] = daog.NewBaseQuickDao(UserInfoMeta)
// 数据结构
type UserInfo struct {
Id int64
Name string
Email string
Age int
Status int8
CreatedAt ttypes.NormalDatetime
UpdatedAt ttypes.NormalDatetime
}UserInfo-ext.go(可修改):
package dal
func init() {
// 可以在这里设置分表函数
// UserInfoMeta.ShardingFunc = func(tableName string, key any) string {
// return fmt.Sprintf("%s_%d", tableName, key.(int64)%10)
// }
}
// 可以在这里添加自定义的数据访问方法package main
import (
"log"
"github.com/rolandhe/daog"
_ "github.com/go-sql-driver/mysql"
)
var datasource daog.Datasource
func init() {
conf := &daog.DbConf{
DbUrl: "root:password@tcp(localhost:3306)/testdb?parseTime=true",
Size: 20, // 最大连接数
Life: 3600, // 连接最大生命周期(秒)
IdleCons: 10, // 最大空闲连接数
IdleTime: 600, // 最大空闲时间(秒)
LogSQL: true, // 开启 SQL 日志
GetConnTimeout: 10, // 获取连接超时(秒)
}
var err error
datasource, err = daog.NewDatasource(conf)
if err != nil {
log.Fatal(err)
}
}
func main() {
defer datasource.Shutdown()
// 使用 datasource 进行数据库操作...
}package main
import (
"fmt"
"log"
"time"
"github.com/rolandhe/daog"
"github.com/rolandhe/daog/ttypes"
txrequest "github.com/rolandhe/daog/tx"
"your/project/dal"
_ "github.com/go-sql-driver/mysql"
)
var datasource daog.Datasource
func init() {
conf := &daog.DbConf{
DbUrl: "root:password@tcp(localhost:3306)/testdb?parseTime=true",
LogSQL: true,
}
var err error
datasource, err = daog.NewDatasource(conf)
if err != nil {
log.Fatal(err)
}
}
func main() {
defer datasource.Shutdown()
// 1. 创建用户
user, err := createUser("张三", "zhangsan@example.com", 25)
if err != nil {
log.Fatal(err)
}
fmt.Printf("创建用户成功,ID: %d\n", user.Id)
// 2. 查询用户
user, err = getUserById(user.Id)
if err != nil {
log.Fatal(err)
}
fmt.Printf("查询用户:%+v\n", user)
// 3. 更新用户
err = updateUserAge(user.Id, 26)
if err != nil {
log.Fatal(err)
}
fmt.Println("更新用户成功")
// 4. 条件查询
users, err := queryActiveUsers()
if err != nil {
log.Fatal(err)
}
fmt.Printf("查询到 %d 个活跃用户\n", len(users))
// 5. 删除用户
err = deleteUser(user.Id)
if err != nil {
log.Fatal(err)
}
fmt.Println("删除用户成功")
}
// 创建用户
func createUser(name, email string, age int) (*dal.UserInfo, error) {
return daog.AutoTransWithResult(func() (*daog.TransContext, error) {
return daog.NewTransContext(datasource, txrequest.RequestWrite, "create-user")
}, func(tc *daog.TransContext) (*dal.UserInfo, error) {
now := ttypes.NormalDatetime(time.Now())
user := &dal.UserInfo{
Name: name,
Email: email,
Age: age,
Status: 1,
CreatedAt: now,
UpdatedAt: now,
}
_, err := dal.UserInfoDao.Insert(tc, user)
if err != nil {
return nil, err
}
// user.Id 已自动回填
return user, nil
})
}
// 根据 ID 查询用户
func getUserById(id int64) (*dal.UserInfo, error) {
return daog.AutoTransWithResult(func() (*daog.TransContext, error) {
return daog.NewTransContext(datasource, txrequest.RequestReadonly, "get-user")
}, func(tc *daog.TransContext) (*dal.UserInfo, error) {
return dal.UserInfoDao.GetById(tc, id)
})
}
// 更新用户年龄
func updateUserAge(id int64, newAge int) error {
return daog.AutoTrans(func() (*daog.TransContext, error) {
return daog.NewTransContext(datasource, txrequest.RequestWrite, "update-user")
}, func(tc *daog.TransContext) error {
modifier := daog.NewModifier().
Add(dal.UserInfoFields.Age, newAge).
Add(dal.UserInfoFields.UpdatedAt, ttypes.NormalDatetime(time.Now()))
_, err := dal.UserInfoDao.UpdateById(tc, modifier, id)
return err
})
}
// 查询活跃用户
func queryActiveUsers() ([]*dal.UserInfo, error) {
return daog.AutoTransWithResult(func() (*daog.TransContext, error) {
return daog.NewTransContext(datasource, txrequest.RequestReadonly, "query-users")
}, func(tc *daog.TransContext) ([]*dal.UserInfo, error) {
matcher := daog.NewMatcher().Eq(dal.UserInfoFields.Status, 1)
return dal.UserInfoDao.QueryListMatcher(tc, matcher,
daog.NewDescOrder(dal.UserInfoFields.CreatedAt))
})
}
// 删除用户
func deleteUser(id int64) error {
return daog.AutoTrans(func() (*daog.TransContext, error) {
return daog.NewTransContext(datasource, txrequest.RequestWrite, "delete-user")
}, func(tc *daog.TransContext) error {
_, err := dal.UserInfoDao.DeleteById(tc, id)
return err
})
}直接调用 daog 包提供的函数,需要传递 TableMeta:
user, err := daog.GetById(tc, id, dal.UserInfoMeta)
_, err := daog.Insert(tc, user, dal.UserInfoMeta)使用生成的 Dao 实例,无需传递 TableMeta:
user, err := dal.UserInfoDao.GetById(tc, id)
_, err := dal.UserInfoDao.Insert(tc, user)两种方式功能完全相同,QuickDao 代码更简洁。