orm

package module
v4.1.0 Latest Latest
Warning

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

Go to latest
Published: Feb 22, 2022 License: MIT Imports: 11 Imported by: 0

README

orm Go version Go Report Card codecov PkgGoDev

目前内置了对以下数据库的支持:

数据库 驱动 状态
mysql mysql github.com/go-sql-driver/mysql Mysql
mariadb mysql github.com/go-sql-driver/mysql Mariadb
sqlite3 sqlite3 github.com/mattn/go-sqlite3 Sqlite3
postgres postgres github.com/lib/pq Postgres

理论上 github.com/jackc/pgx/v4/stdlib 也是可用于 postgres,不过其驱动的注册名称为 pgx。

其它数据库,用户可以通过实现 Dialect 接口,来实现相应的支持。 如果用到了 check 约束,则需要 mysql > 8.0.16、mariadb > 10.2.1。

初始化

默认情况下,orm 包并不会加载任何数据库的实例。所以想要用哪个数据库,需要手动初始化:

import (
    github.com/issue9/orm/v4/dialect  // sqlite3 的 dialect 声明在此处
    _ github.com/mattn/go-sqlite3     // 加载数据库驱动
)

// 初始化一个 DB,表前缀为 prefix_
db1 := orm.NewDB("./db1", dialect.Sqlite3("sqlite3", "prefix_"))

// 另一个 DB 实例
db2 := orm.NewDB("./db2", dialect.Sqlite3("sqlite3", "db2_"))
占位符

SQL 语句可以使用 # 字符在语句中暂替真实的表名前缀,也可以使用 {} 包含一个关键字,使其它成为普通列名,如:

SELECT * FROM #user WHERE {group}=1

在实际执行时,相关的占位符就会被替换成与当前环境想容的实例,如在表名前缀为 p_, 数据库为 mysql 时,会被替换成以下语句,然后再执行:

 SELECT * FROM p_user WHERE `group`=1

DB.Query(),DB.Exec(),DB.Prepare().DB.Where() 及 Tx 与之对应的函数都可以使用占位符。

Model 不能指定占位符,它们默认总会使用占位符,且无法取消。

Model:

orm 包通过 struct tag 来描述 model 在数据库中的结构。大概格式如下:

type User struct {
    Id          int64      `orm:"name(id);ai;"`
    FirstName   string     `orm:"name(first_name);index(index_name)"`
    LastName    string     `orm:"name(first_name);index(index_name)"`

    // 此处group会自动加上引号,无须担心是否为关键字
    Group       string     `orm:"name(group)"`
}

func(u *User) TableName() string { return "#user" }

// 通过 orm.ApplyModeler 接口,指定表的额外数据。若不需要,可不用实现该接口
func(u *User) ApplyModel(m *core.Model) error {
    m.Meta["mysql_engine"] = []string{"innodb"}
    m.Meta["mysql_charset"] = []string{"utf8"}
    return nil
}

目前支持以下的 struct tag:

name(fieldName):

指定当前字段在数据表中的名称,如果未指定,则和字段名相同。 只有可导出的字段才有效果。

len(l1, l2):

指定字段的长度。比如 mysql 中的int(5),varchar(255),double(1,2), 不支持该特性的数据,将会忽略该标签的内容,比如 sqlite3。 NOTE:字符串类型必须指定长度,若长度过大或是将长度设置了-1, 想使用类似于 TEXT 等不定长的形式表达。

如果是日期类型,则第一个可选参数表示日期精度。

nullable(true|false):

相当于定义表结构时的 NULL。

pk:

主键,支持联合主键,给多个字段加上 pk 的 struct tag 即可。

ai:

自增,若指定了自增列,则将自动取消其它的 pk 设置。无法指定起始值和步长。 可手动设置一个非零值来更改某条数据的 AI 行为。

unique(index_name):

唯一索引,支持联合索引,index_name 为约束名, 会将 index_name 为一样的字段定义为一个联合索引。

index(index_name):

普通的关键字索引,同 unique 一样会将名称相同的索引定义为一个联合索引。

occ(true|false)

当前列作为乐观锁字段。

作为乐观锁的字段,其值表示的是线上数据的值,在更新时,会自动给线上的值加 1。

default(value):

指定默认值。相当于定义表结构时的 DEFAULT。 当一个字段如果是个零值(reflect.Zero())时,将会使用它的默认值, 但是系统无法判断该零值是人为指定,还是未指定被默认初始化零值的, 所以在需要用到零值的字段,最好不要用 default 的 struct tag。

fk(fk_name,refTable,refColName,updateRule,deleteRule):

定义物理外键,最少需要指定 fk_name、refTable 和 refColName 三个值。分别对应约束名, 引用的表和引用的字段,updateRule,deleteRule,在不指定的情况下,使用数据库的默认值。 refTable 如果需要表名前缀,需要添加 # 符号。

接口:
  • TableNamer 指定表名;
  • ApplyModeler 通过 ApplyModeler 接口可以指定一些表级别的属性值;
  • AfterFetcher 在拉到数据之后,对该对象执行的一些额外操作。如果需要根据字段做额外工作的,可以使用该接口;
  • BeforeInserter 在执行插入之前,需要执行的操作;
  • BeforeUpdater 在执行更新之前,需要执行的操作;
约束名:

index、unique、check 和 fk 都是可以指定约束名的,在当前数据库中, 约束名必须是唯一的,即便是不同类型的约束,比如已经有一个 unique 的约束名叫作 name, 那么其它类型的约束,就不能再取这个名称了。

如何使用:
Create:

可以通过 DB.Create() 或是 Tx.Create() 创建一张表。

// 创建表
db.Create(&User{})
// 创建多个表,同时创建多张表,主使用 Tx.Create
tx.MultCreate(&User{},&Email{})
Update:
// 将 id 为 1 的记录的 FirstName 更改为 abc;对象中的零值不会被提交。
db.Update(&User{Id:1,FirstName:"abc"})
sqlbuilder.Update(db).Table("#table").Where("id=?",1).Set("FirstName", "abc").Exec()
Delete:
// 删除 id 为 1 的记录
e.Delete(&User{Id:1})
sqlbuilder.Delete(e).Table("#table").Where("id=?",1).Exec()
Insert:
// 插入一条数据
db.Insert(&User{Id:1,FirstName:"abc"})
// 一次性插入多条数据
tx.InsertMany(&User{Id:1,FirstName:"abc"},&User{Id:1,FirstName:"abc"})
Select:
// 导出 id=1 的数据
_,err := sqlbuilder.Select(e, e.Dialect()).Select("*").From("{#table}").Where("id=1").QueryObj(obj)
// 导出 id 为 1 的数据,并回填到 user 实例中
user := &User{Id:1}
err := e.Select(u)
Query/Exec:
// Query 返回参数与 sql.Query 是相同的
sql := "select * from #tbl_name where id=?"
rows, err := e.Query(sql, []interface{}{5})
// Exec 返回参数与 sql.Exec 是相同的
sql = "update #tbl_name set name=? where id=?"
r, err := e.Exec(sql, []interface{}{"name1", 5})
多表查询
type order struct {
    ID int `orm:"name(id);ai"`
    UID int `orm:"name(uid)"`
    User *User `orm:"name(u)"` // sql 语句的 u. 开头的列导入到此对象中
}

sql := "SELECT o.*, u.id AS 'u.id',u.name AS 'u.name' FROM orders AS o LEFT JOIN  users AS u ON o.uid= u.id where id=?"

// 以下查询会将 u.name 和 u.id 导入到 User 指向的对象中
data := []*order{}
rows,err := e.Query(sql, []interface{}{5})
r, err := fetch.Object(rows, &data)
InsertLastID:

像 postgres 之类的数据库,插入语句返回的 sql.Result 并不支持 LastInsertId() 所以得通过其它方式得到该 ID,可以直接尝试使用 InsertLastID 来代码 Insert 操作。

lastID,err := db.InsertLastID(&User{FirstName:"abc"})
事务:

默认的 DB 是不支持事务的,若需要事务支持,则需要调用 DB.Begin() 返回事务对象 Tx,当然并不是所有的数据库都支持事务操作的。 Tx 拥有一组与 DB 相同的接口。

版权

本项目采用 MIT 开源授权许可证,完整的授权说明可在 LICENSE 文件中找到。

Documentation

Overview

Package orm 一个简单小巧的 orm 实现方案

目前内置了对以下数据库的支持:

  1. sqlite3: github.com/mattn/go-sqlite3
  2. mysql: github.com/go-sql-driver/mysql
  3. postgres: github.com/lib/pq

其它数据库,用户可以通过实现 Dialect 接口,来实现相应的支持。

初始化:

默认情况下,orm 包并不会加载任何数据库的实例。所以想要用哪个数据库,需要手动初始化:

import (
    _ github.com/mattn/go-sqlite3       // 加载数据库驱动
    _ github.com/issue9/orm/v4/dialect  // sqlite3 的 dialect 声明在此处
)

// 初始化一个 DB,表前缀为 prefix_
db1 := orm.NewDB("./db1", dialect.Sqlite3("sqlite3", "prefix_"))

// 另一个 DB 实例
db2 := orm.NewDB("./db2", dialect.Sqlite3("sqlite3", "db2_"))

占位符

SQL 语句可以使用 # 字符在语句中暂替真实的表名前缀,也可以使用 {} 包含一个关键字,使其它成为普通列名,如:

select * from #user where {group}=1

在实际执行时,相关的占位符就会被替换成与当前环境想容的实例,如在表名前缀为 p_, 数据库为 mysql 时,会被替换成以下语句,然后再执行:

select * from p_user where `group`=1

DB.Query(),DB.Exec(),DB.Prepare().DB.Where() 及 Tx 与之对应的函数都可以使用占位符。

Model 不能指定占位符,它们默认总会使用占位符,且无法取消。

Model:

orm 包通过 struct tag 来描述 model 在数据库中的结构。大概格式如下:

type User struct {
    Id          int64      `orm:"name(id);ai;"`
    FirstName   string     `orm:"name(first_name);index(index_name)"`
    LastName    string     `orm:"name(first_name);index(index_name)"`

    // 此处group会自动加上引号,无须担心是否为关键字
    Group       string	   `orm:"name(group)"`
}

// 通过 orm.ApplyModeler 接口,指定表的额外数据。若不需要,可不用实现该接口
// 表名 user 会被自动加上表名前缀。
func(u *User) ApplyModel(m *core.Model) error {
    m.Name = "#user"
    m.Meta["engine"] = "innodb"
    m.Meta["charset"] = "utf8"
    return nil
}

目前支持以下的 struct tag:

name(fieldName): 指定当前字段在数据表中的名称,如果未指定,
则和字段名相同。只有可导出的字段才有效果。

len(l1, l2): 指定字段的长度。比如 mysql 中的int(5),varchar(255),double(1,2),
不支持该特性的数据,将会忽略该标签的内容,比如 sqlite3。
NOTE:字符串类型必须指定长度,若长度过大或是将长度设置了 -1,
想使用类似于 TEXT 等不定长的形式表达。
如果是日期类型,则第一个可选参数表示日期精度。

nullable(true|false): 相当于定义表结构时的 NULL。

pk: 主键,支持联合主键,给多个字段加上 pk 的 struct tag 即可。

ai: 自增,若指定了自增列,则将自动取消其它的 pk 设置。无法指定起始值和步长。
可手动设置一个非零值来更改某条数据的 AI 行为。

unique(index_name): 唯一索引,支持联合索引,index_name 为约束名,
会将 index_name 为一样的字段定义为一个联合索引。

index(index_name): 普通的关键字索引,同 unique 一样会将名称相同的索引定义为一个联合索引。

occ(true|false) 当前列作为乐观锁字段。

作为乐观锁的字段,其值表示的是线上数据的值,在更新时,会自动给线上的值加 1。

default(value): 指定默认值。相当于定义表结构时的 DEFAULT。
当一个字段如果是个零值(reflect.Zero())时,将会使用它的默认值,
但是系统无法判断该零值是人为指定,还是未指定被默认初始化零值的,
所以在需要用到零值的字段,最好不要用 default 的 struct tag。

fk(fk_name,refTable,refColName,updateRule,deleteRule):
定义物理外键,最少需要指定 fk_name,refTable,refColName 三个值。
分别对应约束名,引用的表和引用的字段,updateRule,deleteRule,
在不指定的情况下,使用数据库的默认值。
refTable 如果需要表名前缀,需要添加 # 符号。

check(chk_name, expr): check 约束。chk_name 为约束名,expr 为该约束的表达式。
check 约束只能在 ApplyModeler 接口中指定,而不是像其它约束一样,
通过字段的 struct tag 指定。因为 check 约束的表达式可以通过 and 或是 or
等符号连接多条基本表达式,在字段 struct tag 中指定会显得有点怪异。

ApplyModeler:

在 Go 不能将 struct tag 作用于结构体,所以为了指定一些表级别的属性, 只能通过接口的形式,在接口方法中返回一段类似于 struct tag 的字符串, 以达到相同的目的。

在 ApplyModeler 每种数据库可以指定一些自定义的属性,这些属性都将会被保存到 Model.Meta 中,各个数据库的自定义属性以其名称开头,比如 mysql 的 charset 属性, 可以使用 mysql_charset。

同时还包含了以下几种通用的属性信息:

name(val): 指定模型的名称,比如表名,或是视图名称;
check(expr): 指定 check 约束内容。

约束名:

index、unique、check 和 fk 都是可以指定约束名的,在表中,约束名必须是唯一的, 即便是不同类型的约束,比如已经有一个 unique 的约束名叫作 name,那么其它类 型的约束,就不能再取这个名称了。 部分数据库(比如 postgres)可能要求约束名是整个数据库唯一的, 为了统一,在 ORM 中所有数据都强制约束名全局(数据库)唯一。

如何使用:

Create: 可以通过 DB.Create() 或是 Tx.Create() 创建一张表。

// 创建表
db.Create(&User{})
// 创建多个表,同时创建多张表,主使用 Tx.Create
tx.MultCreate(&User{},&Email{})

Update:

// 将 id 为 1 的记录的 FirstName 更改为 abc;对象中的零值不会被提交。
db.Update(&User{Id:1,FirstName:"abc"})
sqlbuilder.Update(db).Table("#table").Where("id=?",1).Set("FirstName", "abc").Exec()

Delete:

// 删除 id 为 1 的记录
e.Delete(&User{Id:1})
sqlbuilder.Delete(e).Table("#table").Where("id=?",1).Exec()

Insert:

// 插入一条数据
db.Insert(&User{Id:1,FirstName:"abc"})
// 一次性插入多条数据
tx.InsertMany(&User{Id:1,FirstName:"abc"},&User{Id:1,FirstName:"abc"})

Select:

// 导出 id=1 的数据
_,err := sqlbuilder.Select(e, e.Dialect()).Select("*").From("{#table}").Where("id=1").QueryObj(obj)
// 导出 id 为 1 的数据,并回填到 user 实例中
user := &User{Id:1}
err := e.Select(u)

Query/Exec:

// Query 返回参数与 sql.Query 是相同的
sql := "select * from #tbl_name where id=?"
rows, err := e.Query(sql, []interface{}{5})
// Exec 返回参数与 sql.Exec 是相同的
sql = "update #tbl_name set name=? where id=?"
r, err := e.Exec(sql, []interface{}{"name1", 5})

事务:

默认的 DB 是不支持事务的,若需要事务支持,则需要调用 DB.Begin() 返回事务对象 Tx,当然并不是所有的数据库都支持事务操作的。 Tx 拥有一组与 DB 相同的接口。

Index

Constants

This section is empty.

Variables

View Source
var ErrNeedAutoIncrementColumn = errors.New("必须存在自增列")

ErrNeedAutoIncrementColumn 当以 LastInsertID 的方式插入一条没有 AI 列的对象时,会返回此错误。

Functions

This section is empty.

Types

type AfterFetcher

type AfterFetcher = fetch.AfterFetcher

AfterFetcher 从数据库查询到数据之后需要执行的操作

type ApplyModeler

type ApplyModeler = core.ApplyModeler

type BeforeInserter

type BeforeInserter interface {
	BeforeInsert() error
}

BeforeInserter 在插入之前调用的函数

type BeforeUpdater

type BeforeUpdater interface {
	BeforeUpdate() error
}

BeforeUpdater 在更新之前调用的函数

type Column

type Column = core.Column

Column 列结构

type DB

type DB struct {
	*sql.DB
	// contains filtered or unexported fields
}

DB 数据库操作实例

func NewDB

func NewDB(dsn string, dialect Dialect) (*DB, error)

NewDB 声明一个新的 DB 实例

不同驱动对时间的处理不尽相同,如果有在不同数据库之间移植的需求, 那么建议将保存时的时区都统一设置为 UTC: postgres 已经固定为 UTC,sqlite3 可以在 dsn 中通过 _loc=UTC 指定, mysql 默认是 UTC,也可以在 DSN 中通过 loc=UTC 指定。

func NewDBWithStdDB

func NewDBWithStdDB(db *sql.DB, dialect Dialect) (*DB, error)

NewDBWithStdDB 从 sql.DB 构建 DB 实例

NOTE: 请确保用于打开 db 的 driverName 参数与 dialect.DriverName() 是相同的, 否则后续操作的结果是未知的。

func (*DB) Begin

func (db *DB) Begin() (*Tx, error)

Begin 开始一个新的事务

func (*DB) BeginTx

func (db *DB) BeginTx(ctx context.Context, opts *sql.TxOptions) (*Tx, error)

BeginTx 开始一个新的事务

func (*DB) Close

func (db *DB) Close() error

Close 关闭连接

同时会清除缓存的模型数据

func (*DB) Create

func (db *DB) Create(v TableNamer) error

Create 创建一张表或是视图

func (*DB) Debug

func (db *DB) Debug(l *log.Logger)

Debug 指定调输出调试内容通道

如果 l 不为 nil,则每次 SQL 调用都会输出 SQL 语句, 预编译的语句,仅在预编译时输出; 如果为 nil,则表示关闭调试。

func (*DB) Delete

func (db *DB) Delete(v TableNamer) (sql.Result, error)

Delete 删除符合条件的数据

查找条件以结构体定义的主键或是唯一约束(在没有主键的情况下)来查找, 若两者都不存在,则将返回 error

func (*DB) Dialect

func (db *DB) Dialect() Dialect

Dialect 返回对应的 Dialect 接口实例

func (*DB) DoTransaction

func (db *DB) DoTransaction(f func(tx *Tx) error) error

DoTransaction 将 f 中的内容以事务的方式执行

func (*DB) DoTransactionTx

func (db *DB) DoTransactionTx(ctx context.Context, opt *sql.TxOptions, f func(tx *Tx) error) error

DoTransactionTx 将 f 中的内容以事务的方式执行

如果执行失败,自动回滚,且返回错误信息。否则会直接提交。

func (*DB) Drop

func (db *DB) Drop(v TableNamer) error

Drop 删除一张表或视图

func (*DB) Exec

func (db *DB) Exec(query string, args ...interface{}) (sql.Result, error)

Exec 执行 SQL 语句

func (*DB) ExecContext

func (db *DB) ExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error)

ExecContext 执行 SQL 语句

func (*DB) Insert

func (db *DB) Insert(v TableNamer) (sql.Result, error)

Insert 插入数据

NOTE: 若需一次性插入多条数据,请使用 tx.Insert()。

func (*DB) InsertMany

func (db *DB) InsertMany(max int, v ...TableNamer) error

InsertMany 一次插入多条数据

会自动转换成事务进行处理。

func (*DB) LastInsertID

func (db *DB) LastInsertID(v TableNamer) (int64, error)

LastInsertID 插入数据并获取其自增的 ID

func (*DB) MultCreate

func (db *DB) MultCreate(objs ...TableNamer) error

MultCreate 创建数据表

如果数据库支持事务 DDL,则会在事务中完成此操作。

func (*DB) MultDelete

func (db *DB) MultDelete(objs ...TableNamer) error

MultDelete 删除一条或是多条数据

会自动转换成事务进行处理。

func (*DB) MultDrop

func (db *DB) MultDrop(objs ...TableNamer) error

MultDrop 删除表结构及数据

如果数据库支持事务 DDL,则会在事务中完成此操作。

func (*DB) MultInsert

func (db *DB) MultInsert(objs ...TableNamer) error

MultInsert 插入一个或多个数据

会自动转换成事务进行处理。

func (*DB) MultSelect

func (db *DB) MultSelect(objs ...TableNamer) error

MultSelect 选择符合要求的一条或是多条记录

会自动转换成事务进行处理。

func (*DB) MultTruncate

func (db *DB) MultTruncate(objs ...TableNamer) error

MultTruncate 清除表内容

重置 ai,但保留表结构。

func (*DB) MultUpdate

func (db *DB) MultUpdate(objs ...TableNamer) error

MultUpdate 更新一条或多条类型。

会自动转换成事务进行处理。

func (*DB) NewModel

func (db *DB) NewModel(obj TableNamer) (*Model, error)

NewModel 从一个 obj 声明一个 Model 实例

obj 可以是一个 struct 实例或是指针。

func (*DB) Prepare

func (db *DB) Prepare(query string) (*core.Stmt, error)

Prepare 预编译查询语句

func (*DB) PrepareContext

func (db *DB) PrepareContext(ctx context.Context, query string) (*core.Stmt, error)

PrepareContext 预编译查询语句

func (*DB) Query

func (db *DB) Query(query string, args ...interface{}) (*sql.Rows, error)

Query 执行一条查询语句

func (*DB) QueryContext

func (db *DB) QueryContext(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error)

QueryContext 执行一条查询语句

func (*DB) QueryRow

func (db *DB) QueryRow(query string, args ...interface{}) *sql.Row

QueryRow 执行一条查询语句

如果生成语句出错,则会 panic

func (*DB) QueryRowContext

func (db *DB) QueryRowContext(ctx context.Context, query string, args ...interface{}) *sql.Row

QueryRowContext 执行一条查询语句

如果生成语句出错,则会 panic

func (*DB) SQLBuilder

func (db *DB) SQLBuilder() *sqlbuilder.SQLBuilder

SQLBuilder 返回 SQL 实例

func (*DB) Select

func (db *DB) Select(v TableNamer) error

Select 查询一个符合条件的数据

查找条件以结构体定义的主键或是唯一约束(在没有主键的情况下 ) 来查找, 若两者都不存在,则将返回 error 若没有符合条件的数据,将不会对参数 v 做任何变动。

查找条件的查找顺序是为 自增 > 主键 > 唯一约束, 如果同时存在多个唯一约束满足条件,则返回错误信息。

func (*DB) TablePrefix

func (db *DB) TablePrefix() string

TablePrefix 返回表名前缀内容内容

func (*DB) Truncate

func (db *DB) Truncate(v TableNamer) error

Truncate 清空一张表

func (*DB) Update

func (db *DB) Update(v TableNamer, cols ...string) (sql.Result, error)

Update 更新数据

零值不会被提交,cols 指定的列,即使是零值也会被更新。

查找条件以结构体定义的主键或是唯一约束(在没有主键的情况下)来查找, 若两者都不存在,则将返回 error

func (*DB) Upgrade

func (db *DB) Upgrade(v TableNamer) (*Upgrader, error)

Upgrade 生成 Upgrader 对象

Upgrader 提供了对现有的数据模型 v 与线上数据表之间的操作。 删除操作需要保证已经存在于数据表; 而添加操作需要保证已经存在于模型 v,又不存在于数据表。

func (*DB) Version

func (db *DB) Version() (string, error)

Version 数据库服务端的版本号

func (*DB) Where

func (db *DB) Where(cond string, args ...interface{}) *WhereStmt

Where 生成 Where 语句

type Decimal

type Decimal = types.Decimal

type Dialect

type Dialect = core.Dialect

Dialect 数据库驱动特有的语言特性实现

type Engine

type Engine interface {
	core.Engine

	// LastInsertID 插入一条数据并返回其自增 ID
	//
	// 理论上功能等同于以下两步操作:
	//  rslt, err := engine.Insert(obj)
	//  id, err := rslt.LastInsertId()
	// 但是实际上部分数据库不支持直接在 sql.Result 中获取 LastInsertId,
	// 比如 postgresql,所以使用 LastInsertID() 会是比 sql.Result
	// 更简单和安全的方法。
	//
	// NOTE: 要求 v 有定义自增列。
	LastInsertID(v TableNamer) (int64, error)

	Insert(v TableNamer) (sql.Result, error)

	Delete(v TableNamer) (sql.Result, error)

	Update(v TableNamer, cols ...string) (sql.Result, error)

	Select(v TableNamer) error

	Create(v TableNamer) error

	Drop(v TableNamer) error

	Truncate(v TableNamer) error

	// InsertMany 插入多条相同的数据
	//
	// 若需要向某张表中插入多条记录,InsertMany() 会比 Insert() 性能上好很多。
	//
	// max 表示一次最多插入的数量,如果超过此值,会分批执行,
	// 但是依然在一个事务中完成。
	//
	// 与 MultInsert() 方法最大的不同在于:
	//  // MultInsert() 可以每个参数的类型都不一样:
	//  vs := []interface{}{&user{...}, &userInfo{...}}
	//  db.Insert(vs...)
	//  // db.InsertMany(500, vs) // 这里将出错,数组的元素的类型必须相同。
	//  us := []*users{&user{}, &user{}}
	//  db.InsertMany(500, us)
	//  db.Insert(us...) // 这样也行,但是性能会差好多
	InsertMany(max int, v ...TableNamer) error

	// MultInsert 一次性插入多条不同的数据
	//
	// 本质上是对 Insert 的多次调用,合并在一个事务中完成。
	MultInsert(objs ...TableNamer) error

	MultSelect(objs ...TableNamer) error

	MultUpdate(objs ...TableNamer) error

	MultDelete(objs ...TableNamer) error

	MultCreate(objs ...TableNamer) error

	MultDrop(objs ...TableNamer) error

	MultTruncate(objs ...TableNamer) error

	SQLBuilder() *sqlbuilder.SQLBuilder

	NewModel(v TableNamer) (*Model, error)
}

Engine 是 DB 与 Tx 的共有接口

type ForeignKey

type ForeignKey = core.ForeignKey

ForeignKey 外键

type Model

type Model = core.Model

Model 表示一个数据库的表模型

type Rat

type Rat = types.Rat

type TableNamer

type TableNamer = core.TableNamer

type Tx

type Tx struct {
	*sql.Tx
	// contains filtered or unexported fields
}

Tx 事务对象

func (*Tx) Create

func (tx *Tx) Create(v TableNamer) error

Create 创建数据表或是视图

func (*Tx) Delete

func (tx *Tx) Delete(v TableNamer) (sql.Result, error)

Delete 删除一条数据

func (*Tx) Dialect

func (tx *Tx) Dialect() Dialect

Dialect 返回对应的 Dialect 实例

func (*Tx) Drop

func (tx *Tx) Drop(v TableNamer) error

Drop 删除表或视图

func (*Tx) Exec

func (tx *Tx) Exec(query string, args ...interface{}) (sql.Result, error)

Exec 执行一条 SQL 语句

func (*Tx) ExecContext

func (tx *Tx) ExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error)

ExecContext 执行一条 SQL 语句

func (*Tx) ForUpdate

func (tx *Tx) ForUpdate(v TableNamer) error

ForUpdate 读数据并锁定

func (*Tx) Insert

func (tx *Tx) Insert(v TableNamer) (sql.Result, error)

Insert 插入一个或多个数据

func (*Tx) InsertMany

func (tx *Tx) InsertMany(max int, v ...TableNamer) error

func (*Tx) LastInsertID

func (tx *Tx) LastInsertID(v TableNamer) (int64, error)

LastInsertID 插入数据,并获取其自增的 ID

func (*Tx) MultCreate

func (tx *Tx) MultCreate(objs ...TableNamer) error

MultCreate 创建数据表

func (*Tx) MultDelete

func (tx *Tx) MultDelete(objs ...TableNamer) error

MultDelete 删除一条或是多条数据

func (*Tx) MultDrop

func (tx *Tx) MultDrop(objs ...TableNamer) error

MultDrop 删除表结构及数据

func (*Tx) MultInsert

func (tx *Tx) MultInsert(objs ...TableNamer) error

MultInsert 插入一个或多个数据

func (*Tx) MultSelect

func (tx *Tx) MultSelect(objs ...TableNamer) error

MultSelect 选择符合要求的一条或是多条记录

func (*Tx) MultTruncate

func (tx *Tx) MultTruncate(objs ...TableNamer) error

MultTruncate 清除表内容

会重置 ai,但保留表结构。

func (*Tx) MultUpdate

func (tx *Tx) MultUpdate(objs ...TableNamer) error

MultUpdate 更新一条或多条类型

func (*Tx) NewModel

func (tx *Tx) NewModel(obj TableNamer) (*Model, error)

NewModel 从一个 obj 声明一个 Model 实例

obj 可以是一个 struct 实例或是指针。

func (*Tx) Prepare

func (tx *Tx) Prepare(query string) (*core.Stmt, error)

Prepare 将一条 SQL 语句进行预编译

func (*Tx) PrepareContext

func (tx *Tx) PrepareContext(ctx context.Context, query string) (*core.Stmt, error)

PrepareContext 将一条 SQL 语句进行预编译

func (*Tx) Query

func (tx *Tx) Query(query string, args ...interface{}) (*sql.Rows, error)

Query 执行一条查询语句

func (*Tx) QueryContext

func (tx *Tx) QueryContext(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error)

QueryContext 执行一条查询语句

func (*Tx) QueryRow

func (tx *Tx) QueryRow(query string, args ...interface{}) *sql.Row

QueryRow 执行一条查询语句

如果生成语句出错,则会 panic

func (*Tx) QueryRowContext

func (tx *Tx) QueryRowContext(ctx context.Context, query string, args ...interface{}) *sql.Row

QueryRowContext 执行一条查询语句

如果生成语句出错,则会 panic

func (*Tx) SQLBuilder

func (tx *Tx) SQLBuilder() *sqlbuilder.SQLBuilder

SQLBuilder 返回 SQL 实例

func (*Tx) Select

func (tx *Tx) Select(v TableNamer) error

Select 读数据

func (*Tx) TablePrefix

func (tx *Tx) TablePrefix() string

TablePrefix 返回表名前缀内容内容

func (*Tx) Truncate

func (tx *Tx) Truncate(v TableNamer) error

Truncate 清除表内容

会重置 ai,但保留表结构。

func (*Tx) Update

func (tx *Tx) Update(v TableNamer, cols ...string) (sql.Result, error)

Update 更新一条类型

func (*Tx) Where

func (tx *Tx) Where(cond string, args ...interface{}) *WhereStmt

Where 生成 Where 语句

type Unix

type Unix = types.Unix

Unix 表示 Unix 时间戳的数据样式

表现为 time.Time,但是保存数据库时,以 unix 时间戳的形式保存。

type Upgrader

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

Upgrader 更新数据表对象

主要针对线上数据与本地模型不相同时,可执行的一些操作。 并没有准确的方法判断线上字段与本地定义的是否相同,比如: varchar(50) 和 text 在 sqlite3 是相同的,但是在其它数据库可能是稍微有差别的, 所以 Upgrader 并不会自动对数据表进行更新,所有更新还是要手动调用相关的函数。

func (*Upgrader) AddColumn

func (u *Upgrader) AddColumn(name ...string) *Upgrader

AddColumn 添加表中的列

列名必须存在于表模型中。

func (*Upgrader) AddConstraint

func (u *Upgrader) AddConstraint(name ...string) *Upgrader

AddConstraint 添加约束

约束必须存在于 model.constraints 中

func (*Upgrader) AddIndex

func (u *Upgrader) AddIndex(name ...string) *Upgrader

AddIndex 添加索引信息

func (*Upgrader) AddPK

func (u *Upgrader) AddPK() *Upgrader

AddPK 添加主键约束

func (*Upgrader) Do

func (u *Upgrader) Do() error

Do 执行操作

func (*Upgrader) DropColumn

func (u *Upgrader) DropColumn(name ...string) *Upgrader

DropColumn 删除表中的列

列名可以不存在于表模型,只在数据库中的表包含该列名,就会被删除。

func (*Upgrader) DropConstraint

func (u *Upgrader) DropConstraint(conts ...string) *Upgrader

DropConstraint 删除约束

func (*Upgrader) DropIndex

func (u *Upgrader) DropIndex(name ...string) *Upgrader

DropIndex 删除索引

func (*Upgrader) DropPK

func (u *Upgrader) DropPK() *Upgrader

DropPK 删除主键约束

func (*Upgrader) Engine

func (u *Upgrader) Engine() Engine

func (*Upgrader) Err

func (u *Upgrader) Err() error

Err 返回执行过程中的错误信息

type WhereStmt

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

WhereStmt 用于生成 where 语句

func (*WhereStmt) And

func (stmt *WhereStmt) And(cond string, args ...interface{}) *WhereStmt

And 添加一条 and 语句

func (*WhereStmt) AndBetween

func (stmt *WhereStmt) AndBetween(col string, v1, v2 interface{}) *WhereStmt

AndBetween 指定 WHERE ... AND col BETWEEN v1 AND v2

func (*WhereStmt) AndGroup

func (stmt *WhereStmt) AndGroup() *sqlbuilder.WhereStmt

AndGroup 开始一个子条件语句

func (*WhereStmt) AndIn

func (stmt *WhereStmt) AndIn(col string, v ...interface{}) *WhereStmt

AndIn 指定 WHERE ... AND col IN(v...)

func (*WhereStmt) AndIsNotNull

func (stmt *WhereStmt) AndIsNotNull(col string) *WhereStmt

AndIsNotNull 指定 WHERE ... AND col IS NOT NULL

func (*WhereStmt) AndIsNull

func (stmt *WhereStmt) AndIsNull(col string) *WhereStmt

AndIsNull 指定 WHERE ... AND col IS NULL

func (*WhereStmt) AndLike

func (stmt *WhereStmt) AndLike(col string, content interface{}) *WhereStmt

AndLike 指定 WHERE ... AND col LIKE content

func (*WhereStmt) AndNotBetween

func (stmt *WhereStmt) AndNotBetween(col string, v1, v2 interface{}) *WhereStmt

AndNotBetween 指定 WHERE ... AND col NOT BETWEEN v1 AND v2

func (*WhereStmt) AndNotIn

func (stmt *WhereStmt) AndNotIn(col string, v ...interface{}) *WhereStmt

AndNotIn 指定 WHERE ... AND col NOT IN(v...)

func (*WhereStmt) AndNotLike

func (stmt *WhereStmt) AndNotLike(col string, content interface{}) *WhereStmt

AndNotLike 指定 WHERE ... AND col NOT LIKE content

func (*WhereStmt) Count

func (stmt *WhereStmt) Count(v TableNamer) (int64, error)

Count 返回符合条件数量

表名来自 v。

func (*WhereStmt) Delete

func (stmt *WhereStmt) Delete(v TableNamer) (sql.Result, error)

Delete 从 v 表中删除符合条件的内容

func (*WhereStmt) Or

func (stmt *WhereStmt) Or(cond string, args ...interface{}) *WhereStmt

Or 添加一条 OR 语句

func (*WhereStmt) OrBetween

func (stmt *WhereStmt) OrBetween(col string, v1, v2 interface{}) *WhereStmt

OrBetween 指定 WHERE ... OR col BETWEEN v1 AND v2

func (*WhereStmt) OrGroup

func (stmt *WhereStmt) OrGroup() *sqlbuilder.WhereStmt

OrGroup 开始一个子条件语句

func (*WhereStmt) OrIn

func (stmt *WhereStmt) OrIn(col string, v ...interface{}) *WhereStmt

OrIn 指定 WHERE ... OR col IN(v...)

func (*WhereStmt) OrIsNotNull

func (stmt *WhereStmt) OrIsNotNull(col string) *WhereStmt

OrIsNotNull 指定 WHERE ... OR col IS NOT NULL

func (*WhereStmt) OrIsNull

func (stmt *WhereStmt) OrIsNull(col string) *WhereStmt

OrIsNull 指定 WHERE ... OR col IS NULL

func (*WhereStmt) OrLike

func (stmt *WhereStmt) OrLike(col string, content interface{}) *WhereStmt

OrLike 指定 WHERE ... OR col LIKE content

func (*WhereStmt) OrNotBetween

func (stmt *WhereStmt) OrNotBetween(col string, v1, v2 interface{}) *WhereStmt

OrNotBetween 指定 WHERE ... OR col BETWEEN v1 AND v2

func (*WhereStmt) OrNotIn

func (stmt *WhereStmt) OrNotIn(col string, v ...interface{}) *WhereStmt

OrNotIn 指定 WHERE ... OR col IN(v...)

func (*WhereStmt) OrNotLike

func (stmt *WhereStmt) OrNotLike(col string, content interface{}) *WhereStmt

OrNotLike 指定 WHERE ... OR col NOT LIKE content

func (*WhereStmt) Select

func (stmt *WhereStmt) Select(strict bool, v interface{}) (int, error)

Select 获取所有符合条件的数据

v 可能是某个对象的指针,或是一组相同对象指针数组。 表名来自 v,列名为 v 的所有列。

func (*WhereStmt) Update

func (stmt *WhereStmt) Update(v TableNamer, cols ...string) (sql.Result, error)

Update 将 v 中内容更新到符合条件的行中

不会更新零值,除非通过 cols 指定了该列。 表名来自 v,列名为 v 的所有列或是 cols 指定的列。

Directories

Path Synopsis
Package core 核心功能
Package core 核心功能
Package dialect 提供了部分数据库对 orm.Dialect 接口的实现
Package dialect 提供了部分数据库对 orm.Dialect 接口的实现
Package fetch 包提供了将 sql.Rows 导出为几种常用数据格式的方法
Package fetch 包提供了将 sql.Rows 导出为几种常用数据格式的方法
internal
createtable
Package createtable 分析 create table 语句的内容
Package createtable 分析 create table 语句的内容
flagtest
Package flagtest 用于生成测试用的命令行参数
Package flagtest 用于生成测试用的命令行参数
model
Package model 管理数据模型
Package model 管理数据模型
sqltest
Package sqltest 提供对 SQL 内容测试的工具
Package sqltest 提供对 SQL 内容测试的工具
tags
Package tags 包实现对特定格式的 struct tag 字符串的分析 1.
Package tags 包实现对特定格式的 struct tag 字符串的分析 1.
test
Package test 提供了整个包的基本测试数据
Package test 提供了整个包的基本测试数据
Package sqlbuilder 提供一套通过字符串拼接来构成 SQL 语句的工具 sqlbuilder 提供了部分 *Hooker 的接口,用于自定义某一条语句的实现。
Package sqlbuilder 提供一套通过字符串拼接来构成 SQL 语句的工具 sqlbuilder 提供了部分 *Hooker 的接口,用于自定义某一条语句的实现。
Package types 提供部分存取数据库的类型
Package types 提供部分存取数据库的类型

Jump to

Keyboard shortcuts

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