2017-02-07 11 views
1

私はmysql-nativeを使用しています。このドライバはvibedの接続プールをサポートしています。データベース接続パターン

"接続プールを使用している場合は、接続を閉じることについて心配する必要はありません。ポイントは、接続を使用する必要があるまで接続が開いたままであるということですプログラムが終了すると、接続は自動的に閉じられます。

"プールは一度(いつでもどこでも)作成できます。その後、データベースを使用するたびに、MySqlPool.lockConnectionを呼び出して接続を取得します。

"接続を閉じると、いつでも接続が切断されます。プールから接続していれば、自動的にプールに戻ります。 "

プールのやり方に関する質問はありますか?私はシングルトンパターンについて読んだことがあり、このケースでは理解できません。

私は次のコードを書いた:

database class: 
import std.stdio; 
import std.string; 
import mysql; 
import vibe.d; 

import config; 
import user; 

class Database 
{ 
    Config config; 
    MySqlPool mydb; 
    Connection connection; 

    this(Config config) 
    { 
     this.config = config; 
     mydb = new MySqlPool(config.dbhost, config.dbuser, config.dbpassword, config.dbname, config.dbport);  
    } 

    void connect() 
    { 
     if(connection is null) 
     { 
      connection = mydb.lockConnection(); 
     } 
     scope(exit) connection.close(); 
    } 

} 

ユーザークラス/構造体:

module user; 

import mysql; 
import vibe.d; 

struct User 
{ 
    int id; 
    string login; 
    string password; 
    string usergroup; 
} 
    void getUserByName(string login) 
    { 
     User user; 
     Prepared prepared = prepare(connection, `SELECT id, login, password, usergroup from users WHERE login=?`); // need to get connection accessible here to make request to DB 
     prepared.setArgs(login); 
     ResultRange result = prepared.query(); 
     if (result.empty) 
      logWarn(`user: "%s" do not exists`, login); 
     else 
     { 
       Row row = result.front; 
       user.id = row[0].coerce!(int); 
       user.login = row[1].coerce!string; 
       user.password = row[2].coerce!string; 
       user.usergroup = row[3].coerce!string; 

     logInfo(`user: "%s" is exists`, login); 
     } 

    } 

私はconnectionインスタンスへのアクセスを得るために、適切な方法であるかを理解することができないという問題が。それはusers構造の中にすべての新しいデータベース接続クラスを作成することは非常にばかげた考えです。しかし、それをより良い方法で行うには? Connection connectionをグローバルにするには?いいですか?それとも正しい方法がありますか?

+0

ユーザーの95%以上が接続プーリングを必要としないことをお勧めします。必要になるまで複雑さを避けることをお勧めします。 –

答えて

1
scope(exit) connection.close(); 

この行を削除します。 connect関数が戻る前にプールから受け取ったばかりの接続を閉じています。あなたがしているのは、直ちにもう一度閉じるために接続を開くことだけです。

getUserByNameを(通常は第1引数として)引数として接続するように変更します。通常、getUserByNameを呼び出す必要があるコードは、いずれも接続を開くか、lockConnection経由でプールから接続を取得してから、その接続をgetUserByNameとそれ以外の使用する必要のあるDB関連機能に渡す必要があります。その後、あなたのコードがgetUserByName(とそれを呼び出す必要がある他のDB機能)を呼び出して終了した後、あなたはもう接続について心配する必要はありませんか、あなたのバイブレーションされたファイバーフィニッシュをさせるか(バイブを使用している場合、プール)またはclose接続(あなたが振動プールから接続を取得していない場合)。

+0

私は接続を開いている場合、このコードの動作はすぐにそれを閉じて要求しています。それは失敗するはずですが、それは仕事です... –

1

これを行う1つの方法は、必要な機能に接続を渡すことです。 getUserByName()をリファクタリングして、引数として接続を取得します。

もう1つの方法は、DAO patternを使用することです。あなたのDAOクラスのコンストラクターは、主なパラメーターの1つとして接続を受け取り、すべてのメソッドはDB操作を行うためにそれを使用します。

+0

シングルトンパターンはどうですか?それは私の場合には良いだろうか? –

+0

私はそうは思わない。 – DejanLekic

+0

DejanLekic、なぜ違いはありますか? –