Back to godoc.org
gitee.com/chunanyong/zorm

package zorm

v1.3.1
Latest Go to latest
Published: Apr 4, 2020 | License: Apache-2.0 | Module: gitee.com/chunanyong/zorm

Overview

Package zorm 使用原生的sql语句,没有对sql语法做限制.语句使用Finder作为载体 占位符统一使用?,zorm会根据数据库类型,语句执行前会自动替换占位符,postgresql 把?替换成$1,$2...;mssql替换成@P1,@p2...;orace替换成:1,:2... 为了保持数据库兼容性,分页语句必须有order by zorm使用 ctx context.Context 参数实现事务传播,ctx从web层传递进来即可,例如gin的c.Request.Context() zorm的事务操作需要显示使用zorm.Transaction(ctx, func(ctx context.Context) (interface{}, error) {})开启

Index

Variables

var FuncGenerateStringID func() string = generateStringID

FuncGenerateStringID 默认生成字符串ID的函数.方便自定义扩展

var FuncLogError func(err error) = defaultLogError

FuncLogError 记录error日志

var FuncLogPanic func(err error) = defaultLogPanic

FuncLogPanic 记录panic日志,默认使用ZormErrorLog实现

var FuncPrintSQL func(sqlstr string, args []interface{}) = defaultPrintSQL

FuncPrintSQL 打印sql语句和参数

var FuncReadWriteStrategy func(rwType int) *DBDao = getDefaultDao

FuncReadWriteStrategy 单个数据库的读写分离的策略,用于外部复写实现自定义的逻辑,rwType=0 read,rwType=1 write 不要放到BaseDao里,BindContextDBConnection已经是指定数据库的连接了,和这个函数会冲突.就作为单数据库读写分离的处理方式,不归属到BaseDao

var LogCalldepth = 4

LogCalldepth 记录日志调用层级,用于定位到业务层代码

func Delete

func Delete(ctx context.Context, entity IEntityStruct) (int, error)

Delete 根据主键删除一个对象.必须是*IEntityStruct类型 ctx不能为nil,参照使用zorm.Transaction方法传入ctx.也不要自己构建DBConnection affected影响的行数,如果异常或者驱动不支持,返回-1

func Insert

func Insert(ctx context.Context, entity IEntityStruct) (int, error)

Insert 保存Struct对象,必须是*IEntityStruct类型 ctx不能为nil,参照使用zorm.Transaction方法传入ctx.也不要自己构建DBConnection affected影响的行数,如果异常或者驱动不支持,返回-1

func InsertEntityMap

func InsertEntityMap(ctx context.Context, entity IEntityMap) (int, error)

InsertEntityMap 保存*IEntityMap对象.使用Map保存数据,用于不方便使用struct的场景,如果主键是自增或者序列,不要entityMap.Set主键的值 ctx不能为nil,参照使用zorm.Transaction方法传入ctx.也不要自己构建DBConnection affected影响的行数,如果异常或者驱动不支持,返回-1

func Query

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

Query 不要偷懒调用QuerySlice返回第一条,1.需要构建一个selice,2.调用方传递的对象其他值会被抛弃或者覆盖. 根据Finder和封装为指定的entity类型,entity必须是*struct类型或者基础类型的指针.把查询的数据赋值给entity,所以要求指针类型 context必须传入,不能为空

func QueryMap

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

QueryMap 根据Finder查询,封装Map context必须传入,不能为空

func QueryMapSlice

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

QueryMapSlice 根据Finder查询,封装Map数组 根据数据库字段的类型,完成从[]byte到golang类型的映射,理论上其他查询方法都可以调用此方法,但是需要处理sql.Nullxxx等驱动支持的类型 context必须传入,不能为空

func QuerySlice

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

QuerySlice 不要偷懒调用QueryMapList,需要处理sql驱动支持的sql.Nullxxx的数据类型,也挺麻烦的 根据Finder和封装为指定的entity类型,entity必须是*[]struct类型,已经初始化好的数组,此方法只Append元素,这样调用方就不需要强制类型转换了 context必须传入,不能为空

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

func Update

func Update(ctx context.Context, entity IEntityStruct) (int, error)

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

func UpdateEntityMap

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

UpdateEntityMap 更新*IEntityMap对象.用于不方便使用struct的场景,主键必须有值 ctx不能为nil,参照使用zorm.Transaction方法传入ctx.也不要自己构建DBConnection affected影响的行数,如果异常或者驱动不支持,返回-1

func UpdateFinder

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

UpdateFinder 更新Finder语句 ctx不能为nil,参照使用zorm.Transaction方法传入ctx.也不要自己构建DBConnection affected影响的行数,如果异常或者驱动不支持,返回-1

func UpdateNotZeroValue

func UpdateNotZeroValue(ctx context.Context, entity IEntityStruct) (int, error)

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

type DBDao

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

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

func NewDBDao

func NewDBDao(config *DataSourceConfig) (*DBDao, error)

NewDBDao 创建dbDao,一个数据库要只执行一次,业务自行控制 第一个执行的数据库为 defaultDao,后续zorm.xxx方法,默认使用的就是defaultDao

func (*DBDao) BindContextDBConnection

func (dbDao *DBDao) BindContextDBConnection(parent context.Context) (context.Context, error)

BindContextDBConnection 多库的时候,通过dbDao创建DBConnection绑定到子context,返回的context就有了DBConnection parent 不能为空

type DataSourceConfig

type DataSourceConfig struct {
	//DSN dataSourceName 连接字符串
	DSN string
	//DriverName 数据库驱动名称,和DBType对应,一个数据库可以有多个驱动(DriverName)
	DriverName string
	//DBType 数据库类型(mysql,postgresql,oracle,mssql,sqlite),zorm判断方言的依据,一个数据库可以有多个驱动(DriverName)
	DBType string
	//PrintSQL 是否打印SQL语句.使用zorm.ZormPrintSQL记录SQL
	PrintSQL bool
	//MaxOpenConns 数据库最大连接数 默认50
	MaxOpenConns int
	//MaxIdleConns 数据库最大空闲连接数 默认50
	MaxIdleConns int
	//ConnMaxLifetimeSecond 连接存活秒时间. 默认600(10分钟)后连接被销毁重建.避免数据库主动断开连接,造成死连接.MySQL默认wait_timeout 28800秒(8小时)
	ConnMaxLifetimeSecond int
}

DataSourceConfig 数据库连接池的配置

type EntityMap

type EntityMap struct {

	//主键列名
	PkColumnName string
	//兼容主键序列.如果有值,优先级最高
	PkSequence string
	// contains filtered or unexported fields
}

EntityMap IEntityMap的基础实现,可以直接使用或者匿名注入

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) GetPkSequence

func (entity *EntityMap) GetPkSequence() string

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

func (*EntityMap) GetTableName

func (entity *EntityMap) GetTableName() string

GetTableName 获取表名称

func (*EntityMap) Set

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

Set 设置数据库字段

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
	//兼容主键序列.如果有值,优先级最高
	GetPkSequence() string
	//针对Map类型,记录数据库字段
	GetDBFieldMap() map[string]interface{}
	//设置数据库字段的值
	Set(key string, value interface{}) map[string]interface{}
}

IEntityMap 使用Map保存数据,用于不方便使用struct的场景,如果主键是自增或者序列,不要entityMap.Set主键的值

type IEntityStruct

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

IEntityStruct structe实体类的接口,所有的struct实体类都要实现这个接口

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对象

Documentation was rendered with GOOS=linux and GOARCH=amd64.

Jump to identifier

Keyboard shortcuts

? : This menu
f or F : Jump to identifier