前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >一文入门gorm和xorm的基本操作(CRUD)

一文入门gorm和xorm的基本操作(CRUD)

作者头像
用户6297767
发布2023-11-21 08:40:40
2930
发布2023-11-21 08:40:40
举报

gorm的CRUD操作

安装

代码语言:javascript
复制
go get -u gorm.io/gorm
go get -u gorm.io/driver/mysql

第一个是gorm的库,第二个是mysql的连接驱动

连接数据库

GORM 官方支持的数据库类型有: MySQL, PostgreSQL, SQlite, SQL Server

创建DB实例

代码语言:javascript
复制
//构建连接字符串
/*注意:想要正确的处理 time.Time ,您需要带上 parseTime 参数, (更多参数)要支持完整的 UTF-8 编码,您需要将 charset=utf8 更改为 charset=utf8mb4 查看 此文章 获取详情*/
dsn := "root:password1234@tcp(127.0.0.1:3306)/gorm?charset=utf8mb4&parseTime=True&loc=Local"
db, _ = gorm.Open(mysql.Open(dsn), &gorm.Config{})

结构体映射数据库表

创建结构体

代码语言:javascript
复制
package main

import (
	"gorm.io/gorm"
)

type User struct {
	gorm.Model
	Name string
	Age  uint8
}

使用db.AutoMigrate(User{})方法从结构体生成数据库表

连接设置

代码语言:javascript
复制
sqlDB, _ := db.DB()

// SetMaxIdleConns 设置空闲连接池中连接的最大数量
sqlDB.SetMaxIdleConns(10)

// SetMaxOpenConns 设置打开数据库连接的最大数量。
sqlDB.SetMaxOpenConns(100)

// SetConnMaxLifetime 设置了连接可复用的最大时间。
sqlDB.SetConnMaxLifetime(time.Hour)

插入数据

代码语言:javascript
复制
//添加数据
func add() {
    //插入单条数据
    user := User{Model: gorm.Model{}, Name: "wmq", Age: 17}
    result := db.Create(&user)
    fmt.Println(user.ID, result.RowsAffected)
    
    //插入指定字段
    result = db.Select("Name", "Age").Create(&User{Name: "前端少年", Age: 22})
    fmt.Println(user, result.RowsAffected)
    
    //切片批量插入
    var users = []User{{Name: "w1"}, {Name: "w2"}, {Name: "w3"}}
    result = db.Create(&users)
    fmt.Println("users", result.RowsAffected, users)
    
    //map批量插入
    db.Model(&User{}).Create(map[string]interface{}{
         "Name": "jinzhu", "Age": 18,
    })
    
    // 根据 `[]map[string]interface{}{}` 批量插入
    db.Model(&User{}).Create([]map[string]interface{}{
        {"Name": "", "Age": nil},
        {"Name": "", "Age": nil},
        {},
    })
}

创建时的Hook操作

// 开始事务 BeforeSave BeforeCreate // 关联前的 save // 插入记录至 db // 关联后的 save AfterCreate AfterSave // 提交或回滚事务

更新数据

  • 使用Save方法 会保存所有的字段,即使字段是零值
代码语言:javascript
复制
//修改
func update() {
	//更新单列
	var user User
	user.Name = "迁客骚人"
	user.Age = 100
	db.Save(&user)
	fmt.Println(user.Name)

	// 条件更新
	db.Model(&User{}).Where("active = ?", true).Update("name", "hello")
	// UPDATE users SET name='hello', updated_at='2013-11-17 21:34:10' WHERE active=true;

	// User 的 ID 是 `111`
	db.Model(&user).Update("name", "hello")
	// UPDATE users SET name='hello', updated_at='2013-11-17 21:34:10' WHERE id=111;

	// 根据条件和 model 的值进行更新
	db.Model(&user).Where("active = ?", true).Update("name", "hello")
	// UPDATE users SET name='hello', updated_at='2013-11-17 21:34:10' WHERE id=111 AND active=true;

	// 根据 `struct` 更新属性,只会更新非零值的字段
	db.Model(&user).Updates(User{Name: "hello", Age: 18})
	// UPDATE users SET name='hello', age=18, updated_at = '2013-11-17 21:34:10' WHERE id = 111;

	// 根据 `map` 更新属性
	db.Model(&user).Updates(map[string]interface{}{"Name": "hello", "Age": 18})
	// UPDATE users SET name='hello', age=18, actived=false, updated_at='2013-11-17 21:34:10' WHERE id=111;

	//批量更新
	// 根据 struct 更新
	db.Model(User{}).Where("role = ?", "admin").Updates(User{Name: "wmq", Age: 18})
	// UPDATE users SET name='hello', age=18 WHERE role = 'admin;

	// 根据 map 更新
	db.Table("users").Where("id IN ?", []int{10, 11}).Updates(map[string]interface{}{"name": "hello", "age": 18})
	// UPDATE users SET name='hello', age=18 WHERE id IN (10, 11);
}

xorm的CRUD操作

xorm的特性

  • 支持Struct和数据库表之间的灵活映射,并支持自动同步
  • 事务支持
  • 同时支持原始SQL语句和ORM操作的混合执行
  • 使用连写来简化调用
  • 支持使用Id, In, Where, Limit, Join, Having, Table, SQL, Cols等函数和结构体等方式作为条件
  • 支持级联加载Struct
  • Schema支持(仅Postgres)
  • 支持缓存
  • 支持根据数据库自动生成xorm的结构体
  • 支持记录版本(即乐观锁)
  • 内置SQL Builder支持
  • 通过EngineGroup支持读写分离和负载均衡

安装

代码语言:javascript
复制
go get xorm.io/xorm

创建 Engine 引擎 创建结构体同步数据库表

代码语言:javascript
复制
// CoonXormMysql 连接数据库
package main

import (
"fmt"
_ "gorm.io/driver/mysql"
"time"
"xorm.io/xorm"
)

//数据库连接基本信息
var (
   userName  string = "root"
   password  string = "12138"
   ipAddress string = "127.0.0.1"
   port      int    = 3306
   dbName    string = "xorm_db"
   charset   string = "utf8mb4"
)

type User struct {
   Id      int64
   Name    string
   Age     int
   Passwd  string    `xorm:"varchar(200)"`
   Created time.Time `xorm:"created"`
   Updated time.Time `xorm:"updated"`
}

var engine *xorm.Engine

// CoonXormMysql 连接数据库
func CoonXormMysql() {
   //构建数据库连接信息
   dataSourceName := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=%s", userName, password, ipAddress, port, dbName, charset)
   //创建引擎
   engine, _ = xorm.NewEngine("mysql", dataSourceName)

   err := engine.Sync2(new(User))
   if err != nil {
      fmt.Println("同步失败")
   }
}

#CRUD操作 使用Engine的insert,query,update,delete等方法

添加

  • 插入一条数据,此时可以用Insert或者InsertOne
代码语言:javascript
复制
user := User{Id: 1, Name: "wmq1", Age: 17, Passwd: "1234567"}
n, _ := engine.Insert(user)
  • 插入数据使用Insert方法,Insert方法的参数可以是一个或多个Struct的指针,一个或多个Struct的Slice的指针。 如果传入的是Slice并且当数据库支持批量插入时,Insert会使用批量插入的方式进行插入。
代码语言:javascript
复制
//user切片
var users []User
users = append(users, User{Id: 2, Name: "wmq2", Age: 11, Passwd: "12344567"})
users = append(users, User{Id: 3, Name: "wmq3", Age: 10, Passwd: "12344567"})
n, _ = engine.Insert(users)

这里虽然支持同时插入,但这些插入并没有事务关系。因此有可能在中间插入出错后,后面的插入将不会继续。此时前面的插入已经成功,如果需要回滚,请开启事务。 批量插入会自动生成Insert into table values (),(),()的语句,因此各个数据库对SQL语句有长度限制,因此这样的语句有一个最大的记录数,根据经验测算在150条左右。大于150条后,生成的sql语句将太长可能导致执行失败。因此在插入大量数据时,目前需要自行分割成每150条插入一次。

查询

代码语言:javascript
复制
//查询
func query() {
   //使用sql语句查询
   results, _ := engine.Query("select * from user")
   fmt.Println(results)
   results2, _ := engine.QueryString("select * from user")
   fmt.Println(results2)
   results3, _ := engine.QueryInterface("select * from user")
   fmt.Println(results3)

   //Get 只能查询单条数据
   user := User{}
   engine.Get(&user)
   fmt.Println("查询单条数据", user)

   //指定条件查询
   user1 := User{Name: "wmq1"}
   engine.Where("name=?", user1.Name).Asc("id").Get(&user1)
   fmt.Println("指定条件查询", user1)

   //获取指定字段的值
   var name string
   engine.Table(&user).Where("id = 3").Cols("name").Get(&name)
   fmt.Println("获取指定字段的值", name)

   //查询多条/所有记录 find
   var users []User //定义切片
   engine.Find(&users)
   fmt.Println("查询多条/所有记录", users)

   //Count 获取记录条数
   user2 := User{Passwd: "12344567"}
   count, _ := engine.Count(&user2)
   fmt.Println("获取记录条数", count)

   //Iterate 和 Rows根据条件遍历数据
   engine.Iterate(&User{Passwd: "12344567"}, func(idx int, bean interface{}) error {
      user := bean.(*User)
      fmt.Println("Iterate 和 Rows根据条件遍历数据", user)
      return nil
   })
   rows, _ := engine.Rows(&User{Passwd: "12344567"})
   defer rows.Close()
   userBean := new(User)
   for rows.Next() {
      rows.Scan(userBean)
      fmt.Println(userBean)
   }
}

修改

代码语言:javascript
复制
//修改
func update() {
   //更新
   user := User{Name: "前端少年汪"}
   n, _ := engine.ID(1).Update(&user)
   fmt.Println(n)
}

删除

代码语言:javascript
复制
//删除
func del() {
   //删除
   var user1 User
   n1, _ := engine.ID(3).Delete(&user1)
   fmt.Println(n1)
   
}

执行一个sql语句

代码语言:javascript
复制
engine.Exec("update user set age = ? where id = ?", 10, 1001)

完整代码

代码语言:javascript
复制
package main

import (
   "fmt"
   _ "gorm.io/driver/mysql"
   "time"
   "xorm.io/xorm"
)

//数据库连接基本信息
var (
   userName  string = "root"
   password  string = "12138"
   ipAddress string = "127.0.0.1"
   port      int    = 3306
   dbName    string = "xorm_db"
   charset   string = "utf8mb4"
)

type User struct {
   Id      int64
   Name    string
   Age     int
   Passwd  string    `xorm:"varchar(200)"`
   Created time.Time `xorm:"created"`
   Updated time.Time `xorm:"updated"`
}

var engine *xorm.Engine

func main() {
   fmt.Println("xorm 学习")

   CoonXormMysql()
   var input int

   var flag bool = true
   for flag {
      fmt.Println("1.添加")
      fmt.Println("2.查询")
      fmt.Println("3.更新")
      fmt.Println("4.删除")
      fmt.Println("5.退出")
      fmt.Scan(&input)
      if input == 1 {
         add()
      } else if input == 2 {
         query()
      } else if input == 3 {
         update()
      } else if input == 4 {
         del()
      } else if input == 5 {
         flag = false
      }
   }

}

// CoonXormMysql 连接数据库
func CoonXormMysql() {
   //构建数据库连接信息
   dataSourceName := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=%s", userName, password, ipAddress, port, dbName, charset)
   //创建引擎
   engine, _ = xorm.NewEngine("mysql", dataSourceName)

   err := engine.Sync2(new(User))
   if err != nil {
      fmt.Println("同步失败")
   }
}

//添加
func add() {
   user := User{Id: 1, Name: "wmq1", Age: 17, Passwd: "1234567"}
   n, _ := engine.Insert(user)
   fmt.Println(n)
   if n >= 1 {
      fmt.Println("插入成功")
   }

   //user切片
   var users []User
   users = append(users, User{Id: 2, Name: "wmq2", Age: 11, Passwd: "12344567"})
   users = append(users, User{Id: 3, Name: "wmq3", Age: 10, Passwd: "12344567"})
   n, _ = engine.Insert(users)

}

//查询
func query() {
   //使用sql语句查询
   results, _ := engine.Query("select * from user")
   fmt.Println(results)
   results2, _ := engine.QueryString("select * from user")
   fmt.Println(results2)
   results3, _ := engine.QueryInterface("select * from user")
   fmt.Println(results3)

   //Get 只能查询单条数据
   user := User{}
   engine.Get(&user)
   fmt.Println("查询单条数据", user)

   //指定条件查询
   user1 := User{Name: "wmq1"}
   engine.Where("name=?", user1.Name).Asc("id").Get(&user1)
   fmt.Println("指定条件查询", user1)

   //获取指定字段的值
   var name string
   engine.Table(&user).Where("id = 3").Cols("name").Get(&name)
   fmt.Println("获取指定字段的值", name)

   //查询多条/所有记录 find
   var users []User //定义切片
   engine.Find(&users)
   fmt.Println("查询多条/所有记录", users)

   //Count 获取记录条数
   user2 := User{Passwd: "12344567"}
   count, _ := engine.Count(&user2)
   fmt.Println("获取记录条数", count)

   //Iterate 和 Rows根据条件遍历数据
   engine.Iterate(&User{Passwd: "12344567"}, func(idx int, bean interface{}) error {
      user := bean.(*User)
      fmt.Println("Iterate 和 Rows根据条件遍历数据", user)
      return nil
   })
   rows, _ := engine.Rows(&User{Passwd: "12344567"})
   defer rows.Close()
   userBean := new(User)
   for rows.Next() {
      rows.Scan(userBean)
      fmt.Println(userBean)
   }
}

//修改
func update() {
   //更新
   user := User{Name: "前端少年汪"}
   n, _ := engine.ID(1).Update(&user)
   fmt.Println(n)
}

//删除
func del() {
   //删除
   var user1 User
   n1, _ := engine.ID(3).Delete(&user1)
   fmt.Println(n1)
}

以上就是go使用gorm或者xorm的一个最简单的crud的基本操作了,当然gorm和xorm的功能远不止如此,更多的特性和功能可以在开发过程中查阅其官网即可

gorm 和 xorm 的区别

gorm 和 xorm 都是 Go 语言中常用的 ORM(对象关系映射)框架。下面是它们的主要区别:

  1. 设计哲学不同:gorm 设计思维更加严谨、规范化,更加注重符合 SQL 标准;xorm 设计思维更加灵活,允许用户通过指定标签轻松映射 struct,提供了更多针对 NoSQL 数据库的支持。
  2. 性能表现不同:根据各自的 benchmark 结果,xorm 的性能通常比 gorm 更高,并且 xorm 对于连接池的处理也更优秀。
  3. 使用方式不同:gorm 支持链式调用和原生 SQL,而 xorm 和 gorm 都支持链式调用和模板语言。
  4. 社区支持度不同:由于 gorm 的设计更加严谨,因此它的稳定性和一致性更高,得到了更加广泛的社区支持和认可。而 xorm 在社区中的影响力不如 gorm,但是在某些特定领域(例如非关系型数据库)中的支持度相对较好。

总体来说,gorm 和 xorm 的目标群体有所不同,gorm 更适合那些需要严格符合 SQL 标准、更加稳定的场景,而 xorm 更适用于需要灵活性和可扩展性的场景。当然,选择哪一个 ORM 还需要根据具体项目的需求和开发者的个人喜好做出决定。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2023-11-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • gorm的CRUD操作
  • 安装
  • 连接数据库
  • 创建DB实例
  • 结构体映射数据库表
  • 连接设置
  • 插入数据
    • 创建时的Hook操作
    • 更新数据
    • xorm的CRUD操作
    • xorm的特性
    • 安装
    • 创建 Engine 引擎 创建结构体同步数据库表
      • 添加
        • 查询
          • 修改
            • 删除
              • 执行一个sql语句
              • 完整代码
              • gorm 和 xorm 的区别
              相关产品与服务
              数据库
              云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档