An overview of the
Beego ORM is a powerful Go LANGUAGE ORM framework, currently the framework has support for MySQL, PostgreSQL, Sqlite3 database drivers.
Install the ORM
go get github.com/astaxie/beego/orm
Copy the code
Initialize the
Create a project
Use the bee API apiProject command to create an apiProject. For details, see beego API command.
Model of relationship between
The foreign key is always on the child table
# One profile for each user; One profile for one user;One2one :User(subtable) -> Profile (primary table); one2one:Profile -> UserCopy the code
The structure of the body
type User struct {
Id int `json:"id"`
Username string `json:"username"`
Password string `json:"password"`
Profile *Profile `orm:"rel(one)" json:"profile"` // OneToOne relation
}
type Profile struct {
Id int `json:"id"`
Gender int `json:"gender"`
Age int `json:"age"`
Address string `json:"address"`
Email string `json:"email"`
User *User `orm:"reverse(one)" json:"-"'// Set one-to-one reverse relationship (optional)}Copy the code
Use the label 'ORm' :"Column (ID) 'annotates the attribute for parsing. `orm:"rel(one)"' stands for one2one 'orm:"reverse(one)"` `orm:"reverse(one)"' marks the inverse relationshipCopy the code
The database information
The registration model:
orm.RegisterModel(new(User), new(Profile))
Copy the code
Custom table name:
func (u *User) TableName() string {
return "users"
}
func (u *Profile) TableName() string {
return "users_profiles"
}
Copy the code
Automatic table building:
orm.RunSyncdb("default".false.true)
Copy the code
Data table structure:
mysql> show tables;
+-------------------+
| Tables_in_play_db |
+-------------------+
| users |
| users_profiles |
+-------------------+
2 rows in set(0.01 SEC) mysql> desc users; +------------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +------------+--------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | username | varchar(255) | NO | | | | | password | varchar(255) | NO | | | | | profile_id | int(11) | NO | UNI | NULL | | +------------+--------------+------+-----+---------+----------------+ 4 rowsin set (0.02 sec)
mysql> desc users_profiles;
+---------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| gender | int(11) | YES | | 0 | |
| age | int(11) | YES | | 0 | |
| address | varchar(255) | YES | | | |
| email | varchar(255) | YES | | | |
+---------+--------------+------+-----+---------+----------------+
5 rows in set (0.01 sec)
Copy the code
Function implementation
Item Parameter Configuration
/apiproject/conf/app.conf
appname = apiproject
httpport = 8090
runmode = dev
autorender = false
copyrequestbody = true
EnableDocs = truesqlconn = root:123456@/play_db? charset=utf8Copy the code
General utils
Paging: / apiproject/utils/page. Go
package utils
var (
PageSize int = 10
)
type Page struct {
Page int `json:"page"`
PageSize int `json:"pageSize"`
TotalPage int `json:"totalPage"`
TotalCount int `json:"totalCount"`
FirstPage bool `json:"firstPage"`
LastPage bool `json:"lastPage"`
List interface{} `json:"list"`
}
func Pagination(count int, page int, pageSize int, list interface{}) Page {
tp := count / pageSize
if count%pageSize > 0 {
tp = count/pageSize + 1
}
return Page{Page: page, PageSize: pageSize, TotalPage: tp, TotalCount: count, FirstPage: page == 1, LastPage: page == tp, List: list}
}
Copy the code
The main entrance
/apiproject/main.go
package main
import (
_ "apiproject/routers"
"github.com/astaxie/beego/orm"
"github.com/astaxie/beego"
_ "github.com/go-sql-driver/mysql"
)
func initMysql/sqlite3 / postgres/mysql/sqlite3 / postgres/mysql/sqlite3 / postgres/mysql/sqlite3 / postgres/mysql/sqlite3 / postgres/mysql/sqlite3 / postgres // orm.RegisterDriver("mysql"Orm.DRMySQL) // OrM must register a database named default to use as the default. // Parameter 2 driverName // Parameter 3 corresponds to the link string orm.RegisterDataBase("default"."mysql", beego.AppConfig.String("sqlconn"))
}
func main() {
if beego.BConfig.RunMode == "dev" {
beego.BConfig.WebConfig.DirectoryIndex = true
beego.BConfig.WebConfig.StaticDir["/swagger"] = "swagger"} // Enable orM Debug mode: It is recommended to enable orm Debug mode during developmenttrue
beego.Run()
}
Copy the code
Routing implementation
Routing, RESTful Controller initialization namespace: / apiproject/routers/router. Go
// @APIVersion 1.0.0
// @Title apiproject API
// @License Apache 2.0
package routers
import (
"apiproject/controllers"
"github.com/astaxie/beego"
)
func init() {
ns := beego.NewNamespace("/v1",
beego.NSNamespace("/object",
beego.NSInclude(
&controllers.ObjectController{},
),
),
beego.NSNamespace("/user",
beego.NSInclude(
&controllers.UserController{},
),
),
)
beego.AddNamespace(ns)
}
Copy the code
/apiproject/routers/commentsRouter_controllers.go
package routers
import (
"github.com/astaxie/beego"
"github.com/astaxie/beego/context/param"
)
func init() {
beego.GlobalControllerRouter["apiproject/controllers:UserController"] = append(beego.GlobalControllerRouter["apiproject/controllers:UserController"],
beego.ControllerComments{
Method: "Post",
Router: `/`,
AllowHTTPMethods: []string{"post"},
MethodParams: param.Make(),
Filters: nil,
Params: nil})
beego.GlobalControllerRouter["apiproject/controllers:UserController"] = append(beego.GlobalControllerRouter["apiproject/controllers:UserController"],
beego.ControllerComments{
Method: "GetAll",
Router: `/`,
AllowHTTPMethods: []string{"get"},
MethodParams: param.Make(),
Filters: nil,
Params: nil})
beego.GlobalControllerRouter["apiproject/controllers:UserController"] = append(beego.GlobalControllerRouter["apiproject/controllers:UserController"],
beego.ControllerComments{
Method: "Get",
Router: `/:uid`,
AllowHTTPMethods: []string{"get"},
MethodParams: param.Make(),
Filters: nil,
Params: nil})
beego.GlobalControllerRouter["apiproject/controllers:UserController"] = append(beego.GlobalControllerRouter["apiproject/controllers:UserController"],
beego.ControllerComments{
Method: "Put",
Router: `/:uid`,
AllowHTTPMethods: []string{"put"},
MethodParams: param.Make(),
Filters: nil,
Params: nil})
beego.GlobalControllerRouter["apiproject/controllers:UserController"] = append(beego.GlobalControllerRouter["apiproject/controllers:UserController"],
beego.ControllerComments{
Method: "Delete",
Router: `/:uid`,
AllowHTTPMethods: []string{"delete"},
MethodParams: param.Make(),
Filters: nil,
Params: nil})
}
Copy the code
The controller to achieve
General controller base: / apiproject/controllers/base. Go
package controllers
import (
"github.com/astaxie/beego"
)
typeBaseController struct {beego.Controller} // Response structtype Response struct {
Code int `json:"code"`
Message string `json:"message"`
Data interface{} `json:"data"'} // Error Response structuretype ErrResponse struct {
Code int `json:"code"`
Message string `json:"message"`}Copy the code
Custom error code coding: / apiproject/controllers/code. Go
package controllers
var (
// Common errors
SUCCESS = &Errno{Code: 0, Message: "Success"}
InternalServerError = &Errno{Code: 10001, Message: "Internal service error"}
ErrBind = &Errno{Code: 10002, Message: "Parameter error"}
ErrDatabase = &Errno{Code: 20001, Message: "Database error"}
ErrToken = &Errno{Code: 20002, Message: "Token issue error"}
ErrNoPermission = &Errno{Code: 20003, Message: "No permission"}
// user errors
ErrUserNotFound = &Errno{Code: 20101, Message: "User not registered"}
ErrUserExist = &Errno{Code: 20102, Message: "User already exists"})Copy the code
General error handling: / apiproject/controllers/errno. Go
package controllers
import "fmt"
type Errno struct {
Code int
Message string
}
func (err Errno) Error() string {
return err.Message
}
// Err represents an error
type Err struct {
Code int
Message string
Err error
}
func New(errno *Errno, err error) *Err {
return &Err{Code: errno.Code, Message: errno.Message, Err: err}
}
func (err *Err) Add(message string) error {
err.Message += "" + message
returnerr } func (err *Err) Addf(format string, args ... interface{}) error { err.Message +="" + fmt.Sprintf(format, args...)
return err
}
func (err *Err) Error() string {
return fmt.Sprintf("Err - code: %d, message: %s, error: %s", err.Code, err.Message, err.Err)
}
func IsErrUserNotFound(err error) bool {
code, _ := DecodeErr(err)
return code == ErrUserNotFound.Code
}
func DecodeErr(err error) (int, string) {
if err == nil {
return SUCCESS.Code, SUCCESS.Message
}
switch typed := err.(type) {
case *Err:
return typed.Code, typed.Message
case *Errno:
return typed.Code, typed.Message
default:
}
return InternalServerError.Code, err.Error()
}
Copy the code
User controller module: / apiproject/controllers/user. Go
package controllers
import (
"apiproject/models"
"apiproject/utils"
"encoding/json"
"strconv"
)
// Operations about Users
type UserController struct {
BaseController
}
// @Title CreateUser
// @Description create users
// @Param body body models.User true "body for user content"
// @Success 200 {int} models.User.Id
// @Failure 403 body is empty
// @router / [post]
func (u *UserController) Post() {
var user models.User
_ = json.Unmarshal(u.Ctx.Input.RequestBody, &user)
uid, _ := models.AddUser(user)
u.Data["json"] = map[string]int64{"uid": uid}
u.ServeJSON()
}
// @Title GetAll
// @Description get all Users
// @Success 200 {object} models.User
// @router / [get]
func (u *UserController) GetAll() {
currentPage, _ := strconv.Atoi(u.Ctx.Input.Query("page"))
if currentPage == 0 {
currentPage = 1
}
pageSize := utils.PageSize
d , err:= models.GetAllUsers(currentPage,pageSize)
code, message := DecodeErr(err)
iferr ! = nil { u.Data["json"] = ErrResponse{code, message}
} else {
u.Data["json"] = Response{code, message, d}
}
u.ServeJSON()
}
// @Title Get
// @Description get user by uid
// @Param uid path string true "The key for staticblock"
// @Success 200 {object} models.User
// @Failure 403 :uid is empty
// @router /:uid [get]
func (u *UserController) Get() {
uid, _ := u.GetInt(":uid")
if uid > 0 {
user, err := models.GetUser(uid)
code, message := DecodeErr(err)
iferr ! = nil { u.Data["json"] = ErrResponse{code, message}
} else {
u.Data["json"] = Response{code, message, user}
}
}
u.ServeJSON()
}
// @Title Update
// @Description update the user
// @Param uid path string true "The uid you want to update"
// @Param body body models.User true "body for user content"
// @Success 200 {object} models.User
// @Failure 403 :uid is not int
// @router /:uid [put]
func (u *UserController) Put() {
uid, _ := u.GetInt(":uid")
if uid > 0 {
var user models.User
_ = json.Unmarshal(u.Ctx.Input.RequestBody, &user)
uu, err := models.UpdateUser(uid, &user)
code, message := DecodeErr(err)
iferr ! = nil { u.Data["json"] = ErrResponse{code, message}
} else {
u.Data["json"] = Response{code, message, uu}
}
}
u.ServeJSON()
}
// @Title Delete
// @Description delete the user
// @Param uid path string true "The uid you want to delete"
// @Success 200 {string} delete success!
// @Failure 403 uid is empty
// @router /:uid [delete]
func (u *UserController) Delete() {
uid, _ := u.GetInt(":uid")
b, err := models.DeleteUser(uid)
code, message := DecodeErr(err)
iferr ! = nil { u.Data["json"] = ErrResponse{code, message}
} else {
u.Data["json"] = Response{code, message, b}
}
u.ServeJSON()
}
Copy the code
The model implemented
The user model module, orm implementation to add and delete: / apiproject/models/user. Go
package models
import (
"apiproject/utils"
"errors"
"github.com/astaxie/beego/orm"
"strconv"
)
type User struct {
Id int `json:"id"`
Username string `json:"username"`
Password string `json:"password"`
Profile *Profile `orm:"rel(one)" json:"profile"` // OneToOne relation
}
type Profile struct {
Id int `json:"id"`
Gender int `json:"gender"`
Age int `json:"age"`
Address string `json:"address"`
Email string `json:"email"`
User *User `orm:"reverse(one)" json:"-"Func (u *User) TableName() string {func (u *User) TableName() string {return "users"
}
func (u *Profile) TableName() string {
return "users_profiles"} // AddUser func AddUser(u User) (id int64, O := orm.neworm () // Start transaction err = O.beguin () // Insert main table profile := profile { Gender: u.Profile.Gender, Age: u.Profile.Age, Address: u.Profile.Address, Email: u.Profile.Email} id, err = o.Insert(&profile)iferr ! = nil {// rollback transaction err = o.ollback ()} // Insert child table user := user {Username: u.userName, Password: u.password, Profile: &Profile{Id: int(id)}} _, err = o.Insert(&user)iferr ! Nil {// Rollback transaction err = o.rolback ()} // Commit transaction err = o.mit ()returnFunc GetUser(uid int) (u *User, err Error) {o := orm.NewOrm() User := &User{id: Uid} err = o.read (user) // The Users object has been obtained, query UserProfilesifuser.Profile ! = nil { err = o.Read(user.Profile) }returnFunc GetAllUsers(p int, size int) (u utils.page, err error) { o := orm.NewOrm() user := new(User) var users []User qs := o.QueryTable(user) count, _ := qs.Limit(-1).Count() _, err = qs.RelatedSel().Limit(size).Offset((p - 1) * size).All(&users)for _, u := range users {
ifu.Profile ! = nil { err = o.Read(u.Profile) } } c, _ := strconv.Atoi(strconv.FormatInt(count, 10))returnPagination(c, p, size, users), err} func UpdateUser(uid int, uu *User) err error) { o := orm.NewOrm() user := User{Id: uid} profile := Profile{Id: uid}if o.Read(&user) == nil {
ifuu.Username ! ="" {
user.Username = uu.Username
}
ifuu.Password ! ="" {
user.Password = uu.Password
}
if o.Read(&profile) == nil {
if uu.Profile.Age > 0 {
profile.Age = uu.Profile.Age
}
ifuu.Profile.Address ! ="" {
profile.Address = uu.Profile.Address
}
if uu.Profile.Gender == 0 || uu.Profile.Gender == 1 {
profile.Gender = uu.Profile.Gender
}
ifuu.Profile.Email ! =""{profile.email = uu.profile.email}} user.profile = &profile // Start transaction err = o.pagin ()if_, err := o.Update(&user); err ! = nil {return nil, errors.New("Modification failed")}if_, err := o.Update(&profile); err ! = nil {return nil, errors.New("Modification failed")}iferr ! = nil { err = o.Rollback() }else {
err = o.Commit()
}
return &user, nil
}
returnFunc DeleteUser(uid int) (b bool, // one2one delete // create an ormer object o := orm.neworm () // Start the transaction err = O.beguin () // Delete the master table profile := profile {Id: uid} _, err = o.Delete(&profile)iferr ! User := user {Id: uid} _, err = o.delete (&user)iferr ! Nil {// Rollback transaction err = o.rolback ()} // Commit transaction err = o.mit ()return// Register model funcinit(){
orm.RegisterModel(new(User), new(Profile))
}
Copy the code
END
The above example realizes the user module add, delete, change, search application interface API function development.