symfony7之doctrine.yaml配置
doctrine:
dbal:
connections:
default: # 主数据库连接
server_version: '8.0'
url: '%env(resolve:DATABASE_PRIMARY_URL)%'
driver: pdo_mysql
charset: utf8mb4
default_table_options:
collate: utf8mb4_unicode_ci
mapping_types:
enum: string
schema_filter: ~^(?!(messenger_messages|migration_versions)$)~
replicas: # 让 SELECT 语句自动走 secondary(从库)
secondary:
url: '%env(resolve:DATABASE_SECONDARY_URL)%'
secondary: # 额外手动指定的从库连接
url: '%env(resolve:DATABASE_SECONDARY_URL)%'
default_connection: default
orm:
auto_generate_proxy_classes: true
enable_lazy_ghost_objects: true
default_entity_manager: default # 默认 entity_manager
entity_managers:
default:
connection: default # 绑定到 dbal.connections.default
mappings:
App:
dir: '%kernel.project_dir%/src/Entity'
prefix: 'App\Entity'
alias: App
tree:
type: attribute # or annotation or xml
alias: Gedmo
prefix: Gedmo\Tree\Entity
dir: "%kernel.project_dir%/vendor/gedmo/doctrine-extensions/src/Tree/Entity"
# add qinhongpub databases so doctrine can ignore them while executing 'doctrine:migration:diff' command
schema_ignore_classes:
- App\Entity\qinhongpub\User
- App\Entity\qinhongpub\Continent
- App\Entity\qinhongpub\Country
- App\Entity\qinhongpub\UserJobtype
- App\Entity\qinhongpub\UserMultipleEmail
- App\Entity\qinhongpub\UserTitle
- App\Entity\qinhongpub\UserWorkplace
- App\Entity\qinhongpub\EmailUserRel
- App\Entity\qinhongpub\ExchangeRate
dql:
string_functions:
concat_ws: DoctrineExtensions\Query\Mysql\ConcatWs
secondary:
connection: secondary # 绑定 `dbal.connections.secondary`
mappings:
App:
dir: '%kernel.project_dir%/src/Entity'
prefix: 'App\Entity'
alias: App
tree:
type: attribute # or annotation or xml
alias: Gedmo
prefix: Gedmo\Tree\Entity
dir: "%kernel.project_dir%/vendor/gedmo/doctrine-extensions/src/Tree/Entity"
dql:
string_functions:
concat_ws: DoctrineExtensions\Query\Mysql\ConcatWs
使用
先在 service.yaml下配置binbd参数
bind:
$em: "@doctrine.orm.default_entity_manager" # _entity_manager 是一个固定的格式,通常是为了与 Doctrine 的内部约定保持一致。Doctrine 会根据配置的 entity_managers 部分的名称自动生成这些实体管理器的服务名称。如果您定义了多个实体管理器(如 default、secondary、third),Doctrine 会为每个管理器生成对应的服务名称,后缀 _entity_manager 是固定的。
$emSlave: "@doctrine.orm.secondary_entity_manager" # _entity_manager 是一个固定的格式,通常是为了与 Doctrine 的内部约定保持一致。Doctrine 会根据配置的 entity_managers 部分的名称自动生成这些实体管理器的服务名称。如果您定义了多个实体管理器(如 default、secondary、third),Doctrine 会为每个管理器生成对应的服务名称,后缀 _entity_manager 是固定的。
例子:
use Doctrine\ORM\EntityManagerInterface;
class MyService
{
private EntityManagerInterface $em;
private EntityManagerInterface $emSlave;
public function __construct(EntityManagerInterface $em, EntityManagerInterface $emSlave)
{
$this->em = $em;
$this->emSlave = $emSlave;
}
public function fetchData()
{
// 从主数据库查询
$data = $this->em->getRepository(SomeEntity::class)->findAll();
// 从从数据库查询
$dataSlave = $this->emSlave->getRepository(SomeEntity::class)->findAll();
return [$data, $dataSlave];
}
}
// 手动切换数据库连接
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\Persistence\ManagerRegistry;
class YourService
{
public function __construct(
private readonly EntityManagerInterface $em,
private readonly ManagerRegistry $doctrine, // 允许手动获取不同的 EntityManager
) {
}
public function getUserFromSlave(int $id)
{
$emSlave = $this->doctrine->getManager('secondary'); // 获取 secondary EntityManager
return $emSlave->getRepository(User::class)->find($id);
}
}
分析
dbal(Database Abstraction Layer[数据库抽象层]) 和 orm(Object-Relational Mapper[ORM 映射层]) 是两个不同的部分,它们各自负责不同的任务,但相互配合使用。
dbal:
作用:
负责管理数据库连接
处理SQL 语句的执行
支持多个数据库连接
提供事务管理
上面配置分析:
dbal.connections.default
这是主数据库连接
replicas 让 SELECT 查询可以自动走 secondary (所以当前的配置,,默认就通过replicas实现了主从数据库操作)
dbal.connections.secondary
这是额外定义的从库连接
主要用于手动切换 EntityManager 使用
default_connection: default
默认情况下,Doctrine 会使用 default 连接
👉 结论:dbal 只管数据库连接,不涉及 ORM 映射
orm:
作用:
负责实体(Entity)和数据库表的映射
让你用 PHP 对象 而不是 SQL 语句操作数据库
需要 EntityManager 来管理数据库操作
支持 多个 EntityManager,每个 EntityManager 可以绑定不同的数据库连接
上面配置分析:
default_entity_manager: default
默认 EntityManager 绑定 dbal.connections.default
entity_managers.default.connection: default
这个 EntityManager 绑定到 default(主数据库)
entity_managers.secondary.connection: secondary
这个 EntityManager 绑定到 secondary(从数据库)
最终效果:
默认 ORM 查询会自动使用 dbal.default
如果是 SELECT 语句,Doctrine 会自动切换到 replicas.secondary
如果是 INSERT/UPDATE/DELETE 语句,Doctrine 仍然使用 dbal.default(主库)
如果手动指定 orm.entity_managers.secondary,那么所有操作都走 dbal.connections.secondary
