I'm working in a project in Symfony 3.0.1 that use five databases with DBAL as data access layer. I always worked in Symfony with ORM and I always used the next MVC model:
Data access:
CONTROLLER -> REPOSITORY (the queries goes here) -> ENTITY
Display results:
CONTROLLER -> render($view,$params) -> VIEW
This model allow short and simple controllers, but now I'm using DBAL so I can't use repositories.
The question is:
How can I achieve a similar model by using DBAL? In others words, Where should I put the queries?
Should I use services instead of repositories?
Note: I only use the select statement in that databases.
Thanks in advance!
You don't need an ORM in order to use entities.
Likewise, you do not need Doctrine to be able to build repositories once a repository is a implementation of design pattern:
Repository
Mediates between the domain and data mapping layers using a
collection-like interface for accessing domain objects.
Read more
Even though you can't use Doctrine ORM you still can to design POPO classes against an abstract model class or/and model interface.
You could inject DBAL Connection object for each model/entity via construct or setter method. After creating repo classes is easy. Returning collection objects, hydrating items or using raw arrays is up to you.
Edit #1
I have added a real worl exemple I have used in the past (few years ago), look:
https://github.com/felipsmartins/misc-and-code-snippets/tree/master/php/model-exemple/src/AppBundle/Model
Edit #2
Regarding services, it would much better if there is specialized and well defined models (as opposed to Anemic Models) working together inside a service which coordinates the whole transaction, in this case it would be what we know by Unit of Work (see Unit of Work Pattern)
Related
there is a Repositories layer in my laravel project. I am a freshman about laravel. I can not fully understand the advantages of this layer. My colleagues tell me that it is purpose to lower the coupling of the codes. Obviously, it is true. But I also look forward to your comments.
Using repositories, we can create complicated query and isolated it behind a readable method name. The coupled used, when using eloquent, we must put the record name in eloquent query, but using repositories, we can hide the record name and put in the other place. So that is give some security reason too. Also we can use for grouped some entities for authoritative users. Repository allows abstraction from data provide engine.
This article can help you.
I'm trying to teach myself ZF2 in conjunction with Doctrine 2. I've completed both the Album tutorial and Blog Tutorial on Zend's website successfully. Now I'm trying to go back and convert the Blog Tutorial to use Doctrine 2. I believe I've successfully setup my config for doctrine and used DI to get it inside of my controller (WriteController.php) since I am able to dump the contents of it within my action. I don't get any errors so long as I don't do anything with it.
My question is what roll does Doctrine take in the Controller -> Service -> Mapper -> Backend layered structure which was taught in the Blog tutorial? (Reference To what I mean)
Also, I'm assuming Backend is referring to my Models. Is this correct?
Would I just replace any references to /Blog/Model/Post with /Blog/Entity/Blog?
The Doctrine is the Mapper. And maybe we could say also the Service (through EntityRepository). But usually you will create your own Service Layer.
The Backend is not the entities it self. Entities in one way to map the several options of backend. As backend you can understand the several options of Relational Databases (Mysql, SqlServer, Oracle, etc) NoSql Databases (like MongoDB), file system and so on.
I didn't understand your last question. But when I use Doctrine I always create my entities in /MyModule/Entity namespace. While when I use the standart Zend/Db I always create in /MyModule/Model. I do that by standardizing matters.
I have to create a php project using Codeigniter and Doctrine.
I worked alot with j2ee and I would like to use the same project structure in my php project.
So here is what i'm thinking:
Controllers eg(UserController)
Services aka Models Interfaces (UserService)
Services Implementantions eg (UserServiceImpl implements UserService)
Dao Interfaces (UserDao)
Dao Interfaces implmentations eg(DoctrineUserDao)
Doctrine Entities
Views
I haven t seen implemented in php projects interfaces for services and dao design pattern is always missing. Are Interfaces and DAO redundant in php mvc projects ?
And another question: as far as I know Codeigniter loads model using the following syntax:
$this->load->model('UserServiceImpl'); which is kind of lame in my opinion, i prefer using autoloader with namespaces, is this bad ?
I've designed a few smaller systems with CodeIgniter, and now I'm designing/building a big one. I always followed the same structure (the one I'm going to describe here) and it worked for me very well so far. For my current project we tried to use Doctrine as the ORM, but in the end I decided to leave it out from the project - it was more of a burden than help.
(I may use slightly different terms for the layers, but I tried to put them in parallel with your terms wherever I could.)
The structure I use is:
Controllers (e.g. /application/controllers/UserController.php)
Data Mapper (ORM) layer (e.g. /models/tables/UserTable.php)
Domain Object layer (e.g. /models/data_models/User.php)
Layouts (e.g. /models/layouts/default.php)
Templates (views) (e.g. /application/templates/user/view-profile.php)
Responsibilities:
(2) Data Mapper layer contains all the SQLs, and all Doctrine EntityManager usages. It stores and retrieves Domain Objects.
(3) Domain Objects represent the entities (with entity metadata described in comments for Doctrine, using the Docblock Annotations format).
(1) Controllers do only the logic of calling the ORM layer, maybe do some restructuring of data or calculations.
(4) The layout layer helps me a lot with separating the quasi-static frame of the pages from the more dynamic content. See CodeIgniter and layouts? if you like the idea.
(5) Templates are basically HTML with a few PHP snippets.
All my files that contain classes contain one class per file, named the same as the filename (as per http://www.php-fig.org/psr/0/) but I don't use namespaces because I find it hard to make it work with CodeIgniter that doesn't use them.
You can load your models in autoloader, especially if you work on a small or medium-sized project and performance is not critial. I always load all my models with the autoloader in these cases. However, on a bigger project it's more worthwhile to load widely-used models in the autoloader and more specific ones in the controller constructor or the more specific ones even in the actions.
What are the advantages of Repositories in Laravel? It seems to be abstracting the Model layer from the business logic of the application. Although it really just seems to make the whole request life cycle just that much more complicated for little gain.
Can someone shed light on the advantage of Laravel repositories?
Edit
After now using repositories for some time I would add the following:
Repositories enforce single responsibility
Repositories should only return one collection of entities
Although separate from dependancy injection the concepts are brothers
Storage abstraction for the actual storage implementation (e.g. MySQL)
Easier testing
Repositories, like in the provided tutorial, aren't necessary a Laravel concept. Rather, they're a form of IoC injection that is possible with Laravel. Any object that might similarly be injected doesn't mean it's a repository. See the video for a good example from Taylor Otwell, which happens to use a "repository" as well: http://vimeo.com/53029232.
In this example, the repository abstracts where the data came from that is passed to the controller. As long as the data passed implements the specified interface, the controller can "blissfully" make use of the interface's defined methods without worry about where the data initially came from. This allows switching the initial source of the data without breaking your controller. You could pull the data from a file, a database, an outside API, a mock object, or just some arbitrary array. Basically, the controller doesn't need to gather the data represented by the repository. It can just receive and use.
In addition to the other answers here, it's worth pointing out that repositories used when used in Laravel can add an extra level of expressiveness. Take for example the following:
$users = User::whereHas("role", function($q) {
$q->where('name', 'moderator');
}, '<', 1)->get();
The code is difficult to read and awkward to look at. It can be encapsulated in a repository method, and demonstrate much clearer code intent:
$users = $userRepository->getUsersWhoAreNotModerators();
This is also achievable using eloquent 'query scopes' but I think using a repository is superior, as is adheres much better to the single responsibility principal, and is doable regardless of whether you are using Eloquent.
Repositories help to keep your controller clean and make reusable code. Functions in repositories can be accessed in one or more controllers, repositories, etc.
Also, all your backend related logic (like fetching data from database or external calls) can be added in repositories to make the logical separation.
One of the main uses of repositories is to create different binding (using interfaces to define your functions and with the help of the app, bind different implementations of the function as per need). For example, two separate repositories (implementing the parent repository/interface) handling database and files for backend data.
The main reason you use repository pattern is to be able to easily change your data source. For example, in my experience the most common change is adding a caching layer, because the repository implements an interface all you need to do is build the new object implementing the same interface with the new methods handling cache and change the binding.
In my experience the repository in Laravel benefits are these:
The most important thing by using repositories is that you can change your ORM any time and for any reason that you prefer. for example, you want to migrate from MySQL eloquent to some other SQLite ORM.
Helps you to keep your controllers clean and readable.
Helps you to reuse your methods in a repository for any other controllers.
You can add BaseRepository to your repositories list, which involves all base methods like all(), get(), findOrFail(), firstOrFail(), paginate(), create(), ... and use them in other repositories.
Using Interfaces for repositories and binding them that also can be used as services in Laravel.
What good is a repository pattern when you have an ORM?
Example. Suppose i have the following (fictional) tables:
Table: users
pk_user_id
fk_userrole_id
username
Table: userroles
fk_userrole_id
role
Now with an orm i could simply put this in a model file:
$user = ORM::load('users', $id);
Now $user is already my object, which could easily be lazy loaded:
(would be even nicer if things are automatically singular/pluralized)
foreach ( $user->userroles()->role as $role )
{
echo $role;
}
Now with the Repository pattern i'd had to create a repository for the Users and one for the Roles. The repository also needs all kinds of functions to retrieve data for me and to store it. Plus it needs to work with Entity models. So i have to create all of those too.
To me that looks like alot of stuff do... When i could simply get the data like i described above with an ORM. And i could store it just as easy:
ORM::store($user);
In this case it would not only store the user object to the database, but also any changes i made to the 'Roles' object aswell. So no need for any extra work like you need with the repository pattern...
So my question basically is, why would i want to use a repository pattern with an ORM? I've seen tutorials where to use that pattern (like with Doctrine). But it really just doesn't make any sense to me... Anyone any explanation for its use in combination with an ORM..??
The ORM is an implementation detail of the Repository. The ORM just makes it easy to access the db tables in an OOP friendly way. That's it.
The repository abstract persistence access, whatever storage it is. That is its purpose. The fact that you're using a db or xml files or an ORM doesn't matter. The Repository allows the rest of the application to ignore persistence details. This way, you can easily test the app via mocking or stubbing and you can change storages if it's needed. Today you might use MySql, tomorrow you'll want to use NoSql or Cloud Storage. Do that with an ORM!
Repositories deal with Domain/Business objects (from the app point of view), an ORM handles db objects. A business objects IS NOT a db object, first has behaviour, the second is a glorified DTO, it only holds data.
Edit
You might say that both repository and ORM abstract access to data, however the devil is in the details. The repository abstract the access to all storage concerns, while the ORM abstract access to a specific RDBMS
In a nutshell, Repository and ORM's have DIFFERENT purposes and as I've said above, the ORM is always an implementation detail of the repo.
You can also check this post about more details about the repository pattern.
ORM and repository pattern...depends on setup.
If you use your ORM entities as the domain layer, then please use no repositories.
If you have a separate domain model and you need to map from that model to ORM entities and so perform a save, then repositories are what you need.
More details you find here (but must be logged to linked-in). Also to understand the difference, check out the definition of the repository pattern.
Most people use classes that they call repositories, but aren't repositories at all, just query classes - this is how/where you should place your queries if you decided to go with the #1 option (see answer above). In this case make sure not to expose DbContext or ISession from that query class, nor to expose CUD-methods from there - remember, Query class!
The #2 option is a tough one. If you do a real repository, all the inputs and outputs on the repository interface will contain clear domain classes (and no database related object). It's forbidden to expose ORM mapped classes or ORM architecture related objects from there. There will be a Save method also. These repositories might also contain queries, but unlike query classes, these repos will do more - they will take your domain aggregate (collection and tree of entities) and save them to DB by mapping those classes to ORM classes and perform a save on ORM. This style (#2) does not needs to use ORM, the repository pattern was primarly made for ADO.NET (any kind of data access).
Anyhow these 2 options are the 2 extremes we can do. A lot of people use repositories with ORM, but they just add an extra layer of code without real function, the only real function there is the query class like behaviour.
Also I'd be careful when someone talks about UnitOfWork, especially with ORM. Almost every sample on the internet is a fail in terms of architecture. If you need UoW, why not use TransactionScope (just make sure you got a wrapper which uses other than Serializable transaction by default). In 99,9% you won't need to manage 2 sets of independent changes in data (so 2 sets of OuW), so TransactionScope will be a fine choce in .NET - for PHP i'd look for some open-session-view implementations...