use query builder or sql doctrine - php

i do some research to answer it but i don't find.
I'd like to know what is the best practice to do select (with join) between :
use query builder ?
$this->getEntityManager()->createQueryBuilder()
->select('e')
->from('Module\Entity\MyEntity 'e')
->innerJoin('Module\Entity\MyEntity2', 'e2', 'WITH', 'e.e2_id = e2.id')...
->where("...")
or
use SQL statement ?
$db = $this->getEntityManager()->getConnection();
$sql = "SELECT * FROM myEntity e
INNER JOIN myEntity2 AS e2 ON e2.id = e.e2_id....
WHERE ....;"
it is safer, faster,... ?

Both have advantages and disadvantages, so it depends on what you need.
SQL
a pure SQL statement is a little bit faster, since you don't have to execute the additional logic coming from Doctrine
since Doctrine tries to support a lot of different databases, some database specific functions are not supported, so you can't use them or have to implement them into Doctrine, which can become a lot of work
DQL
Doctrine forces you to use prepared statements, making prevention of injection attacks easier to enforce as long as you insist on named parameters. But this can be done with pure SQL and PDO too, using named parameters.
Working with entities is much easier. Data is automatically bound into objects and they are managed through your application. Of course this causes a hit with some performance overhead
One disadvantage regarding joins is that you always join the whole table instead of maybe only the two columns you need. And you need relationships defined if the result should come in an object-useful way
Biggest benefit is probably also rarest used: if you change your database you don't need to rewrite all your queries to match the new query structure
Sometimes I find myself in a situation where I could solve a problem directly in a SQL query, but Doctrine doesn't support some of the constructs I would have to use. So I have to decide if I want to lose the Doctrine benefits and go for the pure SQL solution or use DQL and add some more php code, maybe even more otherwise unnecessary queries. But this depends strongly on the situation and can not be answered in general.
In the end I would use DQL wherever possible because it's easier to write and maintain and only switch to SQL when I need some query to be high performance.

Related

Where to put PDO prepared statements in a DB_Connector class - in the constructor or the functions?

My web project has a class called DB_CONNECTOR where all the functions are bundled that interact with the mysql database. These would be functions like get_user(), add_user(), change_user_attribute() and many more. In each of these functions a sql query is executed and as is good practice, I use prepared statements (with named parameters).
Currently the connection to the database is established in the constructor of the class and also all the statements are prepared there. I thought this would be a good idea, so the statements are all immediatly ready for execution.
Now I realized that my use case is often to create a db_connector object, execute one or maybe two functions and then the objects lifecycle ends and at a later step a new one might be constructed (or not). So, I'm not so sure anymore if it smart to put the prepared statements in the constructor as it is forseeable that I will end up with at least 20 or likely more prepared statements.
So my question is:
is it a good idea to prepare all the statements in the constructor even if only one or two are used?
Or should I prepare them in the functions right before execution to avoid stressing the db with unneeded preparations?
This answer is based in both my experience and humble opinion, but I'll try to elaborate my arguments so it isn't just some random guy's opinion.
I don't think the database connection must be the core object in your application, let alone the only one. It'd expect to see an entirely different class for the user, so you can later have further classes for everything else. Otherwise, your application will eventually consist of a single class in a 5000 line file and your class will not be suitable to track entity data at instance level and you'll need to pass variables around in method calls. That's pretty much procedural code in OOP dress.
Also, I don't that making your User class inherits from Database (something pretty frequent nonetheless) is practical at all. Interlacing the database connection and the business logic objects doesn't really simplify application design and actually makes some parts harder.
The design of the database layer itself is pretty much standardised:
One connection per application (or more... you may need to connect to several sources!)
One statement per query.
This is exactly how PDO works.
Given that, it's easier to make the database classes just one more dependency of your entities rather than their grandparent. The injection of this dependency can be done by different means:
Make it a class property:
public function __construct(\PDO $connection)
{
$this->connection = $connection;
}
Pass it to the methods they actually needed (if not many of them):
public function getOrders(\PDO $connection)
{
$stmt = $connection->prepare('SELECT ...');
}
... or use one of those fancy dependency injection containers you can find at Packagist.
Be aware that there're also object-relational mapping (ORM), active record pattern... Those are entirely different families of solutions which may suit your needs or not depending on your use case, but not what I'm describing here.
Said that, it becomes obvious that you prepare the statements at the exact point where you need them. This design doesn't even allow otherwise ;-)

With Doctrine what are the benefits of using DQL over SQL?

Can someone provide me a couple clear (fact supported) reasons to use/learn DQL vs. SQL when needing a custom query while working with Doctrine Classes?
I find that if I cannot use an ORM's built-in relational functionality to achieve something I usually write a custom method in the extended Doctrine or DoctrineTable class. In this method write the needed it in straight SQL (using PDO with proper prepared statements/injection protection, etc...). DQL seems like additional language to learn/debug/maintain that doesn't appear provide enough compelling reasons to use under most common situations. DQL does not seem to be much less complex than SQL for that to warrant use--in fact I doubt you could effectively use DQL without already having solid SQL understanding. Most core SQL syntax ports fairly well across the most common DB's you'll use with PHP.
What am I missing/overlooking? I'm sure there is a reason, but I'd like to hear from people who have intentionally used it significantly and what the gain was over trying to work with plain-ole SQL.
I'm not looking for an argument supporting ORMs, just DQL when needing to do something outside the core 'get-by-relationship' type needs, in a traditional LAMP setup (using mysql, postgres, etc...)
To be honest, I learned SQL using Doctrine1.2 :) I wasn't even aware of foreign-keys, cascade operations, complex functions like group_concat and many, many other things. Indexed search is also very nice and handy thing that simply works out-of-the-box.
DQL is much simpler to write and understand the code. For example, this query:
$query = ..... // some query for Categories
->leftJoin("c.Products p")
It will do left join between Categories and Products and you don't have to write ON p.category_id=c.id.
And if in future you change relation from one-2-many to let's say many-2-many, this same query will work without any changes at all. Doctrine will take care for that. If you would do that using SQL, than all the queries would have to be changed to include that intermediary many-2-many table.
I find DQL more readable and handy. If you configure it correctly, it will be easier to join objects and queries will be easier to write.
Your code will be easy to migrate to any RDBMS.
And most important, DQL is object query language for your object model, not for your relational schema.
Using DQL helps you to deal with Objects.
in case inserting into databae , you will insert an Object
$test = new Test();
$test->attr = 'test';
$test->save();
in case of selecting from databae, you will select an array and then you can fill it in your Object
public function getTestParam($testParam)
{
$q=Doctrine_Query::create()
->select('t.test_id , t.attr')
->from('Test t ')
$p = $q->execute();
return $p;
}
you can check the Doctrine Documentation for more details
Zeljko's answer is pretty spot-on.
Most important reason to go with DQL instead of raw SQL (in my book): Doctrine separates entity from the way it is persisted in database, which means that entities should not have to change as underlying storage changes. That, in turn, means that if you ever wish to make changes on the underlying storage (i.e. renaming columns, altering relationships), you don't have to touch your DQL, because in DQL you use entity properties instead (which only happen to be translated behind the scenes to correct SQL, depending on your current mappings).

using both active record and doctrine in codeigniter

I was curious to know whether its ok if I user codeigniter's active record query besides using doctrine in some cases, simultaneously. Because in some cases, I find active record more easy and quick way to get things done then writing doctrine query. For example, consider the following case where I need to return total number of rows in a table, in doctrine:
$query = $this->em->createQueryBuilder()
->select("count(c)")
->from($this->entity, "c")
->getQuery();
return $query->getSingleScalarResult();
vs via active record:
return $this->db->count_all_results($this->table);
You can see how easy it is in active record. There may be more such cases. So, is there any pros or cons in using both?
Also, will they use two different db connection to perform their operations?
You can use both Doctrine and ActiveRecord at the same time. Swordfish has highlighted the some problems. In addition to that if you bring in new developer team, the learning curve will be more.
I suggest choose one and stick with it. IMO, both are equally good. You should choose based on your current project and personal preference. You can find the very good comparison here
What Does Doctrine Add Above Active Record - CodeIgniter?
Regarding the two queries you mentioned, if you use DQL, it might look simple
$query = $em->createQuery('SELECT COUNT(u.id) FROM Entities\User u');
$count = $query->getSingleScalarResult();
I was curious to know whether its ok if I user codeigniter's active
record query besides using doctrine in some cases, simultaneously
Yes it is ok. There's no rule against it.
Also, will they use two different db connection to perform their
operations?
Depends on how you use them. Connection pooling in PHP is not how it is in other languages. You might have to write a custom class to hook them both up to use a common connection, but its not something that id spend my time for if im in an hurry.
Regarding Pros and Cons
It is good to stick with active record as far as codeigniter is concerned as it is cleaner, efficient and comes as part of codeigniter and provide you almost everything that you might need. You can get the extended active record class from codeigniter forums that extends on the base class to provide some complex join functionality as well.
But technically its not an issue using two layers, other than the fact that it gets messy, and makes two separate connections.
Find the link for the doctrine integration in CI
https://github.com/mitul69/codeigniter-doctrine-integration
I will update more document in couple of days.

Why would one want to write MySQL queries "programmatically like active record?"

I'm working with the TinyMVC framework, and it allows one to "build MySQL queries programmatically, much like active record." The example is embedded here (relevant TinyMVC documentation):
class Members_Model extends TinyMVC_Model
{
function get_members()
{
$this->db->select('foo,bar,baz'); // set selected columns
$this->db->from('mytable'); // set from what table(s)
$this->db->where('foo','test'); // where foo='test'
$this->db->orwhere('foo=? and bar=?',array('test','test2')) // where foo='test' and bar='test2'
$this->db->join('jointable','mytable','jointable.foo=mytable.foo'); // join tables on (optional) condition
$this->db->in('mycolumn',$elements,$islist,$prefix) // IN clause: column, elements (comma-separated or array), $list=boolean is list or array, $prefix: AND|OR
$this->db->orderby('ordercolumn'); // order by column(s)
$this->db->groupby('groupbycolumn'); // group by column(s)
$this->db->limit($limit,$offset); // query limit, optional offset
$this->db->query();
while($row = $this->db->next()) {
$rows[] = $row;
}
return $rows;
}
}
How is this different or better than the writing the SQL query outright:
SELECT foo, bar, baz
FROM mytable
WHERE...
The benefit is that you can have interdependent functions in your controller that can build on your query without having to worry about the order of your SQL. You can have conditional logic to use certain active record manipulations on one query and then simply run it when it's fully populated.
CodeIgniter's active record implementation is extremely useful. I imagine TinyMVC's is very similar.
The codeigniter website gives the following reason
Beyond simplicity, a major benefit to using the Active Record features is that it allows you to create database independent applications, since the query syntax is generated by each database adapter. It also allows for safer queries, since the values are escaped automatically by the system.
it is an opinion (my)...
you can play with part of the query qithout handling long string.
for example:
if(){
$this->db->where($a,$b);
$this->db->where($c,$d);
$this->db->where($e,$f);
}else{
$this->db->where($g,$h);
$this->db->where($i,$j);
$this->db->where($k,$l);
}
writing the above statement in one string is not very nice coding and hard for maintenance.
And in addition to that, you can than generate cross database queries (helps for migration and in shelf products).
that is only one good reason...
It is not really different, it's more to make it easier for you, the programmer. Because if you write the query yourself, you have to worry about security yourself (mysql injection for example) using their model, they do that for you. You only need to put your variables in and done.
It is way easier to be consistent in your code. And easy to always escape strings etc when doing inserts/updates. Security is important.
<troll>
Because some people are allergic to SQL and want to shoehorn objects into relational operations.
Security ? Use prepared statements. Portability ? Have a list of queries per DBM.
And if you have to dynamically generate a query, you may have to rethink how you separate your database layer from your application layer.
</troll>
The advantage of those ways of doing database queries is all this code can be generated quickly using some framework. Which enables you to prototype applications very fast which you'll need often.
And you don't have to learn vendor specific SQL when going from one DBM to another (google "Oracle Limit" to see an example of what I mean).

Data Mapper Design Pattern and Gateways - Newbie question

Please, correct me if I'm wrong:
If we use a Dao/Vo pattern or a TDG pattern we will have a nice code organization by having for each (or at least for a lot of) tables a related class.
The problem with this approach is that or data IS NOT closed inside a given table. We have some domain specific data, like findDogBreed(); or findBookBestSellerAuthor(); and the above patterns don't seem to deal with this nicely.
Once solution is to use Mappers. Mappers will contain a set of methods and properties related to one table BUT they will not be closed to that table only nor will they be related to a specific SQL Schema.
The problem is, if we start to abstract all those things, we will NOT have access to SQL syntax. What if we need our database administrator to work on it ? And on more complex queries, using mappers could lead to a really messy abstraction "thing".
Is this correct ? If so, I'm wondering what paths do we have in order to find a middle term here.
You don't have to lose the option to write SQL manually when you abstract the functionality, even on multiple levels abstraction.
E.g. look at Doctrine, which is Hibernate-inspired ORM for PHP. It allows you to write queries in DQL (Doctrine Query Language) that translates to SQL and automatically maps your entities, but you can also write native SQL (most often for performance optimization), but you need to define the result mapping by yourself.

Categories