一、说明
1.1、orm特性
- 支持 Go 的所有类型存储
- 操作简单,采用简单的 CRUD 风格
- 自动 Join 关联表
- 跨数据库兼容查询
- 允许直接使用 SQL 查询/映射
- 严格完整的测试保证 ORM 的稳定与健壮
1.2、orm支持的数据库
- MySQL:github.com/go-sql-driver/mysql
- TiDB、
- PostgreSQL:github.com/lib/pq
- Sqllite3:github.com/mattn/go-sqlite3
二、ORM连接数据库
此次实践以MySQL数据库为元数据库操作。
2.1、安装package
// 1、安装orm包
> go get github.com/astaxie/beego/orm
// 2、安装MySQL驱动
> go get github.com/go-sql-driver/mysql
2.2、连接数据库
(1)、在配置文件 "conf/app.conf" 里添加数据库的连接信息。
// 可以指定单个数据库的连接信息也可以指定多个库的连接信息(orm支持多个库操作),这里配置两个库的连接信息
dev_username = root
dev_userpwd = rootpwd
dev_dbhost = localhost
dev_dbport = 3306
devdbname = beego_dev_db // 开发库
test_username = root
test_userpwd = rootpwd
test_dbhost = localhost
test_dbport = 3306
testdbname = beego_test_db // 测试库
(2)、在main.go文件里main函数上方定义init函数初始化MySQL连接,具体内容如下:
package main
import (
_ "beego_dev_model/routers"
"github.com/astaxie/beego"
"github.com/astaxie/beego/orm"
_ "github.com/go-sql-driver/mysql" // 一定到导入mysql驱动包,不导入编译时会报错
)
// 初始化mysql连接
func init() {
// 在配置文件“conf/app.conf”里获取开发库的连接信息并拼接数据库连接串
dev_username := beego.AppConfig.String("dev_username")
dev_userpwd := beego.AppConfig.String("dev_userpwd")
dev_dbhost := beego.AppConfig.String("dev_dbhost")
dev_dbport := beego.AppConfig.String("dev_dbport")
devdbname := beego.AppConfig.String("devdbname")
dev_db_data_source := dev_username + ":" + dev_userpwd + "@tcp(" + dev_dbhost + ":" + dev_dbport + ")/" + devdbname + "?charset=utf8"
// 在配置文件“conf/app.conf”里获取测试库的连接信息并拼接数据库连接串
test_username := beego.AppConfig.String("test_username")
test_userpwd := beego.AppConfig.String("test_userpwd")
test_dbhost := beego.AppConfig.String("test_dbhost")
test_dbport := beego.AppConfig.String("test_dbport")
testdbname := beego.AppConfig.String("testdbname")
test_db_data_source := test_username + ":" + test_userpwd + "@tcp(" + test_dbhost + ":" + test_dbport + ")/" + testdbname + "?charset=utf8"
// 注册数据库驱动
orm.RegisterDriver("mysql", orm.DRMySQL)
// 注册两个数据库连接
orm.RegisterDataBase("devdb", "mysql", devdb_data_source, 30)
orm.RegisterDataBase("devdb", "mysql", testdb_data_source, 30)
}
注册数据库参数说明:
- 参数一:数据库的别名,用来在 ORM 中切换数据库使用
- 参数二:驱动名称
- 参数三:数据库连接串("连接数据库用户名:用户密码@tcp(数据库IP:数据库端口号)/数据库名字?charset=utf8")
- 参数四(可选):设置最大空闲连接
- 或根据数据库别名设置:orm.SetMaxIdleConns("default", 30)
- 参数五(可选):设置最大数据库连接
- 或根据数据库别名设置: orm.SetMaxOpenConns("default", 30)
三、orm操作数据初体验
3.1、定义结构体并注册模型
在models目录下新建文件并定义结构体,内容如下
package models
import (
"github.com/astaxie/beego/orm"
"time"
)
// 定义结构体
type User struct {
Id int `orm:"pk;auto"` // `orm:"pk"`:指定当前字段为主键。 `orm:"pk;auto"`:指定当前字段是主键(pk)且自动增长(auto),pk和auto基本都是同时使用的。
Name string `orm:"column(username)"` // `orm:"column(username)"`:指定模型里字段名对应表里的字段名
Age int `orm:"null;index"` // `orm:"null"`:表示该字段允许为Null 。 `orm:"index"`:在当前字段建索引(索引相当于书的目录,方便快速查找数据)
Addr string
}
// 自定义模型对应数据库里的表名
func (u *User) TableName() string {
return "sys_user"
}
// 将结构体注册为orm模型
func init() {
orm.RegisterModel(new(User))
}
3.2、配置参数使支持orm命令行命令建表
在main.go文件里beego.Run()上方添加如下配置
// 命令行支持orm命令的参数
orm.RunCommand()
3.3、使用命令行命令将orm模型自动同步到表里
(1)查看orm命令的帮助
> go run main.go orm -h // 查看orm命令参数
syncdb:自动创建表
sqlall:打印创建表的一些语句(用于检查sql语句)
help:查看帮助
(2)查看syncdb命令帮助
> go run main.go orm syncdb -h
-db:操作的数据别名(默认是default库)
-force:是否删除之前有的表重新创建表(默认值是true),设置true表示删除之前有的表在重建,设置false表示不删除之前有的表(这个参数要慎用,危险!)
-v:详细输出(输出建表的详细信息)
(3)命令实现orm里的模型自动在库里建表
1、删除库里有的同名表并创建新的表(关键参数:-force=true),注意,此命令慎用,危险!
> go run main.go orm syncdb -db=default -force=true -v
2、在库里新建表,如果库里已经有同名的表则什么也不操作
> go run main.go orm syncdb -db=default -v
3、默认:
go run main.go orm syncdb // 默认操作default库,如果有同名的表则什么也不错,没有的表会创建出来
5.3.4、注意:syncdb的-force参数一定要慎用
3.4、执行程序时自动检测模型并建表配置
建议手动同步模型建表,
dbname = "default"
force := false // 是否删除重名表后重建(慎用删除重建,危险!),true:遇到同名的表就删除重建,false:遇到同名表就跳过。
verbose := true // 打印执行的sql语句
err != orm.RunSyncdb(dbname, force, verbose) // 遇到错误立即返回
if err != nil {
fmt.Println("syncdb failed, err:", err)
return
}
四、orm操作不同数据库的方法
func InsertData() {
o := orm.NewOrm() // 示例化orm对象
o.Using("default") // ORM使用的数据(别名),默认使用default库(不指定就默认使用default库),如果使用其他库需要在括号里指定注册库时的别名即可
// 1.定义数据
user := test_orm.User{Name: "优选工具", Age: 22, Addr: "天津"}
id, err := o.Insert(&user) // 执行插入方法
if err != nil {
fmt.Println("insert failed, err:", err)
// return
}
fmt.Println("insert ID:", id)
}