spring dao层注解_Spring– DAO和服务层

本文介绍了如何在Spring中使用DAO层注解,包括@Transcational的使用和事务管理器的配置。文章详细讲解了DAO的实现,如使用Hibernate的SessionFactory,并讨论了不同的注入方式。同时,提到了接口编程和接口安全的重要性。此外,文章还涵盖了测试、JdbcTemplate的使用以及如何通过SQL脚本管理数据库状态。
摘要由CSDN通过智能技术生成

spring dao层注解

欢迎来到Spring教程的第三部分。 在这一部分中,我们将继续编写Timesheet应用程序,这次我们将实现DAO层,业务服务并编写一些测试。

在上一部分中,我们定义了GenericDao接口,该接口告诉我们需要对实体执行哪些操作。 现在我们需要提供实现。 我们将使用Hibernate的工具(使用SessionFactory)编写一个类来执行这些操作。 因此,任何提供的DAO都会自动继承这些基本操作。 我们稍后再讨论。

package org.timesheet.service.impl;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.timesheet.service.GenericDao;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.List;

/**
 * Basic DAO operations dependent with Hibernate's specific classes
 * @see SessionFactory
 */
@Transactional(propagation= Propagation.REQUIRED, readOnly=false)
public class HibernateDao<E, K extends Serializable> implements GenericDao<E, K> {

    private SessionFactory sessionFactory;
    protected Class<? extends E> daoType;

    public HibernateDao() {
        daoType = (Class<E>) ((ParameterizedType) getClass().getGenericSuperclass())
                        .getActualTypeArguments()[0];
    }

    @Autowired
    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    protected Session currentSession() {
        return sessionFactory.getCurrentSession();
    }

    @Override
    public void add(E entity) {
        currentSession().save(entity);
    }

    @Override
    public void update(E entity) {
        currentSession().saveOrUpdate(entity);
    }

    @Override
    public void remove(E entity) {
        currentSession().delete(entity);
    }

    @Override
    public E find(K key) {
        return (E) currentSession().get(daoType, key);
    }

    @Override
    public List<E> list() {
        return currentSession().createCriteria(daoType).list();
    }
}

我希望您注意有关此代码的几件事:

  • 我们在类的顶部使用@Transcational批注。 这基本上意味着,DAO方法将在事务内运行。 为了使其正常工作,我们需要更改persistence-beans.xml文件,并在其中声明将处理事务的事务管理器。 只需添加以下行(新bean定义):
    <bean id='transactionManager'
              class='org.springframework.orm.hibernate3.HibernateTransactionManager'>
            <property name='sessionFactory' ref='sessionFactory' />
        </bean>
  • 我们正在使用setter注入自动装配(@Autowired)SessionFactory。 如您所知,注入的种类更多(字段,setter,构造函数)。 使用Spring时,字段注入看起来最好,因为注释直接位于字段上,而不是构造函数或setter方法上。 另一方面,字段注入是最无用的,因为我们不能手动将其他依赖项设置为私有字段(例如在单元测试中)。 我尽可能地喜欢构造函数注入,因为我不必为依赖项使用mutator(setter)。 因此,以更安全的方式构造对象。 在此特定情况下,我们将使用setter注入,因为我们正在设计此类进行扩展。 如果选择构造函数注入,则所有扩展类都必须具有与超类匹配的构造函数。

    如果您想了解更多有关此的内容,我建议您阅读 Dhanji R. Prasanna撰写的精彩著作
    还要注意,构造函数的第一行正在做一些反射魔术。 那是因为Java在运行时没有泛型,只有在编译时才有泛型,因此它阻止我们编写类似E.class的东西。 因此,我们使用了这个丑陋的技巧。

现在我们有了一些DAO操作的基本模板。 在实际系统中,每个实体通常都有DAO。 这是因为有时那些继承的CRUD操作还不够,您还需要一些其他业务操作 。 我们将定义类型安全的接口(每个DAO的操作集),并且以后仅依赖于控制器中的接口。 我们将使用Hibernate实施它们,并使其自动接线。 创建新的包org.timesheet.service.dao,并在其中添加以下接口–每个实体的DAO:

package org.timesheet.service.dao;

import org.timesheet.domain.Employee;
import org.timesheet.service.GenericDao;

/**
 * DAO of employee.
 */
public interface EmployeeDao extends GenericDao<Employee, Long> {

    /**
     * Tries to remove employee from the system.
     * @param employee Employee to remove
     * @return {@code true} if employee is not assigned to any task
     * or timesheet. Else {@code false}.
     */
    boolean removeEmployee(Employee employee);

}
package org.timesheet.service.dao;

import org.timesheet.domain.Manager;
import org.timesheet.service.GenericDao;

/**
 * DAO of Manager.
 */
public interface ManagerDao extends GenericDao<Manager, Long> {
    /**
     * Tries to remove manager from the system.
     * @param manager Manager to remove
     * @return {@code true} if manager is not assigned to any task.
     * Else {@code false}.
     */
    boolean removeManager(Manager manager);
}
package org.timesheet.service.dao;

import org.timesheet.domain.Task;
import org.timesheet.service.GenericDao;

/**
 * DAO of Task.
 */
public interface TaskDao extends GenericDao<Task, Long> {

    /**
     * Tries to remove task from the system.
     * @param task Task to remove
     * @return {@code true} if there is no timesheet created on task.
     * Else {@code false}.
     */
    boolean removeTask(Task task);

}
package org.timesheet.service.dao;

import org.timesheet.domain.Timesheet;
import org.timesheet.service.GenericDao;

/**
 * DAO of Timesheet.
 */
public interface TimesheetDao extends GenericDao<Timesheet, Long> {
    // no additional business operations atm
}

实施时间。 我们将扩展HibernateDao并实现coresponding接口。 我们需要这些具体的类,因为它将被注入到相应的字段(由接口声明)中。 也许您已经听说过有关此方法的一些内容–称为接口编程,并且您肯定希望使用它。

package org.timesheet.service.impl;

import org.hibernate.Query;
import org.springframework.stereotype.Repository;
import org.timesheet.domain.Employee;
import org.timesheet.service.dao.EmployeeDao;

@Repository('employeeDao')
public class EmployeeDaoImpl extends HibernateDao<Employee, Long> implements EmployeeDao {

    @Override
    public boolean removeEmployee(Employee employee) {
        Query employeeTaskQuery = currentSession().createQuery(
                'from Task t where :id in elements(t.assignedEmployees)');
        employeeTaskQuery.setParameter('id', employee.getId());

        // employee mustn't be assigned on no task
        if (!employeeTaskQuery.list().isEmpty()) {
            return false;
        }

        Query employeeTimesheetQuery = currentSession().createQuery(
                'from Timesheet t where t.who.id = :id');
        employeeTimesheetQuery.setParameter('id', employee.getId());

        // employee mustn't be assigned to any timesheet
        if (!employeeTimesheetQuery.list().isEmpty()) {
            return false;
        }

        // ok, remove as usual
        remove(employee);
        return true;

    }
}
package org.timesheet.service.impl;

import org.hibernate.Query;
import org.springframework.stereotype.Repository;
import org.timesheet.domain.Manager;
import org.timesheet.service.dao.ManagerDao;

@Repository('managerDao')
public class ManagerDaoImpl extends HibernateDao<Manager, Long> implements Manager
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值