effiana / doctrine-json-odm
使用现代关系型数据库管理系统(RDBMS)的JSON类型,为Doctrine ORM提供对象文档映射器。
Requires
- php: ^7.2
- doctrine/orm: ^2.5
- symfony/property-access: ^4.2
- symfony/property-info: ^4.2
- symfony/serializer: ^4.2
Requires (Dev)
- doctrine/doctrine-bundle: ^1.6
- phpunit/phpunit: ^7.5
- symfony/finder: ^4.2
- symfony/framework-bundle: ^4.2
- symfony/phpunit-bridge: ^4.2
This package is auto-updated.
Last update: 2024-09-18 02:47:05 UTC
README
Doctrine ORM的对象文档映射器(ODM),利用现代关系型数据库管理系统(RDBMS)的新JSON类型。
你是否曾经梦想过一款工具,可以将传统高效的数据库映射与现代无模式和无SQL风格的数据库映射结合起来创建强大的数据模型?
使用Doctrine JSON ODM,现在可以轻松创建和查询这种混合数据模型。得益于现代关系型数据库管理系统的JSON类型,查询无模式文档变得容易、强大且非常快速(性能与MongoDB数据库相似)!您甚至可以为这些文档定义索引。
Doctrine JSON ODM允许将PHP对象以JSON文档的形式存储在关系型数据库管理系统的动态列中。它与PostgreSQL(>= 9.4)的JSON和JSONB列以及MySQL(>= 5.7.8)的JSON列兼容。
有关Doctrine JSON ODM背后的概念更多信息,请参阅Benjamin Eberlei在Symfony Catalunya 2016上给出的演示。
安装
要安装此库,请使用Composer,PHP包管理器
composer require dunglas/doctrine-json-odm
如果您使用Symfony 4+或API Platform,您无需做任何操作!如果您直接使用Doctrine,请使用类似以下的自启动代码
<?php require_once __DIR__.'/../vendor/autoload.php'; // Adapt to your path use Doctrine\DBAL\Types\Type; use Doctrine\ORM\EntityManager; use Doctrine\ORM\Tools\Setup; use Effiana\DoctrineJsonOdm\Normalizer\ObjectNormalizer; use Effiana\DoctrineJsonOdm\Type\JsonDocumentType; use Symfony\Component\Serializer\Encoder\JsonEncoder; use Symfony\Component\Serializer\Serializer; use Symfony\Component\Serializer\Normalizer\ObjectNormalizer as BaseObjectNormalizer; if (!Type::hasType('json_document')) { Type::addType('json_document', JsonDocumentType::class); Type::getType('json_document')->setSerializer( new Serializer([new ObjectNormalizer(new BaseObjectNormalizer())], [new JsonEncoder()]) ); } // Sample bootstrapping code here, adapt to fit your needs $isDevMode = true; $config = Setup::createAnnotationMetadataConfiguration([__DIR__ . '/../src'], $_ENV['DEBUG'] ?? false); // Adapt to your path $conn = [ 'dbname' => $_ENV['DATABASE_NAME'], 'user' => $_ENV['DATABASE_USER'], 'password' => $_ENV['DATABASE_PASSWORD'], 'host' => $_ENV['DATABASE_HOST'], 'driver' => 'pdo_mysql' // or pdo_pgsql ]; return EntityManager::create($conn, $config);
使用Symfony 2和3安装
此库为Symfony框架提供了一个包。如果您使用Symfony 4+,它会自动注册。对于Symfony 2和3,您必须自行注册
// ... use Doctrine\Bundle\DoctrineBundle\DoctrineBundle; use Effiana\DoctrineJsonOdm\Bundle\DunglasDoctrineJsonOdmBundle; use Symfony\Bundle\FrameworkBundle\FrameworkBundle; use Symfony\Component\HttpKernel\Kernel; class AppKernel extends Kernel { public function registerBundles() { return [ new FrameworkBundle(), new DoctrineBundle(), new DunglasDoctrineJsonOdmBundle(), // ... ]; } // ... }
使用方法
Doctrine JSON ODM为Doctrine实体的属性提供了json_document
列类型。
使用此类型映射的属性的 内容使用Symfony Serializer序列化,然后存储在数据库的动态JSON列中。
当对象将被活化时,该列的JSON内容将再次转换回原始值,再次得益于Symfony Serializer。所有PHP对象和结构都将被保留(如果您使用Symfony >= 3.1,请参阅常见问题解答)。
您可以使用json_document
类型将任何类型的(可序列化的)PHP数据结构存储在映射的属性中。
示例
namespace AppBundle\Entity; use Doctrine\ORM\Mapping as ORM; /** * This is a typical Doctrine ORM entity. * * @ORM\Entity */ class Foo { /** * @ORM\Column(type="integer") * @ORM\Id * @ORM\GeneratedValue(strategy="AUTO") */ public $id; /** * @ORM\Column(type="string") */ public $name; /** * Can contain anything (array, objects, nested objects...). * * @ORM\Column(type="json_document", options={"jsonb": true}) */ public $misc; // Works with private and protected methods with getters and setters too. }
namespace AppBundle\Entity; /** * This is NOT an entity! It's a POPO (Plain Old PHP Object). It can contain anything. */ class Bar { public $title; public $weight; }
namespace AppBundle\Entity; /** * This is NOT an entity. It's another POPO and it can contain anything. */ class Baz { public $name; public $size; }
将随机对象图存储在数据库的JSON类型中
// $entityManager = $this->get('doctrine')->getManagerForClass(AppBundle\Entity\Foo::class); $bar = new Bar(); $bar->title = 'Bar'; $bar->weight = 12; $baz = new Baz(); $baz->name = 'Baz'; $baz->size = 7; $foo = new Foo(); $foo->name = 'Foo'; $foo->misc = [$bar, $baz] $entityManager->persist($foo); $entityManager->flush();
检索对象图
$foo = $entityManager->find(Foo::class, $foo->getId()); var_dump($foo->misc); // Same as what we set earlier
您可以使用原生查询执行复杂查询。请参阅PostgreSQL文档或MySQL文档了解如何查询存储的JSON文档。
常见问题解答
支持哪些数据库管理系统(DBMS)?
支持PostgreSQL 9.4+和MySQL 5.7+。
支持Doctrine的哪些版本?
支持 Doctrine ORM 2.6+ 和 DBAL 2.6+。
然后,您需要在列映射中设置一个选项
// ... /** * @ORM\Column(type="json_document", options={"jsonb": true}) */ public $foo; // ...
ODM 支持嵌套对象和对象图吗?
是的。
如何添加额外的规范器?
Symfony 序列化器易于扩展。此包注册并使用 ID 为 effiana_doctrine_json_odm.serializer
的服务作为 JSON 类型的序列化器。这意味着我们可以轻松地在我们的 services.yaml
中覆盖它以使用额外的规范器。例如,我们使用 Symfony 的 DateTimeNormalizer
服务,因此我们支持任何是 \DateTimeInterface
实例的属性。请注意,规范器的顺序可能与您使用的规范器相关。
# Add DateTime Normalizer to Dunglas' Doctrine JSON ODM Bundle effiana_doctrine_json_odm.serializer: class: Symfony\Component\Serializer\Serializer arguments: - ['@serializer.normalizer.datetime', '@effiana_doctrine_json_odm.normalizer.object'] - ['@serializer.encoder.json'] public: true
作为旁注:如果您在 services.yaml
中使用自动注入,您可能还需要设置 autowire: false
。
运行测试
要执行测试套件,您需要运行 PostgreSQL 和 MySQL 服务器。在您的 shell 中运行以下命令以设置必需的环境变量
export POSTGRESQL_HOST=127.0.0.1
export POSTGRESQL_USER=dunglas
export POSTGRESQL_PASSWORD=
export POSTGRESQL_DBNAME=my_test_db
export MYSQL_HOST=127.0.0.1
export MYSQL_USER=dunglas
export MYSQL_PASSWORD=
export MYSQL_DBNAME="my_test_db
数据库必须存在。请注意,其内容可能会被删除。
运行测试套件,执行 PHPUnit
phpunit
鸣谢
此包由 Kévin Dunglas、Yanick Witschi 和 杰出的贡献者 提供。由 Les-Tilleuls.coop 赞助。