【GoWeb框架初探————XORM篇】

2024-04-19 00:28
文章标签 框架 初探 xorm goweb

本文主要是介绍【GoWeb框架初探————XORM篇】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1. XORM

xorm 是一个简单而强大的Go语言ORM库. 通过它可以使数据库操作非常简便。
在这里插入图片描述

1.1 特性

  • 支持 Struct 和数据库表之间的灵活映射,并支持自动同步
  • 事务支持
  • 同时支持原始SQL语句和ORM操作的混合执行
  • 使用连写来简化调用
  • 支持使用ID, In, Where, Limit, Join, Having, Table, SQL, Cols等函数和结构体等方式作为条件
  • 支持级联加载Struct
  • Schema支持(仅Postgres)
  • 支持缓存
  • 通过 xorm.io/reverse 支持根据数据库自动生成 xorm 结构体
  • 支持记录版本(即乐观锁)
  • 通过 xorm.io/builder 内置 SQL Builder 支持
  • 上下文缓存支持
  • 支持日志上下文

1.2 驱动支持

目前支持的Go数据库驱动和对应的数据库如下:

  • Mysql5.* / Mysql8.* / Mariadb / Tidb
  • Postgres / Cockroach
  • SQLite
  • MsSql
  • Oracle

1.3 安装

go get xorm.io/xorm

2. 特性功能

2.1 Struct和数据库表映射

func main() {// 数据库连接基本信息var (userName  string = "root"password  string = "password"ipAddress string = "127.0.0.1"port      int    = 3306dbName    string = "go_test"charset   string = "utf8mb4")// 构建数据库连接信息conn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=%s", userName, password, ipAddress, port, dbName, charset)engine, err := xorm.NewEngine("mysql", conn)if err != nil {fmt.Println("数据库连接失败", err)}type User struct {Id      int64Name    stringSalt    stringAge     intPasswd  string    `xorm:"varchar(200)"`Created time.Time `xorm:"created"`Updated time.Time `xorm:"updated"`}// 表同步,以后修改User的结构后只需再执行一遍即可err = engine.Sync(new(User))if err != nil {fmt.Println("表结构同步失败", err)}
}

2.2 数据库的基本操作

2.3.1 数据插入

在数据插入的时候,我们应该要使用地址类型,这样方便数据库进行一些回写操作。

user := pojo.User{Id:     123456,Name:   "gzh",Age:    23,Passwd: "123456",}
// 插入一个对象
// INSERT INTO struct () values ()
n, err := engine.Insert(&user)
// 一次性插入多个
// INSERT INTO struct1 () values ()
// INSERT INTO struct2 () values ()
n, err := engine.Insert(&user1,&user2)
// 插入一个切片
// INSERT INTO struct () values (),(),()
var users []User
users = append(users,user1)
users = append(users,user2)
n, err := engine.Insert(&users)
// 通过map插入数据
// INSERT INTO user (name, age) values (?,?)
affected, err := engine.Table("user").Insert(map[string]interface{}{"name": "lunny","age": 18,
})
// 插入列表map数据
// INSERT INTO user (name, age) values (?,?),(?,?)
affected, err := engine.Table("user").Insert([]map[string]interface{}{{"name": "lunny","age": 18,},{"name": "lunny2","age": 19,},
})

2.3.2 数据查找

2.3.2.1 Get查询单条记录
has, err := engine.Get(&user)
// SELECT * FROM user LIMIT 1has, err := engine.Where("name = ?", name).Desc("id").Get(&user)
// SELECT * FROM user WHERE name = ? ORDER BY id DESC LIMIT 1// 查询一部分/全部属性
var name string
has, err := engine.Table(&user).Where("id = ?", id).Cols("name").Get(&name)
// SELECT name FROM user WHERE id = ?var id int64
has, err := engine.Table(&user).Where("name = ?", name).Cols("id").Get(&id)
has, err := engine.SQL("select id from user").Get(&id)
// SELECT id FROM user WHERE name = ?var id int64
var name string
has, err := engine.Table(&user).Cols("id", "name").Get(&id, &name)
// SELECT id, name FROM user LIMIT 1var valuesMap = make(map[string]string)
has, err := engine.Table(&user).Where("id = ?", id).Get(&valuesMap)
// SELECT * FROM user WHERE id = ?var valuesSlice = make([]interface{}, len(cols))
has, err := engine.Table(&user).Where("id = ?", id).Cols(cols...).Get(&valuesSlice)
// SELECT col1, col2, col3 FROM user WHERE id = ?
2.3.2.2 检测记录是否存在
// 检验数据表中是否存在数据
has, err := testEngine.Exist(new(RecordExist))
// SELECT * FROM record_exist LIMIT 1// 检查数据表中是否存在满足指定条件的数据
has, err = testEngine.Exist(&RecordExist{Name: "test1",})
// SELECT * FROM record_exist WHERE name = ? LIMIT 1has, err = testEngine.Where("name = ?", "test1").Exist(&RecordExist{})
// SELECT * FROM record_exist WHERE name = ? LIMIT 1has, err = testEngine.SQL("select * from record_exist where name = ?", "test1").Exist()
// select * from record_exist where name = ?has, err = testEngine.Table("record_exist").Exist()
// SELECT * FROM record_exist LIMIT 1has, err = testEngine.Table("record_exist").Where("name = ?", "test1").Exist()
// SELECT * FROM record_exist WHERE name = ? LIMIT 1
2.3.2.3 Find 查询多条记录
var users []User
err := engine.Where("name = ?", name).And("age > 10").Limit(10, 0).Find(&users)
// SELECT * FROM user WHERE name = ? AND age > 10 limit 10 offset 0type Detail struct {Id int64UserId int64 `xorm:"index"`
}type UserDetail struct {User `xorm:"extends"`Detail `xorm:"extends"`
}var users []UserDetail
err := engine.Table("user").Select("user.*, detail.*").Join("INNER", "detail", "detail.user_id = user.id").Where("user.name = ?", name).Limit(10, 0).Find(&users)
// SELECT user.*, detail.* FROM user INNER JOIN detail WHERE user.name = ? limit 10 offset 0
2.3.2.4 Iterate 和 Rows 根据条件遍历数据库
Iterate
err := engine.Iterate(&User{Name:name}, func(idx int, bean interface{}) error {user := bean.(*User)return nil
})
// SELECT * FROM usererr := engine.BufferSize(100).Iterate(&User{Name:name}, func(idx int, bean interface{}) error {user := bean.(*User)return nil
})
// SELECT * FROM user Limit 0, 100
// SELECT * FROM user Limit 101, 100
Rows
rows, err := engine.Rows(&User{Name:name})
// SELECT * FROM user
defer rows.Close()
bean := new(Struct)
for rows.Next() {err = rows.Scan(bean)
}
//===============或者==================
rows, err := engine.Cols("name", "age").Rows(&User{Name:name})
// SELECT * FROM user
defer rows.Close()
for rows.Next() {var name stringvar age interr = rows.Scan(&name, &age)
}

2.3.3 数据更新

Update 更新数据,除非使用Cols,AllCols函数指明,默认只更新非空和非0的字段

affected, err := engine.ID(1).Update(&user)
// UPDATE user SET ... Where id = ?affected, err := engine.Update(&user, &User{Name:name})
// UPDATE user SET ... Where name = ?var ids = []int64{1, 2, 3}
affected, err := engine.In(ids).Update(&user)
// UPDATE user SET ... Where id IN (?, ?, ?)// force update indicated columns by Cols
affected, err := engine.ID(1).Cols("age").Update(&User{Name:name, Age: 12})
// UPDATE user SET age = ?, updated=? Where id = ?// force NOT update indicated columns by Omit
affected, err := engine.ID(1).Omit("name").Update(&User{Name:name, Age: 12})
// UPDATE user SET age = ?, updated=? Where id = ?affected, err := engine.ID(1).AllCols().Update(&user)
// UPDATE user SET name=?,age=?,salt=?,passwd=?,updated=? Where id = ?

2.3.4 数据删除

Delete 删除记录,需要注意,删除必须至少有一个条件,否则会报错。要清空数据库可以用EmptyTable

affected, err := engine.Where(...).Delete(&user)
// DELETE FROM user Where ...affected, err := engine.ID(2).Delete(&user)
// DELETE FROM user Where id = ?affected, err := engine.Table("user").Where(...).Delete()
// DELETE FROM user WHERE ...

2.3.5 其他

2.3.5.1 Count 获取记录条数
counts, err := engine.Count(&user)
// SELECT count(*) AS total FROM user
2.3.5.2 Sum 求和函数
agesFloat64, err := engine.Sum(&user, "age")
// SELECT sum(age) AS total FROM useragesInt64, err := engine.SumInt(&user, "age")
// SELECT sum(age) AS total FROM usersumFloat64Slice, err := engine.Sums(&user, "age", "score")
// SELECT sum(age), sum(score) FROM usersumInt64Slice, err := engine.SumsInt(&user, "age", "score")
// SELECT sum(age), sum(score) FROM user
2.3.5.3 条件编辑器
err := engine.Where(builder.NotIn("a", 1, 2).And(builder.In("b", "c", "d", "e"))).Find(&users)
// SELECT id, name ... FROM user WHERE a NOT IN (?, ?) AND b IN (?, ?, ?)

2.3 事务支持

2.3.1 事务的使用

使用事务可以使得多个sql语句具有原子性。

session := engine.NewSession()
defer session.Close()// 开启事务
if err := session.Begin(); err != nil {// if returned then will rollback automatically// 如果发生错误会自动回滚return err
}user1 := Userinfo{Username: "xiaoxiao", Departname: "dev", Alias: "lunny", Created: time.Now()}
if _, err := session.Insert(&user1); err != nil {return err
}user2 := Userinfo{Username: "yyy"}
if _, err := session.Where("id = ?", 2).Update(&user2); err != nil {return err
}if _, err := session.Exec("delete from userinfo where username = ?", user2.Username); err != nil {return err
}// 提交事务
return session.Commit()

2.3.2 事务的简洁写法

res, err := engine.Transaction(func(session *xorm.Session) (interface{}, error) {user1 := Userinfo{Username: "xiaoxiao", Departname: "dev", Alias: "lunny", Created: time.Now()}if _, err := session.Insert(&user1); err != nil {return nil, err}user2 := Userinfo{Username: "yyy"}if _, err := session.Where("id = ?", 2).Update(&user2); err != nil {return nil, err}if _, err := session.Exec("delete from userinfo where username = ?", user2.Username); err != nil {return nil, err}return nil, nil
})

这篇关于【GoWeb框架初探————XORM篇】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/916183

相关文章

Spring 框架之Springfox使用详解

《Spring框架之Springfox使用详解》Springfox是Spring框架的API文档工具,集成Swagger规范,自动生成文档并支持多语言/版本,模块化设计便于扩展,但存在版本兼容性、性... 目录核心功能工作原理模块化设计使用示例注意事项优缺点优点缺点总结适用场景建议总结Springfox 是

Python的端到端测试框架SeleniumBase使用解读

《Python的端到端测试框架SeleniumBase使用解读》:本文主要介绍Python的端到端测试框架SeleniumBase使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全... 目录SeleniumBase详细介绍及用法指南什么是 SeleniumBase?SeleniumBase

C++ HTTP框架推荐(特点及优势)

《C++HTTP框架推荐(特点及优势)》:本文主要介绍C++HTTP框架推荐的相关资料,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录1. Crow2. Drogon3. Pistache4. cpp-httplib5. Beast (Boos

SpringBoot基础框架详解

《SpringBoot基础框架详解》SpringBoot开发目的是为了简化Spring应用的创建、运行、调试和部署等,使用SpringBoot可以不用或者只需要很少的Spring配置就可以让企业项目快... 目录SpringBoot基础 – 框架介绍1.SpringBoot介绍1.1 概述1.2 核心功能2

Spring框架中@Lazy延迟加载原理和使用详解

《Spring框架中@Lazy延迟加载原理和使用详解》:本文主要介绍Spring框架中@Lazy延迟加载原理和使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录一、@Lazy延迟加载原理1.延迟加载原理1.1 @Lazy三种配置方法1.2 @Component

Python Dash框架在数据可视化仪表板中的应用与实践记录

《PythonDash框架在数据可视化仪表板中的应用与实践记录》Python的PlotlyDash库提供了一种简便且强大的方式来构建和展示互动式数据仪表板,本篇文章将深入探讨如何使用Dash设计一... 目录python Dash框架在数据可视化仪表板中的应用与实践1. 什么是Plotly Dash?1.1

基于Flask框架添加多个AI模型的API并进行交互

《基于Flask框架添加多个AI模型的API并进行交互》:本文主要介绍如何基于Flask框架开发AI模型API管理系统,允许用户添加、删除不同AI模型的API密钥,感兴趣的可以了解下... 目录1. 概述2. 后端代码说明2.1 依赖库导入2.2 应用初始化2.3 API 存储字典2.4 路由函数2.5 应

Python GUI框架中的PyQt详解

《PythonGUI框架中的PyQt详解》PyQt是Python语言中最强大且广泛应用的GUI框架之一,基于Qt库的Python绑定实现,本文将深入解析PyQt的核心模块,并通过代码示例展示其应用场... 目录一、PyQt核心模块概览二、核心模块详解与示例1. QtCore - 核心基础模块2. QtWid

最新Spring Security实战教程之Spring Security安全框架指南

《最新SpringSecurity实战教程之SpringSecurity安全框架指南》SpringSecurity是Spring生态系统中的核心组件,提供认证、授权和防护机制,以保护应用免受各种安... 目录前言什么是Spring Security?同类框架对比Spring Security典型应用场景传统

Python结合Flask框架构建一个简易的远程控制系统

《Python结合Flask框架构建一个简易的远程控制系统》这篇文章主要为大家详细介绍了如何使用Python与Flask框架构建一个简易的远程控制系统,能够远程执行操作命令(如关机、重启、锁屏等),还... 目录1.概述2.功能使用系统命令执行实时屏幕监控3. BUG修复过程1. Authorization