【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

相关文章

cross-plateform 跨平台应用程序-03-如果只选择一个框架,应该选择哪一个?

跨平台系列 cross-plateform 跨平台应用程序-01-概览 cross-plateform 跨平台应用程序-02-有哪些主流技术栈? cross-plateform 跨平台应用程序-03-如果只选择一个框架,应该选择哪一个? cross-plateform 跨平台应用程序-04-React Native 介绍 cross-plateform 跨平台应用程序-05-Flutte

Spring框架5 - 容器的扩展功能 (ApplicationContext)

private static ApplicationContext applicationContext;static {applicationContext = new ClassPathXmlApplicationContext("bean.xml");} BeanFactory的功能扩展类ApplicationContext进行深度的分析。ApplicationConext与 BeanF

数据治理框架-ISO数据治理标准

引言 "数据治理"并不是一个新的概念,国内外有很多组织专注于数据治理理论和实践的研究。目前国际上,主要的数据治理框架有ISO数据治理标准、GDI数据治理框架、DAMA数据治理管理框架等。 ISO数据治理标准 改标准阐述了数据治理的标准、基本原则和数据治理模型,是一套完整的数据治理方法论。 ISO/IEC 38505标准的数据治理方法论的核心内容如下: 数据治理的目标:促进组织高效、合理地

ZooKeeper 中的 Curator 框架解析

Apache ZooKeeper 是一个为分布式应用提供一致性服务的软件。它提供了诸如配置管理、分布式同步、组服务等功能。在使用 ZooKeeper 时,Curator 是一个非常流行的客户端库,它简化了 ZooKeeper 的使用,提供了高级的抽象和丰富的工具。本文将详细介绍 Curator 框架,包括它的设计哲学、核心组件以及如何使用 Curator 来简化 ZooKeeper 的操作。 1

【Kubernetes】K8s 的安全框架和用户认证

K8s 的安全框架和用户认证 1.Kubernetes 的安全框架1.1 认证:Authentication1.2 鉴权:Authorization1.3 准入控制:Admission Control 2.Kubernetes 的用户认证2.1 Kubernetes 的用户认证方式2.2 配置 Kubernetes 集群使用密码认证 Kubernetes 作为一个分布式的虚拟

Spring Framework系统框架

序号表示的是学习顺序 IoC(控制反转)/DI(依赖注入): ioc:思想上是控制反转,spring提供了一个容器,称为IOC容器,用它来充当IOC思想中的外部。 我的理解就是spring把这些对象集中管理,放在容器中,这个容器就叫Ioc这些对象统称为Bean 用对象的时候不用new,直接外部提供(bean) 当外部的对象有关系的时候,IOC给它俩绑好(DI) DI和IO

Sentinel 高可用流量管理框架

Sentinel 是面向分布式服务架构的高可用流量防护组件,主要以流量为切入点,从限流、流量整形、熔断降级、系统负载保护、热点防护等多个维度来帮助开发者保障微服务的稳定性。 Sentinel 具有以下特性: 丰富的应用场景:Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应

利用Django框架快速构建Web应用:从零到上线

随着互联网的发展,Web应用的需求日益增长,而Django作为一个高级的Python Web框架,以其强大的功能和灵活的架构,成为了众多开发者的选择。本文将指导你如何从零开始使用Django框架构建一个简单的Web应用,并将其部署到线上,让世界看到你的作品。 Django简介 Django是由Adrian Holovaty和Simon Willison于2005年开发的一个开源框架,旨在简

Yii框架relations的使用

通过在 relations() 中声明这些相关对象,我们就可以利用强大的 Relational ActiveRecord (RAR) 功能来访问资讯的相关对象,例如它的作者和评论。不需要自己写复杂的 SQL JOIN 语句。 前提条件 在组织数据库时,需要使用主键与外键约束才能使用ActiveReocrd的关系操作; 场景 申明关系 两张表之间的关系无非三种:一对多;一对一;多对多; 在

laravel框架实现redis分布式集群原理

在app/config/database.php中配置如下: 'redis' => array('cluster' => true,'default' => array('host' => '172.21.107.247','port' => 6379,),'redis1' => array('host' => '172.21.107.248','port' => 6379,),) 其中cl