下载介绍框架
要使用go语言的orm框架,需要先下载框架并引入:
// 安装工具包
go get xorm.io/xorm
//安装数据库驱动(这里是mysql)
go get -u github.com/go-sql-driver/mysql
//引入框架
import (
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
数据库建设
数据库构建,xorm也提供了数据表的构建功能,直接将结构体以构建为数据的表,专业事还是交给专业的人来做,有navicat这种构建和管理工具更专业。
建立以下数据库:
创建数据库引擎
创建一个引擎。所有的数据库操作都需要基于数据库引擎。 Group引擎用于操作读写分离的数据库或者负载均衡的数据库。 Engine引擎和EngineGroup引擎的API基本相同。所有适用于Engine的API基本上都适用于EngineGroup。
数据库引擎处于单例模式,因此只能使用指针类型。
var Engine *xorm.Engine
一般情况下引擎在包初始化函数init()
中初始化
func init(){
var err error
Engine, err = xorm.NewEngine("mysql", "root:123@/test?charset=utf8")
// err的错误处理
}
可以通过Engine.Ping()
来进行数据库的连接测试是否可以连接到数据库。通过Engine可以完成数据的CURD操作。
日志组件
xorm提供了日志组件来显示SQL,默认显示级别为INFO。日志可以通过运行控制台打印或保存到日志文件中。
Engine.ShowSQL(true)
会在控制台打印出生成的SQL语句;
engine.Logger().SetLevel(core.LOG_DEBUG)
更改控制台日志打印级别(这里是debug级别)
SQL信息也可以保存到日志文件中
f, err := os.Create("sql.log")
if err != nil {
println(err.Error())
return
}
Engine.SetLogger(xorm.NewSimpleLogger(f))
数据库连接池
引擎内部支持连接池接口和相应的功能。
如果需要设置连接池的空闲数大小,可以使用engine.SetMaxIdleConns()
来实现。
如果需要设置最大打开连接数,则可以使用engine.SetMaxOpenConns()
来实现。
数据库映射
创建完数据库引擎后,在使用时查询的数据需要赋值给go的数据结构(一般为结构体),xorm框架提供了多种映射方式。基于约定大于配置
的原则。
- SnakeMapper支持结构体驼峰命名和表结构下划线命名之间的转换,这也是默认的方式。
//设置其他映射方式
Engine.SetMapper(core.SameMapper{
})
type StuTests struct {
StuId int
StuName string
StuAge int
StuSex string
}
//拆入数据
stu0 := StuTests{
0,
"xiaoxu1",
18,
"man",
}
//插入
Engine.Insert(&stu0)
//查询
var stu1 StuTests
Engine.Get(&stu1)
type Accounts struct {
Id int
User string
Password string
Role string
}
var act Accounts
Engine.Table("accounts").Where("id = ?", 1).Cols("user").Get(&act)
fmt.Println(act)
Engine.Get(&act)
fmt.Println(act)
数据库表和字段如下
如上图所示,无论是首字母大写的驼峰命名法还是单个单词的命名法,表名和字段名都可以成功映射。
还有其他映射方式访问非常优秀的学习网站克索姆
- tag标签映射补充映射规则
在Go序列化章节中,tag标签可以序列化json字符串,xorm框架中也使用了这个功能。
type StuTests struct {
StuId int `xorm:"stu_id"`
StuName string `xorm:"stu_name"`
StuAge int `xorm:"stu_age"`
StuSex string `xorm:"stu_sex"`
}
tag标签一般用来做上一个映射方式的补充,应用于一些特殊的命名方式,另外如果表名命名方式也特殊的话可以使用engine.Table()
指定的临时表名。
导出数据库脚本
如果需要通过Web端的按钮导出数据库脚本,实际上是通过Go语言执行数据库脚本,并将sql文件导出到本地。
engine.DumpAll(w io.Writer)
方法返回数据库表的结构和数据的字节数组。
engine.DumpAllToFile(fpath string)
方法将数据库表的结构和数据写入到sql文件。
Engine.DumpAllToFile("./demo.sql")
执行后在文件夹下生成sql文件:
还提供进口支持
engine.Import(r io.Reader)
engine.ImportFile(fpath string)
时间场
在插入数据时需要时间可以在数据中设置生成当前时间,一般情况下编程语言生成的时间类型都是很全面的,在实际使用中一般只需要部分数据YYYY-MM-DD hh:mm:ss
类型。
Datetime:时间日期,格式是YYYY-mm-dd HH:ii:ss,表示的范围是从1000到9999年,有0值:0000-00-00 00:00:00。
Date:日期,就是datetime中的date部分。
Time:时间段,指定的某个区间之间,-时间到+时间。
Timestamp:时间戳,只是从1970年开始的YYYY-mm-dd HH:ii:ss 格式与datetime完全一致。
Year:年份,两种格式, year(2)和year(4):1901到2156
因此程序在插入数据语言时需要进行转换,xorm提供了自动转换组件。
type StuTests struct {
StuId int `xorm:"stu_id"`
StuName string `xorm:"stu_name"`
StuAge int `xorm:"stu_age"`
StuSex string `xorm:"stu_sex"`
CreateTime time.Time `xorm:"created"`
}
在xorm标记中使用created
标记,对应的字段可以为time.Time或者自定义的time.Time或者int,int64等int类型。
stu0 := StuTests{
0,
"xiaoxu1-1",
18,
"man",
time.Now(),
}
Engine.Insert(&stu0)
然后正常插入即可,数据库的大的对应字段设置为datetime
。Updated
用于更新时自动同步当前时间。
数据库操作
XORM提供了很多方法来实现数据库操作,但是小编个人更喜欢直接编写SQL语句的方法,所以接下来我只介绍编写SQL语句的方法。 (如果习惯直接使用框架方法,可以跳过-)
Query 最原始的也支持SQL语句查询,返回的结果类型为 []map[string][]byte。QueryString 返回 []map[string]string, QueryInterface 返回 []map[string]interface{}
第一个方法返回字节数组,第二个方法返回struct的json字符串的形式,第三个方法返回空接口。一般使用第三个方法返回map数组[]map[string]interface{}
result, _ := Engine.QueryInterface("select * from stu_tests")
for index, item := range result {
fmt.Println(index)
fmt.Println(item)
}
Engine.Query
系列只用于执行DQL。
Engine.SQL()
返回值是一个Engine,用于sql和引擎方法混用。
var stu2 []StuTests
Engine.SQL("select * from stu_tests").Find(&stu2)
fmt.Println(stu2)
该方法返回的基本元素为结构体类型,因此查询多条数据需要返回结构体数组。
一般与条件查询结合使用。
Engine.Exec()
用于执行DML,且支持表达式,?
作为占位符
//Engine.Exec()
sql := "update stu_tests set stu_name =? where stu_id =? "
result, err := Engine.Exec(sql, "hebei", 5)
if err != nil {
fmt.Println("demo4.main:update error", err)
return
}
返回result类型为sql.Result
,包含两个方法,分别返回最后插入行数的主键id和影响的行数。
//sql.Result
type Result interface {
LastInsertId() (int64, error)
RowsAffected() (int64, error)
}
Engine.Exec()
支持Insert, Update, Delete方法,支持表达式和占位符。插入就不要写sql了直接用engine.Insert()
方法。
实用方法
- 查询
Engine.SQL(DQL).Find(&变量)
DQL 可以是任何结构化查询语言。通过Find批量查找返回一个结构体数组,使用起来非常方便。
// Engine.SQL() /*
//stu2 := make([]StuTests, 0)
var stu2 []StuTests
Engine.SQL("select * from stu_tests").Find(&stu2)
fmt.Println(stu2)
- 插入
Engine.Insert(...&变量)
通过结构体(结构体映射到数据库表)一键插入数据,支持单条和批量
- 更新
更新情况比较复杂,最常用的是基于主键更新或者基于结构更新。
- 根据主键更新
Engine.ID(1).Update(&user)
UPDATE user SET ... Where id = ?
前一个方法是主键参数,后一个参数是更新后的结构。这个方法是一个整体的结构。需要注意是否需要回显。
Engine.Update(&user, &User{Name:name})
UPDATE user SET ... Where name = ?
结构更新就是传入两个结构体变量,将表中满足第二个结构体数据的数据修改为第一个参数的结构体数据。
Engine.Exec("update user set age = ? where name = ?", age, name)
单个字段修改,使用Engine.Exec
方法对单个字段修改。
- 删除
数据库一般都是软删除,并且在数据库中添加一个状态字段。查询时只需选择查询即可。
- SQL函数
在sql中经常使用sql函数,例如求和函数sum()
,获取记录函数count(*)
,平均数avg()
等,也可以使用一个较为通用的方法Engine.QueryString()
。
Engine.QueryString()
方法返回一个如下的map数组,在SQL查询中几乎所有数据都是以一个二维表的形式展现的。
[]map[string]string
然后这个二维表的数据项被处理并转换成结构。地图类型也是比较直观的类型。对于数据项,列名是键,值是值。多个数组通过数组来存储。因此,大部分查询的数据都可以直接转换为地图类型。
对于需要经常使用单个字段的人来说,将其转换为地图很不方便,需要分析。但是,使用 SQL 方法的一般查询将返回较少的数据。直接转换为地图也是通用的。
//count(*)函数
queryString, err := Engine.QueryString("select count(*) as sum from stu_tests")
if err != nil {
print(err)
return
}
fmt.Println(queryString)
fmt.Println(queryString[0]["sum"])
事务
一些重要的数据需要事物的支持,xorm也提供了事物的支持。
Engine.NewSession()
创建一个事务数据库引擎,默认开启事物,并提供事物关闭方法,事务是原子操作需要提交。
session := Engine.NewSession()
//方法结束后关闭事务
defer session.Close()
// add Begin() before any action
if err := session.Begin(); err != nil {
// if returned then will rollback automatically
return err
}
/** action **/
// add Commit() after all actions
err = session.Commit()
if err != nil {
return
}
http://xorm.topgoer.com/
https://gitea.com/xorm/xorm/src/branch/master/README_CN.md