IT

교리의 기본값

lottoking 2020. 3. 8. 16:25
반응형

교리의 기본값


Doctrine 2에서 기본값을 어떻게 설정합니까?


데이터베이스 기본값은 "이식 적으로"지원되지 않습니다. 데이터베이스 기본값을 사용하는 유일한 방법 은 필드가 맵핑되는 열에 대한 스 니펫 ( 원인 포함)을 columnDefinition지정하는 맵핑 속성을 사용하는 것입니다.SQLDEFAULT

당신이 사용할 수있는:

<?php
/**
 * @Entity
 */
class myEntity {
    /**
     * @var string
     *
     * @Column(name="myColumn", type="string", length="50")
     */
    private $myColumn = 'myDefaultValue';
    ...
}

PHP 수준의 기본값은 새로 생성되고 지속되는 개체에서도 올바르게 사용할 수 있으므로 선호됩니다 (기본 값을 얻기 위해 새 개체를 유지 한 후에는 교리가 데이터베이스로 돌아 가지 않음).


<?php
/**
 * @Entity
 */
class myEntity {
    /**
     * @var string
     *
     * @ORM\Column(name="myColumn", type="integer", options={"default" : 0})
     */
    private $myColumn;
    ...
}

참고이 SQL 사용하는 DEFAULT몇 가지와 같은 분야에 대해 지원되지 않습니다, BLOBTEXT.


엔티티에서 생성자를 설정하고 기본값을 설정하십시오.


사용하다:

options={"default":"foo bar"}

그리고 아닙니다 :

options={"default"="foo bar"}

예를 들어 :

/**
* @ORM\Column(name="foo", type="smallint", options={"default":0})
*/
private $foo

최신 정보

Symfony에 대한 문서읽는 또 다른 이유 는 결코 추세에서 벗어나지 않을 것입니다. 내 경우에 대한 간단한 해결책이 있으며 field type옵션 empty_data을 기본값 으로 설정하는 입니다.

이 솔루션은 양식의 빈 입력이 DB 필드를 null로 설정하는 시나리오에만 해당됩니다.

배경

이전 답변 중 어느 것도 내 특정 시나리오에 도움이되지 않았지만 해결책을 찾았습니다.

다음과 같이 동작 해야하는 양식 필드가 있습니다.

  1. 필요하지 않습니다. 비워 둘 수 있습니다. ( '필수'=> false 사용)
  2. 비워두면 기본적으로 주어진 값으로 설정되어야합니다. 더 나은 사용자 경험을 위해 입력 필드에 기본값을 설정하지 않았지만 html 속성 'placeholder'는 덜 눈에 띄지 않기 때문에 사용했습니다.

그런 다음 여기에 제공된 모든 권장 사항을 시도했습니다. 그것들을 나열하겠습니다 :

  • 엔티티 속성에 대한 기본값을 설정하십시오.
<?php
/**
 * @Entity
 */
class myEntity {
    /**
     * @var string
     *
     * @Column(name="myColumn", type="string", length="50")
     */
    private $myColumn = 'myDefaultValue';
    ...
}
  • 옵션 주석을 사용하십시오.
@ORM\Column(name="foo", options={"default":"foo bar"})
  • 생성자에서 기본값을 설정하십시오.
/**
 * @Entity
 */
class myEntity {
    ...
    public function __construct()
    {
        $this->myColumn = 'myDefaultValue';
    }
    ...
}
Symfony가 Entity 클래스를 사용하는 방식 때문에 모든 것이 효과가 없었습니다.

중대한

Symfony 양식 필드는 Entity 클래스에 설정된 기본값을 대체합니다. 즉, DB 스키마에 기본값이 정의되어있을 수 있지만 양식을 제출할 때 필요하지 않은 필드를 비워두면 메서드 form->handleRequest()내부 form->isValid()에서 Entity클래스의 해당 기본값을 재정 의하여 입력 필드 값으로 설정합니다. 입력 필드 값이 비어 있으면 Entity속성 이로 설정 됩니다 null.

http://symfony.com/doc/current/book/forms.html#handling-form-submissions

내 해결 방법

메소드 form->handleRequest()내부에서 컨트롤러의 기본값을 설정하십시오 form->isValid().

...
if ($myEntity->getMyColumn() === null) {
    $myEntity->setMyColumn('myDefaultValue');
}
...

아름다운 해결책은 아니지만 작동합니다. 아마 만들 수는 validation group있지만이 문제를 데이터 유효성 검사가 아닌 데이터 변환 으로 보는 사람들이있을 수 있습니다 .


세터 재정의 (작동하지 않음)

나는 또한 Entity이런 식으로 세터 를 무시하려고 시도했다 .

...
/**
 * Set myColumn
 *
 * @param string $myColumn
 *
 * @return myEntity
 */
public function setMyColumn($myColumn)
{
    $this->myColumn = ($myColumn === null || $myColumn === '') ? 'myDefaultValue' : $myColumn;

    return $this;
}
...

깨끗해 보이지만 작동하지 않습니다 . 사악한 form->handleRequest()방법이 모델의 세터 방법을 사용하여 데이터를 업데이트하지 않기 때문 form->setData()입니다 (자세한 내용은 자세히 알아보십시오).


내가 사용한 해결 방법은 LifeCycleCallback입니다. 예를 들어, 더 이상 "기본"메소드가 있는지 확인하기 위해 여전히 대기 중 @Column(type="string", default="hello default value")입니다.

/**
 * @Entity @Table(name="posts") @HasLifeCycleCallbacks
 */
class Post implements Node, \Zend_Acl_Resource_Interface {

...

/**
 * @PrePersist
 */
function onPrePersist() {
    // set default date
    $this->dtPosted = date('Y-m-d H:m:s');
}

xml을 사용하여 수행 할 수도 있습니다.

<field name="acmeOne" type="string" column="acmeOne" length="36">
    <options>
        <option name="comment">Your SQL field comment goes here.</option>
        <option name="default">Default Value</option>
    </options>
</field>

mysql 데이터베이스에서도 작동합니다.

Entity\Entity_name:
    type: entity
    table: table_name
    fields: 
        field_name:
            type: integer
            nullable: true
            options:
                default: 1

여기 내가 스스로 해결하는 방법이 있습니다. 아래는 MySQL의 기본값을 가진 엔티티 예제입니다. 그러나 여기에는 엔터티에 생성자를 설정해야하며 기본값을 설정해야합니다.

Entity\Example:
  type: entity
  table: example
  fields:
    id:
      type: integer
      id: true
      generator:
        strategy: AUTO
    label:
      type: string
      columnDefinition: varchar(255) NOT NULL DEFAULT 'default_value' COMMENT 'This is column comment'

이 중 어느 것도 나를 위해 일하지 않았습니다. 교리 사이트에서 기본값을 설정하기 위해 직접 값을 설정하라는 문서가 있습니다.

http://doctrine-orm.readthedocs.io/projects/doctrine-orm/en/latest/reference/faq.html

private $default = 0;

이것은 내가 원하는 가치를 삽입했습니다.


엔티티에 yaml 정의를 사용하면 postgresql 데이터베이스에서 다음이 작동합니다.

Entity\Entity_name:
    type: entity
    table: table_name
    fields: 
        field_name:
            type: boolean
            nullable: false
            options:
                default: false

@romanb에 화려한 답변을 추가합니다.

이는 널 제약 조건이없고 기본값이없는 필드를 작성할 수 없기 때문에 마이그레이션에 약간의 오버 헤드가 추가됩니다.

// this up() migration is autogenerated, please modify it to your needs
$this->abortIf($this->connection->getDatabasePlatform()->getName() != "postgresql");

//lets add property without not null contraint        
$this->addSql("ALTER TABLE tablename ADD property BOOLEAN");

//get the default value for property       
$object = new Object();
$defaultValue = $menuItem->getProperty() ? "true":"false";

$this->addSql("UPDATE tablename SET property = {$defaultValue}");

//not you can add constraint
$this->addSql("ALTER TABLE tablename ALTER property SET NOT NULL");

이 답변으로 데이터베이스의 기본값이 왜 처음에 필요한지 생각하는 것이 좋습니다. 그리고 일반적으로 null 제약 조건이없는 객체를 만들 수 있습니다.


나는 같은 문제로 어려움을 겪었다. 데이터베이스의 기본값을 엔티티로 (자동으로) 원했습니다. 내가 뭘했는지 맞춰봐

<?php
/**
 * Created by JetBrains PhpStorm.
 * User: Steffen
 * Date: 27-6-13
 * Time: 15:36
 * To change this template use File | Settings | File Templates.
 */

require_once 'bootstrap.php';

$em->getConfiguration()->setMetadataDriverImpl(
    new \Doctrine\ORM\Mapping\Driver\DatabaseDriver(
        $em->getConnection()->getSchemaManager()
    )
);

$driver = new \Doctrine\ORM\Mapping\Driver\DatabaseDriver($em->getConnection()->getSchemaManager());
$driver->setNamespace('Models\\');

$em->getConfiguration()->setMetadataDriverImpl($driver);

$cmf = new \Doctrine\ORM\Tools\DisconnectedClassMetadataFactory();
$cmf->setEntityManager($em);
$metadata = $cmf->getAllMetadata();

// Little hack to have default values for your entities...
foreach ($metadata as $k => $t)
{
    foreach ($t->getFieldNames() as $fieldName)
    {
        $correctFieldName = \Doctrine\Common\Util\Inflector::tableize($fieldName);

        $columns = $tan = $em->getConnection()->getSchemaManager()->listTableColumns($t->getTableName());
        foreach ($columns as $column)
        {
            if ($column->getName() == $correctFieldName)
            {
                // We skip DateTime, because this needs to be a DateTime object.
                if ($column->getType() != 'DateTime')
                {
                    $metadata[$k]->fieldMappings[$fieldName]['default'] = $column->getDefault();
                }
                break;
            }
        }
    }
}

// GENERATE PHP ENTITIES!
$entityGenerator = new \Doctrine\ORM\Tools\EntityGenerator();
$entityGenerator->setGenerateAnnotations(true);
$entityGenerator->setGenerateStubMethods(true);
$entityGenerator->setRegenerateEntityIfExists(true);
$entityGenerator->setUpdateEntityIfExists(false);
$entityGenerator->generate($metadata, __DIR__);

echo "Entities created";

생성자에서 값을 설정하면 작동하지만 Doctrine Lifecycle 이벤트를 사용하는 것이 더 나은 솔루션 일 수 있습니다.

prePersist수명주기 이벤트 를 활용하면 초기 지속시에만 엔티티의 기본값을 설정할 수 있습니다.


속성 정의에서 기본값을 설정할 때주의하십시오! 문제없이 유지하려면 대신 생성자에서 수행하십시오. 속성 정의에서 정의한 경우 개체를 데이터베이스에 유지 한 다음 부분적으로로드하면로드되지 않은 속성이 다시 기본값이됩니다. 객체를 다시 유지하려면 위험합니다.

참고 URL : https://stackoverflow.com/questions/3376881/default-value-in-doctrine



반응형