创作不易感谢支持。
一条主写Go和PHP的小菜鸟。平常有时间喜欢自己写点东西,如有不对的地方,欢迎大佬指点。 个人博客:太阳上的雨天 地址:http://blog.caixiaoxin.cn 善于分享,希望有助他人. 非常感谢各位大佬的关注和支持

XORM

xorm 一个简单强大的Go语言ORM库。通过它让操作数据库变得更加简单。

[XORM操作指南]

XORM关系映射,只是Go操作数据库的其中之一。比如还有GORM。至于两者的区别,一搜一大堆,不再介绍。

这里只介绍一下XORM的基本使用。

导入包

go get -u github.com/go-sql-driver/mysql
go get -u github.com/xormplus/xorm

定义结构体

名称映射规则

  • 指责

    结构体名称 ----- 表名

    结构体字段 ------ 表字段

结构体字段属性 ----- 对象的表子段属性

go type’s kind value method xorm type
implemented Conversion Conversion.ToDB / Conversion.FromDB Text
int, int8, int16, int32, uint, uint8, uint16, uint32 Int
int64, uint64 BigInt
float32 Float
float64 Double
complex64, complex128 json.Marshal / json.UnMarshal Varchar(64)
[]uint8 Blob
array, slice, map except []uint8 json.Marshal / json.UnMarshal Text
string Varchar(255)
time.Time DateTime
cascade struct primary key field value BigInt
struct json.Marshal / json.UnMarshal Text
Others Text
bool 1 or 0 Bool

前缀映射、后缀映射、缓存映射

通过 core.NewPrefixMapper(core.SnakeMapper{}, “prefix”) 可以创建一个在SnakeMapper的基础上在命名中添加统一的前缀

例如,如果希望所有的表名都在结构体自动命名的基础上加一个前缀而字段名不加前缀,则可以在engine创建完成后执行以下语句:

tbMapper := core.NewPrefixMapper(core.SnakeMapper{}, "pre_")
engine.SetTableMapper(tbMapper)

执行之后,结构体 type User struct 默认对应的表名就变成了 pre_user 了,而之前默认的是 user

  • 通过 core.NewSufffixMapper(core.SnakeMapper{}, “suffix”) 可以创建一个在SnakeMapper的基础上在命名中添加统一的后缀
  • 通过 core.NewCacheMapper(core.SnakeMapper{}) 可以创建一个组合了其它的映射规则,起到在内存中缓存曾经映射过的命名映射

创建xorm引擎

在xorm里面,可以同时存在多个Orm引擎,一个Orm引擎称为Engine,一个Engine一般只对应一个数据库

db/db.go

package dbimport ("fmt"_ "github.com/go-sql-driver/mysql""github.com/xormplus/xorm"
)var engine *xorm.Enginefunc Init() *xorm.Engine {engine, err := xorm.NewEngine("mysql", "root:root@/test?charset=utf8mb4")if err != nil {panic(err)}err = engine.Ping()if err != nil {fmt.Printf("connect ping failed: %v", err)}engine.ShowSQL(true)return engine
}

写入数据库

先创建两张表,表比较简单,只是做演示使用

CREATE TABLE `users` (`id` int(11) NOT NULL AUTO_INCREMENT,`username` varchar(100) NOT NULL,`password` varchar(100) NOT NULL,`email` varchar(100) NOT NULL,`created_at` timestamp NULL DEFAULT NULL,`updated_at` timestamp NULL DEFAULT NULL,`deleted_at` timestamp NULL DEFAULT NULL,PRIMARY KEY (`id`),UNIQUE KEY `username` (`username`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4;CREATE TABLE `address` (`id` int(11) unsigned NOT NULL AUTO_INCREMENT,`addr` varchar(100) DEFAULT NULL,`created_at` timestamp NULL DEFAULT NULL,`updated_at` timestamp NULL DEFAULT NULL,`deleted_at` timestamp NULL DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

ORM方式写入

同一张表的操作

  • 写入一条数据

    type Users struct {Username  string        `xorm:"username"`Password  string        `xorm:"password""`Email     string           `xorm:"email"`CreatedAt time.Time   `xorm:"created"`UpdatedAt time.Time  `xorm:"updated"`DeletedAt time.Time `  xorm:"deleted"`
    }func main() {engine := db.Init()u := &Users{}u.Username = "test"u.Password = "123456"u.Email = "test@sina.com"affected, err := engine.Insert(u)if err != nil {log.Fatal(fmt.Printf("insert into failed, err: %v", err))}fmt.Println(affected)
    }
  • 批量写入

  1. 使用slice

    func main() {engine := db.Init()u := make([]Users, 2)u[0].Username = "test2"u[0].Password = "123456"u[0].Email = "test2@sina.com"u[1].Username = "test3"u[1].Password = "123456"u[1].Email = "test3@sina.com"affected, err := engine.Insert(u)if err != nil {log.Fatal(fmt.Printf("insert into failed, err: %v", err))}fmt.Println(affected)
    }
    
  2. 使用slice指针批量写入

    func main() {engine := db.Init()u := make([]*Users, 2)u[0] = &Users{}u[0].Username = "test4"u[0].Password = "123456"u[0].Email = "test4@sina.com"u[1] = &Users{}u[1].Username = "test5"u[1].Password = "123456"u[1].Email = "test5@sina.com"affected, err := engine.Insert(u)if err != nil {log.Fatal(fmt.Printf("insert into failed, err: %v", err))}fmt.Println(affected)
    }
    

    多张表的操作

    • 写入一条记录

      type Users struct {Username  string    `xorm:"username"`Password  string    `xorm:"password""`Email     string    `xorm:"email"`CreatedAt time.Time `xorm:"created"`UpdatedAt time.Time `xorm:"updated"`DeletedAt time.Time `xorm:"deleted"`
      }type Address struct {Addr      string    `xorm:"Addr"`CreatedAt time.Time `xorm:"created"`UpdatedAt time.Time `xorm:"updated"`DeletedAt time.Time `xorm:"deleted"`
      }func main() {engine := db.Init()u := &Users{}u.Username = "test4"u.Password = "123456"u.Email = "test4@sina.com"a := &Address{}a.Addr = "杭州"affected, err := engine.Insert(u, a)if err != nil {log.Fatal(fmt.Printf("insert into failed, err: %v", err))}fmt.Println(affected)
      }
      
    • 批量写入

      func main() {engine := db.Init()u := make([]*Users, 2)u[0] = &Users{}u[0].Username = "test6"u[0].Password = "123456"u[0].Email = "test4@sina.com"u[1] = &Users{}u[1].Username = "test7"u[1].Password = "123456"u[1].Email = "test5@sina.com"a := make([]*Address, 2)a[0] = &Address{}a[0].Addr = "杭州"a[1] = &Address{}a[1].Addr = "上海"affected, err := engine.Insert(u, a)if err != nil {log.Fatal(fmt.Printf("insert into failed, err: %v", err))}fmt.Println(affected)
      }
      

      Note: 这里的多表写入并没有使用事务。如果部分成功,部分失败不支持回滚

执行原生sql写入数据

func main() {engine := db.Init()sql := "INSERT INTO users(username, password, email) values (?, ?, ?)"res, err := engine.Exec(sql, "original", "123", "123@sina.com")if err != nil {log.Fatal(fmt.Printf("insert into failed, err: %v", err))}fmt.Println(res)
}

Note: 执行原生sql写入数据,created_at、updated_at时间的值不写的则为空。

原生sql写入还有其余三种方式,这里不再赘述

删除数据

ORM方式删除 - 软删除

在Delete()时,deleted标记的字段将会被自动更新为当前时间而不是去删除该条记录

func main() {engine := db.Init()var u = &Users{}u.Username = "test1"affected, err := engine.Delete(u)if err != nil {log.Fatal(fmt.Printf("deleter into failed, err: %v", err))}fmt.Println(affected)
}

执行原生sql删除 - 物理删除

func main() {engine := db.Init()sql := "DELETE FROM users where id = ?"affected, err := engine.Exec(sql, 1)if err != nil {log.Fatal(fmt.Printf("deleter into failed, err: %v", err))}fmt.Println(affected)
}

Note: 也可以使用原生sql update更新deleted_at时间为当前时间戳,实现软删除。

更新数据

  • update方式

    更新数据使用engine.Update方法,update的参数可以是一个结构体指针或者一个Map[string]interface{}类型。

    1. 当传入的为结构体指针时,只有非空和0的field才会被作为更新的字段。如果非要更新空字段,需要使用Cols方法显示指定更新的列
    2. 当传入的为Map类型时,key为数据库Column的名字,value为要更新的内容。且需要使用engine.Table方法指定表名
func main() {engine := db.Init()engine.ID(13).Update(&Users{Username: "test"})engine.ID(13).Cols("username", "email").Update(&Users{Username: "test2"}) // 会更新username和email两个子段,email为空// map类型affected, err := engine.Table(&Users{}).ID(13).Update(map[string]interface{}{"username": "update_original",})if err != nil {log.Fatal(fmt.Printf("update username failed, err: %v", err))}fmt.Println(affected)
}
  • 执行原生sql更新数据

    func main() {engine := db.Init()sql := "UPDATE users SET username = ?, updated_at = ? WHERE id = ?"res, err := engine.Exec(sql, "aaa", time.Now().Format("2006-01-02 15:04:05"), 13)if err != nil {log.Fatal(fmt.Printf("update username failed, err: %v", err))}fmt.Println(res)
    }
    

查询数据

ORM

  1. 查询一条数据 - GET方法

    func main() {engine := db.Init()// SELECT * FROM user LIMIT 1user1 := &Users{}has, _ := engine.ID(1).Get(user1)if has {fmt.Printf("user1:%v\n", user1)}// SELECT * FROM user WHERE name = ? ORDER BY id DESC LIMIT 1user2 := &Users{}has, _ = engine.Where("username = ?", "aaa").Desc("id").Get(user2)if has {fmt.Printf("user1:%v\n", user1)}
    }
  2. 查询多条数据 - Find 方法

Find()需要传入对象切片的指针或 map 的指针

func main() {engine := db.Init()slicUsers := make([]Users, 0)_ = engine.Find(&slicUsers)fmt.Println(slicUsers)mapUsers := make([]Users, 0)engine.Where("username = ?", "aaa").Find(&mapUsers)fmt.Println(mapUsers)
}
  1. Iterate 效果与Find方法一样,对了一个回调函数处理每条记录

    func main() {engine := db.Init()engine.Where("username = ?", "aaa").Iterate(new(Users), func(i int, bean interface{}) error {users := bean.(*Users)fmt.Println(users)return nil})
    }
    
  2. Count 统计满足条件的数量,参数为struct指针

    func main() {engine := db.Init()count, _ := engine.Where("length(username) > ?", 3).Count(&Users{})fmt.Println(count)
    }
    
  3. Rows方法 和 Iterate方法类似。

    func main() {engine := db.Init()u := &Users{}rows, _ := engine.Where("id > ?", 5).Rows(u)defer rows.Close()for rows.Next() {rows.Scan(u)fmt.Println(u)}
    }
    

原生sql查询

写sql语句,然后执行即可。和更新删除类似,不再赘述。

Go之XORM操作MySQL相关推荐

  1. mysql连接 xorm_golang 使用xorm操作mysql

    xorm 官方介绍:xorm是一个简单而强大的Go语言ORM库. 通过它可以使数据库操作非常简便.xorm的目标并不是让你完全不去学习SQL,我们认为SQL并不会为ORM所替代,但是ORM将可以解决绝 ...

  2. DOS命令行操作MySQL常用命令

    平时用可视化界面用惯了,如果紧急排查问题,没有安装可视化工具的话,只能通过命令来看了. 以备不时之需,我们要熟悉一下命令行操作MySQL. 打开DOS命令窗口:WIN + R 输入cmd,回车 然后输 ...

  3. c语言连接数据库例子,c语言操作mysql数据库小例子_互帮互助(C language MySQL database operation example _ mutual help).doc...

    这是精心收集的精品经典资料,值得下载保存阅读! c语言操作mysql数据库小例子_互帮互助(C language MySQL database operation example _ mutual h ...

  4. python3操作mysql教程_python3操作mysql教程

    一.下载\安装\配置 1. python3 当前最新版本是python3.2,下载地址是 http://www.python.org/ftp/python/3.2.3/python-3.2.3.msi ...

  5. linux mysql c语言编程,在Linux下通过C语言操作MySQL数据库

    2010年1月27日 晚 22:10 作者:longyun(http://www.linuxdiyf.com/mailto:mtd527@gmail.com) 续:小弟最近想学习数据库,并想开发一个简 ...

  6. python如何控制mysql_python如何操作mysql

    mysql 使用 启动服务 sudo systemctl start mysql pip3 install pymysql python 操作数据库: 定义类 import pymysql class ...

  7. c 获取mysql列数据_转 用C API 操作MySQL数据库

    用C API 操作MySQL数据库 参考MYSQL的帮助文档整理 这里归纳了C API可使用的函数,并在下一节详细介绍了它们.请参见25.2.3节,"C API函数描述". 函数 ...

  8. Python模块MySQLdb操作mysql出现2019错误:Can't initialize character set utf-8

    我使用python的MySQLdb模块实现了一个mysql client, 在测试时,出现了如下错误 Python模块MySQLdb操作mysql出现2019错误:Can't initialize c ...

  9. nodejs操作sqlserver数据_pyspark操作MySQL、SQLServer数据库进行数据处理操作

    欢迎访问本人的CSDN博客[Together_CZ],我是沂水寒城. https://yishuihancheng.blog.csdn.net 在大数据处理领域里面,Hadoop和spark可以说是最 ...

最新文章

  1. 研究表明:无人驾驶技术减少拥堵加快进程
  2. IOS设计模式的六大设计原则之开放-关闭原则(OCP,Open-Close Principle)
  3. hadoop使用lzo压缩文件笔记
  4. java实现 SSL双向认证
  5. 653. Two Sum IV - Input is a BST
  6. 正向代理与反向代理的理解
  7. Java NIO框架Mina、Netty、Grizzly介绍与对比(zz)
  8. 在Kibana上查看Apache日志
  9. SQL PASS西雅图之行——会议篇
  10. vue3结合element-plus实现标签手动标注效果
  11. 基于遗传算法的柔性流水车间调度设计与实现(论文+源码+答辩ppt)
  12. 学单片机有什么用?单片机自学网有哪些?
  13. smtplib 抄送邮件_Smtp发送及抄送邮件
  14. WinForm容器内控件批量效验是否允许为空?设置是否只读?设置是否可用等方法分享
  15. 新物联网!新电商平台!
  16. jquery ajax添加ul li,jQuery.ajax动态添加标签无法被获取到
  17. Mysql Json、JsonArray 指定属性查询
  18. 5G网络部署行业应用的关键使能技术
  19. NYOJ 79 导弹拦截
  20. 『2月特刊』伟大的朋友丨拿破仑(1)

热门文章

  1. Python 语音合成(pyttsx3)
  2. 不要通过第三方交易软件进行期货开户
  3. Excel函数——OFFSET函数将多列合并成一列
  4. 《35岁失业再就业指南》
  5. 影视并购,是谁写的万能故事大纲?
  6. HttpClient 带参数get请求
  7. openwrt添加lcd4linux,openwrt添加新设备支持(定制固件一)
  8. idea如何取消debug所有断点
  9. windows 下载 R 和 R studio,以及R语言基本使用
  10. 2022年陕西省工程师职称申报需要提前准备的材料