symfony2의 "Class Table Inheritance"모델을 사용하는 상속이있는 데이터베이스 모델이 있습니다.
Employee는 최상위 상속 모델 인 추상 클래스입니다.
비서는 직원을 연장하는 자녀입니다. 기술자는 또한 직원을 확장하는 자녀입니다.
비서가 기술자를 위해 몇 가지 사항을 관리 할 수있는 응용 프로그램을 구축 중이므로 몇 가지 양식 등이있는 관리자 패널이 있습니다.
비서 저장소는 또한 비서가 응용 프로그램을 통해 인증 할 수있는 UserProvider 인터페이스입니다.
내가 가진 문제는 인증 쿼리가 판별자를 신경 쓰지 않는다는 것입니다 ...
인증 SQL 쿼리 의 디버그
SELECT e0_.*, s1_.*
FROM secretaries s1_
INNER JOIN employees e0_ ON s1_.id = e0_.id
WHERE e0_.removed_at IS NULL AND e0_.is_hidden = ? AND e0_.email = ?
비서와 직원 간의 관계를 관리하는 방법을 이해하지 못합니다. 비서에서 직원으로의 외래 키를 수동으로 포함해야합니까? 아니면 인증 쿼리에서 판별자를 수동으로 처리해야합니까?
내 모델의 기본 사항을 살펴 보겠습니다.
부모 클래스 직원
abstract class Employee
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @var string
*
* @ORM\Column(name="email", type="string", length=255, nullable=true)
*/
protected $email;
// [...] some other fields
}
자식 클래스 장관
class Secretary extends Employee
{
/**
* @var string
*
* @ORM\Column(name="password", type="string", length=255, nullable=true)
* @Assert\NotBlank()
*/
private $password;
/**
* @var string
*
* @ORM\Column(name="salt", type="string", length=40)
*/
private $salt;
/**
* @var array
*
* @ORM\Column(name="roles", type="array")
*/
private $roles;
// [...] some other fields
}
UserProviderInterface의 클래스 SecretaryRepository
class SecretaryRepository extends EntityRepository implements UserProviderInterface
{
public function loadUserByUsername($username)
{
$secretary = null;
$qb = $this->_em->createQueryBuilder();
$qb->select('s')
->from('HygieCoreBundle:Secretary', 's')
->where($qb->expr()->isNull('s.removedAt'))
->andWhere($qb->expr()->eq('s.isHidden', ':isHidden'))
->andWhere($qb->expr()->eq('s.email', ':email'))
->setParameter('isHidden', false)
->setParameter('email', $username)
;
try {
$secretary = $qb->getQuery()->getSingleResult();
}
catch (NoResultException $e) {
throw new UsernameNotFoundException(sprintf('Aucune secrétaire ne possède l\'adresse e-mail : "%s".', $username), 0, $e);
}
return $secretary;
}
// [...] some other methods
}
문제는 간단합니다. INNER JOIN 절은 비서에서 직원에게 외래 키를 사용하지 않고 직접 ID를 사용하기 때문에 올바르지 않습니다. 기술자 ID도 될 수 있습니다!
다음은 내 테이블의 일부 행을 내보내는 것입니다.
INSERT INTO `technicians` (`id`, `speciality`) VALUES
(1, 'Communication')
INSERT INTO `employees` (`id`, `created_at`, `updated_at`, `removed_at`, `is_hidden`, `firstname`, `name`, `entityName`) VALUES
(1, '**sometime**', '**sometime**', NULL, 0, '**TechnicianFirstname**', '**TechnicianName**', 'technician'),
(2, '**sometime**', '**sometime**', NULL, 0, '**SecretaryFirstName**', '**SecretaryName**', 'secretary');
INSERT INTO `secretaries` (`id`, `password`, `salt`, `roles`) VALUES
(1, '**HashedPassword**', '**HashedSalt**', 'O:43:"Doctrine\\Common\\Collections\\ArrayCollection":1:{s:54:"\0Doctrine\\Common\\Collections\\ArrayCollection\0_elements";a:1:{i:0;s:10:"ROLE_ADMIN";}}');
ALTER TABLE `technicians` ADD CONSTRAINT `FK_1DCF6554BF396750` FOREIGN KEY (`id`) REFERENCES `employees` (`id`) ON DELETE CASCADE;
ALTER TABLE `secretaries` ADD CONSTRAINT `FK_ACB3412BF396750` FOREIGN KEY (`id`) REFERENCES `employees` (`id`) ON DELETE CASCADE;
secretaries
테이블에서 직접 데이터를 선택 하므로 실수로 일부 기술자를 선택할 가능성이 없습니다. 이 코드는 안전합니다.
동일한 쿼리에서 비서와 기술자를 모두 선택하려는 경우, 즉 쿼리가 employees
테이블 에서 선택하는 경우 식별기가 필요 합니다.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다