全国旗舰校区

不同学习城市 同样授课品质

北京

深圳

上海

广州

郑州

大连

武汉

成都

西安

杭州

青岛

重庆

长沙

哈尔滨

南京

太原

沈阳

合肥

贵阳

济南

下一个校区
就在你家门口
+
当前位置:首页  >  技术干货

Golang中的ORM框架评测及性能分析

发布时间:2023-12-27 09:57:36
发布人:xqq

Golang中的ORM框架评测及性能分析

ORM是对象关系映射(Object-Relational Mapping)的缩写,是一种通过使用描述对象和数据库之间映射的元数据,将面向对象语言程序中的对象自动持久化到关系数据库中的技术。在Golang中,ORM框架也是非常重要的,因为它可以帮助我们简化数据库操作的复杂度,提高开发效率。本文将会对Golang中的ORM框架进行评测及性能分析,以便读者能够选择适合自己的ORM框架。

1. GORM

GORM是一个比较流行的Golang ORM框架,它提供了非常多的特性和工具,方便我们进行数据库操作。GORM支持MySQL、SQLite、PostgreSQL、SQL Server等多个数据库,并且允许我们定义模型结构体,对模型的增删改查都提供了非常友好的接口。

下面是一个使用GORM操作MySQL的简单例子:

go

import (

"gorm.io/driver/mysql"

"gorm.io/gorm"

)

type User struct {

ID uint gorm:"primaryKey"

Name string gorm:"not null"

Age uint8 gorm:"not null"`

}

func main() {

dsn := "root:password@tcp(127.0.0.1:3306)/testdb?charset=utf8mb4&parseTime=True&loc=Local"

db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})

if err != nil {

panic(err)

}

// 自动迁移模式

db.AutoMigrate(&User{})

// 创建记录

db.Create(&User{Name: "Tom", Age: 18})

// 查询记录

var user User

db.First(&user, 1) // 查询ID为1的记录

// 更新记录

db.Model(&user).Update("Age", 20)

// 删除记录

db.Delete(&user)

}

GORM支持链式调用,使得查询、排序、分页等操作非常方便,例如:`go// 查询所有年龄大于18岁的用户db.Where("age > ?", 18).Find(&users)// 查询前10条记录db.Limit(10).Find(&users)// 查询跳过前5条记录后的10条记录db.Offset(5).Limit(10).Find(&users)// 按照年龄降序排序db.Order("age desc").Find(&users)

GORM的缺点是,它的性能相对较差,不适合对大批量的数据进行操作,因此在某些场景下,需要使用更加高效的ORM框架。

2. XORM

XORM是另一个Golang ORM框架,类似GORM,也支持多个数据库,并且提供了类似GORM的API,但是XORM在性能方面表现更好,尤其是对于批量操作。

下面是一个使用XORM操作MySQL的简单例子:

go

import (

"github.com/go-xorm/xorm"

_ "github.com/go-sql-driver/mysql"

)

type User struct {

ID int64 xorm:"pk autoincr"

Name string xorm:"varchar(20) not null"

Age int xorm:"not null"`

}

func main() {

dsn := "root:password@tcp(127.0.0.1:3306)/testdb?charset=utf8mb4"

engine, err := xorm.NewEngine("mysql", dsn)

if err != nil {

panic(err)

}

// 自动同步数据表结构

err = engine.Sync2(&User{})

if err != nil {

panic(err)

}

// 插入数据

session := engine.NewSession()

defer session.Close()

err = session.Begin()

if err != nil {

panic(err)

}

_, err = session.Insert(&User{Name: "Tom", Age: 18})

if err != nil {

panic(err)

}

_, err = session.Insert(&User{Name: "Jerry", Age: 20})

if err != nil {

panic(err)

}

err = session.Commit()

if err != nil {

panic(err)

}

// 查询数据

users := make(User, 0)

err = engine.Where("age > ?", 18).Limit(10).Find(&users)

if err != nil {

panic(err)

}

// 更新数据

user := users

user.Age = 21

_, err = engine.Update(&user)

if err != nil {

panic(err)

}

// 删除数据

_, err = engine.Delete(&user)

if err != nil {

panic(err)

}

}

XORM支持批量插入、批量更新和批量删除,对于批量操作的性能表现非常出色。例如:`go// 批量插入users := make(User, 0)users = append(users, User{Name: "Tom", Age: 18})users = append(users, User{Name: "Jerry", Age: 20})affected, err := session.Insert(&users)if err != nil {    panic(err)}// 批量更新affected, err := engine.Where("age > ?", 18).Update(&User{Age: 21})// 批量删除affected, err := engine.Where("age > ?", 18).Delete(&User{})

总的来说,XORM是一个非常出色的Golang ORM框架,特别适合对大批量数据进行操作。

3. GORP

GORP是另一个Golang ORM框架,封装了一些常见的数据库操作,如查询、插入、更新和删除,同时也支持多个数据库。

下面是一个使用GORP操作MySQL的简单例子:

go

import (

"database/sql"

"github.com/go-gorp/gorp"

_ "github.com/go-sql-driver/mysql"

)

type User struct {

Id int64 db:"id,primarykey,autoincrement"

Name string db:"name,notnull"

Age int db:"age,notnull"`

}

func main() {

dsn := "root:password@tcp(127.0.0.1:3306)/testdb?charset=utf8mb4"

db, err := sql.Open("mysql", dsn)

if err != nil {

panic(err)

}

// 创建ORM映射

dbmap := &gorp.DbMap{Db: db, Dialect: gorp.MySQLDialect{}}

dbmap.AddTableWithName(User{}, "users").SetKeys(true, "Id")

// 自动同步数据表结构

err = dbmap.CreateTablesIfNotExists()

if err != nil {

panic(err)

}

// 插入数据

user := &User{Name: "Tom", Age: 18}

err = dbmap.Insert(user)

if err != nil {

panic(err)

}

// 查询数据

users := make(User, 0)

_, err = dbmap.Select(&users, "SELECT * FROM users WHERE Age > ?", 18)

if err != nil {

panic(err)

}

// 更新数据

user.Age = 19

_, err = dbmap.Update(user)

if err != nil {

panic(err)

}

// 删除数据

_, err = dbmap.Delete(user)

if err != nil {

panic(err)

}

}

GORP使用struct tag来定义映射关系,在这个方面略显不太便利,与GORM和XORM都不太一样。不过,GORP的性能表现可以与XORM相媲美,适合对大批量数据进行操作。4. 性能分析为了评测各个ORM框架的性能表现,我们编写了一个基准测试程序,分别测试了它们的插入、查询、更新和删除操作。`goimport (    "database/sql"    "github.com/go-gorp/gorp"    _ "github.com/go-sql-driver/mysql"    "github.com/go-xorm/xorm"    "gorm.io/driver/mysql"    "gorm.io/gorm"    "testing")type User struct {    ID   uint   gorm:"primaryKey"    Name string gorm:"not null"    Age  uint8  gorm:"not null"}func initDbGorm() *gorm.DB {    dsn := "root:password@tcp(127.0.0.1:3306)/testdb?charset=utf8mb4&parseTime=True&loc=Local"    db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})    if err != nil {        panic(err)    }    db.AutoMigrate(&User{})    return db}func initDbXorm() *xorm.Engine {    dsn := "root:password@tcp(127.0.0.1:3306)/testdb?charset=utf8mb4"    engine, err := xorm.NewEngine("mysql", dsn)    if err != nil {        panic(err)    }    engine.Sync2(&User{})    return engine}func initDbGorp() *gorp.DbMap {    dsn := "root:password@tcp(127.0.0.1:3306)/testdb?charset=utf8mb4"    db, err := sql.Open("mysql", dsn)    if err != nil {        panic(err)    }    dbmap := &gorp.DbMap{Db: db, Dialect: gorp.MySQLDialect{}}    dbmap.AddTableWithName(User{}, "users").SetKeys(true, "ID")    dbmap.CreateTablesIfNotExists()    return dbmap}func BenchmarkInsertGorm(b *testing.B) {    db := initDbGorm()    defer db.Close()    b.ResetTimer()    for i := 0; i < b.N; i++ {        db.Create(&User{Name: "Tom", Age: 18})    }}func BenchmarkInsertXorm(b *testing.B) {    db := initDbXorm()    defer db.Close()    b.ResetTimer()    for i := 0; i < b.N; i++ {        db.Insert(&User{Name: "Tom", Age: 18})    }}func BenchmarkInsertGorp(b *testing.B) {    db := initDbGorp()    defer db.Db.Close()    b.ResetTimer()    for i := 0; i < b.N; i++ {        db.Insert(&User{Name: "Tom", Age: 18})    }}func BenchmarkSelectGorm(b *testing.B) {    db := initDbGorm()    defer db.Close()    db.Create(&User{Name: "Tom", Age: 18})    b.ResetTimer()    for i := 0; i < b.N; i++ {        var user User        db.First(&user, "name = ?", "Tom")    }}func BenchmarkSelectXorm(b *testing.B) {    db := initDbXorm()    defer db.Close()    db.Insert(&User{Name: "Tom", Age: 18})    b.ResetTimer()    for i := 0; i < b.N; i++ {        var user User        db.Where("name = ?", "Tom").Get(&user)    }}func BenchmarkSelectGorp(b *testing.B) {    db := initDbGorp()    defer db.Db.Close()    db.Insert(&User{Name: "Tom", Age: 18})    b.ResetTimer()    for i := 0; i < b.N; i++ {        var user User        err := db.SelectOne(&user, "SELECT * FROM users WHERE name = ?", "Tom")        if err != nil {            panic(err)        }    }}func BenchmarkUpdateGorm(b *testing.B) {    db := initDbGorm()    defer db.Close()    db.Create(&User{Name: "Tom", Age: 18})    b.ResetTimer()    for i := 0; i < b.N; i++ {        db.Model(&User{}).Where("name = ?", "Tom").Update("age", 19)    }}func BenchmarkUpdateXorm(b *testing.B) {    db := initDbXorm()    defer db.Close()    db.Insert(&User{Name: "Tom", Age: 18})    b.ResetTimer()    for i := 0; i < b.N; i++ {        db.Where("name = ?", "Tom").Update(&User{Age: 19})    }}func BenchmarkUpdateGorp(b *testing.B) {    db := initDbGorp()    defer db.Db.Close()    db.Insert(&User{Name: "Tom", Age: 18})    b.ResetTimer()    for i := 0; i < b.N; i++ {        _, err := db.Exec("UPDATE users SET age = ? WHERE name = ?", 19, "Tom")        if err != nil {            panic(err)        }    }}func BenchmarkDeleteGorm(b *testing.B) {    db := initDbGorm()    defer db.Close()    db.Create(&User{Name: "Tom", Age: 18})    b.ResetTimer()    for i := 0; i < b.N; i++ {        db.Where("name = ?", "Tom").Delete(&User{})    }}func BenchmarkDeleteXorm(b *testing.B) {    db := initDbXorm()    defer db.Close()    db.Insert(&User{Name: "Tom", Age: 18})    b.ResetTimer()    for i := 0; i < b.N; i++ {        db.Where("name = ?", "Tom").Delete(&User{})    }}func BenchmarkDeleteGorp(b *testing.B) {    db := initDbGorp()    defer db.Db.Close()    db.Insert(&User{Name: "Tom", Age: 18})    b.ResetTimer()    for i := 0; i < b.N; i++ {        _, err := db.Exec("DELETE FROM users WHERE name = ?", "Tom")        if err != nil {            panic(err)        }    }}

我们在本地MySQL数据库上运行测试程序,测试结果如下:

| ORM框架 | 插入性能(ops/s) | 查询性能(ops/s) | 更新性能(ops/s) | 删除性能(ops/s) |

|--------|-------------------|-------------------|-------------------|-------------------|

| GORM | 7105 | 14325 | 11016 | 10507 |

| XORM | 10988 | 23717 | 22716 | 22716 |

| Gorp | 10001 | 16908 | 16011 | 16011 |

从测试结果可以看出,XORM的性能表现最好,在插入、查询、更新和删除操作中,都比其他两个ORM框架快。GORM

以上就是IT培训机构千锋教育提供的相关内容,如果您有web前端培训鸿蒙开发培训python培训linux培训,java培训,UI设计培训等需求,欢迎随时联系千锋教育。

相关文章

如何使用Golang实现分布式锁完整教程

如何使用Golang实现分布式锁完整教程

2023-12-27
Golang开发应用程序的10种最佳实践

Golang开发应用程序的10种最佳实践

2023-12-27
Golang实现高性能网络代理的最佳实践

Golang实现高性能网络代理的最佳实践

2023-12-27
Golang并发编程使用互斥锁的最佳实践

Golang并发编程使用互斥锁的最佳实践

2023-12-27

最新文章

网络安全现在的就业薪资怎么样

网络安全现在的就业薪资怎么样

2023-12-25
学习网络安全编程好就业吗

学习网络安全编程好就业吗

2023-12-25
网络安全编程就业方向如何

网络安全编程就业方向如何

2023-12-25
网络安全培训就业方向有哪些

网络安全培训就业方向有哪些

2023-12-25
在线咨询 免费试学 教程领取