【发布时间】:2013-10-09 20:33:58
【问题描述】:
我在浏览一个文档时遇到了一个名为DAO 的术语。我发现它是一个数据访问对象。有人可以解释一下这实际上是什么吗?
我知道它是一种用于访问来自不同类型源的数据的接口,在我的这个小研究中,我碰到了一个叫做数据源或数据源对象的概念,事情变得一团糟我脑海。
我真的很想知道DAO 的使用位置以编程方式是什么。它是如何使用的?任何从非常基本的东西解释这个概念的页面的链接也很感激。
【问题讨论】:
我在浏览一个文档时遇到了一个名为DAO 的术语。我发现它是一个数据访问对象。有人可以解释一下这实际上是什么吗?
我知道它是一种用于访问来自不同类型源的数据的接口,在我的这个小研究中,我碰到了一个叫做数据源或数据源对象的概念,事情变得一团糟我脑海。
我真的很想知道DAO 的使用位置以编程方式是什么。它是如何使用的?任何从非常基本的东西解释这个概念的页面的链接也很感激。
【问题讨论】:
数据访问对象基本上是提供对底层数据库或任何其他持久性存储的访问的对象或接口。
该定义来自: 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 服务器,另一个来处理平面文件等。
【讨论】:
什么是数据访问对象 (DAO) -
它是一个对象/接口,用于访问数据存储数据库中的数据。
我们为什么使用 DAO:
从数据库等数据资源中抽象出数据检索。
其概念是“将数据资源的客户端接口与其数据访问机制分开。”
直接访问数据的问题是数据的来源可以改变。例如,假设您的应用程序部署在访问 Oracle 数据库的环境中。随后将其部署到使用 Microsoft SQL Server 的环境中。如果您的应用程序使用存储过程和特定于数据库的代码(例如生成数字序列),您如何在应用程序中处理这些?你有两个选择:
DAO 模式包含以下内容:
- 数据访问对象接口 - 该接口定义了标准操作要在模型对象上执行。
- 数据访问对象具体类 - 该类实现上述接口。此类负责从数据源获取数据 可以是数据库/xml 或任何其他存储机制。
- 模型对象或值对象 - 此对象是包含 get/set 方法的简单 POJO,用于存储使用 DAO 类检索到的数据。
我希望这能澄清你对 DAO 的理解!
【讨论】:
DAO(数据访问对象)是企业应用程序中非常常用的设计模式。它基本上是用于访问来自每个源(DBMS、XML 等)的数据的模块。我建议你阅读一些例子,比如这个:
请注意,实现原始DAO Pattern 有不同的方法,并且有许多框架可以简化您的工作。例如,iBatis 或 Hibernate 等 ORM(对象关系映射)框架用于将 SQL 查询的结果映射到 java 对象。
希望对你有帮助, 再见!
【讨论】:
数据访问对象模式或 DAO 模式用于将低级数据访问 API 或操作与高级业务服务分开。以下是数据访问对象模式的参与者。
数据访问对象接口 - 此接口定义要在模型对象上执行的标准操作。
数据访问对象具体类-该类实现上述接口。该类负责从数据源获取数据,数据源可以是数据库/xml或任何其他存储机制。
模型对象或值对象 - 此对象是简单的 POJO,包含 get/set 方法来存储使用 DAO 类检索到的数据。
示例代码here..
【讨论】:
我将笼统地说,而不是专门针对 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,而是你可以编写自己的抽象和原生查询。我过去曾这样做过,但后来几乎总是后悔。
【讨论】:
不要被太多的解释弄糊涂了。 DAO:从名字本身来看,它的意思是使用对象访问数据。 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();
}
}
【讨论】:
数据访问对象管理与数据源的连接以获取和存储数据。它为业务对象抽象了底层数据访问实现,以实现对数据源的透明访问。 数据源可以是任何数据库,例如 RDBMS、XML 存储库或平面文件系统等。
【讨论】:
DAO 是一种类似于 3 层架构中的“持久性管理器”的行为,也是 DAO 的设计模式,您可以参考“Gang of Four”一书。 您的应用服务层只需要调用 DAO 类的方法,而无需了解 DAO 方法的隐藏和内部细节。
【讨论】:
Dao 类用于重用 jdbc 逻辑 & Dao(Data Access Object) 是一种设计模式。 dao 是一个包含 JDBC 逻辑的简单 java 类。
数据访问层在单独的业务逻辑层和持久层中被证明是好的。 DAO 设计模式对其客户端完全隐藏了数据访问实现
Java 数据访问对象 (Java DAO) 是业务应用程序中的重要组件。业务应用程序几乎总是需要访问关系数据库或对象数据库中的数据,而 Java 平台提供了许多访问这些数据的技术。最古老和最成熟的技术是使用 Java 数据库连接 (JDBC) API,它提供了对数据库执行 SQL 查询然后一次获取一列结果的能力。
【讨论】:
Pojo 也被视为 Java 中的 Model 类,我们可以在其中为 private 中定义的特定变量创建 getter 和 setter。 记住这里所有的变量都是用 private 修饰符声明的
【讨论】:
我只是想用我在一个项目中经历的一个小故事以我自己的方式来解释它。首先我想解释一下为什么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.class、CategoriesDAO.class 等,这使得代码更可读,更可维护 , 更多解耦。
什么是 DAO?
它是一个对象或接口,可以轻松地从数据库中访问数据,而无需每次都以可重用的方式编写复杂和ugly查询。
【讨论】: