【问题标题】:Data access object (DAO) in JavaJava 中的数据访问对象 (DAO)
【发布时间】:2013-10-09 20:33:58
【问题描述】:

我在浏览一个文档时遇到了一个名为DAO 的术语。我发现它是一个数据访问对象。有人可以解释一下这实际上是什么吗?

我知道它是一种用于访问来自不同类型源的数据的接口,在我的这个小研究中,我碰到了一个叫做数据源或数据源对象的概念,事情变得一团糟我脑海。

我真的很想知道DAO 的使用位置以编程方式是什么。它是如何使用的?任何从非常基本的东西解释这个概念的页面的链接也很感激。

【问题讨论】:

    标签: java dao


    【解决方案1】:

    数据访问对象基本上是提供对底层数据库或任何其他持久性存储的访问的对象或接口。

    该定义来自: http://en.wikipedia.org/wiki/Data_access_object

    还要检查这里的序列图: http://www.oracle.com/technetwork/java/dataaccessobject-138824.html

    也许一个简单的例子可以帮助你理解这个概念:

    假设我们有一个代表员工的实体:

    public class Employee {
    
        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;
        }
    
    }
    

    员工实体将被持久化到数据库中相应的 Employee 表中。 处理操作员工实体所需的数据库操作的简单 DAO 接口如下:

    interface EmployeeDAO {
    
        List<Employee> findAll();
        List<Employee> findById();
        List<Employee> findByName();
        boolean insertEmployee(Employee employee);
        boolean updateEmployee(Employee employee);
        boolean deleteEmployee(Employee employee);
    
    }
    

    接下来我们必须为该接口提供一个具体的实现来处理 SQL 服务器,另一个来处理平面文件等。

    【讨论】:

    • 嗨,拉米,我真的很高兴你尝试用一个非常简单的例子来解释我,这正是我所需要的。你能解释一下你所说的“具体实现”是什么意思吗?你的意思是我们接下来必须通过实现类的接口来编写方法的定义.. ??
    • 是的,没错。就像一个名为 EmployeeSQLServerDAO 的类,它通过以与 SQL Server 相关的方式为其方法提供完整实现来实现 EmployeeDAO 接口
    • 这就是DAO的全部内容??它只是我们为访问数据库而编写的一个类。每当我们需要来自数据库的服务时,我们都会创建一个 DAO 的对象,将其用于数据库操作,然后一旦我们从数据库中获得所需的内容,就摆脱 DAO。我对吗??我可以知道这个 DAO 概念 rami 的范围吗??
    • 是的,顾名思义,DAO 用于访问/更新有关某个实体/类的底层存储。因此,在上面的示例中,我们有一个员工类/实体,我们使用 SQL 服务器数据库表来持久化。 Employee DAO 将包含插入/删除/更新/选择员工的方法
    • @PhilipRego 我们当然可以有多个实现,例如一个 MSSQL 服务器实现,另一个使用 CSV 文件用于单元测试。
    【解决方案2】:

    什么是数据访问对象 (DAO) -

    它是一个对象/接口,用于访问数据存储数据库中的数据

    我们为什么使用 DAO:

    从数据库等数据资源中抽象出数据检索。
    其概念是“将数据资源的客户端接口与其数据访问机制分开。”

    直接访问数据的问题是数据的来源可以改变。例如,假设您的应用程序部署在访问 Oracle 数据库的环境中。随后将其部署到使用 Microsoft SQL Server 的环境中。如果您的应用程序使用存储过程和特定于数据库的代码(例如生成数字序列),您如何在应用程序中处理这些?你有两个选择:

    • 重写您的应用程序以使用 SQL Server 而不是 Oracle(或添加条件代码来处理差异),或者
    • 在应用程序逻辑层和数据访问层之间创建一个层

    DAO 模式包含以下内容:

    • 数据访问对象接口 - 该接口定义了标准操作要在模型对象上执行。
    • 数据访问对象具体类 - 该类实现上述接口。此类负责从数据源获取数据 可以是数据库/xml 或任何其他存储机制。
    • 模型对象或值对象 - 此对象是包含 get/set 方法的简单 POJO,用于存储使用 DAO 类检索到的数据。

    See examples

    我希望这能澄清你对 DAO 的理解!

    【讨论】:

      【解决方案3】:

      DAO(数据访问对象)是企业应用程序中非常常用的设计模式。它基本上是用于访问来自每个源(DBMS、XML 等)的数据的模块。我建议你阅读一些例子,比如这个:

      DAO Example

      请注意,实现原始DAO Pattern 有不同的方法,并且有许多框架可以简化您的工作。例如,iBatis 或 Hibernate 等 ORM(对象关系映射)框架用于将 SQL 查询的结果映射到 java 对象。

      希望对你有帮助, 再见!

      【讨论】:

        【解决方案4】:

        数据访问对象模式或 DAO 模式用于将低级数据访问 API 或操作与高级业务服务分开。以下是数据访问对象模式的参与者。

        数据访问对象接口 - 此接口定义要在模型对象上执行的标准操作。

        数据访问对象具体类-该类实现上述接口。该类负责从数据源获取数据,数据源可以是数据库/xml或任何其他存储机制。

        模型对象或值对象 - 此对象是简单的 POJO,包含 get/set 方法来存储使用 DAO 类检索到的数据。

        示例代码here..

        【讨论】:

          【解决方案5】:

          我将笼统地说,而不是专门针对 Java,因为 DAO 和 ORM 用于所有语言。

          要了解 DAO,您首先需要了解 ORM(对象关系映射)。这意味着如果您有一个名为“person”的表,其中包含“name”和“age”列,那么您将为该表创建对象模板:

          type Person {
          name
          age
          }
          

          现在在 DAO 的帮助下,而不是编写一些特定的查询来获取所有人,对于您使用的任何类型的数据库(可能容易出错),您可以这样做:

          list persons = DAO.getPersons();
          ...
          person = DAO.getPersonWithName("John");
          age = person.age;
          

          您不必自己编写 DAO 抽象,而是它通常是某个开源项目的一部分,具体取决于您使用的语言和框架。

          现在到这里的主要问题。 “..在哪里使用..”。通常,如果您正在编写复杂的业务和特定领域的代码,那么如果没有 DAO,您的生活将非常困难。当然你不需要使用提供的 ORM 和 DAO,而是你可以编写自己的抽象和原生查询。我过去曾这样做过,但后来几乎总是后悔。

          【讨论】:

            【解决方案6】:

            我认为您可以在 oracle 网站上找到最好的示例(以及解释):here。另一个很好的教程可以找到here

            【讨论】:

            • 只有我一个人还是大多数 Java 教程和信息网站都太老了?那个教程是2008年的!许多关于各种 Java 主题的热门搜索结果甚至更早。
            • @bergie3000:这种模式并不新鲜。
            【解决方案7】:

            不要被太多的解释弄糊涂了。 DAO:从名字本身来看,它的意思是使用对象访问数据。 DAO 与其他业务逻辑分离。

            【讨论】:

            • 一旦你将它解构为它的基本含义,它会变得多么有形,这令人难以置信。 “数据访问对象”对我来说听起来如此“陌生”和抽象,但您的简单解释使它变得如此明智和容易理解——即使最初的名称从一开始就应该是显而易见的。
            【解决方案8】:

            Spring JPA DAO

            例如我们有一些实体组。

            对于这个实体,我们创建存储库 GroupRepository。

            public interface GroupRepository extends JpaRepository<Group, Long> {   
            }
            

            然后我们需要创建一个服务层,我们将使用这个存储库。

            public interface Service<T, ID> {
            
                T save(T entity);
            
                void deleteById(ID id);
            
                List<T> findAll();
            
                T getOne(ID id);
            
                T editEntity(T entity);
            
                Optional<T> findById(ID id);
            }
            
            public abstract class AbstractService<T, ID, R extends JpaRepository<T, ID>> implements Service<T, ID> {
            
                private final R repository;
            
                protected AbstractService(R repository) {
                    this.repository = repository;
                }
            
                @Override
                public T save(T entity) {
                    return repository.save(entity);
                }
            
                @Override
                public void deleteById(ID id) {
                    repository.deleteById(id);
                }
            
                @Override
                public List<T> findAll() {
                    return repository.findAll();
                }
            
                @Override
                public T getOne(ID id) {
                    return repository.getOne(id);
                }
            
                @Override
                public Optional<T> findById(ID id) {
                    return repository.findById(id);
                }
            
                @Override
                public T editEntity(T entity) {
                    return repository.saveAndFlush(entity);
                }
            }
            
            @org.springframework.stereotype.Service
            public class GroupServiceImpl extends AbstractService<Group, Long, GroupRepository> {
            
                private final GroupRepository groupRepository;
            
                @Autowired
                protected GroupServiceImpl(GroupRepository repository) {
                    super(repository);
                    this.groupRepository = repository;
                }
            }
            

            在控制器中我们使用这个服务。

            @RestController
            @RequestMapping("/api")
            class GroupController {
            
                private final Logger log = LoggerFactory.getLogger(GroupController.class);
            
                private final GroupServiceImpl groupService;
            
                @Autowired
                public GroupController(GroupServiceImpl groupService) {
                    this.groupService = groupService;
                }
            
                @GetMapping("/groups")
                Collection<Group> groups() {
                    return groupService.findAll();
                }
            
                @GetMapping("/group/{id}")
                ResponseEntity<?> getGroup(@PathVariable Long id) {
                    Optional<Group> group = groupService.findById(id);
                    return group.map(response -> ResponseEntity.ok().body(response))
                            .orElse(new ResponseEntity<>(HttpStatus.NOT_FOUND));
                }
            
                @PostMapping("/group")
                ResponseEntity<Group> createGroup(@Valid @RequestBody Group group) throws URISyntaxException {
                    log.info("Request to create group: {}", group);
                    Group result = groupService.save(group);
                    return ResponseEntity.created(new URI("/api/group/" + result.getId()))
                            .body(result);
                }
            
                @PutMapping("/group")
                ResponseEntity<Group> updateGroup(@Valid @RequestBody Group group) {
                    log.info("Request to update group: {}", group);
                    Group result = groupService.save(group);
                    return ResponseEntity.ok().body(result);
                }
            
                @DeleteMapping("/group/{id}")
                public ResponseEntity<?> deleteGroup(@PathVariable Long id) {
                    log.info("Request to delete group: {}", id);
                    groupService.deleteById(id);
                    return ResponseEntity.ok().build();
                }    
            }
            

            【讨论】:

            • 这似乎解释了存储库模式,而不是原始作者要求的 DAO 模式。此外,我认为您的示例可能会产生误导,因为您的界面应遵循类似 Collection 的方法,因此您的某些操作不适合。
            【解决方案9】:

            数据访问对象管理与数据源的连接以获取和存储数据。它为业务对象抽象了底层数据访问实现,以实现对数据源的透明访问。 数据源可以是任何数据库,例如 RDBMS、XML 存储库或平面文件系统等。

            【讨论】:

              【解决方案10】:

              DAO 是一种类似于 3 层架构中的“持久性管理器”的行为,也是 DAO 的设计模式,您可以参考“Gang of Four”一书。 您的应用服务层只需要调用 DAO 类的方法,而无需了解 DAO 方法的隐藏和内部细节。

              【讨论】:

                【解决方案11】:

                Dao 类用于重用 jdbc 逻辑 & Dao(Data Access Object) 是一种设计模式。 dao 是一个包含 JDBC 逻辑的简单 java 类。

                数据访问层在单独的业务逻辑层和持久层中被证明是好的。 DAO 设计模式对其客户端完全隐藏了数据访问实现

                Java 数据访问对象 (Java DAO) 是业务应用程序中的重要组件。业务应用程序几乎总是需要访问关系数据库或对象数据库中的数据,而 Java 平台提供了许多访问这些数据的技术。最古老和最成熟的技术是使用 Java 数据库连接 (JDBC) API,它提供了对数据库执行 SQL 查询然后一次获取一列结果的能力。

                【讨论】:

                  【解决方案12】:

                  Pojo 也被视为 Java 中的 Model 类,我们可以在其中为 private 中定义的特定变量创建 getter 和 setter。 记住这里所有的变量都是用 private 修饰符声明的

                  【讨论】:

                    【解决方案13】:

                    我只是想用我在一个项目中经历的一个小故事以我自己的方式来解释它。首先我想解释一下为什么DAO很重要?而不是去什么是DAO?以便更好地理解。

                    为什么 DAO 很重要?
                    在我的一个项目中,我使用了Client.class,其中包含了我们系统用户的所有基本信息。在我需要客户端的地方,然后每次我需要在需要的地方进行丑陋的查询。然后觉得降低了可读性,做了很多多余的样板代码

                    然后我的一位高级开发人员介绍了QueryUtils.class,其中所有查询都使用public static 访问修饰符添加,然后我不需要到处进行查询。假设当我需要激活的客户端时,我只需调用 -

                    QueryUtils.findAllActivatedClients();
                    

                    这样,我对我的代码做了一些优化。

                    但是还有一个问题!!!

                    我觉得 QueryUtils.class 增长非常快。该类中包含 100 多个方法,阅读和使用也非常麻烦。因为这个类包含另一个域模型的其他查询(例如 - 产品、类别位置等)

                    然后是超级英雄先生。 CTO引入了一个名为DAO的新解决方案,最终解决了这个问题。我觉得 DAO 是非常特定于领域的。例如,他创建了一个名为 ClientDAO.class 的 DAO,其中可以找到所有与 Client.class 相关的查询,这对我来说似乎很容易使用和维护。巨大的 QueryUtils.class 被分解为许多其他特定于域的 DAO,例如 - ProductsDAO.classCategoriesDAO.class 等,这使得代码更可读,更可维护 , 更多解耦

                    什么是 DAO?

                    它是一个对象或接口,可以轻松地从数据库中访问数据,而无需每次都以可重用的方式编写复杂ugly查询。

                    【讨论】:

                      猜你喜欢
                      • 2021-12-09
                      • 1970-01-01
                      • 2016-10-07
                      • 2014-08-06
                      • 2011-11-22
                      • 2021-08-27
                      • 1970-01-01
                      • 1970-01-01
                      相关资源
                      最近更新 更多