问题
In my database I've a table file
and a table file_content
. The file
table stores the metadata of the file such as name
, mime
and some more. The file_content
stores a blob with the file content. I'm not storing the blob in the same table as the metadata for performance reasons only.
For a 'version 2' of my project I'm looking into Doctrine (2.3). To me, a "File" seems to be one entity, with properties such as name
, mime
, extension
, content
that should be used like this:
$file = new File();
$file->setName('hello.txt');
$file->setMime('text/plain');
$file->setContent('Hello world!')
$em->persist($file);
$em->flush();
Is this behaviour possible? To me it makes no sense to create two entities for something that's really just one entity. I could not find anything about it in the documentation and I read in a 2-year-old topic that it isn't possible in Doctrine 2.1: Doctrine 2.1 - Map entity to multiple tables
Someone any suggestions how to handle this correctly? I'm new to Doctrine and have been playing around with it a bit to see if it's the right choice for my project. Thanks.
回答1:
Do you have the ability to alter the schema of your database? If so, I'd consider consolidating this into one table.
Barring that, you may want to try a one-to-one relationship in Doctrine. Perhaps something like:
class File {
private $id;
private $name;
private $mime;
private $content;
}
class Content {
private $id;
private $data;
private $fileId;
}
If you map Content->fileId with a one-to-one relationship to File->id, then you can do things like:
$file->getContent()->getData();
$file->getContent()->setData("something different");
Here's some more info on one-to-one mappings: http://docs.doctrine-project.org/en/2.0.x/reference/association-mapping.html#one-to-one-unidirectional
回答2:
I'm going to suggest a different approach even though it's a somewhat older question. Instead of making two entities, you should make three.
Create FileMetadata, which holds name, mimetype, etc. Create FileContent, which holds the content. Then, create a third entity File which holds a one-to-one connection with one of each of the other types, and give it a bunch of methods that simply call the matching methods on the sub entities.
So for example in File, the setName method would look like this:
public function setName() {
$this->getFileMetadata()->getName();
}
And set would look like this:
public function setName( $name ) {
$this->getFileMetadata()->setName( $name );
}
The constructor of the File entity should create a new FileMetadata and a new FileContent on creation and should NOT have a setFilemetadata or setFilecontent method; these two entities should be completely shielded from your application.
Now you have the File entity, which handles exactly like you want (a single entity, no additional sub-entities) which is still stored neatly in two (well, three really) different tables.
回答3:
You could map both tables, resulting in File
and FileContent
, and add a one-to-one relationship between the two.
Then add getter/setter methods for the file content in the File
class. In these you'd have to call the corresponding methods in FileContent
.
来源:https://stackoverflow.com/questions/18213381/how-to-save-one-doctrine-entity-to-two-database-tables-required-for-mysql-optim