参考:xorm操作指南,这边有一些配置或者其他的数据库配置(主要是mysql)会省去,具体查看该文档。
文章目录
1、特性
- 支持Struct和数据库表之间的灵活映射,并支持自动同步
- 事务支持,支持嵌套事务(支持类JAVA Spring的事务传播机制)
- 同时支持原始SQL语句和ORM操作的混合执行
- 使用连写来简化调用
- 支持使用Id, In, Where, Limit, Join, Having, Table, Sql, Cols等函数和结构体等方式作为条件
- 支持级联加载Struct
- 支持类ibatis方式配置SQL语句(支持xml配置文件、json配置文件、xsql配置文件,支持pongo2、jet、html/template模板和自定义实现配置多种方式)
- 支持动态SQL功能
- 支持一次批量混合执行多个CRUD操作,并返回多个结果集
- 支持数据库查询结果直接返回Json字符串和xml字符串
- 支持SqlMap配置文件和SqlTemplate模板密文存储和解析
- 支持缓存
- 支持主从数据库(Master/Slave)数据库读写分离
- 支持根据数据库自动生成xorm的结构体
- 支持记录版本(即乐观锁)
- 支持查询结果集导出csv、tsv、xml、json、xlsx、yaml、html功能
- 支持SQL Builder github.com/go-xorm/builder
这些xorm的特性看下来,感觉和你在java中用mybatis或者hibernate还是比较类似的。主要开发比较关注的特性有下面这些(我觉得):
1 支持实体和表的属性映射、2 事务传播的支持,spring的事务传播的实现可以参考我的csdn文章、5 和mybatis之前的分页插件还有其他一些插件还是挺类似的 7 自己写sql,这个功能我觉得很强 14 这个有点类似hibernate的逆向工程
2、安装
安装很简单,安装命令:go get -u github.com/xormplus/xorm
3、Orm引擎(包含配置)
他这边有一个说明,感觉还是很有用的:
在xorm里面,可以同时存在多个Orm引擎,一个Orm引擎称为Engine,一个Engine一般只对应一个数据库。
感觉这个东西好处在于说我一个项目可能存在多个数据库,而不是传统的web架构,比如说现在在做的游戏,可能跨服和单区服的数据库不在同一个库,那么这个功能就派上用处了。就是不同的场景传入不同的数据引擎以达到操作不同数据库的目的。
1、创建(mysql为例)
这边以连接mysql数据为例:
import (
_ "github.com/go-sql-driver/mysql"
"github.com/xormplus/xorm"
)
var engine *xorm.Engine
func main() {
var err error
engine, err = xorm.NewEngine("mysql", "root:123@/test?charset=utf8")
}
2、ping操作
创建完成engine之后,并没有立即连接数据库,此时可以通过engine.Ping()来进行数据库的连接测试是否可以连接到数据库。
-
另外对于某些数据库有连接超时设置的,可以通过起一个定期Ping的Go程来保持连接鲜活。扫描二维码关注公众号,回复: 10380859 查看本文章
具体的操作应该是看对应的场景是否有对应的需求。
3、操作日志
配置对应的日志输出级别和sql的展示,这个和hibernate有点类似。具体的配置如下:
1、配置输出sql
engine.ShowSQL(true)
,则会在控制台打印出生成的SQL语句;
2、配置打印日志级别
engine.Logger().SetLevel(core.LOG_DEBUG)
,则会在控制台打印调试及以上的信息;
3、配置输出到文件
如果需要配置输出到文件的话,需要通过调用 NewSimpleLogger(w io.Writer)
接收一个io.Writer
接口,具体方式如下:
f, err := os.Create("sql.log")
if err != nil {
println(err.Error())
return
}
engine.SetLogger(xorm.NewSimpleLogger(f))
4、连接池操作
这个和java的数据库框架类似的设置操作:
如果需要设置连接池的空闲数大小,可以使用
engine.SetMaxIdleConns()
来实现。
-
如果需要设置最大打开连接数,则可以使用engine.SetMaxOpenConns()
来实现。
4、表-结构体 映射
1、映射规则配置
1-名称映射规则
主要负责结构体名称到表名和结构体field到表字段的名称 映射。由core.IMapper接口的实现者来管理,xorm内置了三种IMapper实现.
- core.SnakeMapper:支持struct为驼峰式命名,表结构为下划线命名之间的转换,这个是默认的Maper;
- core.SameMapper:支持结构体名称和对应的表名称以及结构体field名称与对应的表字段名称相同的命名;
- core.GonicMapper:和SnakeMapper很类似,但是对于特定词支持更好,比如ID会翻译成id而不是i_d。
2-设置方法
engine.SetMapper(core.SameMapper{})
3-混合使用和自定义
- 如果你使用了别的命名规则映射方案,也可以自己实现一个IMapper
- 表名称和字段名称的映射规则默认是相同的,当然也可以设置为不同,如:
//表名的映射和字段映射分开,这个还是比较灵活的。 engine.SetTableMapper(core.SameMapper{}) engine.SetColumnMapper(core.SnakeMapper{})
4-对应的类型映射
前缀映射,这个感觉没什么太多用处,可以参考:前缀映射
2、自定义映射和映射规则优先级
1-自定义表名和优先级
这边看了一下第一种自定义临时表名的方法还是有点魔幻的,没找到对应资料,看了源码还是没怎么理解他的处理,正常第二种方式应该最常用, 后面再研究第一种方式吧
第一种方式:通过engine.Table()(engine是xorm引擎对象) 方法可以改变struct对应的数据库表的名称
第二种方式:实现TableName() string
接口,就跟下面这样,我随便截了个项目中的图
第三种方式:就是我们上面说的 Mapper 自动映射的表名
上述三个方法按照顺序优先级执行。mapper排在最后,留给很大的自定义空间。
2-字段映射
字段映射有两种方式,感觉这个自定义的空间还是有的
第一种方式:通过sturct中field对应的Tag中使用**xorm:"‘column_name’"**可以使该field对应的Column名称为指定名称。(这里使用两个单引号将Column名称括起来是为了防止名称冲突,因为我们在Tag中还可以对这个Column进行更多的定义。如果名称不冲突的情况,单引号也可以不使用。)
第二种方式:Mapper 自动映射的字段名
同样是按照前后优先级,Mapper映射的优先级最低
3-Column属性定义
Column属性tag定义不只是定义名称映射,还可以定义其他的属性。我这边只把可能会在项目中常用到的列举出来,具体的还是看原文:Column属性定义
Tag属性名 | 作用说明 |
---|---|
name | 当前field对应的字段的名称,可选,如不写,则自动根据field名字和转换规则命名,如与其它关键字冲突,请使用单引号括起来。 |
pk | 是否是Primary Key,如果在一个struct中有多个字段都使用了此标记,则这多个字段构成了复合主键,支持int32,int,int64,uint32,uint,uint64,string这7种Go的数据类型 |
[not ]null 或 notnull | 是否可以为空 |
autoincr | 是否自增 |
unique或unique(uniquename) | 是否是唯一,如不加括号则该字段不允许重复;如加上括号,则括号中为联合唯一索引的名字 |
- | 这个Field将不进行字段映射 |
-> | 这个Field将只写入到数据库而不从数据库读取 |
<- | 这个Field将只从数据库读取,而不写入到数据库 |
created | 这个Field将在Insert时自动赋值为当前时间 |
updated | 这个Field将在Insert或Update时自动赋值为当前时间 |
default 0或default(0) | 设置默认值,紧跟的内容如果是Varchar等需要加上单引号 |
4-Column映射其他规则
1、如果field名称为Id而且类型为int64并且没有定义tag,则会被xorm视为主键,并且拥有自增属性。如果想用Id以外的名字或非int64类型做为主键名,必须在对应的Tag上加上xorm:"pk"来定义主键(如果是Id字段,但是加上了xorm的tag并且没有声明为pk,应该是不会被当成主键的。)
2、string类型默认映射为varchar(255),如果需要不同的定义,可以在tag中自定义,如:varchar(1024)
3、支持type MyString string等自定义的field,支持Slice, Map等field成员,这些成员默认存储为Text类型,并且默认将使用Json格式来序列化和反序列化。
4、支持数据库字段类型为Blob类型。如果是Blob类型,则先使用Json格式序列化再转成[]byte格式。如果是[]byte或者[]uint8,则不做转换二十直接以二进制方式存储。
5、实现了Conversion接口的类型或者结构体,将根据接口的转换方式在类型和数据库记录之间进行相互转换,这个接口的优先级是最高的。
就像下面这样,顺便说一下接口继承的快捷键是Ctrl + i,拿去不谢
xorm各个数据库对应表结构类型,查看原文,这边就不给出了:Column属性定义