zorm

package module
v1.0.8 Latest Latest
Warning

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

Go to latest
Published: Mar 7, 2020 License: Apache-2.0 Imports: 16 Imported by: 33

README

zorm

介绍

golang轻量级ORM,readygo子项目
API文档

go get gitee.com/chunanyong/zorm 

基于原生sql语句编写,是springrain的精简和优化. 自带代码生成器
代码简单,总计2000行左右,注释详细,方便定制修改.
支持事务传播,这是zorm诞生的主要原因

生产使用参考 UserStructService.go

示例
  1. 生成实体类或手动编写,建议使用代码生成器 https://gitee.com/chunanyong/readygo/tree/master/codeGenerator

//UserOrgStructTableName 表名常量,方便直接调用
const UserOrgStructTableName = "t_user_org"

// UserOrgStruct 用户部门中间表
type UserOrgStruct struct {
  //引入默认的struct,隔离IEntityStruct的方法改动
  zorm.EntityStruct

  //Id 编号
  Id string `column:"id"`

  //UserId 用户编号
  UserId string `column:"userId"`

  //OrgId 机构编号
  OrgId string `column:"orgId"`

  //ManagerType 0会员,1员工,2主管
  ManagerType int `column:"managerType"`

  //------------------数据库字段结束,自定义字段写在下面---------------//

}

//GetTableName 获取表名称
func (entity *UserOrgStruct) GetTableName() string {
  return UserOrgStructTableName
}

//GetPKColumnName 获取数据库表的主键字段名称.因为要兼容Map,只能是数据库的字段名称.
func (entity *UserOrgStruct) GetPKColumnName() string {
  return "id"
}

  1. 初始化zorm

    dataSourceConfig := zorm.DataSourceConfig{
    Host:     "127.0.0.1",
    Port:     3306,
    DBName:   "readygo",
    UserName: "root",
    PassWord: "root",
    DBType:   "mysql",
     }
     zorm.NewBaseDao(&dataSourceConfig)
    
  2. var user permstruct.UserStruct
    err := zorm.SaveStruct(context.Background(), &user)
    
  3. err := zorm.DeleteStruct(context.Background(),&user)
    
  4. err := zorm.UpdateStruct(context.Background(),&user)
    //finder更新
    err := zorm.UpdateFinder(context.Background(),finder)
    
  5. finder := zorm.NewSelectFinder(permstruct.UserStructTableName)
    page := zorm.NewPage()
    var users = make([]permstruct.UserStruct, 0)
    err := zorm.QueryStructList(context.Background(), finder, &users, &page)
    
  6. 事务传播

    //匿名函数return的error如果不为nil,事务就会回滚
    _, errSaveUserStruct := zorm.Transaction(ctx, func(ctx context.Context) (interface{}, error) {
    
    	//事务下的业务代码开始
    	errSaveUserStruct := zorm.SaveStruct(ctx, userStruct)
    
    	if errSaveUserStruct != nil {
    		return nil, errSaveUserStruct
    	}
    
    	return nil, nil
    	//事务下的业务代码结束
    
    })
    
  7. 生产示例

    //FindUserOrgByUserId 根据userId查找部门UserOrg中间表对象
    func FindUserOrgByUserId(ctx context.Context, userId string, page *zorm.Page) ([]permstruct.UserOrgStruct, error) {
    if len(userId) < 1 {
    	return nil, errors.New("userId不能为空")
    }
    finder := zorm.NewFinder().Append("SELECT re.* FROM  ").Append(permstruct.UserOrgStructTableName).Append(" re ")
    finder.Append("   WHERE re.userId=?    order by re.managerType desc   ", userId)
    
    userOrgs := make([]permstruct.UserOrgStruct, 0)
    errQueryList := zorm.QueryStructList(ctx, finder, &userOrgs, page)
    if errQueryList != nil {
    	return nil, errQueryList
    }
    
    return userOrgs, nil
    }
    
  8. 测试

    //函数测试
    go test -run TestAdd2
    //性能测试
    go test -bench=.
    go test -v -bench=. -cpu=8 -benchtime="3s" -timeout="5s" -benchmem
    

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func DeleteStruct

func DeleteStruct(ctx context.Context, entity IEntityStruct) error

DeleteStruct 根据主键删除一个对象.必须是*IEntityStruct类型 ctx不能为nil,参照使用zorm.Transaction方法传入ctx.也不要自己构建DBConnection

func GenerateStringID

func GenerateStringID() string

GenerateStringID 生成主键字符串

func QueryMap

func QueryMap(ctx context.Context, finder *Finder) (map[string]interface{}, error)

QueryMap 根据Finder查询,封装Map bug(springrain)需要测试一下 in 数组, like ,还有查询一个基础类型(例如 string)的功能 context上下文必须传入,如果外部有变量声明,禁止自行获取构建

func QueryMapList

func QueryMapList(ctx context.Context, finder *Finder, page *Page) ([]map[string]interface{}, error)

QueryMapList 根据Finder查询,封装Map数组 根据数据库字段的类型,完成从[]byte到golang类型的映射,理论上其他查询方法都可以调用此方法,但是需要处理sql.Nullxxx等驱动支持的类型 context上下文必须传入,如果外部有变量声明,禁止自行获取构建

func QueryStruct

func QueryStruct(ctx context.Context, finder *Finder, entity interface{}) error

QueryStruct 不要偷懒调用QueryStructList返回第一条,1.需要构建一个selice,2.调用方传递的对象其他值会被抛弃或者覆盖. 根据Finder和封装为指定的entity类型,entity必须是*struct类型或者基础类型的指针.把查询的数据赋值给entity,所以要求指针类型 context上下文必须传入,如果外部有变量声明,禁止自行获取构建

func QueryStructList

func QueryStructList(ctx context.Context, finder *Finder, rowsSlicePtr interface{}, page *Page) error

QueryStructList 不要偷懒调用QueryMapList,需要处理sql驱动支持的sql.Nullxxx的数据类型,也挺麻烦的 根据Finder和封装为指定的entity类型,entity必须是*[]struct类型,已经初始化好的数组,此方法只Append元素,这样调用方就不需要强制类型转换了 context上下文必须传入,如果外部有变量声明,禁止自行获取构建

func SaveEntityMap

func SaveEntityMap(ctx context.Context, entity IEntityMap) error

SaveEntityMap 保存*IEntityMap对象.使用Map保存数据,需要在数据中封装好包括Id在内的所有数据.不适用于复杂情况 ctx不能为nil,参照使用zorm.Transaction方法传入ctx.也不要自己构建DBConnection

func SaveStruct

func SaveStruct(ctx context.Context, entity IEntityStruct) error

SaveStruct 保存Struct对象,必须是*IEntityStruct类型 bug(chunanuyong) 如果是自增主键,需要返回.需要sql驱动支持 ctx不能为nil,参照使用zorm.Transaction方法传入ctx.也不要自己构建DBConnection

func Transaction

func Transaction(ctx context.Context, doTransaction func(ctx context.Context) (interface{}, error)) (interface{}, error)

Transaction 的示例代码 //匿名函数return的error如果不为nil,事务就会回滚 zorm.Transaction(ctx context.Context,func(ctx context.Context) (interface{}, error) {

	//业务代码

	//return的error如果不为nil,事务就会回滚
    return nil, nil
})

事务方法,隔离dbConnection相关的API.必须通过这个方法进行事务处理,统一事务方式 如果入参dbConnection为nil,使用defaultDao开启事务并最后提交.如果入参dbConnection没有事务,调用dbConnection.begin()开启事务并最后提交.如果入参dbConnection有事务,只使用不提交,有开启方提交事务.但是如果遇到错误或者异常,虽然不是事务的开启方,也会回滚事务,让事务尽早回滚. dbConnection的传入,还可以处理多个数据库的情况. 不要去掉匿名函数的context参数,因为如果Transaction的context中没有dbConnection,会新建一个context并放入dbConnection,此时的context指针已经变化,不能直接使用Transaction的context参数 bug(springrain)如果有大神修改了匿名函数内的参数名,例如改为ctx2,这样业务代码实际使用的是Transaction的context参数,如果为没有dbConnection,会抛异常,如果有dbConnection,实际就是一个对象.影响有限.也可以把匿名函数抽到外部 return的error如果不为nil,事务就会回滚

func UpdateEntityMap

func UpdateEntityMap(ctx context.Context, entity IEntityMap) error

UpdateEntityMap 更新*IEntityMap对象.使用Map修改数据,需要在数据中封装好包括Id在内的所有数据.不适用于复杂情况 ctx不能为nil,参照使用zorm.Transaction方法传入ctx.也不要自己构建DBConnection

func UpdateFinder

func UpdateFinder(ctx context.Context, finder *Finder) error

UpdateFinder 更新Finder语句 ctx不能为nil,参照使用zorm.Transaction方法传入ctx.也不要自己构建DBConnection

func UpdateStruct

func UpdateStruct(ctx context.Context, entity IEntityStruct) error

UpdateStruct 更新struct所有属性,必须是*IEntityStruct类型 ctx不能为nil,参照使用zorm.Transaction方法传入ctx.也不要自己构建DBConnection

Types

type BaseDao

type BaseDao struct {
	// contains filtered or unexported fields
}

BaseDao 数据库操作基类,隔离原生操作数据库API入口,所有数据库操作必须通过BaseDao进行.

func NewBaseDao

func NewBaseDao(config *DataSourceConfig) (*BaseDao, error)

NewBaseDao 一个数据库要只执行一次,业务自行控制 第一个执行的数据库为 defaultDao var once sync.Once 创建baseDao

func (*BaseDao) GetDBConnection

func (baseDao *BaseDao) GetDBConnection() (*DBConnection, error)

GetDBConnection 获取一个dbConnection 如果参数dbConnection为nil,使用默认的datasource进行获取dbConnection.如果是多库,就需要使用Dao手动调用GetDBConnection(),获得dbConnection,传给需要的方法

func (*BaseDao) UpdateStructNotNil

func (baseDao *BaseDao) UpdateStructNotNil(ctx context.Context, entity IEntityStruct) error

UpdateStructNotNil 更新struct不为nil的属性,必须是*IEntityStruct类型 ctx不能为nil,参照使用zorm.Transaction方法传入ctx.也不要自己构建DBConnection

type DBConnection

type DBConnection struct {
	// contains filtered or unexported fields
}

DBConnection 数据库dbConnection会话,可以原生查询或者事务 方法都应包含 dbConnection DBConnection这样的入参,context上下文必须传入,如果外部有变量声明,禁止自行获取构建

type DataSourceConfig

type DataSourceConfig struct {
	Host     string
	Port     int
	DBName   string
	UserName string
	PassWord string
	//mysql,postgres,oci8,adodb
	DBType string
}

DataSourceConfig 数据库连接池的配置

type EntityMap

type EntityMap struct {
	// contains filtered or unexported fields
}

EntityMap IBaseEntity的基础实现,所有的实体类都匿名注入.这样就类似实现继承了,如果接口增加方法,调整这个默认实现即可

func NewEntityMap

func NewEntityMap(tbName string) *EntityMap

NewEntityMap 初始化Map,必须传入表名称

func (*EntityMap) GetDBFieldMap

func (entity *EntityMap) GetDBFieldMap() map[string]interface{}

GetDBFieldMap 针对Map类型,记录数据库字段

func (*EntityMap) GetPKColumnName

func (entity *EntityMap) GetPKColumnName() string

GetPKColumnName 获取数据库表的主键字段名称.因为要兼容Map,只能是数据库的字段名称.

func (*EntityMap) GetTableName

func (entity *EntityMap) GetTableName() string

GetTableName 获取表名称

func (*EntityMap) Put

func (entity *EntityMap) Put(key string, value interface{}) map[string]interface{}

Put 设置非数据库字段

func (*EntityMap) Set

func (entity *EntityMap) Set(key string, value interface{}) map[string]interface{}

Set 设置数据库字段

func (*EntityMap) SetPKColumnName

func (entity *EntityMap) SetPKColumnName(pkName string)

SetPKColumnName 设置主键的名称

type EntityStruct

type EntityStruct struct {
}

EntityStruct IBaseEntity 的基础实现,所有的实体类都匿名注入.这样就类似实现继承了,如果接口增加方法,调整这个默认实现即可

func (*EntityStruct) GetPKColumnName

func (entity *EntityStruct) GetPKColumnName() string

GetPKColumnName 获取数据库表的主键字段名称.因为要兼容Map,只能是数据库的字段名称.

func (*EntityStruct) GetPkSequence

func (entity *EntityStruct) GetPkSequence() string

GetPkSequence Oracle和pgsql没有自增,主键使用序列.优先级高于GetPKColumnName方法

type Finder

type Finder struct {

	//注入检查,默认true 不允许SQL注入的 ' 单引号
	InjectionCheck bool
	//CountFinder 自定义的查询总条数Finder,使用指针默认为nil.主要是为了在group by等复杂情况下,为了性能,手动编写总条数语句
	CountFinder *Finder
	//是否自动查询总条数,默认true.同时需要Page不为nil,才查询总条数
	SelectTotalCount bool
	// contains filtered or unexported fields
}

Finder 查询数据库的载体,所有的sql语句都要通过Finder执行.

func NewDeleteFinder

func NewDeleteFinder(tableName string) *Finder

NewDeleteFinder 根据表名初始化删除的Finder, DELETE FROM tableName

func NewFinder

func NewFinder() *Finder

NewFinder 初始化一个Finder,生成一个空的Finder

func NewSelectFinder

func NewSelectFinder(tableName string, strs ...string) *Finder

NewSelectFinder 根据表名初始化查询的Finder NewSelectFinder("tableName") SELECT * FROM tableName NewSelectFinder("tableName", "id,name") SELECT id,name FROM tableName

func NewUpdateFinder

func NewUpdateFinder(tableName string) *Finder

NewUpdateFinder 根据表名初始化更新的Finder, UPDATE tableName SET

func (*Finder) Append

func (finder *Finder) Append(s string, values ...interface{}) *Finder

Append 添加SQL和参数的值,第一个参数是语句,后面的参数[可选]是参数的值,顺序要正确. 例如: finder.Append(" and id=? and name=? ",23123,"abc") 只拼接SQL,例如: finder.Append(" and name=123 ")

func (*Finder) AppendFinder

func (finder *Finder) AppendFinder(f *Finder) (*Finder, error)

AppendFinder 添加另一个Finder finder.AppendFinder(f)

func (*Finder) GetSQL

func (finder *Finder) GetSQL() (string, error)

GetSQL 返回Finder封装的SQL语句

type IEntityMap

type IEntityMap interface {
	//获取表名称
	GetTableName() string
	//获取数据库表的主键字段名称.因为要兼容Map,只能是数据库的字段名称.
	GetPKColumnName() string
	//针对Map类型,记录数据库字段
	GetDBFieldMap() map[string]interface{}
}

IEntityMap Entity实体类接口,所有实体类必须实现,否则baseDao无法执行.baseDao函数形参只有Finder和IBaseEntity

type IEntityStruct

type IEntityStruct interface {
	//获取表名称
	GetTableName() string
	//获取数据库表的主键字段名称.因为要兼容Map,只能是数据库的字段名称.
	GetPKColumnName() string
	//兼容主键序列.如果有值,优先级最高
	GetPkSequence() string
}

IEntityStruct Entity实体类接口,所有实体类必须实现,否则baseDao无法执行.baseDao函数形参只有Finder和IBaseEntity

type Page

type Page struct {
	//当前页码,从1开始
	PageNo int
	//每页多少条,默认20条
	PageSize int
	//数据总条数
	TotalCount int
	//总共多少页
	PageCount int
	//是否是第一页
	FirstPage bool
	//是否有上一页
	HasPrev bool
	//是否有下一页
	HasNext bool
	//是否是最后一页
	LastPage bool
}

Page 分页对象

func NewPage

func NewPage() Page

NewPage 创建Page对象

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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