DAO层应该实现哪些方法?

What methods the DAO layer should implement?

我现在正在写web应用,卡在了DAO层的设计阶段。已经浏览了有关该主题的各种文章,但仍未达到清晰度。 我的问题是: 允许在 DAO classes 中声明和实现什么样的方法? 它们只是一组有限的 CRUD 操作(创建、读取、更新、删除)吗?使用一些适合您开发业务逻辑层的具体需求的自定义方法来扩展此集合是否被认为是一种好的做法? 例如: 我有一个名为 User 的实体 class,其字段完全反映了相应的数据库 table。假设我要在授权时验证用户的登录名和密码。在这种情况下哪种方法更合适?我是否应该调用通用 CRUD 方法 List<User> findAll() 来检索所有用户并在业务逻辑方法中验证这些具体的登录名和密码(类似于 boolean validateUser(String login, String password, List<User> users))。或者我应该直接在 DAO class?

中添加一些非 CRUD 方法,例如 boolean checkUser(String login, String password)

简短的回答是否定的:不要在 dao 层中添加任何业务逻辑。让每一层都有自己的责任,这样当其他人(甚至你)需要改变时,他们就会知道去哪里找。

编辑: 其他答案:

Q:在DAO中允许声明和实现什么样的方法类?

A:允许您访问数据库对象或其属性的方法。即 public User getOldUsers(), public boolean isUserExist(Long userId)etc...

问:它们只是一组有限的 CRUD 操作(创建、读取、更新、删除)吗?

答:是的,您还可以控制持久性或事务属性

问:通用 CRUDS?

答:我从事的几乎所有项目都使用通用 CRUDS (AbstractDao 类) 并添加其他方法

I'm being writing web application right now and got stuck at the stage of designing the DAO layer.

您是使用普通的旧 servlet 还是使用网络框架(例如 Spring MVC)手动编写它来减轻您的痛苦?

  1. And my question is: What kind of methods are allowed to be declared and implemented in DAO classes? Are they just limited set of CRUD operations (create, read, update, delete)?**

一般来说,是的——这些方法应该仅限于 CRUD 操作。

  1. Is it considered a good practice to extend this set with some custom methods fitting in your concrete needs in developing a business logic layer?**

在合理范围内,是的。

For example: I have an entity class named User which fields are fully reflect a corresponding database table. Let's suppose I'm about to validate user's login and password while authorization. What approach would be more appropriate in that situation? Should I call generic CRUD method List findAll() to retrieve all users and validate these concrete login and password in method of business logic (something like boolean validateUser(String login, String password, List users)). Or should I add some not CRUD method like boolean checkUser(String login, String password) directly in DAO class?

除了您的 DAO classes 应该具有的标准 CRUD 方法之外,您还可以添加一个辅助方法,例如: User findUser(String login) 其工作是 return 指定 login 参数的填充 User 对象,如果登录名不存在则为 null。

User findUser(String login) 应该利用 List<User> findAll(),它应该已经存在于 DAO class 中的其余 CRUD 方法中。可以这样实现:

public User findUser(String login) {
    User user = null;
    final SearchCriteria criteria = buildSearchCriteria(login); // construct a search criteria from the login parameter
    List<User> users = findAll(criteria);  
    if (null != users) {
       assert (users.size() == 1) : "More than one user was matched - login must be unique.";
       user = users.get(0);
    }
    return user;
}

总而言之,你只需要2个方法来实现授权逻辑:

  1. User findUser(String login) 在你的 DAO 层和;

  2. boolean checkUser(String login, String password) 将在您的前端层中。如果您没有使用任何 Web 框架,此方法将在您的 servlet 中实现,否则此方法将进入您的控制器 class(如果您使用的是 MVC 框架)。