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.