DAO 类 和 Service 类 的用途
For what to use DAO classes and Service classes
我读过有关 DAO classes 和 Service classes 的内容,但我不明白它们的用途。
我已经在 Maven 中使用 spring 和休眠启动了一个项目,直到现在我已经在 servlet.xml 中添加了休眠的配置:
<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
<property name="annotatedClasses">
<list>
<value>com.fabbydesign.model.Useradmin</value>
</list>
</property>
</bean>
controller的登录方法是这样的:
@RequestMapping(value = "/do.html", method = RequestMethod.POST)
public String doLogin(@Valid @ModelAttribute("userLogin") LoginForm lf, BindingResult bindingResult, Map<String, Object> model, HttpServletRequest request){
//bindingResult.rejectValue("username", "label.title"); - to add new message error
logger.trace("showLogin - post");
//check fields if the filds are filled and respects the size from beans
if(bindingResult.hasErrors())
return "login";
boolean userExists = loginService.checkLogin(lf.getUsername(), lf.getPassword());
if(!userExists){
bindingResult.rejectValue("username", "login.username.wrongUserOrPassword");
return "login";
}
else{//set session
request.getSession().setAttribute(adminSesName, true);
}
return "redirect:/admin/dashboard.html";
}
loginServiceImpl:
@Service("loginService")
public class LoginServiceImpl 实现 LoginService {
@Autowired
private LoginDAO loginDAO;
public void setLoginDAO(LoginDAO loginDAO) {
this.loginDAO = loginDAO;
}
public Boolean checkLogin(String userName, String userPassword) {
return loginDAO.checkLogin(userName, userPassword);
}
和 loginDAOimpl:
@Repository("loginDAO")
public class LoginDAOImpl 实现 LoginDAO {
@Resource(name = "sessionFactory")
protected SessionFactory sessionFactory;
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
protected Session getSession() {
return sessionFactory.openSession();
}
final static Logger logger = Logger.getLogger(LoginDAOImpl.class);
public boolean checkLogin(String username, String password) {
Boolean userFound = false;
Session session = sessionFactory.openSession();
String sql = "from Useradmin where username = ?";
Query<?> query = session.createQuery(sql);
query.setParameter(0, username);
List<?> list = query.list();
if ((list != null) && (list.size() == 1)) {
Useradmin ua = (Useradmin) list.get(0);
if (BCrypt.checkpw(password, ua.getPassword())) {
userFound = true;
}
}
return userFound;
}
那么,我应该在服务 classes 和 DAO classes 中写什么?
我的理解是,从数据库中操作数据的代码需要保留在 DAO classes 中,但是服务 classes 是做什么用的?
谢谢!
DAO 提供到数据库和操作的连接。
服务层提供对发送到 DAO 和从 DAO 发送的数据进行操作的逻辑。
还有安全性 - 如果您有与数据库无关的服务层,则除了通过服务之外,从客户端访问数据库会更加困难。
Service层提供业务操作和调用DAO层。
DAO层是针对数据库层的。这意味着它执行数据操作。这是您放置数据检索、数据保存和其他数据库操作的地方。
这个问题的答案可能非常详尽,所以我会尽量在此处坚持一些细节,并在必要时 post 链接。
一些基础工作,
分层和分层架构:您必须了解应用程序的层和层之间的区别。
参考资料:-
What is the difference between tier vs layer application?
N-Tiered vs N-Layered architecture/design
因此,如果您的应用程序具有三个主要层:表示层、服务层和数据库层,服务层就是保留服务 类 的层。这是将核心业务逻辑添加到您的应用程序的地方。例如。如果您正在开发一个使用三层的票务应用程序,并且您已经添加了全面的身份验证功能。
- 网页将成为表示层的一部分。
- 用户身份验证、加密检查等功能,
超时检查等将成为您服务层的一部分(服务
类)
- 与数据库的连接和各自的交互将在数据库层 (Hibernate) 处理
另外:
如今,应用程序架构不仅仅局限于三层系统。越来越多地采用分布式应用程序架构,其中上面第 2 点提到的服务层被分解为多个小服务,每个服务都有自己的数据库。 (关键字检查:Microservices)。此外,他们使用消息队列进行交互,但谈论所有这些事情与这个问题无关。
推荐:
1. 您浏览了有关服务层设计的文章,以及不同的需求如何导致服务的不同设计 类。
2. 您阅读了服务设计中常用的设计模式,例如提供者、工厂、单例等。
希望我已经回答了你的问题。
N.B:您需要用 'architecture' 标记您的问题,因为它更像是架构问题而不是 Java 编程。
你可以参考这个简单的例子:
1.PersonDao
只关心数据库操作
package com.pechen.dao;
import java.util.List;
import com.pechen.entity.Person;
public interface PersonDao {
public void save(Person p);
public List<Person> list();
}
2.PersonDaoImpl
是实现。
package com.pechen.dao;
import java.util.List;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.springframework.beans.factory.annotation.Autowired;
import com.pechen.entity.Person;
public class PersonDaoImpl implements PersonDao {
@Autowired
private SessionFactory sessionFactory;
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
public void save(Person p) {
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
session.save(p);
tx.commit();
session.close();
}
@SuppressWarnings("unchecked")
public List<Person> list() {
Session session = sessionFactory.openSession();
List<Person> rst = session.createQuery("from person").getResultList();
session.close();
return rst;
}
}
3。 PersonService
关心业务逻辑,在数据库操作之前可以做任何想做的事
package com.pechen.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import com.pechen.dao.PersonDao;
import com.pechen.dao.PersonDaoImpl;
import com.pechen.entity.Person;
public class PersonService {
@Autowired
private PersonDao personDao;
public void setPersonDao(PersonDaoImpl personImpl) {
this.personDao = personImpl;
}
public void savePerson(Person person) {
// other business logic
this.personDao.save(person);
System.out.println("Save person successfully: " + person);
}
public List<Person> getPersons() {
// other business logic
return this.personDao.list();
}
}
我读过有关 DAO classes 和 Service classes 的内容,但我不明白它们的用途。 我已经在 Maven 中使用 spring 和休眠启动了一个项目,直到现在我已经在 servlet.xml 中添加了休眠的配置:
<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
<property name="annotatedClasses">
<list>
<value>com.fabbydesign.model.Useradmin</value>
</list>
</property>
</bean>
controller的登录方法是这样的:
@RequestMapping(value = "/do.html", method = RequestMethod.POST)
public String doLogin(@Valid @ModelAttribute("userLogin") LoginForm lf, BindingResult bindingResult, Map<String, Object> model, HttpServletRequest request){
//bindingResult.rejectValue("username", "label.title"); - to add new message error
logger.trace("showLogin - post");
//check fields if the filds are filled and respects the size from beans
if(bindingResult.hasErrors())
return "login";
boolean userExists = loginService.checkLogin(lf.getUsername(), lf.getPassword());
if(!userExists){
bindingResult.rejectValue("username", "login.username.wrongUserOrPassword");
return "login";
}
else{//set session
request.getSession().setAttribute(adminSesName, true);
}
return "redirect:/admin/dashboard.html";
}
loginServiceImpl:
@Service("loginService")
public class LoginServiceImpl 实现 LoginService {
@Autowired
private LoginDAO loginDAO;
public void setLoginDAO(LoginDAO loginDAO) {
this.loginDAO = loginDAO;
}
public Boolean checkLogin(String userName, String userPassword) {
return loginDAO.checkLogin(userName, userPassword);
}
和 loginDAOimpl:
@Repository("loginDAO")
public class LoginDAOImpl 实现 LoginDAO {
@Resource(name = "sessionFactory")
protected SessionFactory sessionFactory;
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
protected Session getSession() {
return sessionFactory.openSession();
}
final static Logger logger = Logger.getLogger(LoginDAOImpl.class);
public boolean checkLogin(String username, String password) {
Boolean userFound = false;
Session session = sessionFactory.openSession();
String sql = "from Useradmin where username = ?";
Query<?> query = session.createQuery(sql);
query.setParameter(0, username);
List<?> list = query.list();
if ((list != null) && (list.size() == 1)) {
Useradmin ua = (Useradmin) list.get(0);
if (BCrypt.checkpw(password, ua.getPassword())) {
userFound = true;
}
}
return userFound;
}
那么,我应该在服务 classes 和 DAO classes 中写什么? 我的理解是,从数据库中操作数据的代码需要保留在 DAO classes 中,但是服务 classes 是做什么用的? 谢谢!
DAO 提供到数据库和操作的连接。
服务层提供对发送到 DAO 和从 DAO 发送的数据进行操作的逻辑。
还有安全性 - 如果您有与数据库无关的服务层,则除了通过服务之外,从客户端访问数据库会更加困难。
Service层提供业务操作和调用DAO层。
DAO层是针对数据库层的。这意味着它执行数据操作。这是您放置数据检索、数据保存和其他数据库操作的地方。
这个问题的答案可能非常详尽,所以我会尽量在此处坚持一些细节,并在必要时 post 链接。
一些基础工作,
分层和分层架构:您必须了解应用程序的层和层之间的区别。
参考资料:- What is the difference between tier vs layer application?
N-Tiered vs N-Layered architecture/design
因此,如果您的应用程序具有三个主要层:表示层、服务层和数据库层,服务层就是保留服务 类 的层。这是将核心业务逻辑添加到您的应用程序的地方。例如。如果您正在开发一个使用三层的票务应用程序,并且您已经添加了全面的身份验证功能。
- 网页将成为表示层的一部分。
- 用户身份验证、加密检查等功能, 超时检查等将成为您服务层的一部分(服务 类)
- 与数据库的连接和各自的交互将在数据库层 (Hibernate) 处理
另外: 如今,应用程序架构不仅仅局限于三层系统。越来越多地采用分布式应用程序架构,其中上面第 2 点提到的服务层被分解为多个小服务,每个服务都有自己的数据库。 (关键字检查:Microservices)。此外,他们使用消息队列进行交互,但谈论所有这些事情与这个问题无关。
推荐: 1. 您浏览了有关服务层设计的文章,以及不同的需求如何导致服务的不同设计 类。 2. 您阅读了服务设计中常用的设计模式,例如提供者、工厂、单例等。
希望我已经回答了你的问题。
N.B:您需要用 'architecture' 标记您的问题,因为它更像是架构问题而不是 Java 编程。
你可以参考这个简单的例子:
1.PersonDao
只关心数据库操作
package com.pechen.dao;
import java.util.List;
import com.pechen.entity.Person;
public interface PersonDao {
public void save(Person p);
public List<Person> list();
}
2.PersonDaoImpl
是实现。
package com.pechen.dao;
import java.util.List;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.springframework.beans.factory.annotation.Autowired;
import com.pechen.entity.Person;
public class PersonDaoImpl implements PersonDao {
@Autowired
private SessionFactory sessionFactory;
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
public void save(Person p) {
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
session.save(p);
tx.commit();
session.close();
}
@SuppressWarnings("unchecked")
public List<Person> list() {
Session session = sessionFactory.openSession();
List<Person> rst = session.createQuery("from person").getResultList();
session.close();
return rst;
}
}
3。 PersonService
关心业务逻辑,在数据库操作之前可以做任何想做的事
package com.pechen.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import com.pechen.dao.PersonDao;
import com.pechen.dao.PersonDaoImpl;
import com.pechen.entity.Person;
public class PersonService {
@Autowired
private PersonDao personDao;
public void setPersonDao(PersonDaoImpl personImpl) {
this.personDao = personImpl;
}
public void savePerson(Person person) {
// other business logic
this.personDao.save(person);
System.out.println("Save person successfully: " + person);
}
public List<Person> getPersons() {
// other business logic
return this.personDao.list();
}
}