对象关系映射(英语:(Object Relational Mapping,简称ORM,或O/RM,或O/R mapping),是一种程序技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换 。从效果上说,它其实是创建了一个可在编程语言里使用的--“虚拟对象数据库”。
beego 中自带的 orm,
各主流的golang orm介绍
golang可以通过原始的 执行数据库的操作,也可以采用ORM执行。
当前较为主流/活跃的orm有gorm、xorm、gorose等
1、xorm
-
文档
支持的数据库有:mysql、mymysql、postgres、tidb、sqlite、mssql、oracle;事务性支持
链式api
has, err := engine.Where("name = ?", name).Desc("id").Get(&user)
err := engine.Where(builder.NotIn("a", 1, 2).And(builder.In("b", "c", "d", "e"))).Find(&users)
支持原生sql操作;查询缓存;可根据数据库反转生成代码;级联加载;提供sql语句日志输出;支持批量查询处理
// 每次处理100条
// SELECT * FROM user Limit 0, 100
// SELECT * FROM user Limit 101, 100
err := engine.BufferSize(100).Iterate(&User{Name:name}, func(idx int, bean interface{}) error {
user := bean.(*User)
return nil
})
自动化的读写分离/主从式
dataSourceNameSlice := []string{masterDataSourceName, slave1DataSourceName, slave2DataSourceName}
engineGroup, err := xorm.NewEngineGroup(driverName, dataSourceNameSlice)
go get github.com/go-xorm/xorm
代码示例:
package main
import (
"fmt"
_ "github.com/go-sql-driver/mysql"
"github.com/go-xorm/xorm"
"github.com/micro/go-log"
)
//定义结构体(xorm支持双向映射)
type User struct {
UserId int64 `xorm:"pk autoincr"` //指定主键并自增
Name string `xorm:"unique"` //唯一的
Age float64
Time int64 `xorm:"updated"` //修改后自动更新时间
CreateTime int64 `xorm:"created"` //创建时间
//Version int `xorm:"version"` //乐观锁
}
//定义orm引擎
var x *xorm.Engine
func init() {
var err error
x, err = xorm.NewEngine("mysql", "root:[email protected](127.0.0.1:3306)/xorm?charset=utf8") //xorm代表数据库名称
if err != nil {
log.Fatal("数据库连接失败:", err)
}
//创建的表名称为User
if err := x.Sync(new(User)); err != nil {
log.Fatal("数据表同步失败:", err)
//log.Fatal()
}
}
func main() {
//执行对应的操作
}
//添加数据
func Insert(name string, age float64) (int64, bool) {
user := new(User)
user.Name = name
user.Age = age
affected, err := x.Insert(user) //affected:受影响的行
if err != nil {
return affected, false
}
return affected, true
}
//删除数据
func Del(id int64) {
user := new(User)
x.Id(id).Delete(user)
}
//修改数据
func update(id int64, user *User) bool {
affected, err := x.Id(id).Update(user)
if err != nil {
log.Fatal("修改数据发生错误:", err)
}
if affected == 0 {
return false // 未发生影响,即没有修改成功
}
return true
}
func ExecDb() {
sql:="delete from user where user_id=?"
result, err := x.Exec(sql,"6") //原生sql操作 :可以用作 增 删 改(对数据有响应的操作)
if err != nil {
log.Fatal("执行数据库操作发生错误:", err)
}
fmt.Println(result.LastInsertId())
affected, _ := result.RowsAffected()
fmt.Println("受影响的行数是:",affected)
}
//查询方式1
func query01(id int64) *User {
user := &User{UserId: id}
is, err := x.Get(user)
if err != nil {
log.Fatal("查询数据发生错误:", err)
}
if !is {
log.Fatal("查询的数据不存在")
}
return user
}
//查询方式02
func query02() {
sql:="select * from user where name=?"
resultsSlice, err := x.Query(sql,"jz333") //原生sql操作 :查询操作
if err!=nil{
log.Log("查询失败")
}
fmt.Println("开始查询。。。。")
for _,value:=range resultsSlice{
fmt.Println(string(value["user_id"]),string(value["name"]),string(value["age"]))
}
}
2、gorm
hook机制(Before/After Create/Save/Update/Delete/Find);对象关系Has One, Has Many, Belongs To, Many To Many, Polymorphism;热加载;支持原生sql操作;事务性
链式api
tx := db.Where("name = ?", "jinzhu").Where("age = ?", 20).Find(&users)
支持的数据库有:mysql、postgre、sqlite、sqlserver
查询操作
// Get first record, order by primary key
db.First(&user)
//// SELECT * FROM users ORDER BY id LIMIT 1;
// plain sql
db.Where("name = ? AND age >= ?", "jinzhu", "22").Find(&users)
// map
db.Where(&User{Name: "jinzhu", Age: 20}).First(&user)
//// SELECT * FROM users WHERE name = "jinzhu" AND age = 20 LIMIT 1;
代码示例:
package main
import (
"fmt"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
"github.com/micro/go-log"
"time"
)
//gorm 用 tag 的方式来标识 mysql 里面的约束
type Like struct {
ID int `gorm:"primary_key"`
Ip string `gorm:"type:varchar(20);not null;index:ip_idx"`
Ua string `gorm:"type:varchar(256);not null;"`
Title string `gorm:"type:varchar(128);not null;index:title_idx"`
CreatedAt time.Time
}
var db *gorm.DB
func init() {
var err error
db, err = gorm.Open("mysql", "root:[email protected](127.0.0.1:3306)/testdb?charset=utf8")
if err != nil {
log.Fatal("数据库连接出现了问题:", err)
return
}
}
//特别注意:结构体名称为:Like,创建的表的名称为:likes
func createTable() {
if !db.HasTable(&Like{}) {
err := db.CreateTable(&Like{}).Error
if err != nil {
fmt.Print("创建表失败", err)
return
}
fmt.Println("添加表成功")
return
}
fmt.Println("数据表已经存在")
}
func insert() {
like := &Like{
Ip: "ip",
Ua: "ua",
Title: "title",
CreatedAt: time.Now(),
}
err := db.Create(like).Error
if err != nil {
fmt.Println("添加数据失败:", err)
return
}
fmt.Println("添加数据成功")
}
func del() {
result := db.Where(&Like{ID: 2}).Delete(Like{})
fmt.Println("受影响的行:",result.RowsAffected)
}
func update() {
db.Model(&Like{}).Update("Ip","127.0.0.1") //修改方式1
result := db.Model(&Like{ID:2}).Update(Like{Ua: "admin2", Title: "gorm2 application"})//条件更新 Like{ID:3}
fmt.Println("受影响的行:",result.RowsAffected)
}
func query() {
likes:=make([]Like,0) //会自动扩容
db.Where("ip=?","ip").Find(&likes) //查询到的有可能为多行,所以采用结构体切片
for _,like:=range likes{
fmt.Println("查询到的数据是:",like.ID,like.Title)
}
}
func DbTransaction() error {
tx:=db.Begin()//开启事务
tempDb:=tx.Create(&Like{Title:"gorm的事务:"})
if err:=tempDb.Error;err!=nil{
tx.Rollback()//出现错误,回滚
return err
}
tx.Commit()//提交
return nil
}
//支持原生的sql:增、删、改
func ExecSql(id int) {
sql:="delete from likes where id=?"
tempDb:=db.Exec(sql,id)
fmt.Println(tempDb.RowsAffected)
}
//支持原生的sql:查询
//支持原生的sql:查询
func ExecQuery(id int) {
sql:="select * from likes where id=?"
like:=&Like{}
db.Raw(sql,id).Find(like)
fmt.Println(like.Title,like.Ua)
}
func main() {
//createTable()
insert()
// update()
query()
//del()
}
3、gorose
gorose相关内容再次就不用示例演示了。具体内容可以参考一下资料。