2017-02-07 43 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,为什么有什么区别? –