我在我的实体中使用 json_array 来存储公交城市(Symfony 3.1项目)。我的实体摘录如下:
class Travel {
/**
* @var integer
*
* @ORM\Column(name="travel_id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $travelId;
/* OTHER VARIABLES HERE */
/**
* @var integer
* @ORM\Column(name="transit_cities", type="json_array", nullable=true)
*/
protected $transitCities;
/* OTHER VARIABLES HERE */
public function __construct() {
$this->transitCities = new ArrayCollection();
}
/* GETTERS AND SETTERS HERE */
}
在我的表单中,我使用的是ChoiceType :: class,其allow_add设置为 true 。用户可以选择添加新值并删除现有值:
$builder->add('transitCities', CollectionType::class, array(
'entry_type' => null,
'prototype' => true,
'allow_add' => true,
'allow_delete' => true,
'delete_empty' => true,
'error_bubbling'=> false,
'entry_options' => array(
'attr' => array('class' => 'transit-cities')
),
))
使用默认的成功表单提交,这非常有效(没有在控制器内部设置任何特殊内容)。持久化数据具有以下结构:
[
0 => "City 1",
1 => "City 2",
// and so on
]
其中密钥(本例中为0和1)由Doctrine自动生成。但我想使用自己的密钥而不是默认的索引号,最好还添加其他相关信息,如下所示:
[
{'123' => 'City 1', 'dateTime' => 'Travel-date 1', 'opt'=> 1},
{'45' => 'City 2', 'dateTime' => 'Travel-date 2', 'opt'=> 2},
// and so on
]
123和45可以是city-id的FK,而dateTime和opt可以是每行的其他相关信息。
==== 已添加详细信息 ===
这是我的城市实体:
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Cities
*
* @ORM\Table(name="city")
* @ORM\Entity
* @ORM\Entity(repositoryClass="AppBundle\Repository\CityRepository")
*/
class City
{
/**
* @var string
* @ORM\Column(name="name", type="string", length=70, nullable=false)
*/
private $name;
/**
* @var string
*
* @ORM\Column(name="country", type="string", length=32, nullable=false)
*/
private $country;
/**
* @var integer
*
* @ORM\Column(name="city_id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $cityId;
/* CONST */
public function __toString() {
return $this->name;
}
/* OTHER PARAMETERS HERE */
/* GETTERS AND SETTERS */
/**
* Set name
*
* @param string $name
*
* @return City
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* Get cityId
*
* @return integer
*/
public function getCityId()
{
return $this->cityId;
}
}
我想将cityId用于json_key。例如,如果用户选择了城市"伦敦"与相应的cityId如100和再次city" Amsterdam"使用cityId 115,然后json_array中的键对应该是:
{' 100' => '伦敦',' dateTime' => ' 2000-01-01',' opt' => 1}
{' 115' => '阿姆斯特丹',' dateTime' => ' 2000-01-02',' opt' => 4}
其中, dateTime 由用户使用js-date-picker选取,而 opt 仅取代任意值,例如。 Transit-Cities可以由用户根据自己的选择添加和删除(已经运行)。
如何实现这一目标?请建议。
答案 0 :(得分:3)
您可以创建custom mapping type以方便您的自定义json数组。
来自文档:
<?php
namespace My\Project\Types;
use Doctrine\DBAL\Types\Type;
use Doctrine\DBAL\Platforms\AbstractPlatform;
/**
* My custom json city type.
*/
class JsonCityType extends Type
{
const MYTYPE = 'json_city_type';
public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform)
{
// Get json array type
return $platform->getJsonTypeDeclarationSQL('json_array');
}
public function convertToPHPValue($value, AbstractPlatform $platform)
{
// This is executed when the value is read from the database. Make your conversions here, optionally using the $platform.
}
public function convertToDatabaseValue($value, AbstractPlatform $platform)
{
// This is executed when the value is written to the database. Make your conversions here, optionally using the $platform.
}
public function getName()
{
return self::MYTYPE; // modify to match your constant name
}
}
像这样使用:
/**
* @var integer
* @ORM\Column(name="transit_cities", type="json_city_type", nullable=true)
*/
protected $transitCities; // ;
您需要在doctrine config中注册自定义类型:
'doctrine' => array(
'configuration' => array(
'orm_default' => array(
'types' => array(
'json_city_type' => My\Project\Types\JsonCityType::class
)
)
)
)
我保留了自定义convertToPHPValue
和convertToDatabaseValue
中的键和值的逻辑,因为我不知道从哪里获取数据。
答案 1 :(得分:0)
我尝试使用数据类型json_array
做了几件事但没有按预期工作。因此,为了简化操作,我切换到simple_array
数据类型并添加了3个新属性;即cityId
,dateTime
和opt
。所以我的新实体类看起来如下所示:
class Travel {
/**
* @var integer
*
* @ORM\Column(name="travel_id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $travelId;
/* OTHER PROPERTIES HERE */
/**
* @var integer
*
* @ORM\Column(name="transit_cities", type="simple_array", nullable=true)
*/
protected $transitCities;
/**
* @var integer
*
* @ORM\Column(name="date_time", type="simple_array", nullable=true)
*/
protected $dateTime;
/**
* @var integer
*
* @ORM\Column(name="opt", type="simple_array", nullable=true)
*/
protected $opt;
/* OTHER PROPERTIES + GETTERS AND SETTERS HERE */
}
虽然我在将来的任何时候都错过了向json_array
添加新属性的灵活性;尽管如此,现在好处是使用WHERE XX IN array()
子句搜索更简单。