El framework Kohana PHP, aparte de poseer un interesante y muy completo ORM, tiene otra opción que nos permite mejorar nuestras consultas a la base de datos.
Este se llama QueryBuilder, el cual como su nombre lo indica es un constructor de consultas.
En el post anterior, comente como usar el ORM de kohana, el cual como vemos nos ahorra mucho trabajo y nos permite hacer consultas complejas mediante el uso de la orientación a objetos, sin embargo no todo es tan maravilloso como suena, una de las cosas mas contraproducentes que tiene este y la mayoría de ORM’s es la siguiente.
Ejemplo de lo que sucede al hacer una consulta usando el ORM
|
1 2 3 4 5 |
//Consulta ORM $result = ORM::factory('users')->find_all(); //Consulta generada $sql = 'select * from users'; |
Como vemos por default, nos esta haciendo un select *, esta consulta puede afectar seriamente nuestro rendimiento cuando nuestra tabla contiene muchos registro o muchos campos, además de que cuando tenemos tablas con un campo ambiguo, hacer funcionar bien el ORM puede darnos varios dolores de cabeza.
Los desarrolladores de kohana, antes de lanzar el ORM, crearon un constructor de consultas, el cual nos da toda la potencia de el lenguaje SQL, pero usando técnicas de orientación a objetos usando PHP.
Para usarla lo haremos configurando todo lo necesario como lo hicimos en el post anterior, y crearemos los querys de la siguiente forma.
* Uso de método estático DB::query()
|
1 2 |
//Sintaxis $query = DB::query(integer $type,String $sql); |
Esta es una de las herramientas mas completas que tenemos dentro del QueryBuilder, básicamente es un método estático en donde recibe dos parámetros, el primero de tipo integer que en realidad es una constante de la clase Database, en donde le indicamos que tipo de consulta haremos( select, delete, insert, update), veamos su equivalencia.
|
1 2 3 4 |
Database::SELECT; // corresponde a 1 Database::INSERT; // corresponde a 2 Database::UPDATE; // corresponde a 3 Database::DELETE; // corresponde a 4 |
El segundo parámetro es string donde indicamos la consulta que necesitemos hacer la cual puede incluir algunas variables las cuales estarán indicadas mediante dos puntos y el nombre de variable, el cual no tiene nada que ver con las variables de PHP, y posteriormente se le puede indicar el valor de dicha variable mediante el método param, parameters o bind.
Veamos como quedaría una consulta normal
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
$user = 'ajaxman'; //Nótese la variable :user $query = DB::query(Database::SELECT, 'SELECT id,username FROM users WHERE username = :user'); //Asignación de la variable :user a variable PHP $user. $query->param(':user',$user); /*** Ejemplo de como seria en modo normal de PHP y MySQL ***/ $query = 'SELECT id,username FROM users WHERE username = '.$user; |
Pero aun no tenemos terminada nuestra consulta, para que se ejecute debemos especificarlo explícitamente mediante el método execute.
Veamos algunos ejemplos de como usar lo que hemos visto en un query complejo y algunas variantes de como hacer esto.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
//Declaración de variables en hardcode, esto debe de ser de otra forma, // dentro de una clase (Modelo) y un método correspondiente // Solo esta así por que es ejemplo $user = 'ajaxman'; $password = 'passworddificil001'; //Forma 1 $query = DB::query(Database::SELECT, 'SELECT id,username FROM users WHERE username = :user and password = :pass'); $query->param(':user',$user); $query->param(':pass',$password); $query->execute(); //Forma 2 //También podemos hacer el query de esta forma, y podemos usar la que mas nos guste $query = DB::query(Database::SELECT, 'SELECT id,username FROM users WHERE username = :user and password = :pass') ->param(':user',$user); ->param(':pass',$password); ->execute(); //Nótese que son métodos que se adhieren al mismo método estático (luego veremos como usar esta técnica) //ya que nos permite un código mas claro //Forma 3 //Los parámetros podemos pasarlos como un array,veamos el tercer ejemplo $query = DB::query(Database::SELECT, 'SELECT id,username FROM users WHERE username = :user and password = :pass') $query->parameters(array( ':user' => $user, ':pass' => $pass, )); $query->execute(); //Forma 4 //Esta forma es mediante el uso de el método bind y es útil para hacer muchos inserts ya que se apoya de //El uso de arrays, y foreach para hacer los inserts $users = array( 'ajaxman' => 'passworddificil002', 'javier' => 'passworddificil003' ); $query = DB::query(Database::INSERT, 'INSERT INTO users (username, password) VALUES (:user, :pass)') ->bind(':user', $username) ->bind(':pass', $password); foreach ($users as $username => $password) { $query->execute(); } //El ejemplo anterior vemos que con el foreach se esta ejecutando el query pero además antes de ejecutarse reemplaza :user y :pass //por cada uno de los elementos del array que definimos arriba |
Como vemos hay muchas formas de usar DB::query(), y podemos hacer la mayoría de consultas con este método estático.
Cuando empecé este post, pensaba abarcar otros métodos del QueryBuilder como DB::select, DB::expr, entre otros, sin embargo creo que se extendió demasiado este método, asi que esta sera la parte I, en la próxima parte veremos si acabo el post, si no de todas formas, ahí les aviso, de momento esperen la parte 2.
Toda esta información fue basada en mi experiencia con kohana y documentación de las siguientes API’s
API:Database
API: Database_Query
Y la documentación de kohana framework (Version 3.1.x): Prepared Statements