Golang中的ORM框架评测及性能分析
创新互联公司专注于企业全网整合营销推广、网站重做改版、清江浦网站定制设计、自适应品牌网站建设、HTML5建站、成都商城网站开发、集团公司官网建设、成都外贸网站建设、高端网站制作、响应式网页设计等建站业务,价格优惠性价比高,为清江浦等各大城市提供网站开发制作服务。
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. XORMXORM是另一个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. GORPGORP是另一个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
我们在本地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< 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) } }}新闻名称:Golang中的ORM框架评测及性能分析
分享网址:http://lswzjz.com/article/dgppsch.html