# Orm
通过 dsn
连接数据库 driver
,读取 schema
信息生成 ORM
结构体定义及相关辅助代码。
# 使用
# 注解
+zz:orm:[schema][:options...]
# 注解对象
所有对象
# 必填参数
# schema
要读取的数据库 schema
名,多个可用 ,
分隔。
示例: +zz:orm:my_database
# 可选参数
# filename
指定生成的文件路径,默认 ./zzgen.orm.go
示例: +zz:orm:schema:filename=./models/
# driver
指定使用生成 schemadriver
,此 driver
不同于 sql.Driver
,为本工具独立维护对不同数据库种类的不同类型的生成器。
外部生成器可通过 .so
插件形式加载。
默认 mysql
。
示例: +zz:orm:schema:driver=sqlite
# type
指定生成时的数据类型映射。 格式 ${数据库DATA_TYPE}=${Golang类型}
示例: +zz:orm:schema:type=varchar=MyString
可以使用 ,
连接多个指定类型。
示例: +zz:orm:schema:type=varchar=MyString,varchar(255)=string,int unsign=uint
数据库格式匹配的优先级由不同 schemadriver
自行控制。
若要指定 Nullable
类型,可使用 *
前缀。
示例: +zz:orm:schema:type=*varchar=sql.NullString,*json=*json.RawMessage
# table
指定生成的数据表,默认 *
即选取全部数据表进行生成。
可以使用 ,
连接多个表。
示例: +zz:orm:schema:table=user,car,order
# password
通常开发者都是在本地开发环境进行 orm
的生成和基于生成内容进行开发。
因此 driver
会提供一个对应数据库类型默认安装本地连接的 dsn
模版。
如 mysql
通常为 root:${pwd}@tcp(localhost:3306)/
使用者可以只提供 password
,就能通过默认安装地址和用户完成访问。
建议通过以以下方式使用,示例:
read -s pwd && gozz run -p "orm:password=${pwd}" ./
# dsn
如果对数据库连接地址有额外需求,可通过提供完整 dsn
进行访问。
涉及 :
时要使用 \
进行参数转义
示例:
read -s pwd && gozz run -p "orm:dsn=dev_user\:${pwd}@tcp(192.168.1.2\:3306)/" ./
# 示例
示例项目 (opens new window) 示例SQL (opens new window)
package orm01
// +zz:orm:{{ .Name }}
type employees struct{}
执行 gozz run -p "orm:password=***" ./
生成 zzgen.orm.go
和模版文件。
// Code generated by gozz:orm github.com/go-zing/gozz. DO NOT EDIT.
package orm01
import (
"context"
"database/sql"
"encoding/json"
"time"
)
var (
_ = (*context.Context)(nil)
_ = (*json.RawMessage)(nil)
_ = (*time.Time)(nil)
_ = (*sql.NullString)(nil)
)
var tables = []interface{}{
CurrentDeptEmp{},
Departments{},
DeptEmp{},
DeptEmpLatestDate{},
DeptManager{},
Employees{},
Salaries{},
Titles{},
}
// employees.current_dept_emp
// VIEW
const TableCurrentDeptEmp = "current_dept_emp"
type CurrentDeptEmp struct {
// emp_no : int
EmpNo int
// dept_no : char(4)
DeptNo string
// from_date : NULLABLE date
FromDate interface{}
// to_date : NULLABLE date
ToDate interface{}
}
func (CurrentDeptEmp) TableName() string { return TableCurrentDeptEmp }
func (m *CurrentDeptEmp) FieldMapping(dst map[string]interface{}) {
dst["emp_no"] = &m.EmpNo
dst["dept_no"] = &m.DeptNo
dst["from_date"] = &m.FromDate
dst["to_date"] = &m.ToDate
}
type SliceCurrentDeptEmp []CurrentDeptEmp
func (s *SliceCurrentDeptEmp) Iterate(f func(interface{}, bool) bool) {
for i := 0; ; i++ {
if c := i >= len(*s); !c {
if !f(&(*s)[i], c) {
return
}
} else if n := append(*s, CurrentDeptEmp{}); f(&n[i], c) {
*s = n
} else {
*s = n[:i]
return
}
}
}
// employees.departments
const TableDepartments = "departments"
type Departments struct {
// dept_no : char(4)
DeptNo string
// dept_name : varchar(40)
DeptName string
}
func (Departments) TableName() string { return TableDepartments }
func (m *Departments) FieldMapping(dst map[string]interface{}) {
dst["dept_no"] = &m.DeptNo
dst["dept_name"] = &m.DeptName
}
type SliceDepartments []Departments
func (s *SliceDepartments) Iterate(f func(interface{}, bool) bool) {
for i := 0; ; i++ {
if c := i >= len(*s); !c {
if !f(&(*s)[i], c) {
return
}
} else if n := append(*s, Departments{}); f(&n[i], c) {
*s = n
} else {
*s = n[:i]
return
}
}
}
// employees.dept_emp
const TableDeptEmp = "dept_emp"
type DeptEmp struct {
// emp_no : int
EmpNo int
// dept_no : char(4)
DeptNo string
// from_date : date
FromDate interface{}
// to_date : date
ToDate interface{}
}
func (DeptEmp) TableName() string { return TableDeptEmp }
func (m *DeptEmp) FieldMapping(dst map[string]interface{}) {
dst["emp_no"] = &m.EmpNo
dst["dept_no"] = &m.DeptNo
dst["from_date"] = &m.FromDate
dst["to_date"] = &m.ToDate
}
type SliceDeptEmp []DeptEmp
func (s *SliceDeptEmp) Iterate(f func(interface{}, bool) bool) {
for i := 0; ; i++ {
if c := i >= len(*s); !c {
if !f(&(*s)[i], c) {
return
}
} else if n := append(*s, DeptEmp{}); f(&n[i], c) {
*s = n
} else {
*s = n[:i]
return
}
}
}
// employees.dept_emp_latest_date
// VIEW
const TableDeptEmpLatestDate = "dept_emp_latest_date"
type DeptEmpLatestDate struct {
// emp_no : int
EmpNo int
// from_date : NULLABLE date
FromDate interface{}
// to_date : NULLABLE date
ToDate interface{}
}
func (DeptEmpLatestDate) TableName() string { return TableDeptEmpLatestDate }
func (m *DeptEmpLatestDate) FieldMapping(dst map[string]interface{}) {
dst["emp_no"] = &m.EmpNo
dst["from_date"] = &m.FromDate
dst["to_date"] = &m.ToDate
}
type SliceDeptEmpLatestDate []DeptEmpLatestDate
func (s *SliceDeptEmpLatestDate) Iterate(f func(interface{}, bool) bool) {
for i := 0; ; i++ {
if c := i >= len(*s); !c {
if !f(&(*s)[i], c) {
return
}
} else if n := append(*s, DeptEmpLatestDate{}); f(&n[i], c) {
*s = n
} else {
*s = n[:i]
return
}
}
}
// employees.dept_manager
const TableDeptManager = "dept_manager"
type DeptManager struct {
// emp_no : int
EmpNo int
// dept_no : char(4)
DeptNo string
// from_date : date
FromDate interface{}
// to_date : date
ToDate interface{}
}
func (DeptManager) TableName() string { return TableDeptManager }
func (m *DeptManager) FieldMapping(dst map[string]interface{}) {
dst["emp_no"] = &m.EmpNo
dst["dept_no"] = &m.DeptNo
dst["from_date"] = &m.FromDate
dst["to_date"] = &m.ToDate
}
type SliceDeptManager []DeptManager
func (s *SliceDeptManager) Iterate(f func(interface{}, bool) bool) {
for i := 0; ; i++ {
if c := i >= len(*s); !c {
if !f(&(*s)[i], c) {
return
}
} else if n := append(*s, DeptManager{}); f(&n[i], c) {
*s = n
} else {
*s = n[:i]
return
}
}
}
// employees.employees
const TableEmployees = "employees"
type Employees struct {
// emp_no : int
EmpNo int
// birth_date : date
BirthDate interface{}
// first_name : varchar(14)
FirstName string
// last_name : varchar(16)
LastName string
// gender : enum('M','F')
Gender string
}
func (Employees) TableName() string { return TableEmployees }
func (m *Employees) FieldMapping(dst map[string]interface{}) {
dst["emp_no"] = &m.EmpNo
dst["birth_date"] = &m.BirthDate
dst["first_name"] = &m.FirstName
dst["last_name"] = &m.LastName
dst["gender"] = &m.Gender
}
type SliceEmployees []Employees
func (s *SliceEmployees) Iterate(f func(interface{}, bool) bool) {
for i := 0; ; i++ {
if c := i >= len(*s); !c {
if !f(&(*s)[i], c) {
return
}
} else if n := append(*s, Employees{}); f(&n[i], c) {
*s = n
} else {
*s = n[:i]
return
}
}
}
// employees.salaries
const TableSalaries = "salaries"
type Salaries struct {
// emp_no : int
EmpNo int
// salary : int
Salary int
// from_date : date
FromDate interface{}
// to_date : date
ToDate interface{}
}
func (Salaries) TableName() string { return TableSalaries }
func (m *Salaries) FieldMapping(dst map[string]interface{}) {
dst["emp_no"] = &m.EmpNo
dst["salary"] = &m.Salary
dst["from_date"] = &m.FromDate
dst["to_date"] = &m.ToDate
}
type SliceSalaries []Salaries
func (s *SliceSalaries) Iterate(f func(interface{}, bool) bool) {
for i := 0; ; i++ {
if c := i >= len(*s); !c {
if !f(&(*s)[i], c) {
return
}
} else if n := append(*s, Salaries{}); f(&n[i], c) {
*s = n
} else {
*s = n[:i]
return
}
}
}
// employees.titles
const TableTitles = "titles"
type Titles struct {
// emp_no : int
EmpNo int
// title : varchar(50)
Title string
// from_date : date
FromDate interface{}
// to_date : NULLABLE date
ToDate interface{}
}
func (Titles) TableName() string { return TableTitles }
func (m *Titles) FieldMapping(dst map[string]interface{}) {
dst["emp_no"] = &m.EmpNo
dst["title"] = &m.Title
dst["from_date"] = &m.FromDate
dst["to_date"] = &m.ToDate
}
type SliceTitles []Titles
func (s *SliceTitles) Iterate(f func(interface{}, bool) bool) {
for i := 0; ; i++ {
if c := i >= len(*s); !c {
if !f(&(*s)[i], c) {
return
}
} else if n := append(*s, Titles{}); f(&n[i], c) {
*s = n
} else {
*s = n[:i]
return
}
}
}