前提
- Go言語そのものに慣れていない
- MySQLはVagrantで適当にCentOS6.6に構築
- MacでGolangの実行環境を整えてトライアンドエラー
- 利用したのは gorm
いざ実践!
- サンプルを写経して、実行。
- 検索結果が取得できない。
- 他のテーブルを検索するようにしたらWarningが表示された。
実行結果
$ go run db_connect.go
該当レコードなし
(Error 1054: Unknown column 'sample.deleted_at' in 'where clause')
[2016-08-14 19:47:53]
該当レコードなし
なぜ検索結果が存在しないのか?
- Rubyとかのアクティブレコードベースの概念だけあって、構造体名とテーブル名の関係は単数 <> 複数の形でないといけなかった
- 単数形のテーブル名を利用したい場合は、単数形のオプションを付けないといけなかった
- db.SingularTable(true)
- ※テーブル名を別途指定する方法もあるが省略
誤り箇所1
CREATE TABLE `sample` (
-- 以降省略
誤り箇所2
type Sample struct {
// 以降省略
なぜ警告が表示されるのか?
- オブジェクト定義の際に、
gorm.Model
としていた箇所のせいで gorm の推奨カラムが追加されていた
誤り箇所
type Sample struct {
gorm.Model
ID uint
Name string `gorm:"type:varchar(45);"`
}
最終的な実行ソース
db_sample.go
// DBアクセスsample.go
package main
import (
"fmt"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
)
type Sample struct {
// メモ:gorm.Modelは構造体で、IDとか勝手に足してくれる存在、CreatedAtとかDeletedAtとか
// テーブル構造が異なる場合は、自分で専用の構造体を用意しないといけない
// ただし、SoftDeleteは上手く動かない?(※要調査)
// gorm.Model
ID uint64 `gorm:"primary_key"`
Name string `gorm:"type:varchar(45);"`
}
type User struct {
ID uint64 `gorm:"primary_key"`
Email string `gorm:"type:varchar(255);"`
Name string `gorm:"type:varchar(45);"`
}
func main() {
db, err := gorm.Open("mysql", "testuser:testuser@/go_sample?charset=utf8&parseTime=True&loc=Local")
if err != nil {
panic("failed to connect database")
}
// テーブル名が複数系でない場合、これを指定すること
db.SingularTable(true)
// 実行ログ出力
db.LogMode(true)
var sample Sample
var count = 0
db.First(&sample, 2).Count(&count)
if count == 0 {
fmt.Println("該当レコードなし")
} else {
fmt.Println("id:" + fmt.Sprint(sample.ID))
fmt.Println("name:" + sample.Name)
}
var user User
db.First(&user).Count(&count)
if count == 0 {
fmt.Println("該当レコードなし")
} else {
fmt.Println("id:" + fmt.Sprint(user.ID))
}
}
ddl_sample.sql
CREATE TABLE `sample` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(45) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
ddl_user.sql
CREATE TABLE `user` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`email` varchar(255) DEFAULT NULL,
`name` varchar(45) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
残課題
- 件数をわざわざ取得しないで存在しないチェックを行いたい
- ID == 0 でも良いけれど、美しくない
TODOリスト
- 複雑な検索結果の取得
- 登録・更新・削除
- トランザクション制御
- リレーションの貼り方、概念的な整理
- デフォルトのカラム構造以外で SoftDelete する方法
- ソースの自動生成