Definition
In summary, DAO is a pattern of projects where an object:
- provides an interface that abstracts data access;
- reads and writes from the data source (database, file, memory, etc.); and
- encapsulates the access to the data, so that the other classes do not need to know about it.
Architecture
In a common web application following the MVC model, the Daos are together with the Model doing support work, integrating the data source to the system object model.
Source: Introduction to the JDBC
Responsibilities
Following the principle of sole responsibility, a DAO should not be responsible for more than access to data.
Defining who does what can be a problem when we think about the architecture of a system, but much of it is because we mix things up.
If you look at the diagram above, it is easy to identify the responsibility of each element.
Suppose the user is accessing the home page of the web system. Then a common interaction could be:
- A controller receives the user’s request
- That one controller calls the method of service suitable to get the information for that page
- The service calls one or more methods of Daos to obtain the necessary information and returns the data to the controller
- The controller receives the data and redirects the user to a view that will render the page’s HTML
Additionally, we have to:
- Controllers perform logic related to user navigation on the system, i.e., which URL or action displays which page.
- Services execute system logic, which can include managing transactions and processing data
Therefore, in general, each DAO method should make a single read or write to the database and should not control transactions or perform additional operations, such as making changes to the data received from the service.
I can tell from experience that it is often a temptation for you to put business rules or transactional control in the DAO, after all it is a place where all information will eventually pass. But sooner or later it will conflict with some other part of the system. Therefore, if there is a common rule to be applied in an entity, create a specific service for it and have all other services point to it.
Implementation
The advantage of using a specific class for data access is to avoid spreading Sqls everywhere, making the maintenance and evolution of a system a nightmare.
In general, the accesses to the data are grouped by similarity, for example, one class per table. However, it is not always that this makes sense, especially when the system is not only made of simple registrations (CRUD).
A clear example are systems that have advanced searches in which they access multiple tables. In this case, each situation needs to be analyzed case by case. In the case of searches, a specific DAO would be interesting.
Using interfaces is optional. See, Java has a bad reputation for using many interfaces, but this has its reasons, for example:
- Allow multiple implementations for different databases without changing the system
- Allow different versions to coexist in the same version of the system (this may be useful in some cases, such as when some field may or may not exist and you want to update the system without requiring field creation)
- Facilitate unit testing by creating Fakes implementations of Daos, for example, that use lists in memory, although frameworks like Mockito can generate mocks dynamically without an interface
Interfacing
Have a very simple but complete example on my Github of a DAO encapsulating the entity Usuario
.
The interface looks like this:
public interface UsuarioDao {
Usuario findByNomeUsuario(String string);
void atualizarUltimoAcesso(Integer id, Date data);
}
And the implementation using Spring JDBC Template:
public class UsuarioDaoImpl implements UsuarioDao {
@Autowired
private JdbcTemplate jdbcTemplate;
public Usuario findByNomeUsuario(String nomeUsuario) {
try {
return jdbcTemplate.queryForObject(
"select * from usuario where nome_usuario = ?",
new UsuarioRowMapper(),
nomeUsuario);
} catch (EmptyResultDataAccessException e) {
return null;
}
}
public void atualizarUltimoAcesso(Integer id, Date data) {
jdbcTemplate.update(
"update usuario set ultimo_acesso = ? where id = ?", data, id);
}
}
Sem Interface
The same interface-free DAO and using pure JDBC gets like this:
public class UsuarioDao {
private DataSource ds;
public void setDataSource(DataSource ds) {
this.ds = ds;
}
public Usuario findByNomeUsuario(String string) {
Connection con = null;
PreparedStatement ps = null;
try {
con = ds.getConnection();
ps = con.prepareStatement("select * from usuario where nome_usuario = ?");
ps.setString(1, string);
ResultSet rs = ps.executeQuery();
if (rs.next()) {
Usuario usuario = new Usuario();
usuario.setId(rs.getInt("id"));
usuario.setNomeUsuario(rs.getString("nome_usuario"));
usuario.setSenha(rs.getString("senha"));
usuario.setNome(rs.getString("nome"));
usuario.setUltimoAcesso(rs.getTimestamp("ultimo_acesso"));
return usuario;
} else {
return null;
}
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException(e);
} finally {
if (con != null) {
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
public void atualizarUltimoAcesso(Integer id, Date data) {
Connection con = null;
PreparedStatement ps = null;
try {
con = ds.getConnection();
ps = con.prepareStatement("update usuario set ultimo_acesso = ? where id = ?");
ps.setTimestamp(1, new java.sql.Timestamp(data.getTime()));
ps.setInt(2, id);
ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException(e);
} finally {
if (con != null) {
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
We should use DAO these days?
Many would say no.
Orms like Hibernate or Eclipselink try to do all the heavy lifting to move the data between the objects and the tables. I have seen systems that directly manipulated JPA entities in business rules.
I would say that kind of solution is not scalable, which means it will create problems as the system grows. Precisely because of this, many use the Repository project standard, which is a slightly different type of DAO, even when using JPA.
In my opinion, the DAO standard is still, in general, the best way to implement the interface with the database in a system. I say this because interacting with the bank is a responsibility that is part of almost every system and, if you do not put in the DAO, will end up putting somewhere else. And you don’t want to mix responsibilities, go?
Why The Java Tag?
– Pablo Almeida
See the edition, I forgot to mention that I would like to see how it is used in Java.
– gato
The DAO is the intermediary with the database, it makes connection and transactions with this. Who handles the business rule is the model. But they are concepts that cause a little confusion even for those who do not have custom with even Patterns design.
– user28595
@Diegofelipe is he part of some other pattern? Or is the DAO one thing? I hope someone responds too, the staff is using it in college no one else understands what it is and how it works to be able to use it.
– gato