#Beego
目次
- インストール方法・環境構築
- logの出力方法
- マイグレーション
自分がいろいろ忘れないように覚書程度に記載
基本的にマニュアルどおりに作っていけばよい。ハチが可愛い
公式サイト
前提:goが使える。
- インストール(環境設定)
- プロジェクト作成
- ルーティング
##インストール
go get -u github.com/beego/bee
go get -u github.com/astaxie/beego
以上
cliツールがあり、今回はAPIとしてプロジェクトを作成
#GOPATH/srcのディレクトリの下で下記コマンド
bee api testapi
#自動的に必要なファイルがtestapi下に生成される
cd testapi
#サーバを起動
bee run -downdoc=true -gendoc=true
[http://127.0.0.1:8080/swagger/]
APIドキュメントもいっしょに作成される
設定は下記ファイルにて行う
testapi\conf\app.conf
ただし、アプリ名はなぜかディレクトリ名となってしまう。解決方法がわかる方いたら教えてほしい
環境別の設定の仕方
ここではまった。
ドキュメントには
[dev]
httpport = 8080
[prod]
httpport = 8088
[test]
httpport = 8888
こんな感じで書いてあるが
bee run -runmode=prod
とか書いてもデフォルト値が設定され動かない。
すると、config.goにこんな記述が…
if os.Getenv("BEEGO_RUNMODE") != "" {
filename = os.Getenv("BEEGO_RUNMODE") + ".app.conf"
}}
なるほど、-runmode=prod
で起動するときは ファイル名をprod.app.conf
にすればよいみたい。
[dev]
httpport = 8080
[dev]
httpport = 8088
動いた!ただbee run で実行するときは/conf/app.conf
が必要
#logの出力の仕方
下記を実行
go get github.com/astaxie/beego/logs
import (
"github.com/astaxie/beego/logs"
)
func main() {
// 一般的
l := logs.GetLogger()
l.Println("this is a message of http")
//ORMのログ
logs.GetLogger("ORM").Println("this is a message of orm")
//デバッグのログ
logs.Debug("my book is bought in the year of ", 2016)
logs.Info("this %s cat is %v years old", "yellow", 3)
logs.Warn("json is a type of kv like", map[string]int{"key": 2016})
logs.Error(1024, "is a very", "good game")
logs.Critical("oh,crash")
}
Migration:マイグレーション
MySQLの設定
mysql> SELECT user, host, plugin FROM mysql.user;
+------------------+-----------+-----------------------+
| user | host | plugin |
+------------------+-----------+-----------------------+
| mysql.infoschema | localhost | caching_sha2_password |
| mysql.session | localhost | caching_sha2_password |
| mysql.sys | localhost | caching_sha2_password |
| root | localhost | mysql_native_password |
+------------------+-----------+-----------------------+
4 rows in set (0.00 sec)
#やらないとこのエラーが出る
Could not show migrations table: The authentication plugin is not supported.
###モデルファイルの作成
beegoのCLIツールで簡単に作れる
bee generate model テーブル名 -fields="name:int"
※-fieldsは適当でよい。後でカラム等は簡単に修正できるため。
bee generate model sample_mst -fields="name:int"`
______
| ___ \
| |_/ / ___ ___
| ___ \ / _ \ / _ \
| |_/ /| __/| __/
\____/ \___| \___| v1.10.0
2019/04/13 04:08:39 INFO ▶ 0001 Using 'Sample_mst' as model name
2019/04/13 04:08:39 INFO ▶ 0002 Using 'models' as package name
create /go/src/xxx/models/sample_mst.go
2019/04/13 04:08:39 SUCCESS ▶ 0003 Model successfully generated!
作成されたファイル↓
(ID)は勝手に挿入される。テーブルのカラムは type Sample_mst struct
の部分で再定義すれば問題ない。
package models
import (
"errors"
"fmt"
"reflect"
"strings"
"github.com/astaxie/beego/orm"
)
//モデル定義
type Sample_mst struct {
Id int64 `orm:"auto"`
Name int
}
func init() {
orm.RegisterModel(new(Sample_mst))
}
// AddSample_mst insert a new Sample_mst into database and returns
// last inserted Id on success.
func AddSample_mst(m *Sample_mst) (id int64, err error) {
o := orm.NewOrm()
id, err = o.Insert(m)
return
}
// GetSample_mstById retrieves Sample_mst by Id. Returns error if
// Id doesn't exist
func GetSample_mstById(id int64) (v *Sample_mst, err error) {
o := orm.NewOrm()
v = &Sample_mst{Id: id}
if err = o.QueryTable(new(Sample_mst)).Filter("Id", id).RelatedSel().One(v); err == nil {
return v, nil
}
return nil, err
}
// GetAllSample_mst retrieves all Sample_mst matches certain condition. Returns empty list if
// no records exist
func GetAllSample_mst(query map[string]string, fields []string, sortby []string, order []string,
offset int64, limit int64) (ml []interface{}, err error) {
o := orm.NewOrm()
qs := o.QueryTable(new(Sample_mst))
// query k=v
for k, v := range query {
// rewrite dot-notation to Object__Attribute
k = strings.Replace(k, ".", "__", -1)
qs = qs.Filter(k, v)
}
// order by:
var sortFields []string
if len(sortby) != 0 {
if len(sortby) == len(order) {
// 1) for each sort field, there is an associated order
for i, v := range sortby {
orderby := ""
if order[i] == "desc" {
orderby = "-" + v
} else if order[i] == "asc" {
orderby = v
} else {
return nil, errors.New("Error: Invalid order. Must be either [asc|desc]")
}
sortFields = append(sortFields, orderby)
}
qs = qs.OrderBy(sortFields...)
} else if len(sortby) != len(order) && len(order) == 1 {
// 2) there is exactly one order, all the sorted fields will be sorted by this order
for _, v := range sortby {
orderby := ""
if order[0] == "desc" {
orderby = "-" + v
} else if order[0] == "asc" {
orderby = v
} else {
return nil, errors.New("Error: Invalid order. Must be either [asc|desc]")
}
sortFields = append(sortFields, orderby)
}
} else if len(sortby) != len(order) && len(order) != 1 {
return nil, errors.New("Error: 'sortby', 'order' sizes mismatch or 'order' size is not 1")
}
} else {
if len(order) != 0 {
return nil, errors.New("Error: unused 'order' fields")
}
}
var l []Sample_mst
qs = qs.OrderBy(sortFields...).RelatedSel()
if _, err = qs.Limit(limit, offset).All(&l, fields...); err == nil {
if len(fields) == 0 {
for _, v := range l {
ml = append(ml, v)
}
} else {
// trim unused fields
for _, v := range l {
m := make(map[string]interface{})
val := reflect.ValueOf(v)
for _, fname := range fields {
m[fname] = val.FieldByName(fname).Interface()
}
ml = append(ml, m)
}
}
return ml, nil
}
return nil, err
}
// UpdateSample_mst updates Sample_mst by Id and returns error if
// the record to be updated doesn't exist
func UpdateSample_mstById(m *Sample_mst) (err error) {
o := orm.NewOrm()
v := Sample_mst{Id: m.Id}
// ascertain id exists in the database
if err = o.Read(&v); err == nil {
var num int64
if num, err = o.Update(m); err == nil {
fmt.Println("Number of records updated in database:", num)
}
}
return
}
// DeleteSample_mst deletes Sample_mst by Id and returns error if
// the record to be deleted doesn't exist
func DeleteSample_mst(id int64) (err error) {
o := orm.NewOrm()
v := Sample_mst{Id: id}
// ascertain id exists in the database
if err = o.Read(&v); err == nil {
var num int64
if num, err = o.Delete(&Sample_mst{Id: id}); err == nil {
fmt.Println("Number of records deleted in database:", num)
}
}
return
}
接続
接続情報は直書してもいいが、/conf/app.conf
に記載する
//mySQLの設定
mysql_driver = "mysql"
mysql_user = "root"
mysql_password = "password"
mysql_host = "127.0.0.1"
mysql_db = "sample-db"
package main
import (
"fmt"
_ "xxx/routers" //自分のルータがあれば
"strings"
"time"
"github.com/astaxie/beego"
_ "github.com/go-sql-driver/mysql"
)
func main() {
beego.Run()
}
func init() {
orm.RegisterDriver("mysql", orm.DRMySQL)
driver := beego.AppConfig.String("mysql_driver")
user := beego.AppConfig.String("mysql_user")
pass := beego.AppConfig.String("mysql_password")
host := beego.AppConfig.String("mysql_host")
port := beego.AppConfig.String("mysql_host")
db := beego.AppConfig.String("mysql_db")
datasource := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8", user, pass, host, port, db)
orm.RegisterDataBase("default", driver, datasource, 30)
}
DBを作成するためにやることは2つ。
モデルにorm.RegisterModel(new(モデル))を追加
mainにorm.RunSyncdb("default", false, true)を追加
RegisterModelはテーブルやカラムがなかった場合、作成してくれる