Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In which layer do I access database in a MVC design [closed]

I have a question regarding database access in a mvc application. Where should my database access logic placed?

should it be placed in each model? (if I have a Person model)

Person p = new Person();
p.save();

should it be placed in each controller? or should I create a different set of classes only to perform the database logic, which means I have an additional layer in addition to model,view and controller?

How is this done? Also what if an ORM is used?

like image 655
DesirePRG Avatar asked Feb 10 '23 06:02

DesirePRG


2 Answers

In MVC pattern, M means models, V means view, C means controller. A common MVC application progress is that once a request is coming, controller get it and do necessary processing, retrieving results data, then pass the results data to view for rendering. After view layer is rendered, it displays to users via GUI.

Controller can be regarded as a commander, it controls process, but it is not good to handle data retrieving in controller. Model should be responsible for retrieving and organizing data. That means data objects should be stored in Model instead of Controller, Controller calls Model to retrieve data objects.

For your case, my suggestion is it needs following components:

  1. PersonController, it calls PersonService.savePerson(Person person) method to save data(or in other case it retrieves result). I suggest Controller layer should be thin.
  2. PersonService, it has method savePerson(Person person), this method calls PersonDAO.savePerson(Person person) method to save/retrieve projects data(here it saves data), and maybe other handling. Here business logic goes.
  3. PersonDAO, it has several methods which deal with Person objects(like savePerson(Person person), getAllPersons()), deal with database in this layer. But these methods should be independent with business logic(as business logic should be deal in PersonService).
  4. Person object, it is value object, it just defines what attributes a Person should have, like name, age, etc, with get/set methods, used for passing data through different layers. It does not deal with database at all.

While for uncomplex application, Service layer is not very necessary and can be integrated to Controller layer, which means just PersonController is ok.

like image 134
coderz Avatar answered Feb 12 '23 20:02

coderz


Others have pointed out that database access is a Controller function, but I recommend that you create a new library project to handle the database interaction. Typically this will have a name like "customerService.jar" - i.e. it encapsulates everythng you want to do to a customer. This will simplify your application, and add greatly to the reusability of your code.

This would be by approach:

  • Define an interface that exposes business level operations (eg. changeUserRole(long userId, Role newRole) or makePayment(long accountId, BigDecimal amount) rather than the CRUD approach of updateUser(User user) etc. Typically some of the methods exposed by the interface will look like CRUD methods but might do more at the database end (e.g. check account status, maintain audit tables).
  • Implement your business logic in this layer. Purists would say that there should be a separate layer for the business logic, but this makes it difficult to use SQL facilities (joins in particular) to efficiently access the database. In my experience these two layers need to be combined to keep the system simple and performant.
  • Use an ORM tool to access the database and map from business objects to the database. (MyBatis is my favorite). If your database accurately reflects your business model, then you probably won't need separate DAO and business objects.
  • Inject an instance of your customerService into your web MVC controller. The job of the controller is now to validate user input, populate the model, pass through requests to the customerService and put response data back into the model.

So if your needs change in future (e.g. You need to create an IOS or Android native app) you have a re-usable service that will happily do the job. Similarly if the architects insist on exposing it as a REST or SOAP service, you only need add the "glue logic" to implement the REST or SOAP service.

Also, it is easy to mock out the customerService in web unit tests.

Best of luck!

like image 21
kiwiron Avatar answered Feb 12 '23 19:02

kiwiron