2017-02-07 47 views
1

我使用mysql-native。該驅動程序支持vibed的連接池。在dlang新聞組開發者Nick Sabalausky寫道:數據庫連接模式

「如果你使用的是連接池,你不需要擔心關閉連接,整個過程就是連接保持打開狀態,直到你需要使用連接池當你的程序結束時,連接將自行關閉。「

「您可以創建一次池(無論何時何地)。然後,每次要使用數據庫時,都可以通過調用MySqlPool.lockConnection來獲得連接。」

「調用'close'將始終關閉連接,如果你從池中獲得了連接,那麼當你不再使用它時它會自動返回到池中,不需要做任何特別的事情。 「

關於如何完成池的問題?我已閱讀關於單身模式,不能不知道是這種情況。

我寫了下面的代碼:

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將連接作爲參數(通常作爲第一個參數)。通常情況下,無論代碼需要調用getUserByName都應該打開一個連接,或通過lockConnection從池中獲取連接,然後將該連接傳遞給getUserByName以及任何其他需要使用的與DB相關的功能。然後,在您的代碼完成後,調用getUserByName(以及其他任何需要調用的數據庫功能),您不必擔心連接問題,並讓您的振動光纖完成(如果您使用振動並獲得了連接一個池),或者你連接(如果你沒有從振動池中獲得連接)。

+0

但是如果我打開連接,立即關閉它並請求,該代碼如何工作。它應該失敗,但它的工作... –

1

一種方法是將連接傳遞給需要它的函數。所以你會重構你的getUserByName()來將連接作爲參數。

另一種選擇是使用DAO pattern。您的DAO類的構造函數會將連接作爲主要參數之一,並且所有方法都將使用它來執行數據庫操作。

+0

單身模式呢?對我的情況好嗎? –

+0

我不這麼認爲。 – DejanLekic

+0

DejanLekic,爲什麼有什麼區別? –