tourze / doctrine-upsert-bundle
Doctrine的upsert支持
Installs: 2 018
Dependents: 5
Suggesters: 0
Security: 0
Stars: 0
Watchers: 1
Forks: 0
Open Issues: 0
pkg:composer/tourze/doctrine-upsert-bundle
Requires
- php: ^8.1
- doctrine/dbal: ^4.0
- doctrine/doctrine-bundle: ^2.13
- doctrine/orm: ^3.0
- doctrine/persistence: ^3.1 || ^4
- nesbot/carbon: ^2.72 || ^3
- psr/log: ^3|^2|^1
- symfony/config: ^6.4
- symfony/dependency-injection: ^6.4
- symfony/doctrine-bridge: ^6.4
- symfony/framework-bundle: ^6.4
- symfony/http-kernel: ^6.4
- symfony/property-access: ^6.4
- symfony/yaml: ^6.4 || ^7.1
- tourze/bundle-dependency: 0.0.*
- tourze/doctrine-entity-checker-bundle: ~0.0.8
- yiisoft/strings: ^2.1
Requires (Dev)
- phpstan/phpstan: ^2.1
- phpunit/phpunit: ^10.0
This package is auto-updated.
Last update: 2025-10-31 19:56:36 UTC
README
Efficient UPSERT (insert or update) capabilities for Doctrine ORM with automatic SQL generation and multi-database support.
Table of Contents
- Features
- Requirements
- Installation
- Quick Start
- Entity Requirements
- Advanced Usage
- API Reference
- Contributing
- License
- Changelog
Features
- Single and Batch UPSERT Operations
- MySQL:
INSERT ... ON DUPLICATE KEY UPDATE - SQLite:
INSERT ... ON CONFLICT ... DO UPDATE SET
- MySQL:
- Automatic Database Platform Detection - Works seamlessly with MySQL and SQLite
- Smart Unique Constraint Detection - Automatically identifies unique constraints from entity metadata
- Extensible Provider System - Custom UPSERT providers via
ProviderInterface - Safe Error Handling - Prevents EntityManager closure on errors
- Automatic Timestamp Management - Handles
create_timeandupdate_timefields intelligently
Requirements
- PHP >= 8.1
- doctrine/orm >= 3.0
- doctrine/dbal >= 4.0
- symfony >= 6.4
Installation
composer require tourze/doctrine-upsert-bundle
Quick Start
Configuration
Register the bundle in config/bundles.php:
return [ Tourze\DoctrineUpsertBundle\DoctrineUpsertBundle::class => ['all' => true], ];
Basic Usage
use App\Entity\User; use Tourze\DoctrineUpsertBundle\Service\UpsertManager; // Inject UpsertManager (or use dependency injection) public function __construct( private UpsertManager $upsertManager ) {} // Single entity upsert $user = new User(); $user->setEmail('user@example.com'); $user->setName('John Doe'); // Returns the persisted entity (may be different from input) $persistedUser = $this->upsertManager->upsert($user);
Batch UPSERT
// Batch upsert with array data $userData = [ ['email' => 'user1@example.com', 'name' => 'User 1'], ['email' => 'user2@example.com', 'name' => 'User 2'], ]; $affectedRows = $this->upsertManager->executeBatch($userData, User::class);
Low-Level UPSERT
// Direct SQL execution $insertData = ['email' => 'user@example.com', 'name' => 'John']; $updateData = ['name' => 'John Doe Updated']; // Optional $affectedRows = $this->upsertManager->execute('users', $insertData, $updateData);
Entity Requirements
Your entities must have unique constraints defined for UPSERT operations:
use Doctrine\ORM\Mapping as ORM; #[ORM\Entity] #[ORM\Table(name: 'users')] #[ORM\UniqueConstraint(name: 'user_email_unique', columns: ['email'])] class User { #[ORM\Id] #[ORM\GeneratedValue] #[ORM\Column(type: 'integer')] private int $id; #[ORM\Column(type: 'string', unique: true)] private string $email; #[ORM\Column(type: 'string')] private string $name; // Or use individual unique columns // #[ORM\Column(type: 'string', unique: true)] // private string $username; }
Advanced Usage
Custom Update Time Handling
The bundle automatically handles update_time fields:
class User { #[ORM\Column(type: 'datetime')] private \DateTime $createTime; #[ORM\Column(type: 'datetime')] private \DateTime $updateTime; public function setUpdateTime(\DateTime $updateTime): self { $this->updateTime = $updateTime; return $this; } }
Extending with Custom Providers
Create custom database platform support:
use Tourze\DoctrineUpsertBundle\Service\ProviderInterface; class PostgreSQLUpsertProvider implements ProviderInterface { public function supports(string $platform): bool { return $platform === 'postgresql'; } public function getUpsertQuery(string $table, array $insertData, array $updateData): string { // Implementation for PostgreSQL UPSERT return "INSERT INTO {$table} ... ON CONFLICT ... DO UPDATE SET ..."; } }
API Reference
UpsertManager
upsert(object $entity, bool $fetchAgain = true): object- Upsert single entityexecute(string $table, array $insertData, array $updateData = []): int- Execute raw upsertexecuteBatch(array $data, string $repositoryClass): int- Batch upsert operation
Supported Platforms
- MySQL: Uses
INSERT ... ON DUPLICATE KEY UPDATE - SQLite: Uses
INSERT ... ON CONFLICT ... DO UPDATE SET
Contributing
- Fork the repository
- Create a feature branch
- Follow PSR-12 coding standards
- Add tests for new features
- Submit a pull request
License
MIT License © tourze
Changelog
See [CHANGELOG.md] or Git history for version updates and changes.