【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
})

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/33.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

记录 nginx 出现 403 forbidden 和 404 的解决经历

403 当我修改了 nginx 所展示的页面路径了以后,访问 nginx 所在的 8080 端口就出现了403 forbidden 的错误 首先通过以下查看进程的命令 ps -aux|grep nginx发现 worker process 对应的启动用户是 nobody 是错的 (图中是 root,是改正后的样子…

【uniapp踩坑记】——微信小程序转发保存图片

关于微信小程序转发&保存图片 微信小程序图片转发保存简单说明网络图片的转发保存base64流形式图片转发保存 已经好多年没写博客了,最近使用在用uniapp开发一个移动版管理后台,记录下自己踩过的一些坑 吃相别太难看,搞一堆下头僵尸号来点…

vite(vue3)配置内网ip访问的方法步骤

如果没有进行配置,运行项目之后,看到的访问地址是本地访问地址,其他人访问不了。 如下: 一、配置 “ vite.config.ts ” 文件 server: {host: 0.0.0.0 }, 如图所示: 添加 server 配置后保存 “ vite.config.ts ” 文…

深度学习发展中的继承和创新

深度学习是一步一步发展而来的,新的成就也是在原有的基础上,逐步取得突破,有一些东西是一点一点变化,突破发展而来的,也就是每一次小的突破和每一次小的突破累积起来,构成一个明显的进步。我们可以通过观察…

C语言 ─── 操作符详解

目录 1. 算术操作符 2. 移位操作符 2.1 左移操作符 2.2 右移操作符 3. 位操作符 4. 复合赋值符 5. 单目操作符 6. 逗号表达式 7. 隐式类型转换 7.1 整型提升的意义: 7.2 如何进行整体提升呢? 8. 算术转换 ★★★数组名 1. 算术操作符 -…

实现联系人前后端界面,实现分页查询04.15

实现联系人前后端界面,实现分页查询项目包-CSDN博客 项目结构 数据库中建立两个表: 完整的后端目录 建立联系人People表,分组Type表,实现对应实体类 根据需求在mapper中写对应的sql语句 查询所有,删除,添…

js BOM模型常用方法梳理

1、Bom定义 BOM是操作浏览器的模型,主要是对浏览器的一些操作。 2、获取浏览器窗口的尺寸 window.innerHeight:获取窗口的高度。 window.innerWidth:湖区窗口的宽度,只在window浏览器下使用。 3、弹出层 alert:弹出框。 confirm:确认框。返回值有true …

数据治理实战——元数据管理

一、元数据概述 1.1 定义 描述数据的数据,本质还是数据。数据本身带有的技术属性与其在业务运行中的业务属性,称其为元数据,例如:表数据量,占用空间,字段信息,业务描述,负责人&…

计算机视觉实验五——图像分割

计算机视觉实验五——图像分割 一、实验目标二、实验内容1.了解图割操作,实现用户交互式分割,通过在一幅图像上为前景和背景提供一些标记或利用边界框选择一个包含前景的区域,实现分割①图片准备②代码③运行结果④代码说明 2.采用聚类法实现…

单调队列(C/C++)

引言: 单调队列和单调栈都是一种数据结构,应用十分广泛,在蓝桥杯、ICPC、CCPC等著名编程赛事都是重点的算法,今天博主将自己对单调栈与单调队列的理解以及刷题的经验,用一篇博客分享给大家,希望对大家有所…

在线拍卖系统|基于Springboot的在线拍卖系统设计与实现(源码+数据库+文档)

在线拍卖系统目录 基于Springboot的在线拍卖系统设计与实现 一、前言 二、系统设计 三、系统功能设计 1、前台: 2、后台 用户功能模块 5.2用户功能模块 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&#xff1a…

使用脚本部署openstack平台

两台虚拟机,compute和controller 建议两台虚拟机都配置,内存4G,硬盘60G,网络要在虚拟机设置这里添加一个网络适配器,第一个是主机模式192.168.10.0,第二个是NAT模192.168.20.0, 可以在此处了解一…

Unity Standalone File Browser,Unity打开文件选择器

Unity Standalone File Browser,Unity打开文件选择器 下载地址:GitHub链接: https://github.com/gkngkc/UnityStandaloneFileBrowser简单的示例代码 using SFB; using System; using System.IO; using UnityEngine; using UnityEngine.UI;…

从三大层次学习企业架构框架TOGAF

目录 前言 掌握TOGAF的三个层次 层次1:怎么学? 层次2:怎么用? 层次3:怎么思? 结束语 前言 对于一名架构师来讲,如果说编程语言是知识库层次中的入门石,那么企业架构框架则相当…

cesium加载倾斜影像数据(模拟雨、雪、雾、无人机飞行、测距、箭头标绘、电子围栏等)

实现效果如下: 功能菜单如下: 加载倾斜影像核心代码: var palaceTileset new Cesium.Cesium3DTileset({url: http://127.0.0.1:9002/tileset.json,//控制切片视角显示的数量,可调整性能maximumScreenSpaceError: 0.1,maximumNum…

python/pygame 挑战魂斗罗 笔记(三)

感觉最难的部分已经解决了,下面开始发射子弹。 一、建立ContraBullet.py文件,Bullit类: 1、设定子弹速度 Config.py中设定子弹移动速度为常量Constant.BULLET_SPEED 8。 2、载入子弹图片: 图片也是6张,子弹发出后…

OceanBase数据库日常运维快速上手

这里为大家汇总了从租户创建、连接数据库,到数据库的备份、归档、资源配置调整等,在OceanBase数据库日常运维中的操作指南。 创建租户 方法一:通过OCP 创建 确认可分配资源 想要了解具体可分配的内存量,可以通过【资源管理】功…

Unity 对APK签名

关键代码 PS D:\UnityProject\YueJie> jarsigner -verbose -keystore D:\UnityProject\YueJie\user.keystore -signedjar D:\UnityProject\YueJie\meizuemptyapk-release-signed.apk D:\UnityProject\YueJie\MeizuEmpty-release-unsigned.apk 1 示例 # jarsigner的命令格…

【C++从练气到飞升】08---模板

🎈个人主页:库库的里昂 ✨收录专栏:C从练气到飞升 🎉鸟欲高飞先振翅,人求上进先读书。 目录 一、泛型编程 什么是泛型编程: 二、函数模板 1. 函数模板概念 2. 函数模板格式 3. 函数模板的原理 4. 函数模板的实例…

Ubuntu 传输文件

scp [选项] 源文件 目标路径 以下是一些常用的 scp 命令选项: -r:递归复制目录和子目录。 -P:指定远程 SSH 服务器的端口号。 -i:指定用于身份验证的私钥文件。 -p:保留源文件的时间戳、权限和所有者。 -v&#x…