因为DAO层基本的就是CRUD操作,变化不是很大,要是有变化的那就是查询。而确实没有必要为每一个实体写一个完整的DAO,但是没有还不行,那就“抽取”出来吧。而Service依赖与DAO层,有时就是简单调用一下,也确实没有必要每个都写。总之,不爱写多个,那就写一个通用的,而其他的继承或实现这个通用的可以了。
还是用代码说话吧。
package org.monday.dao; import java.io.Serializable; import java.util.List; /** * BaseDAO 定义DAO的通用操作 * * @author Monday */ public interface BaseDao<T> { public void save(T entity); public void update(T entity); public void delete(Serializable id); public T findById(Serializable id); public List<T> findByHQL(String hql, Object... params); }
上面的DAO只定义了一些常见的方法,有需要通用的方法,可以随便加,然后实现它就行了。
package org.monday.dao.impl; import java.io.Serializable; import java.lang.reflect.ParameterizedType; import java.util.List; import javax.annotation.Resource; import org.hibernate.Query; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.monday.dao.BaseDao; /** * BaseDaoImpl 定义DAO的通用操作的实现 * * @author Monday */ @SuppressWarnings("unchecked") public class BaseDaoImpl<T> implements BaseDao<T> { private Class<T> clazz; /** * 通过构造方法指定DAO的具体实现类 */ public BaseDaoImpl() { ParameterizedType type = (ParameterizedType) this.getClass().getGenericSuperclass(); clazz = (Class<T>) type.getActualTypeArguments()[0]; System.out.println("DAO的真实实现类是:" + this.clazz.getName()); } /** * 向DAO层注入SessionFactory */ @Resource private SessionFactory sessionFactory; /** * 获取当前工作的Session */ protected Session getSession() { return this.sessionFactory.getCurrentSession(); } public void save(T entity) { this.getSession().save(entity); } public void update(T entity) { this.getSession().update(entity); } public void delete(Serializable id) { this.getSession().delete(this.findById(id)); } public T findById(Serializable id) { return (T) this.getSession().get(this.clazz, id); } public List<T> findByHQL(String hql, Object... params) { Query query = this.getSession().createQuery(hql); for (int i = 0; params != null && i < params.length; i++) { query.setParameter(i, params); } return query.list(); } }
以上是BaseDao和它的实现类。
那下面以CustomerDao与OrderDao为例,编写具体的Dao
package org.monday.dao; import org.monday.domain.Customer; /** * 客户DAO继承BaseDAO * * @author Monday */ public interface CustomerDao extends BaseDao<Customer> { /** * 若BaseDAO 没有定义的方法,可以在这里添加 */ }
package org.monday.dao.impl; import org.monday.dao.CustomerDao; import org.monday.domain.Customer; import org.springframework.stereotype.Repository; /** * 客户DAO的实现类 继承BaseDaoImpl 显示客户DAO接口 * * @author Monday */ @Repository(value = "customerDao") public class CustomerDaoImpl extends BaseDaoImpl<Customer> implements CustomerDao { /** * 若CustomerDao 定义了BaseDAO没有的方法,则可以在这里实现 */ }
package org.monday.dao; import org.monday.domain.Order; /** * 订单DAO继承BaseDAO * * @author Monday */ public interface OrderDao extends BaseDao<Order> { /** * 若BaseDAO 没有定义的方法,可以在这里添加 */ }
package org.monday.dao.impl; import org.monday.dao.OrderDao; import org.monday.domain.Order; import org.springframework.stereotype.Repository; /** * 订单DAO的实现类 继承BaseDaoImpl 显示订单DAO接口 * * @author Monday */ @Repository(value = "orderDao") public class OrderDaoImpl extends BaseDaoImpl<Order> implements OrderDao { /** * 若OrderDao 定义了BaseDAO没有的方法,则可以在这里实现 */ }
至于具体的Service怎么写呢?看下面:
package org.monday.service; import java.io.Serializable; import java.util.List; /** * BaseService 定义Service的通用操作 * * @author Monday */ public interface BaseService<T> { public void save(T entity); public void update(T entity); public void delete(Serializable id); public T getById(Serializable id); public List<T> getByHQL(String hql, Object... params); }
package org.monday.service.impl; import java.io.Serializable; import java.util.List; import javax.annotation.Resource; import org.monday.dao.BaseDao; import org.monday.service.BaseService; import org.springframework.transaction.annotation.Transactional; /** * BaseServiceImpl 定义Service的通用操作的实现 * * @author Monday */ @Transactional public class BaseServiceImpl<T> implements BaseService<T> { /** * 注入BaseDao */ private BaseDao<T> dao; @Resource public void setDao(BaseDao<T> dao) { this.dao = dao; } public void save(T entity) { dao.save(entity); } public void update(T entity) { dao.update(entity); } public void delete(Serializable id) { dao.delete(id); } public T getById(Serializable id) { return dao.findById(id); } public List<T> getByHQL(String hql, Object... params) { return dao.findByHQL(hql, params); } }
package org.monday.service; import org.monday.domain.Customer; /** * 客户Service继承BaseService * * @author Monday */ public interface CustomerService extends BaseService<Customer> { /** * 若BaseService 没有定义的方法,可以在这里添加 */ }
package org.monday.service.impl; import javax.annotation.Resource; import org.monday.dao.BaseDao; import org.monday.domain.Customer; import org.monday.service.CustomerService; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; /** * 客户Service的实现类 继承BaseServiceImpl 显示客户Service接口 * * @author Monday */ @Service("customerService") @Transactional public class CustomerServiceImpl extends BaseServiceImpl<Customer> implements CustomerService { /** * 注入DAO */ @Resource(name = "customerDao") public void setDao(BaseDao<Customer> dao) { super.setDao(dao); } /** * 若CustomerService 定义了BaseService没有的方法,则可以在这里实现 */ }
package org.monday.service; import org.monday.domain.Order; /** * 订单Service继承BaseService * * @author Monday */ public interface OrderService extends BaseService<Order> { /** * 若BaseService 没有定义的方法,可以在这里添加 */ }
package org.monday.service.impl; import javax.annotation.Resource; import org.monday.dao.BaseDao; import org.monday.domain.Order; import org.monday.service.OrderService; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; /** * 订单Service的实现类 继承BaseServiceImpl 显示订单Service接口 * * @author Monday */ @Service(value = "orderService") @Transactional public class OrderServiceImpl extends BaseServiceImpl<Order> implements OrderService { /** * 注入DAO */ @Resource(name = "orderDao") public void setDao(BaseDao<Order> dao) { super.setDao(dao); } /** * 若CustomerService 定义了BaseService没有的方法,则可以在这里实现 */ }
这里只是提供了一个思路。可能代码还有不严谨的地方,欢迎补充指正。
容易出现的两个异常:
1.org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here
答案:要加@Transactional注解
除了要在这里加注解
@Service("customerService")
@Transactional
public class CustomerServiceImpl extends BaseServiceImpl<Customer> implements CustomerService {}
这里也要加
@Transactional
public class BaseServiceImpl<T> implements BaseService<T> {}
2.org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'customerService':
Injection of resource fields failed;
nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException:
No unique bean of type [org.monday.dao.BaseDao] is defined:
expected single matching bean but found 2: [customerDao, orderDao]
答案:
(参考)
注入具体的DAO
@Resource(name="customerDao")
public void setDao(BaseDao<Customer> dao) {
super.setDao(dao);
}
PS:画个图好了。
相关推荐
整合Struts2、Hibernate和Spring,我们通常会使用Spring的ApplicationContext来管理Bean,包括Action类、Service层和DAO层。Service层作为业务逻辑层,调用DAO层的方法进行数据操作。而DAO层通过泛型接口和实现类,...
总的来说,"SSHWithAnnotationDemo"项目展示了如何利用现代Java技术栈的高级特性,包括Struts2、Spring3和Hibernate的注解功能,DAO层的泛型设计以及通用的分页实现,来构建一个高效、可维护的Web应用。这样的实践...
在Java Web开发中,S2SH(Struts2 + Spring + Hibernate)是一个常见的技术栈,它结合了MVC框架Struts2、依赖注入容器Spring以及持久层框架Hibernate,以实现高效且灵活的Web应用开发。在这个基于Annotation并对DAO...
本项目"基于Struts2 Spring Hibernate开发的BBS论坛"是一个典型的MVC(Model-View-Controller)架构的实例,旨在帮助初学者理解并掌握这些技术的实际应用。 Struts2作为MVC框架,主要负责控制层,它的主要任务是...
本文将深入探讨如何基于注解的方式整合Spring与Hibernate,帮助新手更好地理解和实践这两个框架的整合。 首先,让我们了解Spring中的注解。Spring注解如`@Autowired`、`@Service`、`@Repository`和`@Controller`...
"hibernate 通用接口架构"是指利用Hibernate框架,通过设计DAO(Data Access Object)层的接口来实现业务逻辑与数据访问的解耦,从而提高代码的可复用性和可维护性。 首先,我们来理解DAO层的作用。DAO层作为业务...
本文将详细解析如何利用Spring和Hibernate来实现一个通用的DAO(Data Access Object)层,以提高代码复用性和项目开发效率。 首先,让我们了解Spring框架。Spring是一个全面的企业级应用开发框架,提供了依赖注入...
同时,还需要配置Hibernate的实体类、DAO层接口及其实现、Service层接口及其实现、以及Controller层。 接着,创建Hibernate的实体类,通过注解(如@Entity、@Table、@Id、@GeneratedValue等)定义与数据库表的映射...
具体来说,Spring可以将Web层、Service层、DAO层以及PO(Plain Old Java Object)对象无缝整合在一起,形成一个完整而高效的应用程序架构。 - **Web层**:处理与用户交互相关的部分,如HTTP请求的接收、处理以及...
在文档"struts+spring+hibernate通用分页方法.doc"中,可能会详细阐述如何配置这些框架的整合,如何编写Action、Service、DAO以及视图层的代码,以及如何测试和优化分页性能,例如缓存策略、预加载等。 这个通用...
在实际项目中,Spring 通常用于管理 Hibernate 的 SessionFactory,提供事务管理,并通过 AOP 实现数据访问层的通用方法,如开启和提交事务、处理异常等。 从文件名称 "Spring3.2.5Hibernate4.0.1Integration" 来看...
6. **DAO和Service层**:实现数据访问对象(DAO)接口和业务服务(Service)接口,处理数据库操作和业务逻辑。 7. **Action和视图**:编写Struts Action类,实现用户请求的处理逻辑,返回相应的视图结果。 8. **测试...
总结,Spring与Hibernate的整合极大地提高了开发效率,通过Spring的IoC和AOP特性,我们可以轻松地管理数据访问层,实现通用的增删改查方法。同时,Spring Data的加入让查询更加简洁,降低了对SQL的依赖。在实际项目...
而HibernateDAO则是基于Hibernate进行数据访问的对象,是业务逻辑层和持久层之间的桥梁。本文将详细探讨HibernateDAO的实现方式以及常见设计模式,旨在帮助开发者更好地理解和运用这一技术。 1. HibernateDAO的基本...
总结来说,使用Hibernate、Struts和Spring实现的通用分页查询,涉及了Java Web开发中的多个层次,包括模型、持久层接口、持久层实现、业务层和服务层的交互,以及视图层的渲染。这种分页机制灵活且可复用,可以适应...
在本项目中,Spring被用来管理数据库的SessionFactory,以及控制业务逻辑层(Service)与数据访问层(DAO)之间的交互。 **Hibernate框架**:Hibernate是一个优秀的ORM(Object-Relational Mapping)框架,它简化了...
5. **整合Hibernate和Spring**:在Spring的配置文件中声明SessionFactory Bean,并将它注入到Service层,Service层再注入到DAO层。这样,Service和DAO可以通过Spring获取SessionFactory,进行数据操作。 6. **测试**...
下面我们将深入探讨基于注解的SSH实现通用DAO的CRUD(创建、读取、更新、删除)操作。 首先,让我们从Spring开始。在Spring 4中,注解的使用已经非常广泛,例如`@Autowired`用于自动装配bean,`@Service`、`@...
本文将深入探讨如何利用Spring和Hibernate实现完整的分页功能,并结合MySQL数据库进行操作。 首先,Spring是一个轻量级的框架,它提供了全面的DI服务,允许开发者通过XML配置或注解来管理对象的生命周期和依赖关系...