Ai
1 Star 0 Fork 0

go-libs/db-xorm

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
dao.go 12.32 KB
一键复制 编辑 原始数据 按行查看 历史
非一般 提交于 2025-07-22 21:28 +08:00 . List with sort
// Author: wsfuyibing <682805@qq.com>
// Date: 2025-04-10
package src
import (
"context"
"strings"
"xorm.io/xorm"
)
type (
// Dao is an alias of Database Access Object, It's read and write data on
// database server such as mysql, postgres.
Dao[T any] struct {
sess *xorm.Session
key string
typ T
}
DaoFieldNameForPrimaryKey interface {
PrimaryKeyName() string
}
DaoFieldNameForPrimaryKeyValue interface {
PrimaryKeyValue() any
}
)
// NewDao creates a dao instance with given model type and model struct. Data
// in database operated depends on model type.
//
// type ModelService struct {
// Dao *db.Dao[models.Model]
// }
//
// func NewModelService(dbs ...*framework.DB) *ModelService {
// o := &ModelService{}
// o.Dao = db.NewDao[models.ErpSales](models.ErpSales{})
// o.Dao.WithConn(dbs...)
// o.Dao.WithKey("db")
// return o
// }
func NewDao[T any](t T) *Dao[T] {
return &Dao[T]{
typ: t,
key: DefaultKey,
}
}
// +---------------------------------------------------------------------------+
// | Common operations |
// +---------------------------------------------------------------------------+
// Master returns a session from master connection.
func (o *Dao[T]) Master(ctx context.Context) (*xorm.Session, error) {
if o.sess != nil {
return o.sess, nil
}
return Config.GetSlave(ctx, o.key)
}
// Slaver returns a session from slaver connection.
func (o *Dao[T]) Slaver(ctx context.Context) (*xorm.Session, error) {
if o.sess != nil {
return o.sess, nil
}
return Config.GetSlave(ctx, o.key)
}
// WithSess bind a session of database connection.
func (o *Dao[T]) WithSess(ss ...*xorm.Session) *Dao[T] {
if len(ss) > 0 && ss[0] != nil {
o.sess = ss[0]
}
return o
}
// WithKey bind a connection key for connector.
func (o *Dao[T]) WithKey(k string) *Dao[T] {
if k != "" {
o.key = k
}
return o
}
// +---------------------------------------------------------------------------+
// | Read / Get one record |
// +---------------------------------------------------------------------------+
// GetBy returns a model specified column and value.
//
// // sql: SELECT * FROM `table` WHERE `id` = 10 LIMIT 1
// svc.Dao.GetBy(ctx, "id", 10)
func (o *Dao[T]) GetBy(ctx context.Context, column string, value any) (model *T, has bool, err error) {
return o.GetByMap(ctx, map[string]any{
column: value,
})
}
// GetById returns a model by given primary key value.
//
// // sql: SELECT * FROM `table` WHERE `id` = 10 LIMIT 1
// svc.Dao.GetById(ctx, 10)
func (o *Dao[T]) GetById(ctx context.Context, value any) (model *T, has bool, err error) {
return o.GetByMap(ctx, map[string]any{
o.parsePrimaryKeyName(): value,
})
}
// GetByMap returns a model by given condition with mapper param.
//
// // sql: SELECT * FROM `table` WHERE `id` = 10 LIMIT 1
// svc.Dao.GetByMap(ctx, map[string]any{
// "id": 10
// })
func (o *Dao[T]) GetByMap(ctx context.Context, condition map[string]any) (model *T, has bool, err error) {
var sess *xorm.Session
// Open a session from slaver connection.
if sess, err = o.Slaver(ctx); err != nil {
return
}
// Init an empty model.
model = &o.typ
// Send query on database.
if has, err = sess.Where(condition).Get(model); err != nil || !has {
model = nil
}
return
}
// GetByStruct returns a model with model condition. It's ignore default value
// condition such as zero or empty string.
//
// // sql: SELECT * FROM `table` WHERE `id` = 10 LIMIT 1
// svc.Dao.GetByModel(ctx, &models.Model{
// Id: 10,
// })
func (o *Dao[T]) GetByStruct(ctx context.Context, t T) (model *T, has bool, err error) {
var sess *xorm.Session
// Open a session from slaver connection.
if sess, err = o.Slaver(ctx); err != nil {
return
}
// Init an empty model.
model = &o.typ
// Send query on database.
if has, err = sess.Where(t).Get(model); err != nil || !has {
model = nil
}
return
}
// +---------------------------------------------------------------------------+
// | Read / List records. |
// +---------------------------------------------------------------------------+
// ListByMap returns a list of models by given condition with map param.
//
// sql: SELECT * FROM `table` WHERE `user_id` = 1
// svc.Dao.GetByModel(ctx, map[string]any{
// "user_id": 1
// })
func (o *Dao[T]) ListByMap(ctx context.Context, m map[string]any, sorts ...string) (list []*T, err error) {
var sess *xorm.Session
// Open a session from slaver connection.
if sess, err = o.Slaver(ctx); err != nil {
return
}
// Init an empty model list.
list = make([]*T, 0)
// Send query on database.
if len(sorts) > 0 {
err = sess.Where(m).OrderBy(strings.Join(sorts, ",")).Find(&list)
} else {
err = sess.Where(m).Find(&list)
}
if err != nil {
list = nil
}
return
}
// ListByStruct returns a list of models by given condition with model struct.
//
// // sql: SELECT * FROM `table` WHERE `user_id` = 10
// svc.Dao.GetByModel(ctx, &models.Model{
// UserId: 1
// })
func (o *Dao[T]) ListByStruct(ctx context.Context, t *T, sorts ...string) (list []*T, err error) {
var sess *xorm.Session
// Open a session from slaver connection.
if sess, err = o.Slaver(ctx); err != nil {
return
}
// Init an empty model list.
list = make([]*T, 0)
// Send query on database.
if len(sorts) > 0 {
err = sess.OrderBy(strings.Join(sorts, ",")).Find(&list, t)
} else {
err = sess.Find(&list, t)
}
if err != nil {
list = nil
}
return
}
// +---------------------------------------------------------------------------+
// | Read / List records with paginator. |
// +---------------------------------------------------------------------------+
// PagingByMap returns a list of models by given condition with map and calculate
// total items in table.
func (o *Dao[T]) PagingByMap(ctx context.Context, m map[string]any, page, size int, sorts ...string) (list []*T, total int64, err error) {
var sess *xorm.Session
// Open a session from slaver connection.
if sess, err = o.Slaver(ctx); err != nil {
return
}
// Execute matched record count.
if total, err = sess.Table(o.typ).Where(m).Count(); err != nil {
return
}
// Return if no matched record.
if total == 0 {
return
}
// Init an empty model list.
list = make([]*T, 0)
// Send query on database.
if len(sorts) > 0 {
err = sess.Where(m).OrderBy(strings.Join(sorts, ",")).Limit(size, (page-1)*size).Find(&list)
} else {
err = sess.Where(m).Limit(size, (page-1)*size).Find(&list)
}
if err != nil {
list = nil
}
return
}
// PagingByStruct returns a list of models by given condition with model struct and
// calculate total items in table.
func (o *Dao[T]) PagingByStruct(ctx context.Context, t *T, page, size int, sorts ...string) (list []*T, total int64, err error) {
var sess *xorm.Session
// Open a session from slaver connection.
if sess, err = o.Slaver(ctx); err != nil {
return
}
// Execute matched record count.
if total, err = sess.Count(t); err != nil {
return
}
// Return if no matched record.
if total == 0 {
return
}
// Init an empty model list.
list = make([]*T, 0)
// Send query on database.
if len(sorts) > 0 {
err = sess.OrderBy(strings.Join(sorts, ",")).Limit(size, (page-1)*size).Find(&list, t)
} else {
err = sess.Limit(size, (page-1)*size).Find(&list, t)
}
if err != nil {
list = nil
}
return
}
// +---------------------------------------------------------------------------+
// | Write / Add new record |
// +---------------------------------------------------------------------------+
// AddByStruct adds a model by given model struct.
//
// svc.Dao.AddByModel(ctx, &models.Model{
// UserId: 1,
// ...
// })
func (o *Dao[T]) AddByStruct(ctx context.Context, t *T) (model *T, err error) {
var sess *xorm.Session
// Open a session from master connection.
if sess, err = o.Master(ctx); err != nil {
return
}
// Send query on database.
if _, err = sess.Insert(t); err == nil {
model = t
}
return
}
// +---------------------------------------------------------------------------+
// | Write / Delete records |
// +---------------------------------------------------------------------------+
// DeleteBy delete records by given condition with key value pairs. Param k is
// column name and v is column value.
//
// // sql: DELETE FORM `table` WHERE `id` = 1
// svc.Dao.DeleteBy(ctx, "id", 1)
func (o *Dao[T]) DeleteBy(ctx context.Context, k string, v any) (affects int64, err error) {
return o.DeleteByMap(ctx, map[string]any{k: v})
}
// DeleteById delete records by given condition with primary key value. Param v is
// an integer value of primary key.
//
// // sql: DELETE FORM `table` WHERE `id` = 1
// svc.Dao.DeleteById(ctx, 1)
func (o *Dao[T]) DeleteById(ctx context.Context, v any) (affects int64, err error) {
return o.DeleteByMap(ctx, map[string]any{o.parsePrimaryKeyName(): v})
}
// DeleteByMap delete records by given condition with multiple key value pairs.
//
// // sql: DELETE FORM `table` WHERE `status` = 0 AND `status_type` = "error"
// svc.Dao.DeleteByMap(ctx, map[string]any{
// "status": 0,
// "status_type": "error",
// })
func (o *Dao[T]) DeleteByMap(ctx context.Context, m map[string]any) (affects int64, err error) {
var sess *xorm.Session
// Open a session from master connection.
if sess, err = o.Master(ctx); err != nil {
return
}
// Send delete request.
affects, err = sess.Where(m).Delete(o.typ)
return
}
// DeleteByStruct delete records by given condition with struct definition.
//
// // sql: DELETE FORM `table` WHERE `status` = 1 AND `status_type` = "error"
// svc.Dao.DeleteByMap(ctx, models.Model{
// "status": 1,
// "status_type": "error",
// })
func (o *Dao[T]) DeleteByStruct(ctx context.Context, t *T) (affects int64, err error) {
var sess *xorm.Session
// Open a session from master connection.
if sess, err = o.Master(ctx); err != nil {
return
}
// Send delete query on database.
affects, err = sess.Delete(t)
return
}
// +---------------------------------------------------------------------------+
// | Write |
// +---------------------------------------------------------------------------+
// UpdateFieldsById updates a record with key value pairs by primary key.
//
// // sql: UPDATE `table` SET `name` = "test", `age` = 18 WHERE `id` = 10
// svc.Dao.UpdateMapById(ctx, map[string]any{
// "name": "test",
// "age": 18,
// }, 10)
func (o *Dao[T]) UpdateFieldsById(ctx context.Context, fields map[string]any, v any) (affects int64, err error) {
return o.UpdateFieldsByMap(ctx, fields, map[string]any{
o.parsePrimaryKeyName(): v,
})
}
// UpdateFieldsByMap updates a record with map condition.
//
// // sql: UPDATE `table` SET `name` = "test", `age` = 18 WHERE `id` = 10 AND `status` = 0
// svc.Dao.UpdateFieldsByMap(ctx, map[string]any{
// "name": "test",
// "age": 18,
// }, map[string]any{
// "id": 10,
// "status": 0,
// })
func (o *Dao[T]) UpdateFieldsByMap(ctx context.Context, fields, condition map[string]any) (affects int64, err error) {
var sess *xorm.Session
// Open a session from master connection.
if sess, err = o.Master(ctx); err != nil {
return
}
// Send update query on database.
affects, err = sess.Table(o.typ).Where(condition).Update(fields)
return
}
func (o *Dao[T]) UpdateModel(ctx context.Context, model *T) (affects int64, err error) {
var sess *xorm.Session
// Open a session from master connection.
if sess, err = o.Master(ctx); err != nil {
return
}
// Send update query on database.
affects, err = sess.Where(map[string]any{
o.parsePrimaryKeyName(): o.parsePrimaryKeyValue(),
}).Update(model)
return
}
// +---------------------------------------------------------------------------+
// | Access methods |
// +---------------------------------------------------------------------------+
func (o *Dao[T]) parsePrimaryKeyName() string {
var ptr any = &o.typ
if v, ok := ptr.(DaoFieldNameForPrimaryKey); ok {
return v.PrimaryKeyName()
}
return "id"
}
func (o *Dao[T]) parsePrimaryKeyValue() any {
var ptr any = &o.typ
if v, ok := ptr.(DaoFieldNameForPrimaryKeyValue); ok {
return v.PrimaryKeyValue()
}
return 0
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/go-libs/db-xorm.git
git@gitee.com:go-libs/db-xorm.git
go-libs
db-xorm
db-xorm
v1.2.6

搜索帮助