golang轻量级SQLite数据库ORM功能插件库ormlite的使用
golang轻量级SQLite数据库ORM功能插件库ormlite的使用
ormlite是一个轻量级的包,实现了类似ORM的功能和SQLite数据库的辅助工具。
Model
该包操作符合Model
接口的模型。任何结构体如果有存储数据的表,我们就称之为模型。
type Model interface {
Table() string
}
CRUD
该包提供了一系列函数来创建、读取、更新和删除数据。
QueryStruct
从表中加载数据并扫描到提供的结构体中。如果查询范围太广加载了多行数据,将扫描最后一行。此函数还支持加载关系(将在下面描述)。
type SimpleStruct struct {
IntField int64 `ormlite:"col=rowid,primary"`
Text string
UnusedField bool `ormlite:"-"`
}
var s SimpleStruct
err := QueryStruct(db, "", nil, &s)
示例中使用的标签说明:
col
- 指定自定义列名扫描到字段primary
- 表示模型主键,主要用于保存模型时-
- 对包隐藏字段,使其不受任何影响
QuerySlice
与QueryStruct非常相似,只是它将多行数据加载到切片中。
Upsert
此函数用于保存或更新现有模型。如果模型有primary
字段且其值为零,则此模型将被插入到模型的表中。否则,模型的记录将根据其当前值更新(不包括has-one
关系)。此函数还支持更新相关模型,但不包括创建或编辑many-to-many
相关模型。
err := Upsert(db, &s)
Insert
用于插入模型的函数。与Upsert
不同,它在约束错误时返回错误。
Delete
此函数…是的,它使用主键值从数据库中删除模型。如果模型没有主键或其值为零,将返回错误。由于有时了解删除操作是否真的在数据库中发生很有用,该函数将检查受影响的行数,如果行数不为正,则返回特殊的ErrNoRowsAffected
。
Options
type Options struct {
// 添加where子句到查询
Where Where
Limit int
Offset int
OrderBy *OrderBy
// 加载关系到指定深度,
// 如果深度为0则不加载任何关系
RelationDepth int
}
对于大多数查询,使用DefaultOptions()
就足够了,它的关系深度为1。
如果已经有包含Options的变量,可以使用以下函数扩展它们:
- WithLimit
- WithOffset
- WithOrder
- WithWhere
例如:
opts := ormlite.WithWhere(ormlite.DefaultOptions(), ormlite.Where{"id": 1})
Relations
QueryStruct、QuerySlice和Upsert支持加载模型之间的关系,支持的关系类型有:
- Has One
- Has Many
- Many To Many
由于可以控制加载关系的深度,因此不必担心循环加载。但有几种标签可以配置关系。
Has One
type Model struct {
Related ormlite.Model `ormlite:"has_one,col=related_model_id"`
}
has_one
表示此字段代表与其他模型的has one关系类型col
是一个可选参数,用于指定相关模型外键的自定义列名
Has Many
type Model struct {
Related []ormlite.Model `ormlite:"has_many"`
}
has_many
是唯一表示has many关系的参数,但要求相关模型必须有primary
字段
Many To Many
type Model struct {
Related []ormlite.Model `ormlite:"many_to_many,table=mapping_table,field=model_id"`
RelatedActive []ormlite.Model `ormlite:"many_to_many,table=mapping_table(active=1),field=model_id"`
}
many_to_many
表示字段代表多对多关系table(附加条件)
应包含映射表名以检索关系信息。如果需要使用附加条件映射实体,可以在括号中指定描述它们的sql。目前只支持一个附加字段field
应指定映射表中具有原始模型外键的列
还有一个要求是相关模型的主键字段必须包含ref
设置,该设置指定其在映射表中的外键列名。
通过相关项搜索
有时通过相关项搜索多对多模型很有用,因此运行以下代码:
type Author struct {
Id int `ormlite:"primary,ref=author_id"`
Topics []*Topic `ormlite:"many_to_many,table=author_topics,field=author_id"`
Name string
}
func (a *Author) Table() string { return "authors" }
type Topic struct {
Id int `ormlite:"primary,ref=topic_id"`
Authors []*Author `ormlite:"many_to_many,table=author_topics,field=topic_id"`
Content string
}
func (p *Topic) Table() string { return "topics" }
func main() {
db, err := sql.Open("sqlite3", ":memory:?_fk=1")
if err != nil {
panic(err)
}
_, err = db.Exec(`
create table authors(id integer primary key, name text);
create table topics(id integer primary key, content text, author_id int);
create table author_topics(author_id integer, topic_id integer);
`)
if err != nil {
panic(err)
}
john := &Author{Name: "John"}
err = ormlite.Upsert(db, john)
if err != nil {
panic(err)
}
pete := &Author{Name: "Pete"}
err = ormlite.Upsert(db, pete)
if err != nil {
panic(err)
}
cars := &Topic{Content: "Cars", Authors: []*Author{john, pete}}
err = ormlite.Upsert(db, cars)
if err != nil {
panic(err)
}
bikes := &Topic{Content: "Bikes", Authors: []*Author{john}}
err = ormlite.Upsert(db, bikes)
if err != nil {
panic(err)
}
planes := &Topic{Content: "Plains", Authors: []*Author{pete}}
err = ormlite.Upsert(db, planes)
if err != nil {
panic(err)
}
var carAuthors []*Author
err = ormlite.QuerySlice(db, &ormlite.Options{RelatedTo: []ormlite.IModel{&Topic{Id: cars.Id}}}, &carAuthors)
if err != nil {
panic(err)
}
var planeAuthors []*Author
err = ormlite.QuerySlice(db, &ormlite.Options{RelatedTo: []ormlite.IModel{&Topic{Id: planes.Id}}}, &planeAuthors)
if err != nil {
panic(err)
}
fmt.Print("Car authors: ")
for _, a := range carAuthors {
fmt.Printf("%s ", a.Name)
}
fmt.Print("\n")
fmt.Print("Plane authors: ")
for _, a := range planeAuthors {
fmt.Printf("%s ", a.Name)
}
将输出:
Car authors: John Pete
Plane authors: Pete
比较运算符
默认情况下,包使用=
运算符来比较Where
结构中引入的值,字符串除外,它们使用LIKE
运算符进行比较。但可以使用以下其他运算符列表:
Greater
代表>
GreaterOrEqual
代表>=
Less
代表<
LessOrEqual
代表<=
NotEqual
代表!=
BitwiseAND
代表value&? > 0
BitwiseANDStrict
代表value&? = 0
StrictString
- 默认情况下字符串比较使用LIKE
运算符,StrictString
将强制使用=
要使用这些运算符,只需用它们包装值
opts := &ormlite.Options{Where: {"Age": GreaterOrEqual(10)}}
更多示例
参见测试。
更多关于golang轻量级SQLite数据库ORM功能插件库ormlite的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于golang轻量级SQLite数据库ORM功能插件库ormlite的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
ormlite - Golang轻量级SQLite ORM库使用指南
ormlite是一个轻量级的Golang ORM库,专门为SQLite数据库设计,提供了简单易用的API来操作SQLite数据库。下面我将详细介绍ormlite的使用方法。
安装ormlite
go get github.com/mattn/ormlite
基本使用方法
1. 定义模型结构体
type User struct {
ID int `orm:"primary_key"`
Name string `orm:"size:100"`
Age int
CreatedAt time.Time `orm:"auto_now_add"`
UpdatedAt time.Time `orm:"auto_now"`
}
2. 初始化数据库连接
import (
"github.com/mattn/ormlite"
_ "github.com/mattn/go-sqlite3"
)
func main() {
db, err := ormlite.Open("sqlite3", "test.db")
if err != nil {
panic(err)
}
defer db.Close()
// 自动迁移表结构
err = db.AutoMigrate(&User{})
if err != nil {
panic(err)
}
}
3. CRUD操作示例
创建记录
// 创建单个记录
user := User{Name: "Alice", Age: 25}
result := db.Create(&user)
if result.Error != nil {
panic(result.Error)
}
// 批量创建
users := []User{
{Name: "Bob", Age: 30},
{Name: "Charlie", Age: 35},
}
result = db.Create(&users)
查询记录
// 查询单个记录
var user User
result := db.First(&user, 1) // 通过主键查询
result = db.First(&user, "name = ?", "Alice") // 条件查询
// 查询多个记录
var users []User
result = db.Where("age > ?", 20).Find(&users)
// 排序和限制
result = db.Order("age desc").Limit(10).Find(&users)
更新记录
// 更新单个字段
result := db.Model(&User{}).Where("id = ?", 1).Update("name", "Alice Updated")
// 更新多个字段
result = db.Model(&user).Updates(User{Name: "Alice", Age: 26})
// 更新所有匹配记录
result = db.Model(&User{}).Where("age > ?", 30).Update("age", ormlite.Expr("age + ?", 1))
删除记录
// 删除单个记录
result := db.Delete(&User{}, 1)
// 条件删除
result = db.Where("name = ?", "Bob").Delete(&User{})
4. 事务处理
err := db.Transaction(func(tx *ormlite.DB) error {
if err := tx.Create(&User{Name: "TxUser", Age: 40}).Error; err != nil {
return err
}
if err := tx.Model(&User{}).Where("name = ?", "Alice").Update("age", 27).Error; err != nil {
return err
}
return nil
})
if err != nil {
panic(err)
}
5. 高级查询
// 预加载关联(如果有关联关系)
type Post struct {
ID int
Title string
Content string
UserID int
User User
}
var post Post
db.Preload("User").First(&post, 1)
// 原生SQL查询
var users []User
db.Raw("SELECT * FROM users WHERE age > ?", 25).Scan(&users)
// 计数
var count int64
db.Model(&User{}).Where("age > ?", 20).Count(&count)
特性总结
- 轻量级: 专门为SQLite优化,不包含复杂ORM的所有功能
- 简单API: 类似GORM的API设计,学习曲线平缓
- 自动迁移: 支持自动创建和更新表结构
- 事务支持: 提供简单的事务处理机制
- 链式调用: 支持方法链式调用构建查询
注意事项
- ormlite是专门为SQLite设计的,不适用于其他数据库
- 对于复杂查询,可能需要直接使用原生SQL
- 性能敏感场景下,可以考虑直接使用database/sql接口
- 确保在结构体字段中正确定义标签(如primary_key等)
ormlite非常适合中小型项目,特别是那些需要简单ORM功能而不想引入复杂框架的场景。它的轻量级特性和对SQLite的专门优化使其成为这类项目的理想选择。