Doctrine / Symfony:在使用 QueryBuilder 之前将自定义类型转换为数据库值

Posted

技术标签:

【中文标题】Doctrine / Symfony:在使用 QueryBuilder 之前将自定义类型转换为数据库值【英文标题】:Doctrine / Symfony: convert custom type to database value before using QueryBuilder 【发布时间】:2015-02-21 12:37:11 【问题描述】:

我已经为 Uuid 定义了一个自定义的 Doctrine 数据类型。当我使用find($uuid) 搜索对象时,它可以正常工作,即在执行查询之前使用convertToDatabaseValue() 转换属性,并在检索到值时使用convertTophpValue() 转换回来。

如果我使用 QueryBuilder,转换将不起作用。示例:

$qb = $this->createQueryBuilder('s');
$qb = $qb->where( //some conditions...
      $qb->expr()->eq( 's.uuid', ':uuid' ))->setParameter( 'uuid', $uuid );

我发现了两个类似的未回答的问题:

Symfony Doctrine datatype only works in findBy not querybuilder Doctrine 2 Custom Types

看起来转换实际上被忽略了。

如何在执行查询之前强制转换参数?有没有办法从存储库中访问自定义数据类型的convertToDatabaseValue() 函数?

谢谢

【问题讨论】:

【参考方案1】:

是的setParameter() 有第三个参数,但是第三个参数的类型为 string 对我有用,而不是对象。

您可以通过以下方式进行。

$qb = $this->createQueryBuilder('s');
$qb = $qb->where( //some conditions...
      $qb->expr()->eq( 's.uuid', ':uuid' ))->setParameter( 'uuid', $uuid, 'uuid' );

如果您不知道数据类型“uuid”的确切键是什么。 然后使用print_r(Type::getTypesMap()); 获取添加的所有数据类型的列表。

在我的情况下是

Array
(
    [array] => Doctrine\DBAL\Types\ArrayType
    [simple_array] => Doctrine\DBAL\Types\SimpleArrayType
    [json_array] => Doctrine\DBAL\Types\JsonArrayType
    [object] => Doctrine\DBAL\Types\ObjectType
    [boolean] => Doctrine\DBAL\Types\BooleanType
    [integer] => Doctrine\DBAL\Types\IntegerType
    [smallint] => Doctrine\DBAL\Types\SmallIntType
    [bigint] => Doctrine\DBAL\Types\BigIntType
    [string] => Doctrine\DBAL\Types\StringType
    [text] => Doctrine\DBAL\Types\TextType
    [datetime] => Doctrine\DBAL\Types\DateTimeType
    [datetimetz] => Doctrine\DBAL\Types\DateTimeTzType
    [date] => Doctrine\DBAL\Types\DateType
    [time] => Doctrine\DBAL\Types\TimeType
    [decimal] => Doctrine\DBAL\Types\DecimalType
    [float] => Doctrine\DBAL\Types\FloatType
    [binary] => Doctrine\DBAL\Types\BinaryType
    [blob] => Doctrine\DBAL\Types\BlobType
    [guid] => Doctrine\DBAL\Types\GuidType    
    [geometry] => CrEOF\Spatial\DBAL\Types\GeometryType
    [point] => CrEOF\Spatial\DBAL\Types\Geometry\PointType
    [polygon] => CrEOF\Spatial\DBAL\Types\Geometry\PolygonType
    [linestring] => CrEOF\Spatial\DBAL\Types\Geometry\LineStringType
)

我的教义代码是这样的。

$queryBuilder = $this->createQueryBuilder('c');
        $queryBuilder
            ->where('st_contains(:polygon, point(c.latitude, c.longitude) ) = 1')
            ->setParameter('polygon', $city->getPolygon(), 'polygon');

【讨论】:

【参考方案2】:

解决方法如下:函数setParameter() 有第三个参数$type,用于声明参数的类型。可以使用 Doctrine Type 类的getType() 函数检索自定义声明的类型:

$qb = $this->createQueryBuilder('s');
$qb = $qb->where( //some conditions...
      $qb->expr()->eq( 's.uuid', ':uuid' ))->setParameter( 'uuid', $uuid, Type::getType('uuid') );

【讨论】:

以上是关于Doctrine / Symfony:在使用 QueryBuilder 之前将自定义类型转换为数据库值的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Symfony 4 上配置 Doctrine 以使用 yaml 映射

在 Symfony 中使用 Doctrine 的 DBAL 检索布尔值

Symfony - 使用Doctrine创建复杂查询

Doctrine / Symfony:在使用 QueryBuilder 之前将自定义类型转换为数据库值

在 Symfony2 中使用 Doctrine 映射异常错误

如何在 Doctrine2 (Symfony2) 中按案例排序