您的位置:首页 > 编程语言 > Java开发

基于Spring、Hibernate的通用DAO层与Service层的实现

2018-01-24 13:10 531 查看
因为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:画个图好了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: