1

我用mysql-native. 该驱动程序是 supportvibed的连接池。在 dlang 新闻组mysql-native开发人员 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全球化?好吗?还是有更正确的方法?

4

2 回答 2

1
scope(exit) connection.close();

删除该行。connect它会在函数返回之前关闭您刚刚从池中收到的连接。您所做的只是打开一个连接以立即再次关闭它。

更改getUserByName为将连接作为参数(通常作为第一个参数)。通常,任何需要调用的代码都getUserByName应该打开一个连接,或者通过 从池中获取一个连接,lockConnection然后将该连接传递给getUserByName它需要使用的任何其他与 DB 相关的函数。然后,在您的代码完成调用getUserByName(以及它需要调用的任何其他 DB 函数)之后,您要么不再担心连接,而是让您的 vibed 光纤完成(如果您使用 vibed 并从池)或您close的连接(如果您没有从振动池获得连接)。

于 2017-02-07T16:44:19.447 回答
1

一种方法是将连接传递给需要它的函数。因此,您将重构您的 getUserByName() 以将连接作为参数。

另一种选择是使用DAO 模式。DAO 类的构造函数将连接作为主要参数之一,所有方法都将使用它来执行 DB 操作。

于 2017-02-07T09:38:43.003 回答