DAO
La clase DAO es responsable de las operaciones de carga y persistencia de los modelos :
Conexión a la base de datos
Compruebe que los parámetros de conexión a la base de datos se han introducido correctamente en el archivo de configuración:
Ubiquity config -f=database
Desde la versión 2.3.0
El inicio de la base de datos con DAO::startDatabase($config)
en el archivo services.php es inútil, no es necesario iniciar la base de datos, la conexión se realiza automáticamente en la primera petición. Usa DAO::start()
en el archivo app/config/services.php cuando uses varias bases de datos (con la característica multi db)
Carga de datos
Cargar una instancia
Cargando una instancia de la clase models\User con id 5.
use Ubiquity\orm\DAO;
use models\User;
$user=DAO::getById(User::class, 5);
Cargar una instancia utilizando una condición:
use Ubiquity\orm\DAO;
use models\User;
DAO::getOne(User::class, 'name= ?',false,['DOE']);
Carga de BelongsTo
Por defecto, los miembros definidos por una relación belongsTo se cargan automáticamente
Cada usuario pertenece a una sola categoría:
$user=DAO::getById(User::class,5);
echo $user->getCategory()->getName();
Es posible evitar esta carga por defecto; el tercer parámetro permite cargar o no los miembros belongsTo:
$user=DAO::getOne(User::class,5, false);
echo $user->getCategory();// NULL
Carga de HasMany
La carga de miembros hasMany debe ser siempre explícita; el tercer parámetro permite la carga explícita de miembros.
Cada usuario tiene muchos grupos:
$user=DAO::getOne(User::class,5,['groupes']);
foreach($user->getGroupes() as $groupe){
echo $groupe->getName().'<br>';
}
Clave primaria compuesta
O bien el modelo ProductDetail correspondiente a un producto pedido en una orden y cuya clave primaria es compuesta:
1 namespace models;
2
3use Ubiquity\attributes\items\Id;
4
5 class ProductDetail{
6
7 #[Id]
8 private $idProduct;
9
10 #[Id]
11 private $idCommand;
12
13 ...
14 }
1 namespace models;
2
3 class ProductDetail{
4 /**
5 * @id
6 */
7 private $idProduct;
8
9 /**
10 * @id
11 */
12 private $idCommand;
13
14 ...
15 }
El segundo parámetro $keyValues puede ser un array si la clave primaria es compuesta:
$productDetail=DAO::getOne(ProductDetail::class,[18,'BF327']);
echo 'Command:'.$productDetail->getCommande().'<br>';
echo 'Product:'.$productDetail->getProduct().'<br>';
Carga multiple de objetos
Carga de instancias de la clase User:
$users=DAO::getAll(User::class);
foreach($users as $user){
echo $user->getName()."<br>";
}
Consulta mediante condiciones
Consultas sencillas
El parámetro condition equivale a la parte WHERE de una sentencia SQL:
$users=DAO::getAll(User::class,'firstName like "bren%" and not suspended',false);
Para evitar inyecciones SQL y beneficiarse de la preparación de sentencias, es preferible realizar una consulta parametrizada:
$users=DAO::getAll(User::class,'firstName like ? and suspended= ?',false,['bren%',false]);
UQueries
El uso de U-queries permite establecer condiciones sobre los miembros asociados:
Selección de usuarios cuya organización tiene el dominio lecnam.net:
$users=DAO::uGetAll(User::class,'organization.domain= ?',false,['lecnam.net']);
Es posible ver la solicitud generada en los registros (si el registro está activado):
El resultado puede verificarse seleccionando a todos los usuarios de esta organización:
$organization=DAO::getOne(Organization::class,'domain= ?',['users'],['lecnam.net']);
$users=$organization->getUsers();
Los registros correspondientes:
Contando
Pruebas de existencia
if(DAO::exists(User::class,'lastname like ?',['SMITH'])){
//there's a Mr SMITH
}
Contando
Contar las instancias, lo que no hay que hacer, si los usuarios no están ya cargados:
$users=DAO::getAll(User::class);
echo "there are ". \count($users) ." users";
Lo que hay que hacer:
$count=DAO::count(User::class);
echo "there are $count users";
Con una condición:
$notSuspendedCount=DAO::count(User::class, 'suspended = ?', [false]);
con una condición sobre los objetos asociados:
Número de usuarios pertenecientes a la organización denominada OTAN.
$count=DAO::uCount(User::class,'organization.name= ?',['OTAN']);
Modificación de datos
Añadir una instancia
Añadir una organización:
$orga=new Organization();
$orga->setName('Foo');
$orga->setDomain('foo.net');
if(DAO::save($orga)){
echo $orga.' added in database';
}
Añadir una instancia de Usuario, en una organización:
$orga=DAO::getById(Organization::class, 1);
$user=new User();
$user->setFirstname('DOE');
$user->setLastname('John');
$user->setEmail('doe@bar.net');
$user->setOrganization($orga);
if(DAO::save($user)){
echo $user.' added in database in '.$orga;
}
Actualización de una instancia
En primer lugar, debe cargarse la instancia:
$orga=DAO::getOne(Organization::class,'domain= ?',false,['foo.net']);
$orga->setAliases('foo.org');
if(DAO::save($orga)){
echo $orga.' updated in database';
}
Borrar una instancia
Si la instancia se carga desde la base de datos:
$orga=DAO::getById(Organization::class,5,false);
if(DAO::remove($orga)){
echo $orga.' deleted from database';
}
Si la instancia no está cargada, es más apropiado utilizar el método delete:
if(DAO::delete(Organization::class,5)){
echo 'Organization deleted from database';
}
Eliminar varias instancias
Eliminar varias instancias sin carga previa:
if($res=DAO::deleteAll(models\User::class, 'id in (?,?,?)',[1,2,3])){
echo "$res elements deleted";
}
Consultas masivas
Las consultas masivas permiten realizar varias operaciones (inserción, modificación o supresión) en una sola consulta, lo que contribuye a mejorar el rendimiento.
Inserciones masivas
Ejemplo de inserciones:
$u = new User();
$u->setName('Martin1');
DAO::toInsert($u);
$u = new User();
$u->setName('Martin2');
DAO::toInsert($u);
//Perform inserts
DAO::flushInserts();
Actualizaciones masivas
Ejemplo de actualizaciones:
$users = DAO::getAll(User::class, 'name like ?', false, [
'Martin%'
]);
foreach ($users as $user) {
$user->setName(\strtoupper($user->getName()));
DAO::toUpdate($user);
}
DAO::flushUpdates();
Borrado masivo
Ejemplo de eliminación
$users = DAO::getAll(User::class, 'name like ?', false, [
'BULK%'
]);
DAO::toDeletes($users);
DAO::flushDeletes();
El método DAO::flush() puede ser llamado si hay inserciones, actualizaciones o borrados pendientes.
Transacciones
Transacciones explícitas
Todas las operaciones DAO se pueden insertar en una transacción, de forma que se pueda atomizar una serie de cambios:
try{
DAO::beginTransaction();
$orga=new Organization();
$orga->setName('Foo');
DAO::save($orga);
$user=new User();
$user->setFirstname('DOE');
$user->setOrganization($orga);
DAO::save($user);
DAO::commit();
}catch (\Exception $e){
DAO::rollBack();
}
En caso de múltiples bases de datos definidas en la configuración, los métodos relacionados con transacciones pueden tomar el offset de base de datos definido en parámetro.
DAO::beginTransaction('db-messagerie');
//some DAO operations on messagerie models
DAO::commit('db-messagerie');
Transacciones implícitas
Algunos métodos DAO utilizan implícitamente transacciones para agrupar operaciones de inserción, actualización o eliminación.
$users=DAO::getAll(User::class);
foreach ($users as $user){
$user->setSuspended(true);
DAO::toUpdate($user);
}
DAO::updateGroups();//Perform updates in a transaction
Clase SDAO
La clase SDAO acelera las operaciones CRUD para las clases de negocio sin relaciones.
En este caso, los modelos deben declarar únicamente los miembros públicos y no respetar la encapsulación habitual.
1 namespace models;
2 class Product{
3 /**
4 * @id
5 */
6 public $id;
7
8 public $name;
9
10 ...
11 }
La clase SDAO hereda de DAO y tiene los mismos métodos para realizar operaciones CRUD.
use Ubiquity\orm\DAO;
$product=DAO::getById(Product::class, 5);
Consultas DAO preparadas
La preparación de ciertas peticiones puede mejorar el rendimiento con los servidores Swoole, Workerman o Roadrunner.
Esta preparación inicializa los objetos que luego se utilizarán para ejecutar la consulta.
Esta inicialización se realiza al inicio del servidor, o al inicio de cada worker, si existe tal evento.
Ejemplo swoole
Preparación
$swooleServer->on('workerStart', function ($srv) use (&$config) {
\Ubiquity\orm\DAO::startDatabase($config);
\Ubiquity\orm\DAO::prepareGetById('user', User::class);
\Ubiquity\orm\DAO::prepareGetAll('productsByName', Product::class,'name like ?');
});
Utilización
public function displayUser($idUser){
$user=DAO::executePrepared('user',[1]);
echo $user->getName();
}
public function displayProducts($name){
$products=DAO::executePrepared('productsByName',[$name]);
...
}