Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql Symfony 4中未使用原始查询的从属项_Mysql_Symfony_Doctrine_Slave_Rawsql - Fatal编程技术网

Mysql Symfony 4中未使用原始查询的从属项

Mysql Symfony 4中未使用原始查询的从属项,mysql,symfony,doctrine,slave,rawsql,Mysql,Symfony,Doctrine,Slave,Rawsql,我使用Symfony 4与现有的主/从MySQL设置接口,并使用原始sql对服务器执行查询。原始SQL是目前唯一的选择 我正在使用ShowFullProcessList;在DB服务器上监视使用哪个DB,我只看到到主服务器的连接。似乎没有任何奴隶被使用过 作为参考,我设置了两个dbal连接,默认设置不是主/从,并使用orm映射。第二个是我遇到问题的主/从服务器,这是我对其执行原始sql查询的服务器 以下是我的原则。yml: doctrine: dbal: default_c

我使用Symfony 4与现有的主/从MySQL设置接口,并使用原始sql对服务器执行查询。原始SQL是目前唯一的选择

我正在使用ShowFullProcessList;在DB服务器上监视使用哪个DB,我只看到到主服务器的连接。似乎没有任何奴隶被使用过

作为参考,我设置了两个dbal连接,默认设置不是主/从,并使用orm映射。第二个是我遇到问题的主/从服务器,这是我对其执行原始sql查询的服务器

以下是我的原则。yml:

doctrine:
    dbal:
        default_connection: default
        connections:
            default:
                driver:   pdo_mysql
                host:     "%env(DATABASE_HOST)%"
                dbname:   "db1"
                user:     "%env(DATABASE_USER)%"
                password: "%env(DATABASE_PASS)%"
                charset:  UTF8
            ds:
                driver:   pdo_mysql
                host:     "%env(DS_DATABASE_HOST)%"
                dbname:   "db2"
                user:     "%env(DS_DATABASE_USER)%"
                password: "%env(DS_DATABASE_PASS)%"
                slaves:
                    slave1:
                        host:     "%env(DS_DATABASE_SLAVE1_HOST)%"
                        user:     "%env(DS_DATABASE_USER)%"
                        password: "%env(DS_DATABASE_PASS)%"
                        dbname:   "db2"
                    slave2:
                        host:     "%env(DS_DATABASE_SLAVE2_HOST)%"
                        user:     "%env(DS_DATABASE_USER)%"
                        password: "%env(DS_DATABASE_PASS)%"
                        dbname:   "db2"

orm:
    default_entity_manager: default
    entity_managers:
        default:
            connection: default
            mappings:
                Main:
                    is_bundle: false
                    type: annotation
                    dir: '%kernel.project_dir%/src/Entity/Main'
                    prefix: 'App\Entity\Main'
                    alias: Main
        ds:
            connection: ds
我已在my services.yml中配置了实体管理器,如下所示:

# Entity managers
App\Service\Database\MainEntityManager:
    arguments:
        $wrapped: '@doctrine.orm.default_entity_manager'
App\Service\Database\DSEntityManager:
    arguments:
        $wrapped: '@doctrine.orm.ds_entity_manager'
实体管理器(在本例中为DSEntityManager)被注入到类的构造函数中,然后按照如下方式执行查询:

    $result = $this->em->getConnection()->prepare($sql);
    $result->execute($args);
如果我缺少任何有用的配置,请告诉我


非常感谢您的帮助。

谢谢@Cerad的提示,这让我找到了正确的方向。由于我不再尝试对未映射到实体的原始查询使用实体管理器,所以我可以直接使用连接

我创建了一个扩展MasterSlaveConnection的包装器类。只要我使用executeQuery(),它就可以工作。根据文档,必须使用它来查询从属对象。但是,我的查询需要使用prepare()和query(),这两种方法都强制主连接

因此,在我的新包装器类中,我创建了两个新方法,prepareSlave()和querySlave(),它们的作用与原来的方法相同;但是,它们执行$this->connect('slave');而不是$this->connect('master')

现在,我所有的读取查询都命中slave,其他所有查询都命中master

因此,以下是我为实现这一目标而对上述配置所做的以下更新:

信条

        ds:
            driver:   pdo_mysql
            host:     "%env(DS_DATABASE_HOST)%"
            dbname:   "db2"
            user:     "%env(DS_DATABASE_USER)%"
            password: "%env(DS_DATABASE_PASS)%"
            wrapper_class: "%env(DS_DATABASE_PASS)%"
            slaves: App\Service\Database\DSWrapper
                slave1: ...
服务.yml

# DBAL connections
App\Service\Database\DSWrapper: '@doctrine.dbal.ds_connection'
我的新包装类

class DSWrapper extends MasterSlaveConnection
{
public function prepareSlave($statement)
{
    $this->connect('slave');

    try {
        $stmt = new Statement($statement, $this);
    } catch (\Exception $ex) {
        throw DBALException::driverExceptionDuringQuery($this->_driver, $ex, $statement);
    }

    $stmt->setFetchMode($this->defaultFetchMode);

    return $stmt;
}

public function querySlave()
{
    $this->connect('slave');

    $args = func_get_args();

    $logger = $this->getConfiguration()->getSQLLogger();
    if ($logger) {
        $logger->startQuery($args[0]);
    }

    $statement = $this->_conn->query(...$args);

    if ($logger) {
        $logger->stopQuery();
    }

    return $statement;
}
}

因此,现在如果我需要执行一个通常需要使用prepare()和query()的查询,我将使用prepareSlave()和querySlave()。

不需要ds实体管理器,您可以直接插入连接对象并使用它。事实上,有一个这样的提示,你可以反对它。从未使用过主/从设备,因此直接注入连接是否真的有用值得怀疑。