daox

package module
v1.0.0-rc1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 3, 2023 License: MIT Imports: 12 Imported by: 6

README

daox

基于 sqlx + go-redis 的轻量级数据库访问辅助工具,daox 的定位是 sqlx 的功能增强,不是一个 orm。

封装了基础 crud api,实现了sqlbuilder,通过 api 生成 sql,无需手动拼接。

实现了代码生成器,有内置生成文件模板,也可以自定义模板。

安装

go get github.com/fengjx/daox

CRUD

在MySQL创建测试表

create table user_info
(
    id       bigint comment '主键',
    uid      bigint                not null,
    nickname varchar(32) default '' null comment '昵称',
    sex      tinyint     default 0 not null comment '性别',
    utime    bigint      default 0 not null comment '更新时间',
    ctime    bigint      default 0 not null comment '创建时间',
    primary key pk(id),
    unique uni_uid (uid)
) comment '用户信息表';

创建 dao 对象

db := sqlx.MustOpen("mysql", "root:1234@tcp(localhost:3306)/demo")
db.Mapper = reflectx.NewMapperFunc("json", strings.ToTitle)
dao := daox.NewDAO(db, "user_info", "id", reflect.TypeOf(&User{}), daox.IsAutoIncrement())

新增

for i := 0; i < 20; i++ {
    sec := time.Now().Unix()
    user := &User{
        Uid:      100 + int64(i),
        Nickname: randString(6),
        Sex:      int32(i) % 2,
        Utime:    sec,
        Ctime:    sec,
    }
    id, err := dao.Save(user)
    if err != nil {
        log.Panic(err)
    }
    log.Println(id)
}


查询

// id 查询
user := new(User)
err := dao.GetByID(1, user)

// 批量id查询
var list []User
err = dao.ListByIds(&list3, 10, 11)

// 指定字段查询单条记录
user := new(User)
err := dao.GetByColumn(daox.OfKv("uid", 10000), user)

// 指定字段查询多条记录
var list []*User
err := dao.List(daox.OfKv("sex", 0), &list)

// 指定字段查询多个值
var list []*User
err = dao.ListByColumns(daox.OfMultiKv("uid", 10000, 10001), &list)

修改

user := new(User)
err := dao.GetByID(10, user)
user.Nickname = "update-name-10"
// 全字段更新
ok, err := dao.Update(user)
log.Printf("update res - %v", ok)

// 部分字段更新
ok, err = dao.UpdateField(11, map[string]interface{}{
    "nickname": "update-name-11",
})
log.Printf("update res - %v", ok)

删除

// 按 id 删除
ok, err := dao.DeleteById(21)
log.Printf("delete res - %v", ok)

user := new(User)
err = dao.GetByID(21, user)
log.Printf("delete by id res - %v", user.Id)

// 按指定字段删除
affected, err := dao.DeleteByColumn(daox.OfKv("uid", 101))
log.Printf("delete by column res - %v", affected)

// 按字段删除多条记录
affected, err = dao.DeleteByColumns(daox.OfMultiKv("uid", 102, 103))
log.Printf("multiple delete by column res - %v", affected)

缓存

user := new(User)
// 按id查询并缓存
err := dao.GetByIDCache(10, user)
log.Printf("get by id with cache - %v", user)

// 删除缓存
err = dao.DeleteCache("id", 10)

// 按指定字段查询并缓存
cacheUser := new(User)
err = dao.GetByColumnCache(daox.OfKv("uid", 10001), cacheUser)
log.Printf("get by uid with cache - %v", cacheUser)

sqlbuilder

创建Builder对象

// 通过dao对象实例方法创建
dao.SQLBuilder()

// 独立使用
sqlbuilder.New("user_info")

构造sql

querySQL, err := sqlbuilder.New("user_info").Select().
    Columns("id", "username", "age", "sex", "ctime").
    Where(
        sqlbuilder.C().
            Where(true, "age > ?").
            And(true, "sex = ?"),
    ).
    OrderBy(sqlbuilder.Desc("ctime")).
    Offset(10).
    Limit(10).Sql()
// SELECT `id`, `username`, `age`, `sex`, `ctime` FROM `user_info` WHERE age > ? AND sex = ? ORDER BY `ctime` DESC LIMIT 10 OFFSET 10;
log.Println(querySQL)


inserter := sqlbuilder.New("user_info").Insert().
    Columns("username", "age", "sex")

sql, err := inserter.Sql()
//  INSERT INTO `user_info`(`username`, `age`, `sex`) VALUES (?, ?, ?);
log.Println(sql)

nameSql, err := inserter.NameSql()
// INSERT INTO `user_info`(`username`, `age`, `sex`) VALUES (:username, :age, :sex);
log.Println(nameSql)


updateSQL, err := sqlbuilder.New("user_info").
    Update().
    Columns("username", "age").
        Where(sqlbuilder.C().Where(true, "id = ?")).
    Sql()
// UPDATE `user_info` SET `username` = ?, `age` = ? WHERE id = ?;
log.Println(updateSQL)


deleteSQL, err := sqlbuilder.New("user_info").Delete().
    Where(sqlbuilder.C().Where(true, "id = ?")).
    Sql()
// DELETE FROM `user_info` WHERE id = ?;
log.Println(deleteSQL)

更多示例请查看sqlbuilder/sql_test.go

代码生成

安装代码生成工具
$ go install github.com/fengjx/daox/cmd/gen@latest
$ gen -h

GLOBAL OPTIONS:
   -f value    config file path
   --help, -h  show help

生成代码

$ gen -f gen.yml

配置示例说明

ds:
  type: mysql
  dsn: root:1234@tcp(localhost:3306)/demo
target:
  custom:
    tag-name: json
    out-dir: ./out
    template-dir:
    var:
      a: aa
      b: bb
  tables:
    - user_info
参数 必须 说明
ds.type 数据库类型,暂时值支持 mysql
ds.dsn 数据库连接
target.custom.tag-name model 字段的 tagName
target.custom.out-dir 文件生成路径
target.custom.template-dir 自定义模板文件路径
target.custom.var 自定义参数,map结构,可以在模板文件中使用
target.custom.tables 需要生成文件的表名,list 结构

自定义模板说明

通过text/template来渲染文件内容,模板语法不在此赘述,可自行查看参考文档。

模板中可以使用的变量,详细可以查看源码cmd/gen/gen.go

attr := map[string]interface{}{
    "Var":     config.Target.Custom.Var,
    "TagName": config.Target.Custom.TagName,
    "Table":   table,
}

模板中可以使用的函数

  • utils.FirstUpper: 首字母大写
  • utils.FirstLower: 首字母小写
  • utils.SnakeCase: 转下划线风格字符串
  • utils.TitleCase: 转驼峰风格字符串
  • utils.GonicCase: 转go风格驼峰字符串,user_id -> userID
  • utils.LineString: 空字符串使用横线"-"代替
  • SQLType2GoTypeString: sql类型转go类型字符串
funcMap := template.FuncMap{
    "FirstUpper":           utils.FirstUpper,
    "FirstLower":           utils.FirstLower,
    "SnakeCase":            utils.SnakeCase,
    "TitleCase":            utils.TitleCase,
    "GonicCase":            utils.GonicCase,
    "LineString":           utils.LineString,
    "SQLType2GoTypeString": SQLType2GoTypeString,
}

参考_example/gen

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrUpdatePrimaryKeyRequire = errors.New("[daox] Primary key require for update")
)

Functions

This section is empty.

Types

type BatchCreateDataFun

type BatchCreateDataFun func(missItems []interface{}) (map[interface{}]interface{}, error)

type CacheProvider

type CacheProvider struct {
	RedisClient *redis.Client
	Version     string
	KeyPrefix   string
	ExpireTime  time.Duration // 缓存时长
}

func NewCacheProvider

func NewCacheProvider(redisCtl *redis.Client, keyPrefix string, version string, expireTime time.Duration) *CacheProvider

func (*CacheProvider) BatchDel

func (c *CacheProvider) BatchDel(key string, items ...string) error

func (*CacheProvider) BatchFetch

func (c *CacheProvider) BatchFetch(key string, items []interface{}, dest interface{}, fun BatchCreateDataFun) error

BatchFetch dest: must a slice fun: to create miss data

func (*CacheProvider) CheckPointer

func (c *CacheProvider) CheckPointer(value reflect.Value) error

func (*CacheProvider) Del

func (c *CacheProvider) Del(key string, item string) error

func (*CacheProvider) Fetch

func (c *CacheProvider) Fetch(key string, item interface{}, dest interface{}, fun CreateDataFun) error

Fetch invalidStale 当缓存过期时,是否使用旧值

type CreateDataFun

type CreateDataFun func() (interface{}, error)

type DB added in v1.1.0

type DB struct {
	*sqlx.DB
}

func MustOpen

func MustOpen(driverName, dataSourceName string) *DB

func NewDB

func NewDB(db *sqlx.DB) *DB

func Open

func Open(driverName, dataSourceName string) (*DB, error)

type Dao

type Dao struct {
	DBMaster      *DB
	DBRead        *DB
	TableMeta     *TableMeta
	CacheProvider *CacheProvider
}

func NewDAO

func NewDAO(master *sqlx.DB, tableName string, primaryKey string, structType reflect.Type, opts ...Option) *Dao

func (*Dao) BatchFetch

func (dao *Dao) BatchFetch(field string, items []interface{}, dest interface{}, fun BatchCreateDataFun) error

BatchFetch 注意不会按 items 顺序返回

func (*Dao) BatchReplaceInto

func (dao *Dao) BatchReplaceInto(models interface{}, omitColumns ...string) (int64, error)

BatchReplaceInto 批量新增,使用 replace into 方式 omitColumns 不需要 insert 的字段

func (*Dao) BatchSave

func (dao *Dao) BatchSave(models interface{}, omitColumns ...string) (int64, error)

BatchSave 批量新增 omitColumns 不需要 insert 的字段

func (*Dao) DBColumns

func (dao *Dao) DBColumns(omitColumns ...string) []string

func (*Dao) DeleteByColumn

func (dao *Dao) DeleteByColumn(kv *KV) (int64, error)

func (*Dao) DeleteByColumns

func (dao *Dao) DeleteByColumns(kvs *MultiKV) (int64, error)

func (*Dao) DeleteByID

func (dao *Dao) DeleteByID(id interface{}) (bool, error)

func (*Dao) DeleteCache

func (dao *Dao) DeleteCache(field string, values ...interface{}) error

func (*Dao) Fetch

func (dao *Dao) Fetch(field string, item string, dest interface{}, fun CreateDataFun) error

Fetch query one row

func (*Dao) GetByColumn

func (dao *Dao) GetByColumn(kv *KV, dest Model) (bool, error)

GetByColumn get one row bool: exist or not

func (*Dao) GetByColumnCache

func (dao *Dao) GetByColumnCache(kv *KV, dest Model) (bool, error)

func (*Dao) GetByID

func (dao *Dao) GetByID(id interface{}, dest Model) (bool, error)

func (*Dao) GetByIDCache

func (dao *Dao) GetByIDCache(id interface{}, dest Model) (bool, error)

func (*Dao) GetColumnsByModel

func (dao *Dao) GetColumnsByModel(model interface{}, omitColumns ...string) []string

func (*Dao) GetColumnsByType

func (dao *Dao) GetColumnsByType(typ reflect.Type, omitColumns ...string) []string

GetColumnsByType 通过字段 tag 解析数据库字段

func (*Dao) List

func (dao *Dao) List(kv *KV, dest interface{}) error

func (*Dao) ListByColumns

func (dao *Dao) ListByColumns(kvs *MultiKV, dest interface{}) error

func (*Dao) ListByIDs

func (dao *Dao) ListByIDs(dest interface{}, ids ...interface{}) error

func (*Dao) ReplaceInto

func (dao *Dao) ReplaceInto(dest Model, omitColumns ...string) (int64, error)

ReplaceInto omitColumns 不需要 insert 的字段

func (*Dao) SQLBuilder

func (dao *Dao) SQLBuilder() *sqlbuilder.Builder

func (*Dao) Save

func (dao *Dao) Save(dest Model, omitColumns ...string) (int64, error)

Save omitColumns 不需要 insert 的字段

func (*Dao) TableName

func (dao *Dao) TableName() string

func (*Dao) Update

func (dao *Dao) Update(m Model) (bool, error)

func (*Dao) UpdateField

func (dao *Dao) UpdateField(idValue interface{}, fieldMap map[string]interface{}) (bool, error)

type KV

type KV struct {
	Key   string
	Value interface{}
}

func OfKv

func OfKv(key string, value interface{}) *KV

type Model

type Model interface {
	GetID() interface{}
}

type MultiKV

type MultiKV struct {
	Key    string
	Values []interface{}
}

func OfMultiKv

func OfMultiKv(key string, values ...interface{}) *MultiKV

func (*MultiKV) AddValue

func (kv *MultiKV) AddValue(val string) *MultiKV

type Option

type Option func(*Dao)

func IsAutoIncrement

func IsAutoIncrement() Option

func WithCache

func WithCache(redisClient *redis.Client) Option

func WithCacheExpireTime

func WithCacheExpireTime(cacheExpireTime time.Duration) Option

func WithCacheVersion

func WithCacheVersion(cacheVersion string) Option

func WithDBRead

func WithDBRead(read *sqlx.DB) Option

type SliceToMapFun

type SliceToMapFun = func([]*Model) map[interface{}]*Model

type TableMeta

type TableMeta struct {
	TableName       string
	StructType      reflect.Type
	Columns         []string
	PrimaryKey      string
	IsAutoIncrement bool
}

func (*TableMeta) OmitColumns

func (meta *TableMeta) OmitColumns(omit ...string) []string

OmitColumns 数据库表字段 omit 包含的字段

Directories

Path Synopsis
_example
daox command
sqlbuilder command
cmd
gen command
ql

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL