From 94615ea30baa6718c8df1a291710e85c67091d52 Mon Sep 17 00:00:00 2001 From: Shin Kojima Date: Thu, 26 Dec 2013 00:32:29 +0900 Subject: [PATCH] [ja] apply patch --- ja/ebook/05.5.md | 499 +++++++++++++++++++++++------------------------ 1 file changed, 249 insertions(+), 250 deletions(-) diff --git a/ja/ebook/05.5.md b/ja/ebook/05.5.md index ff9427c5..620328b8 100644 --- a/ja/ebook/05.5.md +++ b/ja/ebook/05.5.md @@ -1,250 +1,249 @@ -# 5.5 beedbライブラリを使用してORM開発を行う -beedbは私が開発したGoによるORM操作のためのライブラリです。これはGo styleの方法でデータベースに対し操作を行います。structからテーブルの記録へのマッピングを実現します。beedbは十分軽量なGo ORMフレームワークです。このライブラリを開発した動機は複雑なORM学習曲線を引き下げたいと思ったからです。出来る限りORMの実行効率と機能の間でバランスをとったつもりです。beedbは現在オープンソースのGo ORMフレームワークの中で比較的完全なライブラリのひとつです。また、実行効率も相当良く、機能も基本的に需要を満足させています。しかし現在はまだアソシエーション関係をサポートしておらず、これは次のバージョンの主なポイントです。 - -beedbはdatabase/sql標準インターフェースをサポートしたORMライブラリです。そのため、理論上では、データベースドライバがdatabase/sqlインターフェースをサポートしていさえすればすんなりbeedbを使うことができます。現在までに私がテストしたドライバパッケージは以下のとおり: - -Mysql:github.com/ziutek/mymysql/godrv[*] - -Mysql:code.google.com/p/go-mysql-driver[*] - -PostgreSQL:github.com/bmizerany/pq[*] - -SQLite:github.com/mattn/go-sqlite3[*] - -MS ADODB: github.com/mattn/go-adodb[*] - -ODBC: bitbucket.org/miquella/mgodbc[*] - -## インストール - -beedbはgo get方式によるインストールをサポートしています。これはGo Styleの方式に完全に則って実装されています。 - - go get github.com/astaxie/beedb - -## 初期化の方法 -まず対応するデータベースドライバパッケージをimportする必要があります。database/sql標準インターフェースパッケージおよびbeedbパッケージです: - - import ( - "database/sql" - "github.com/astaxie/beedb" - _ "github.com/ziutek/mymysql/godrv" - ) - -必要なパッケージをインポートした後、データベースへの接続を開く必要があります。その後beedbオブジェクト(たとえばMySQLとします)を作成します - - db, err := sql.Open("mymysql", "test/xiemengjun/123456") - if err != nil { - panic(err) - } - orm := beedb.New(db) - -beedbのNew関数は2つの引数を必要とします。一つ目の引数は標準インターフェースのdbで、二つ目の引数は利用するデータベースエンジンです。もしあなたが使用するデータベースエンジンがMySQL/Sqliteだった場合、二つ目の引数は省略してもかまいません。 - -もしSQLServerをお使いであれば、このように初期化する必要があります: - - orm = beedb.New(db, "mssql") - -もしPostgreSQLをお使いであれば、初期化は以下のようになります: - - orm = beedb.New(db, "pg") - -現在beedbはプリントデバッグをサポートしていますので、下のコードでデバッグを行うことができます。 - - beedb.OnDebug=true - -以降の例では前のデータベースのテーブルUserinfoを採用します。まず目的のstructを作成します。 - - type Userinfo struct { - Uid int `PK` //もしテーブルのプライマリキーがidでなければ、pkコメントを追加する必要があります。このフィールドがプライマリキーであることを明示します。 - Username string - Departname string - Created time.Time - } - ->ご注意ください。beedbはキャメルケースの命名規則を自動でスネークケースのフィールドに変換します。たとえば`UserInfo`という名前のStructを定義した場合、低レイヤで実装される際に`user_info`と変換されます。フィールドの命名もこのルールに従います。 - -## データの挿入 -下のコードはどのように記録を挿入するか示しています。我々が操作しているのはstructオブジェクトで、元々のsql文ではありません。Saveインターフェースをコールしてデータをデータベースに保存します。 - - var saveone Userinfo - saveone.Username = "Test Add User" - saveone.Departname = "Test Add Departname" - saveone.Created = time.Now() - orm.Save(&saveone) - -挿入後、挿入に成功した際のインクリメンタルなIDが`saveone.Uid`です。Saveインターフェースは自動的に保存します。 - -beedbインターフェースはもう一種類の挿入の方法を提供しています。mapデータ挿入です。 - - add := make(map[string]interface{}) - add["username"] = "astaxie" - add["departname"] = "cloud develop" - add["created"] = "2012-12-02" - orm.SetTable("userinfo").Insert(add) - -複数のデータを挿入 - - addslice := make([]map[string]interface{}) - add:=make(map[string]interface{}) - add2:=make(map[string]interface{}) - add["username"] = "astaxie" - add["departname"] = "cloud develop" - add["created"] = "2012-12-02" - add2["username"] = "astaxie2" - add2["departname"] = "cloud develop2" - add2["created"] = "2012-12-02" - addslice =append(addslice, add, add2) - orm.SetTable("userinfo").Insert(addslice) - -上の操作方法はメソッドチェーンによる検索にすこし似ています。jqueryに詳しい方はとても馴染みがあるのではないでしょうか。毎回コールされるmethodはすべてもともとのormオブジェクトを返しているので、継続してオブジェクトの他のmethodをコールすることができます。 - -上でコールしたSetTable関数はORMに対して、これから実行するこのmapに対応したデータベーステーブルが`userinfo`であると明示しています。 - -## データの更新 -つづけて上の例で更新操作をご覧にいれましょう。現在saveoneのプライマリキーはすでに値が存在します。この時saveインターフェースをコールして、beedb内は自動的にupdateをコールすることによってデータの更新を行います。挿入操作ではありません。 - - saveone.Username = "Update Username" - saveone.Departname = "Update Departname" - saveone.Created = time.Now() - orm.Save(&saveone) //現在saveoneにはプライマリキーがあります。更新操作を行います。 - -データの更新はmap操作の直接の使用をサポートしています。 - - t := make(map[string]interface{}) - t["username"] = "astaxie" - orm.SetTable("userinfo").SetPK("uid").Where(2).Update(t) - -ここではいくつかのbeedbの関数をコールしてみます。 - -SetPK:ORMに対して、データベースのテーブル`userinfo`のプライマリキーが`uid`であることを明示します。 - -Where:条件を設定するために用いられます。複数の引数をサポートし、第一引数がもし整数であった場合、Where("プライマリキー=?",値)がコールされたものとなります。 -Update関数はmap型のデータを受け取り、データの更新を実行します。 - -## データの検索 -beedbの検索インターフェースは使いやすく、具体的な使用方法は下の例をご覧ください。 - -例1、プライマリキーによってデータを取得: - - var user Userinfo - //Whereは2つの引数を受け取ります。int型の引数をサポートします。 - orm.Where("uid=?", 27).Find(&user) - - -例2: - - var user2 Userinfo - orm.Where(3).Find(&user2) // これは上の省略版です。プライマリキーは省略できます。 - -例3、プライマリキーではない条件: - - var user3 Userinfo - //Whereは2つの引数を受け取ります。文字列型の引数をサポートします。 - orm.Where("name = ?", "john").Find(&user3) -例4、もっと複雑な条件: - - var user4 Userinfo - //Whereは3つの引数をサポートします。 - orm.Where("name = ? and age < ?", "john", 88).Find(&user4) - - -下のインターフェースを通して複数のデータを取得できます。例をご覧ください。 - -例1、条件id>3にもとづいて、20からはじまる10件のデータを取得します。 - - var allusers []Userinfo - err := orm.Where("id > ?", "3").Limit(10,20).FindAll(&allusers) - -例2、limitの第二引数は省略できます。デフォルトは0から開始となります。10件のデータを取得します。 - - var tenusers []Userinfo - err := orm.Where("id > ?", "3").Limit(10).FindAll(&tenusers) - -例3、すべてのデータを取得します。 - - var everyone []Userinfo - err := orm.OrderBy("uid desc,username asc").FindAll(&everyone) - -上ではLimit関数があります。これは検索結果の数をコントロールするのに用いられます。 - -Limit:2つの引数をサポートします。第一引数は検索数を表し、第二引数は取得するデータの開始位置を表しています。デフォルトは0です。 - -OrderBy:この関数は検索をソートするために用いられます。引数はソートの条件である必要があります。 - -上の例では取得するデータが直接structオブジェクトにマッピングされます。もし、データをmapとして取得したいだけであれば、下の方法で実現することができます: - - a, _ := orm.SetTable("userinfo").SetPK("uid").Where(2).Select("uid,username").FindMap() - -上とこの例の中ではまた新しいインターフェースの関数Selectがでてきました。この関数はいくつのフィールドを検索したいのか定義するために用いられます。デフォルトでは全てのフィールドとなる`*`となります。 - -FindMap()関数は`[]map[string][]byte`型を返します。そのため、自分自身で型変換を行う必要があります。 - -## データの削除 -beedbは豊富なデータ削除インターフェースを備えています。下の例をご覧ください。 - -例1、単一のデータを削除 - - //saveoneは上の例で示したあのsaveoneです。 - orm.Delete(&saveone) - -例2、複数のデータを削除 - - //alluserは上で定義した複数のデータのsliceです。 - orm.DeleteAll(&alluser) - -例3、sqlにしたがってデータを削除 - - orm.SetTable("userinfo").Where("uid>?", 3).DeleteRow() - - -## リレーション検索 -現在beedbはstructのリレーションをサポートしていません。しかしいくつかのアプリケーションはリレーションによる検索を必要としています。そのため、現在beedbは簡単なソリューションを提供しています。 - - a, _ := orm.SetTable("userinfo").Join("LEFT", "userdeatail", "userinfo.uid=userdeatail.uid").Where("userinfo.uid=?", 1).Select("userinfo.uid,userinfo.username,userdeatail.profile").FindMap() - -上のコードでは新しいインターフェースのJoin関数が出て来ました。この関数には3つの引数があります。 - -- 第一引数には:INNER, LEFT, OURTER, CROSS等が入れられます -- 第二匹数は接続するテーブルを表します -- 第三引数は接続の条件を表します - - -## Group ByとHaving -いくつかのアプリケーションがgroup byとhavingの機能を必要としているため、beedbも簡単な実現方法を提供しています。 - - a, _ := orm.SetTable("userinfo").GroupBy("username").Having("username='astaxie'").FindMap() - -上のコードで現れる2つの新しいインターフェースの関数 - -GroupBy:groupbyのフィールドを実行するために用いられます - -Having:havingを実行する際の条件を指定するために用いられます - -## 一歩進んで -現在beedbはすでに多くの国内外からのユーザによってフィードバックを得ています。現在作り直しを考えています。以降ではいくつかの方面で改良が行われる予定です。 - -- interface設計の実装。database/sql/driverの設計に似て、beedbのインターフェースを設計します。その後対応するデータベースのCRUD操作を実現します。 -- リレーショナルデータベースの設計の実現。一対一、一対多、多対多のサポートを実現します。コードは以下のとおり: - - - type Profile struct{ - Nickname string - Mobile string - } - - type Userinfo struct { - Uid int `PK` - Username string - Departname string - Created time.Time - Profile `HasOne` - } - -- 自動的にデータベース、テーブル、インデックスを作成 -- 接続プールの実現、goroutineを採用。 - -## links - * [目次]() - * 前へ: [PostgreSQLデータベースの使用](<05.4.md>) - * 次へ: [NOSQLデータベースの操作](<05.6.md>) - +# 5.5 beedbライブラリを使用してORM開発を行う +beedbは私が開発したGoによるORM操作のためのライブラリです。これはGo styleの方法でデータベースに対し操作を行います。structからテーブルの記録へのマッピングを実現します。beedbは十分軽量なGo ORMフレームワークです。このライブラリを開発した動機は複雑なORM学習曲線を引き下げたいと思ったからです。出来る限りORMの実行効率と機能の間でバランスをとったつもりです。beedbは現在オープンソースのGo ORMフレームワークの中で比較的完全なライブラリのひとつです。また、実行効率も相当良く、機能も基本的に需要を満足させています。しかし現在はまだアソシエーション関係をサポートしておらず、これは次のバージョンの主なポイントです。 + +beedbはdatabase/sql標準インターフェースをサポートしたORMライブラリです。そのため、理論上では、データベースドライバがdatabase/sqlインターフェースをサポートしていさえすればすんなりbeedbを使うことができます。現在までに私がテストしたドライバパッケージは以下のとおり: + +Mysql:github.com/ziutek/mymysql/godrv[*] + +Mysql:code.google.com/p/go-mysql-driver[*] + +PostgreSQL:github.com/bmizerany/pq[*] + +SQLite:github.com/mattn/go-sqlite3[*] + +MS ADODB: github.com/mattn/go-adodb[*] + +ODBC: bitbucket.org/miquella/mgodbc[*] + +## インストール + +beedbはgo get方式によるインストールをサポートしています。これはGo Styleの方式に完全に則って実装されています。 + + go get github.com/astaxie/beedb + +## 初期化の方法 +まず対応するデータベースドライバパッケージをimportする必要があります。database/sql標準インターフェースパッケージおよびbeedbパッケージです: + + import ( + "database/sql" + "github.com/astaxie/beedb" + _ "github.com/ziutek/mymysql/godrv" + ) + +必要なパッケージをインポートした後、データベースへの接続を開く必要があります。その後beedbオブジェクト(たとえばMySQLとします)を作成します + + db, err := sql.Open("mymysql", "test/xiemengjun/123456") + if err != nil { + panic(err) + } + orm := beedb.New(db) + +beedbのNew関数は2つの引数を必要とします。一つ目の引数は標準インターフェースのdbで、二つ目の引数は利用するデータベースエンジンです。もしあなたが使用するデータベースエンジンがMySQL/Sqliteだった場合、二つ目の引数は省略してもかまいません。 + +もしSQLServerをお使いであれば、このように初期化する必要があります: + + orm = beedb.New(db, "mssql") + +もしPostgreSQLをお使いであれば、初期化は以下のようになります: + + orm = beedb.New(db, "pg") + +現在beedbはプリントデバッグをサポートしていますので、下のコードでデバッグを行うことができます。 + + beedb.OnDebug=true + +以降の例では前のデータベースのテーブルUserinfoを採用します。まず目的のstructを作成します。 + + type Userinfo struct { + Uid int `PK` //もしテーブルのプライマリキーがidでなければ、pkコメントを追加する必要があります。このフィールドがプライマリキーであることを明示します。 + Username string + Departname string + Created time.Time + } + +>ご注意ください。beedbはキャメルケースの命名規則を自動でスネークケースのフィールドに変換します。たとえば`UserInfo`という名前のStructを定義した場合、低レイヤで実装される際に`user_info`と変換されます。フィールドの命名もこのルールに従います。 + +## データの挿入 +下のコードはどのように記録を挿入するか示しています。我々が操作しているのはstructオブジェクトで、元々のsql文ではありません。Saveインターフェースをコールしてデータをデータベースに保存します。 + + var saveone Userinfo + saveone.Username = "Test Add User" + saveone.Departname = "Test Add Departname" + saveone.Created = time.Now() + orm.Save(&saveone) + +挿入後、挿入に成功した際のインクリメンタルなIDが`saveone.Uid`です。Saveインターフェースは自動的に保存します。 + +beedbインターフェースはもう一種類の挿入の方法を提供しています。mapデータ挿入です。 + + add := make(map[string]interface{}) + add["username"] = "astaxie" + add["departname"] = "cloud develop" + add["created"] = "2012-12-02" + orm.SetTable("userinfo").Insert(add) + +複数のデータを挿入 + + addslice := make([]map[string]interface{}) + add:=make(map[string]interface{}) + add2:=make(map[string]interface{}) + add["username"] = "astaxie" + add["departname"] = "cloud develop" + add["created"] = "2012-12-02" + add2["username"] = "astaxie2" + add2["departname"] = "cloud develop2" + add2["created"] = "2012-12-02" + addslice =append(addslice, add, add2) + orm.SetTable("userinfo").InsertBatch(addslice) + +上の操作方法はメソッドチェーンによる検索にすこし似ています。jqueryに詳しい方はとても馴染みがあるのではないでしょうか。毎回コールされるmethodはすべてもともとのormオブジェクトを返しているので、継続してオブジェクトの他のmethodをコールすることができます。 + +上でコールしたSetTable関数はORMに対して、これから実行するこのmapに対応したデータベーステーブルが`userinfo`であると明示しています。 + +## データの更新 +つづけて上の例で更新操作をご覧にいれましょう。現在saveoneのプライマリキーはすでに値が存在します。この時saveインターフェースをコールして、beedb内は自動的にupdateをコールすることによってデータの更新を行います。挿入操作ではありません。 + + saveone.Username = "Update Username" + saveone.Departname = "Update Departname" + saveone.Created = time.Now() + orm.Save(&saveone) //現在saveoneにはプライマリキーがあります。更新操作を行います。 + +データの更新はmap操作の直接の使用をサポートしています。 + + t := make(map[string]interface{}) + t["username"] = "astaxie" + orm.SetTable("userinfo").SetPK("uid").Where(2).Update(t) + +ここではいくつかのbeedbの関数をコールしてみます。 + +SetPK:ORMに対して、データベースのテーブル`userinfo`のプライマリキーが`uid`であることを明示します。 + +Where:条件を設定するために用いられます。複数の引数をサポートし、第一引数がもし整数であった場合、Where("プライマリキー=?",値)がコールされたものとなります。 +Update関数はmap型のデータを受け取り、データの更新を実行します。 + +## データの検索 +beedbの検索インターフェースは使いやすく、具体的な使用方法は下の例をご覧ください。 + +例1、プライマリキーによってデータを取得: + + var user Userinfo + //Whereは2つの引数を受け取ります。int型の引数をサポートします。 + orm.Where("uid=?", 27).Find(&user) + + +例2: + + var user2 Userinfo + orm.Where(3).Find(&user2) // これは上の省略版です。プライマリキーは省略できます。 + +例3、プライマリキーではない条件: + + var user3 Userinfo + //Whereは2つの引数を受け取ります。文字列型の引数をサポートします。 + orm.Where("name = ?", "john").Find(&user3) +例4、もっと複雑な条件: + + var user4 Userinfo + //Whereは3つの引数をサポートします。 + orm.Where("name = ? and age < ?", "john", 88).Find(&user4) + + +下のインターフェースを通して複数のデータを取得できます。例をご覧ください。 + +例1、条件id>3にもとづいて、20からはじまる10件のデータを取得します。 + + var allusers []Userinfo + err := orm.Where("id > ?", "3").Limit(10,20).FindAll(&allusers) + +例2、limitの第二引数は省略できます。デフォルトは0から開始となります。10件のデータを取得します。 + + var tenusers []Userinfo + err := orm.Where("id > ?", "3").Limit(10).FindAll(&tenusers) + +例3、すべてのデータを取得します。 + + var everyone []Userinfo + err := orm.OrderBy("uid desc,username asc").FindAll(&everyone) + +上ではLimit関数があります。これは検索結果の数をコントロールするのに用いられます。 + +Limit:2つの引数をサポートします。第一引数は検索数を表し、第二引数は取得するデータの開始位置を表しています。デフォルトは0です。 + +OrderBy:この関数は検索をソートするために用いられます。引数はソートの条件である必要があります。 + +上の例では取得するデータが直接structオブジェクトにマッピングされます。もし、データをmapとして取得したいだけであれば、下の方法で実現することができます: + + a, _ := orm.SetTable("userinfo").SetPK("uid").Where(2).Select("uid,username").FindMap() + +上とこの例の中ではまた新しいインターフェースの関数Selectがでてきました。この関数はいくつのフィールドを検索したいのか定義するために用いられます。デフォルトでは全てのフィールドとなる`*`となります。 + +FindMap()関数は`[]map[string][]byte`型を返します。そのため、自分自身で型変換を行う必要があります。 + +## データの削除 +beedbは豊富なデータ削除インターフェースを備えています。下の例をご覧ください。 + +例1、単一のデータを削除 + + //saveoneは上の例で示したあのsaveoneです。 + orm.Delete(&saveone) + +例2、複数のデータを削除 + + //alluserは上で定義した複数のデータのsliceです。 + orm.DeleteAll(&alluser) + +例3、sqlにしたがってデータを削除 + + orm.SetTable("userinfo").Where("uid>?", 3).DeleteRow() + + +## リレーション検索 +現在beedbはstructのリレーションをサポートしていません。しかしいくつかのアプリケーションはリレーションによる検索を必要としています。そのため、現在beedbは簡単なソリューションを提供しています。 + + a, _ := orm.SetTable("userinfo").Join("LEFT", "userdeatail", "userinfo.uid=userdeatail.uid").Where("userinfo.uid=?", 1).Select("userinfo.uid,userinfo.username,userdeatail.profile").FindMap() + +上のコードでは新しいインターフェースのJoin関数が出て来ました。この関数には3つの引数があります。 + +- 第一引数には:INNER, LEFT, OURTER, CROSS等が入れられます +- 第二匹数は接続するテーブルを表します +- 第三引数は接続の条件を表します + + +## Group ByとHaving +いくつかのアプリケーションがgroup byとhavingの機能を必要としているため、beedbも簡単な実現方法を提供しています。 + + a, _ := orm.SetTable("userinfo").GroupBy("username").Having("username='astaxie'").FindMap() + +上のコードで現れる2つの新しいインターフェースの関数 + +GroupBy:groupbyのフィールドを実行するために用いられます + +Having:havingを実行する際の条件を指定するために用いられます + +## 一歩進んで +現在beedbはすでに多くの国内外からのユーザによってフィードバックを得ています。現在作り直しを考えています。以降ではいくつかの方面で改良が行われる予定です。 + +- interface設計の実装。database/sql/driverの設計に似て、beedbのインターフェースを設計します。その後対応するデータベースのCRUD操作を実現します。 +- リレーショナルデータベースの設計の実現。一対一、一対多、多対多のサポートを実現します。コードは以下のとおり: + + + type Profile struct{ + Nickname string + Mobile string + } + + type Userinfo struct { + Uid int `PK` + Username string + Departname string + Created time.Time + Profile `HasOne` + } + +- 自動的にデータベース、テーブル、インデックスを作成 +- 接続プールの実現、goroutineを採用。 + +## links + * [目次]() + * 前へ: [PostgreSQLデータベースの使用](<05.4.md>) + * 次へ: [NOSQLデータベースの操作](<05.6.md>)