Go语言学习笔记—xorm


一 xorm简介

xorm是一个简单而强大的Go语言ORM库. 通过它可以使数据库操作非常简便。xorm的目标并不是让你完全不去学习SQL,我们认为SQL并不会为ORM所替代,但是ORM将可以解决绝大部分的简单SQL需求。xorm支持两种风格的混用。

官方文档:https://xorm.io/zh/docs/

1.1 特性

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

1.2 驱动支持

二 第一个xorm应用

2.1 安装库

go get xorm.io/xorm
go get github.com/go-sql-driver/mysql

2.2 创建数据库

C:\Users\Mechrevo>mysql -uroot -p
Enter password: ******
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 20
Server version: 8.0.19 MySQL Community Server - GPL

Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> create database test_xorm;
Query OK, 1 row affected (0.48 sec)

mysql> use test_xorm;
Database changed

2.3 连接数据库

package main

import (
	"fmt"

	_ "github.com/go-sql-driver/mysql"
	"xorm.io/xorm"
)

var engine *xorm.Engine

func main() {
   

	var err error

	engine, err = xorm.NewEngine("mysql", "root:960690@/test_xorm?charset=utf8")
	if err != nil {
   
		fmt.Printf("err : %v\n", err)
	} else {
   
		err2 := engine.Ping()
		if err2 != nil {
   
			fmt.Printf("err2 : %v\n", err2)
		} else {
   
			print("数据库连接成功!")
		}
	}
}

运行结果:

[Running] go run "e:\golang开发学习\go_pro\test.go"
[xorm] [info]  2022/08/11 17:04:41.129767 PING DATABASE mysql
数据库连接成功!
[Done] exited with code=0 in 2.191 seconds

2.4 创建结构体

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

2.5 创建表

// 创建表
err3 := engine.Sync(new(User))
if err3 != nil {
   
	fmt.Printf("err2 : %v\n", err3)
} else {
   
	fmt.Println("表创建成功!")
}

数据库查看:

在这里插入图片描述

2.6 添加数据

// 添加数据
user := User{
   
	Id:     1,
	Name:   "Psych",
	Salt:   "salt",
	Age:    18,
	Passwd: "666",
}
i, err4 := engine.Insert(&user)
if err4 != nil {
   
	fmt.Printf("err : %v\n", err4)
} else {
   
	fmt.Printf("创建记录数量: %v\n", i)
}

数据库查看:

在这里插入图片描述

2.7 完整代码

package main

import (
	"fmt"
	"time"

	_ "github.com/go-sql-driver/mysql"
	"xorm.io/xorm"
)

var engine *xorm.Engine

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

func main() {
   

	var err error

	engine, err = xorm.NewEngine("mysql", "root:960690@/test_xorm?charset=utf8")
	if err != nil {
   
		fmt.Printf("err : %v\n", err)
	} else {
   
		err2 := engine.Ping()
		if err2 != nil {
   
			fmt.Printf("err2 : %v\n", err2)
		} else {
   
			print("数据库连接成功!")
		}
	}

	// 创建表
	err3 := engine.Sync(new(User))
	if err3 != nil {
   
		fmt.Printf("err2 : %v\n", err3)
	} else {
   
		fmt.Println("表创建成功!")
	}

	// 添加数据
	user := User{
   
		Id:     1,
		Name:   "Psych",
		Salt:   "salt",
		Age:    18,
		Passwd: "666",
	}
	i, err4 := engine.Insert(&user)
	if err4 != nil {
   
		fmt.Printf("err : %v\n", err4)
	} else {
   
		fmt.Printf("创建记录数量: %v\n", i)
	}
}

三 xorm定义表结构体

3.1 表名称映射规则

跟名称相关的函数包含在 xorm.io/xorm/names 下。名称映射规则主要负责结构体名称到表名和结构体 field 到表字段的名称映射。由 names.Mapper 接口的实现者来管理,xorm 内置了三种 Mapper 实现:names.SnakeMappernames.SameMappernames.GonicMapper

  • SnakeMapper:支持struct为驼峰式命名,表结构中为下划线命名之间的转换。该种规则为xorm默认的Maper;
  • SameMapper:映射规则支持结构体名称和对应的表名称以及结构体field名称与对应的表字段名称相同的命名;
  • GonicMapper:该映射规则和驼峰式命名类似,但是对于特定词支持性更好,比如ID将会翻译成id,而不是驼峰式的i_d。

当前SnakeMapper为默认值,如果需要改变时,在engine创建完成后使用

engine.SetMapper(names.GonicMapper{
   })

另外,可以设置表名和表字段分别为不同的映射规则:

engine.SetTableMapper(names.SameMapper{})

engine.SetColumnMapper(names.SnakeMapper{})

测试:

package main

import (
	"fmt"
	"time"

	_ "github.com/go-sql-driver/mysql"
	"xorm.io/xorm"
	"xorm.io/xorm/names"
)

var engine *xorm.Engine

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

func init() {
   
	var err error

	engine, err = xorm.NewEngine("mysql", "root:960690@/test_xorm?charset=utf8")
	if err != nil {
   
		fmt.Printf("err : %v\n", err)
	} else {
   
		err2 := engine.Ping()
		if err2 != nil {
   
			fmt.Printf("err2 : %v\n", err2)
		} else {
   
			print("数据库连接成功!")
		}
	}
}

func main() {
   
	engine.ShowSQL(true)

	// engine.SetMapper(names.GonicMapper{})
	engine.SetMapper(names.SnakeMapper{
   })
	// engine.SetMapper(names.SameMapper{})

	// 创建表
	err := engine.Sync(new(LoginUser))
	if err != nil {
   
		fmt.Printf("err : %v\n", err)
	} else {
   
		fmt.Println("表创建成功!")
	}
}

数据库查看:

在这里插入图片描述

3.2 前缀映射,后缀映射和缓存映射

  • 通过 names.NewPrefixMapper(names.SnakeMapper{}, "prefix") 可以创建一个在 SnakeMapper 的基础上在命名中添加统一的前缀,当然也可以把 SnakeMapper{} 换成 SameMapper 或者你自定义的 Mapper。

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

tbMapper := names.NewPrefixMapper(names.SnakeMapper{
   }, "prefix_")
engine.SetTableMapper(tbMapper)

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

  • 通过 names.NewSuffixMapper(names.SnakeMapper{}, "suffix") 可以创建一个在 SnakeMapper 的基础上在命名中添加统一的后缀,当然也可以把SnakeMapper换成SameMapper或者你自定义的Mapper。
  • 通过 names.NewCacheMapper(names.SnakeMapper{}) 可以创建一个组合了其它的映射规则,起到在内存中缓存曾经映射过的命名映射。

测试:

package main

import (
	"fmt"
	"time"

	_ "github.com/go-sql-driver/mysql"
	"xorm.io/xorm"
	"xorm.io/xorm/names"
)

var engine *xorm.Engine

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

func init() {
   
	var err error

	engine, err = xorm.NewEngine("mysql", "root:960690@/test_xorm?charset=utf8")
	if err != nil {
   
		fmt.Printf("err : %v\n", err)
	} else {
   
		err2 := engine.Ping()
		if err2 != nil {
   
			fmt.Printf("err2 : %v\n", err2)
		} else {
   
			print(
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值