What is dao in java example

The DAO Design Pattern in Java / Spring Boot

The DAO (Data Access Object) design pattern is a popular way of separating the persistence layer from the rest of your application. It provides a way to abstract away the details of database operations, and helps improve the maintainability and testability of your code. In this blog post, we’ll explore the DAO pattern in Java/Spring Boot, and provide code examples to illustrate how it works.

Setting up the Project

To get started with the DAO pattern in Java/Spring Boot, you’ll need to create a new Spring Boot project and include the necessary dependencies. Here’s an example pom.xml file:

    org.springframework.boot spring-boot-starter-web   org.springframework.boot spring-boot-starter-data-jpa    com.h2database h2 test   

In this example, we’ve included the spring-boot-starter-web and spring-boot-starter-data-jpa dependencies, which provide the necessary components for building a web application with database access. We’ve also included the h2 database dependency for testing purposes.

Defining Entities

In the DAO pattern, entities are POJOs that map to tables in a relational database. To define an entity in Spring Boot, you’ll need to create a class with appropriate annotations, such as @Entity , @Table , and @Id . Here’s an example:

@Entity @Table(name = "customers") public class Customer  @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String firstName; private String lastName; // getters and setters > 

In this example, we’ve defined a Customer entity that maps to a customers table in the database. We’ve used the @Id and @GeneratedValue annotations to specify the primary key, and included firstName and lastName fields.

Defining DAO Interfaces

Once you’ve defined your entities, you can create DAO interfaces that define the operations that can be performed on the database. Here’s an example DAO interface for the Customer entity:

public interface CustomerDao  ListCustomer> getAll(); OptionalCustomer> getById(Long id); Customer save(Customer customer); void delete(Customer customer); > 

In this example, we’ve defined a CustomerDao interface that includes methods for getting all customers, getting a customer by ID, saving a customer, and deleting a customer.

Implementing DAO Interfaces

To implement a DAO interface, you’ll need to create a class that provides the actual implementation of the methods. Here’s an example implementation of the CustomerDao interface:

@Repository public class CustomerDaoImpl implements CustomerDao  @Autowired private EntityManager entityManager; @Override public ListCustomer> getAll()  return entityManager.createQuery("SELECT c FROM Customer c", Customer.class).getResultList(); > @Override public OptionalCustomer> getById(Long id)  return Optional.ofNullable(entityManager.find(Customer.class, id)); > @Override public Customer save(Customer customer)  return entityManager.merge(customer); > @Override public void delete(Customer customer)  entityManager.remove(customer); > > 

In this example, we’ve implemented the CustomerDao interface using the EntityManager provided by Spring Boot’s JPA implementation. We’ve used the @Repository annotation to indicate that this class should be treated as a repository component by Spring Boot. The getAll() method uses the createQuery() method of the EntityManager to retrieve all Customer entities from the database. The getById() method uses the find() method of the EntityManager to retrieve a Customer entity by ID. The save() method uses the merge() method of the EntityManager to save a new or updated Customer entity to the database. The delete() method uses the remove() method of the EntityManager to delete a Customer entity from the database.

Using DAO Interfaces

Now that we’ve defined and implemented our DAO interface, we can use it in our application to perform database operations. Here’s an example of how to use the CustomerDao interface in a controller class:

@RestController @RequestMapping("/customers") public class CustomerController  @Autowired private CustomerDao customerDao; @GetMapping public ListCustomer> getAllCustomers()  return customerDao.getAll(); > @GetMapping("/") public ResponseEntityCustomer> getCustomerById(@PathVariable Long id)  OptionalCustomer> customer = customerDao.getById(id); if (customer.isPresent())  return ResponseEntity.ok(customer.get()); > else  return ResponseEntity.notFound().build(); > > @PostMapping public ResponseEntityCustomer> createCustomer(@RequestBody Customer customer)  Customer savedCustomer = customerDao.save(customer); return ResponseEntity.created(URI.create("/customers/" + savedCustomer.getId())).body(savedCustomer); > @PutMapping("/") public ResponseEntityCustomer> updateCustomer(@PathVariable Long id, @RequestBody Customer customer)  OptionalCustomer> existingCustomer = customerDao.getById(id); if (existingCustomer.isPresent())  customer.setId(id); Customer savedCustomer = customerDao.save(customer); return ResponseEntity.ok(savedCustomer); > else  return ResponseEntity.notFound().build(); > > @DeleteMapping("/") public ResponseEntityVoid> deleteCustomer(@PathVariable Long id)  OptionalCustomer> customer = customerDao.getById(id); if (customer.isPresent())  customerDao.delete(customer.get()); return ResponseEntity.noContent().build(); > else  return ResponseEntity.notFound().build(); > > > 

In this example, we’ve created a CustomerController class that uses the CustomerDao interface to perform CRUD (create, read, update, delete) operations on the Customer ** entity. We’ve used the @Autowired annotation to inject an instance of the CustomerDao interface into the controller. The getAllCustomers() method returns a list of all customers. The getCustomerById() method retrieves a customer by ID. The createCustomer() method saves a new customer. The updateCustomer() method updates an existing customer. The deleteCustomer() method deletes a customer.

Conclusion

The DAO pattern is a powerful way to abstract away the details of database operations and improve the maintainability and testability of your code. I hope this has been helpful, and that you’re now able to use the DAO pattern in your own projects.

Источник

Data Access Object

Code that depends on specific features of data resources ties together business logic with data access logic. This makes it difficult to replace or modify an application’s data resources.

The Data Access Object (or DAO) pattern:

  • separates a data resource’s client interface from its data access mechanisms
  • adapts a specific data resource’s access API to a generic client interface

The DAO pattern allows data access mechanisms to change independently of the code that uses the data.

Detailed Description

See the Core J2EE TM Patterns

Detailed Example

The Java Pet Store sample application uses the DAO pattern both for database vendor-neutral data access, and to represent XML data sources as objects.

    Accessing a database with a DAO. A Data Access Object class can provide access to a particular data resource without coupling the resource’s API to the business logic. For example, sample application classes access catalog categories, products, and items using DAO interface CatalogDAO . Reimplementing CatalogDAO for a different data access mechanism (to use a Connector, for example), would have little or no impact on any classes that use CatalogDAO , because only the implementation would change. Each potential alternate implementation of CatalogDAO would access data for the items in the catalog in its own way, while presenting the same API to the class that uses it. The following code excerpts illustrate how the sample application uses the DAO pattern to separate business logic from data resource access mechanisms:

      Interface CatalogDAO defines the DAO API. Notice that the methods in the interface below make no reference to a specific data access mechanism. For example, none of the methods specify an SQL query, and they throw only exceptions of type CatalogDAOSysException . Avoiding mechanism-specific information in the DAO interface, including exceptions thrown, is essential for hiding implementation details.
     public interface CatalogDAO
     public class CloudscapeCatalogDAO implements CatalogDAO < . public static String GET_CATEGORY_STATEMENT = "select name, descn " + " from (category a join category_details b on a.catid=b.catid) " + " where locale = ? and a.catid = ?"; . public Category getCategory(String categoryID, Locale l) throws CatalogDAOSysException < Connection c = null; PreparedStatement ps = null; ResultSet rs = null; Category ret = null; try < c = getDataSource().getConnection(); ps = c.prepareStatement(GET_CATEGORY_STATEMENT,ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY); ps.setString(1, l.toString()); ps.setString(2, categoryID); rs = ps.executeQuery(); if (rs.first()) < ret = new Category(categoryID, rs.getString(1), rs.getString(2)); >rs.close(); ps.close(); c.close(); return ret; > catch (SQLException se) < throw new CatalogDAOSysException("SQLException: " + se.getMessage()); >> . > 
         select name, descn from (category a join category_details b on a.catid=b.catid) where locale = ? and a.catid = ?  .   select name, descn from category a, category_details b where a.catid = b.catid and locale = ? and a.catid = ?  .  

    Method GenericCatalogDAO.getCategory chooses the SQL corresponding to the configured database type, and uses it to fetch a category from the database via JDBC. The following code excerpt shows shows the implementation of the method.

     public Category getCategory(String categoryID, Locale locale) throws CatalogDAOSysException < Connection connection = null; ResultSet resultSet = null; PreparedStatement statement = null; try < connection = getDataSource().getConnection(); String[] parameterValues = new String[] < locale.toString(), categoryID >; statement = buildSQLStatement(connection, sqlStatements, XML_GET_CATEGORY, parameterValues); resultSet = statement.executeQuery(); if (resultSet.first()) < return new Category(categoryID, resultSet.getString(1), resultSet.getString(2)); >return null; > catch (SQLException exception) < throw new CatalogDAOSysException("SQLException: " + exception.getMessage()); >finally < closeAll(connection, statement, resultSet); >> 
     public static Screens loadScreenDefinitions(URL location) < Element root = loadDocument(location); if (root != null) return getScreens(root); else return null; >. public static Screens getScreens(Element root) < // get the template String defaultTemplate = getTagValue(root, DEFAULT_TEMPLATE); if (defaultTemplate == null) < System.err.println("*** ScreenDefinitionDAO error: " + " Default Template not Defined."); return null; >Screens screens = new Screens(defaultTemplate); getTemplates(root, screens); // get screens NodeList list = root.getElementsByTagName(SCREEN); for (int loop = 0; loop < list.getLength(); loop++) < Node node = list.item(loop); if ((node != null) && node instanceof Element) < String templateName = ((Element)node).getAttribute(TEMPLATE); String screenName = ((Element)node).getAttribute(NAME); HashMap parameters = getParameters(node); Screen screen = new Screen(screenName, templateName, parameters); if (!screens.containsScreen(screenName)) < screens.addScreen(screenName, screen); >else < System.err.println("*** Non Fatal errror: Screen " + screenName + " defined more than once in screen definitions file"); >> > return screens; > . 

    Источник

    Data Access Object (DAO). Уровень класса

    При проектировании информационной системы выявляются некоторые слои, которые отвечают за взаимодействие различных модулей системы. Соединение с базой данных является одной из важнейшей составляющей приложения. Всегда выделяется часть кода, модуль, отвечающающий за передачу запросов в БД и обработку полученных от неё ответов. В общем случае, определение Data Access Object описывает его как прослойку между БД и системой. DAO абстрагирует сущности системы и делает их отображение на БД, определяет общие методы использования соединения, его получение, закрытие и (или) возвращение в Connection Pool.

    Вершиной иерархии DAO является абстрактный класс или интерфейс с описанием общих методов, которые будут использоваться при взаимодействии с базой данных. Как правило, это методы поиска, удаление по ключу, обновление и т.д.

    public abstract class AbstractController  < public abstract ListgetAll(); public abstract E getEntityById(K id); public abstract E update(E entity); public abstract boolean delete(K id); public abstract boolean create(E entity); > 

    Набор методов не является завершённым, он зависит от конкретной системы. Фиктивный тип K является ключом сущности, редкая таблица, описывающая сущность, не имеет первичного ключа. Так же, в данном классе будет логичным разместить метод закрытие экземпляра PrepareStatement.

    public void closePrepareStatement(PreparedStatement ps) < if (ps != null) < try < ps.close(); >catch (SQLException e) < e.printStackTrace(); >> > 
    Уровень класса


    Реализация DAO на уровне класса подразумевает использование одного единственного коннекта для вызова более чем одного метода унаследованного DAO класса. В этом случае, в вершине иерархии DAO AbstractController, в качестве поля объявляется connection. Абстрактный класс будет выглядеть следующим образом.

    public abstract class AbstractController  < private Connection connection; private ConnectionPool connectionPool; public AbstractController() < connectionPool = ConnectionPool.getConnectionPool(); connection = connectionPool.getConnection(); >public abstract List getAll(); public abstract E update(E entity); public abstract E getEntityById(K id); public abstract boolean delete(K id); public abstract boolean create(E entity); // Возвращения экземпляра Connection в пул соединений public void returnConnectionInPool() < connectionPool.returnConnection(connection); >// Получение экземпляра PrepareStatement public PreparedStatement getPrepareStatement(String sql) < PreparedStatement ps = null; try < ps = connection.prepareStatement(sql); >catch (SQLException e) < e.printStackTrace(); >return ps; > // Закрытие PrepareStatement public void closePrepareStatement(PreparedStatement ps) < if (ps != null) < try < ps.close(); >catch (SQLException e) < e.printStackTrace(); >> > > 

    Стоит отметить, что в данном примере мы получаем экземпляр Connection из пула соединений, что соответственно стоит реализовать или воспользоваться уже готовыми решениями. Создаём методы по получению getPrepareStatement(String sql) и его закрытию closePrepareStatement(PreparedStatement ps) . Реализация конкретного DAO класса, при такой логике, никогда не должна закрывать в своих методах соединение с базой данных. Соединение закрывается в той части бизнес-логики, от куда был вызван метод. Пример конкретного DAO класса будет выглядеть следующим образом.

    public class UserController extends AbstractController  < public static final String SELECT_ALL_USERS = "SELECT * FROM SHEMA.USER"; @Override public ListgetAll() < Listlst = new LinkedList<>(); PreparedStatement ps = getPrepareStatement(SELECT_ALL_PLANET); try < ResultSet rs = ps.executeQuery(); while (rs.next()) < User user = new User(); planet.setId(rs.getInt(1)); planet.setName(rs.getString(2)); lst.add(user); >> catch (SQLException e) < e.printStackTrace(); >finally < closePrepareStatement(ps); >return lst; > @Override public Planet getEntityById(Integer id) < return null; >@Override public boolean delete(Integer id) < return false; >@Override public boolean create(Planet entity) < return false; >> 
    public class User implements Serializable < private int id; private String name; public int getId() < return id; >public void setId(int id) < this.id = id; >public String getName() < return name; >public void setName(String name) < this.name = name; >@Override public String toString() < return "User'; > > 

    Экземпляр Connection доступен методу getPrepareStatement(String sql), который в свою очередь доступен любому методу конкретного DAO класса. Стоит помнить, что следует закрывать экземпляр PrepareStatement сразу после его отработки в блоках finally, а возвращать соединение в пул returnConnectionInPool() в части логики системы, где был вызван метод.

    Источник

    Читайте также:  Python zipfile utf 8
Оцените статью