1

I'm working on my own MVC framework in PHP. Its model layer consists of

  • Domain objects (also known as "models"), which encapsulate the business logic and
  • Data mappers, for transfering the data between the domain objects and the database.

A data mapper abstract class does not exist, each data mapper class containing its own implementation of the data access layer. The class methods of the data mappers contain, or will contain complex sql statements.

My question is: Under these circumstances, is the use of a query builder class - responsible for building the sql statements - a limitation, or are there some good arguments, why this component should be implemented?

I appreciate your help. Thank you.

  • 2
    The query builders are useful, when you have multiple conditions, that would alter the query itself (for example, combining various conditions in the `WHERE` part of your query). The penalty for it is - queries become harder to comprehend and you have nothing, that you can copy-paste in your SQL client to try out. In my experience, the problem, that query builder solve, can also be fixed by just having multiple data mappers for same domain object. You just pick the mapper at repository level, which fits your domain objects state. – tereško Jul 04 '17 at 11:45
  • @tereško Thank you for your comment. That's an interesting argument - to construct and chose proper mappers instead. –  Jul 04 '17 at 13:30
  • For the users who downvote(d) my question: Please let me know the motive(s) of your downvotes, so that I can change my question correspondingly. This way we can contribute together to the continuous improvement of this website. Thank you. –  Jul 04 '17 at 13:39
  • @aendeerei I didn't down vote, but the question is vague and hard to folllow. Particularly the first two paragraphs; 1. What's your definition of a "domain object", 2. "The project should contain complex queries on multiple databases and tables.". The project? Yeah so, must projects do. 3. In the 2nd paragraph, what is the relationship between the first and second sentence exactly? – spinkus Jul 05 '17 at 02:23
  • @spinkus You have right. I will update the answer immediately. Thank you for your advices! I appreciate it. Please feel free to tell me if something else remains unclear. –  Jul 05 '17 at 02:30
  • @spinkus I updated the answer. Indeed it was somehow unclear. A domain object is a "model", as many people name it. About the multiple databases and tables, I wanted to mean the access of multiple databases on multiple servers. The part with the ORM and Active Record is out now, because actually it had no relevance. Thanks again ;-) –  Jul 05 '17 at 03:29
  • @spinkus If you are unfamiliar with the terminology of "domain object", perhaps you should read "Domain-Driven Design: Tackling Complexity in the Heart of Software" by Eric Evans. – Joshua Jones Jul 05 '17 at 12:58

1 Answers1

1

1.) A well featured query builder could be an advantage, in that it could provide an interface which would abstract the SQL dialect. Therefore, you could write your data mapper implementations without the need to consider the specific RDBMS you will be working with.

2.) In some of my DAO or Service classes, I may have two (or more) functions that perform slightly different queries against the same table(s). Sometimes, these queries can be quite large, and have a number of joins or sub-queries while only differing in the columns used in the WHERE clause. While it might make sense to keep these functions separated with signatures like, getEmployeesAgedBetween(Range<Integer> range) and getSalariedEmployeesAgedBetween(Range<Integer> range), these functions can grow quite quickly in number based upon your needs. Looking to refactor a case like this, I would aim for a more robust method that parameterizes all possible differences between these methods. It is apparent that I am only looking to make a more dynamic WHERE clause under the hood, so I would not necessarily need a full-fledged query builder. However, a WHERE clause builder would be quite useful. Using such an implementation, I could refactor the above functions into a single method with a signature like getEmployees(Where<EmployeeDAO.FIELDS> where). I have actually implemented such a method, and both my coworkers and myself have enjoyed working with, and maintaining such methods over the prior implementations.

Joshua Jones
  • 1,364
  • 1
  • 9
  • 15
  • 2
    In all my years I haven't actually participated in a project, which involved changing the underlying RDBMS. It's a good argument in theory, but the usecase is extremely rare in practice. – tereško Jul 04 '17 at 11:48
  • 1
    Out of my 10 years of experience, I would agree that if the project is not meant for distribution, changing the target RDBMS is rare. However, I am currently involved in a very large migration from Oracle to PostgreSQL, and I wish they had abstracted the dialect. – Joshua Jones Jul 04 '17 at 12:53
  • @jjones Thank you very much for your answer. Your use-case regarding the migration from a RDBMS to another just made me realise the importance of a query builder implementation. Good point! –  Jul 04 '17 at 13:24
  • @jjones Hi. As you probably saw, or will soon see, the bounty on my question suddenly disappeared. Today I had the surprise myself, to discover that the bounty was given back to me. That's most probably a secondary (unwanted) effect of some other change I asked today from the contact support team. I already signalized the problem to the admins and I expect to be resolved these days. So, as soon as possible I'll put the bounty back on my question and decide at the end of it's period (or earlier) the answer to receive it. Sorry for the unpleasant situation! –  Jul 06 '17 at 22:04
  • @aendeerei no problem. I'm not here for the points. Just trying to give to the community whatever I can offer. – Joshua Jones Jul 06 '17 at 22:51
  • @jjones You have given me a very good argument. Thank you again! I open a bounty for a further week. So, if you think of another argument please feel free to share with me. Any idea is important for me. P.S: As you see, I managed to find a solution together with the support team for my prior account problem, e.g. bounty removing. I'm happy to give it to you, even if a bit late ;-) –  Jul 12 '17 at 03:10
  • @jjones It seems indeed quite useful such an implementation. I will think of how it should look like. Right now it's a bit abstract, until I apply it. Then I will certainly discover it's power. Thank you! P.S: I tried to open a new bounty, but the SO team said that I need a minimum of 300 reputations. So, it will take a bit more time... –  Jul 13 '17 at 19:44
  • Hi, @jjones. As I already told you, I reopened a bounty for my question. After the 7 days I'll take all the answers into consideration, including your second one, which you were so kind to provide. Bye. –  Jul 18 '17 at 04:31
  • @jjones Thank you very much for a very good answer! P.S: I can't stop wondering myself why I got only one answer for my question - yours - even though it was viewed 250 times. Do you have any idea? Because it's a real mistery to me :-) –  Jul 23 '17 at 20:16
  • @aendeerei Well the question was a theoretical one, and stack overflow doesn't really seem to be a theoretical forum. Also, I've written a few PHP MVC frameworks; some tools I would suggest are: router - [fastroute](https://github.com/nikic/FastRoute), DI - [auryn](https://github.com/rdlowrey/auryn), and try to utilize the [PSR-7 interfaces](http://www.php-fig.org/psr/psr-7/), [guzzle](http://docs.guzzlephp.org/en/stable/) and [zend diactoros](https://github.com/zendframework/zend-diactoros) are good tools for PSR-7 – Joshua Jones Jul 23 '17 at 20:37
  • @jjones Mistery solved then :-) It seems that my project already follows your recommendations: though no router yet - my own choice for the moment, Auryn and PSR-7 (which I just began to implement some days ago, in order to replace my current implementation). Actually I were on the guzzle github in the moment of your comment :-) I will look into Zend diactoros too. Thank you for your time and precious advices! I appreciate it. –  Jul 23 '17 at 20:53