Before I jump into implementing the classes, let’s first understand what DAO is. If you already know what DAO is, feel free to jump to the code examples. If not, bear with me.
DAO stands for Data Access Object and it is a structural pattern which isolates the business layer (logic) from the persistence layer (such as database) by using an abstract API.
Put simply, the object (DAO) provides an abstract interface to a database. The positive is that the application (the bussiness layer/logic) does not know any details about the database as this is DAO’s job. It separates business logic and the data.
Let’s implement the DAO pattern.
The most famous example given when working with DAO is User – name, email, password. In this article, I will be using an Employee – name, email example.
Employee.java
public class Employee { //members private String name; private String email; // constructor Employee(String n, String e) { name = n; email = e; } // setter methods public void setName(String n) { name = n; } public void setEmail(String e) { email = e; } // getter methods public String getName() { return name; } public String getEmail() { return email; } }
Breakdown
There isn’t much going on in the above class. A standard constructor/setter/getter methods class.
Before we write our EmployeeDAO class, let’s first take a look at what the Dao<T> interface contains.
public interface Dao<T> { Optional<T> get(long id); List<T> getAll(); void save(T t); void update(T t, String[] params); void delete(T t); }
It has get, getAll, save, update, delete methods. In a nutshell, CRUD operations on objects of type T. Now our next objective is to implement that interface in our EmployeeDAO.java class.
EmployeeDAO.java
public class EmployeeDAO implements Dao<Employee> { // will act as a "mini-database" private List<Employee> employees = new ArrayList<>(); // Constructor public EmployeeDAO() { // Populate our list of employees with 3 Demos employees.add(new Employee("Demo1", "Demo1@example.com")); employees.add(new Employee("Demo2", "Demo2@example.com")); employees.add(new Employee("Demo3", "Demo3@example.com")); } // Overriding the Dao interface methods @Override public Employee get(long id) { return employees.get((int) id)); } @Override public List<Employee> getAll() { return employees; } @Override public void save(Employee emp) { employees.add(emp); } @Override public void update(Employee employee, String[] params) { // Check for validity if (params[0].length() != 0|| params[1].length() != 0) { // Initialize the employee employee.setName(params[0]); employee.setEmail(params[1]); // Add the Initialized employee to the list of employees (a.k.a. DB) employees.add(employee); } } @Override public void delete(Employee employee) { employees.remove(employee); } }
Breakdown
Thanks to the implements Dao<Employee> code, we have access to all the methods that we are overriding because we are taking that functionality from the Dao API. As mentioned in the comments, the employees list can be thought of as a database for simplicity sake. Can you see now why this pattern is very powerful and more importantly, how it works? The Employee class and the EmployeeDAO exist without relying on each other. If you are familiar with OO (Object-oriented) concepts, then you could associate this relationship with Aggregation in the OOP world.
Now it’s time to create the application, a.k.a. the business layer or the logic.
DemoApplication.java
public class DemoApplication { // Declare an instance of Dao private static Dao employeeDao; public static void main (String[] args) { employeeDao = new EmployeeDAO(); Employee demoEmployee1 = getEmployee(0); employeeDao.update(demoEmployee1, new String[] { "Hugh", "hugh.demo@demo.com" }); Employee demoEmployee2 = getEmployee(1); employeeDao.update(demoEmployee2, new String[] { "Marry", "marry.demo@demo.com" }); Employee demoEmployee3 = getEmployee(2); employeeDao.update(demoEmployee3, new String[] { "Sharry", "sharry.demo@demo.com" }); // print all the employee in the database for (Employee emp : employeeDao.getAll()) { System.out.println(emp.getName()); } // add an entry to the database Employee newDemoEmp = new Employee("Slim", "slimmy@demo.com"); employeeDao.save(newDemoEmp); // print all the employee in the database after we have added another entry for (Employee emp : employeeDao.getAll()) { System.out.println(emp.getName()); } } private static Employee getEmployee(long id) { // Fetch the employee from the Database based on the id provided // Keep in mind that the .get method used below is coming from the DAO class Employee emp = employeeDao.get(id); // Return that employee return emp; } }
Breakdown
Even though the code above is heavily commented, I will still add a couple of things about it. Above our main method, we declare a Dao instance that we will be using for using the Overriden methods we did earlier.
Notice how we created another getter method in this class that is called “getEmployee(long id)”. This method uses another “get(long id)” method. The inner get method is the one we overrode in EmployeeDAO class. After we have fetched that employee with the given id, we assign it, and straight after that we use the update method which we, again, overrode. We are passing in the employee instance we want to be updating as well as the new name and the new email we want to give to that employee.
After that, we use the getAll() method which we overrode, which gives us back the List of the employees. After that, we simply add a newly created Employee to the List and then we print the employees again, now with 1 more entry.
Conclusion
DAO should perform database operations and organize the data in a way that is accessable outside the class.Typically, the classes that use the DAO class is either the Application itself or a Service class that you have.
In two words, DAO provides data to your services.