【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.hqwc.cn/news/636922.html

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

相关文章

请编写一个函数void fun(int m,int k,int xx[]),该函数的功能是:将大于整数m且紧靠m的k个素数存入xx所指的数组中。

本文收录于专栏:算法之翼 https://blog.csdn.net/weixin_52908342/category_10943144.html 订阅后本专栏全部文章可见。 本文含有题目的题干、解题思路、解题思路、解题代码、代码解析。本文分别包含C语言、C++、Java、Python四种语言的解法和详细的解析。 题干 请编写一个函…

vector简单介绍

目录 学习语法,不必拘泥,重要的是要学会和理解。所有的一切,例如做题,学习、看书、各种行为都是手段,为着我们更好的运用。因为,最终都是为了更好的去理解某个东西,以便于更好的去改造这个世界…

C语言 | 自定义类型:联合和枚举

目录: ----前言 1. 联合体 1.1 联合体类型的声明 1.2 联合体的特点 1.3 相同成员的结构体和联合体对比 1.4 联合体大小的计算 1.5 联合的使用 1.6联合体的练习 2. 枚举 2.1 枚举类型的声明 2.2 枚举类型的优点 2.3 枚举类型的使用 --前言: c语言中内…

OpenVINO安装教程 npm版

从 npm Registry安装 OpenVINO™ 工具套件的英特尔发行版 请注意: 仅提供 JavaScript API 专用于所有主要操作系统的用户:Windows、Linux 和 macOS (所有 x86_64 / ARM64 架构) macOS 仅支持 CPU 推理 系统要求软件要求 Window…

博客网站/部署服务器---继上篇前端页面接入后端

目录 准备工作 创建用户类博客类与连接数据库 创建博客类 创建用户类 创建连接数据库工具类 实现对数据库数据博客的操作 实现对数据库用户的操作 创建数据库语句 登录页面 前端 后端 博客列表 前端 注销登录 写入数据 判断用户是否登录 替换页面用户昵称 后…

分类预测 | Matlab实现CNN-LSTM-SAM-Attention卷积长短期记忆神经网络融合空间注意力机制的数据分类预测

分类预测 | Matlab实现CNN-LSTM-SAM-Attention卷积长短期记忆神经网络融合空间注意力机制的数据分类预测 目录 分类预测 | Matlab实现CNN-LSTM-SAM-Attention卷积长短期记忆神经网络融合空间注意力机制的数据分类预测分类效果基本描述程序设计参考资料 分类效果 基本描述 1.Mat…

目标检测——防护装备数据集

一、重要性及意义 防护装备中的头盔和背心检测具有至关重要的重要性和深远的意义,主要体现在以下几个方面: 首先,它们对于保护工作人员的人身安全起着至关重要的作用。在各类工作环境中,尤其是那些涉及高空作业、机械操作或交通…

Linux基本命令之正则表达式(转义字符)

一:查看二进制文件 strings 命令:strings 文件名 生成链接文件 ln 命令:ln 选项 源文件(f1) 链接文件(f2) 软连接:eg:ln -s f1 f2 软链接不能跨分区链接,但可以在同一分区的不同目录下链接…

故障诊断 | 用于跨机器工况下故障诊断的深度判别迁移学习网络附Pytorch代码

目录 基础代码小结基础 目前,研究者已经提出了很多用于解决目标域和源域之间的分布对齐和知识迁移问题的领域自适应方法。然而,大多数研究方法只关注到边缘分布对齐,忽略了目标域和源域之间判别性特征的学习。因此,在某些案例中,这些方法仍然不能很好地满足故障诊断要求。…

从OWASP API Security TOP 10谈API安全

1.前言 应用程序编程接口(API)是当今应用驱动世界创新的一个基本元素。从银行、零售、运输到物联网、 自动驾驶汽车、智慧城市,API 是现代移动、SaaS 和 web 应用程序的重要组成部分,可以在面向客 户、面向合作伙伴和内部的应用程…

android开发 多进程的基本了解

目录 如何开启多进程?理解多进程模式的运行机制 如何开启多进程? 给四大组件在androidMenifest中指定android:precess <activityandroid:name".ThreeActivity"android:exported"false"android:process"com.my.process.three.remote" />…

数据恢复宝典:应对磁盘损坏无法读取的终极攻略

当电脑屏幕上突然弹出“磁盘损坏无法读取”的提示时&#xff0c;许多人的心情都会瞬间跌入谷底。那些存储在磁盘中的重要文件、珍贵的回忆&#xff0c;似乎在一瞬间都化为乌有。面对这样的困境&#xff0c;我们该如何应对&#xff1f;本文将深入探讨磁盘损坏无法读取的原因&…