我对DAO和服务层模式有疑问,我正在使用Spring 3和Hibernate 4作为一个小应用程序。
关于我的申请的小描述
我有一个小应用程序,在这个应用程序中,员工和部门数据以JSF形式显示。
部门数据使用主数据数据表以表格形式显示,相关员工数据使用datatable以表格形式显示,这也是详细(主细节)场景。单击主数据表中的按钮后,将显示一个弹出式窗口,其中可以输入有关部门的详细信息,并在数据库表中保留数据(删除和更新的情况相同)。
我的设计如下所示
DAO层
public interface GenericDAO<T> {
public void create(T entity);
public void update(T entity);
public void delete(T entity);
}
public interface DepartmentDAO extends GenericDAO<Department>
--methods for getting Department list and others
public void findDepartment(DepartmentData data);
-----
public interface EmployeeDAO extends GenericDAO<Employee>
--methods for getting Employeelist and others
---
服务层
public interface DepartmentService {
public void findDepartment(DepartmentData data);
-- other methods
}
@Transactional
@Named
public class DepartmentServiceImpl implements DepartmentService {
@Inject
DepartmentDAO departmentDAO;
-- implementation of methods
}
public interface EmployeeService {
public void findEmployees(EmployeeData data);
-- other methods
}
@Transactional
@Named
public class EmployeeServiceImpl implements EmployeeService {
@Inject
EmployeeDAO employeeDAO;
-- implementation of methods
}
我的问题是,对于Department和Employee,我应该使用一个服务接口或类,就像我对JSF使用一个ManagedBean一样,还是应该为Department和Employee使用单独的惰性面和类?如果将所有DAO方法都包含在一个服务实现类中,并且具有@ transactions,那么在数据库事务处理时,它会出现性能问题吗?是否应该使用类似于GenericDAO的通用服务接口?
有什么帮助是非常值得赞赏的吗?
更新1
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd"
>
<context:component-scan base-package="net.test" />
<!-- Data Source Declaration -->
<bean id="DataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="jdbc/myDS"/>
</bean>
<bean
class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />
<bean class="org.springframework.orm.hibernate4.HibernateExceptionTranslator" />
<!-- JPA Entity Manager Factory -->
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="DataSource" />
<property name="packagesToScan" value="net.test.entity" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true" />
<property name="generateDdl" value="false" />
<property name="databasePlatform" value="${jdbc.dialectClass}" />
</bean>
</property>
</bean>
<bean id="defaultLobHandler" class="org.springframework.jdbc.support.lob.DefaultLobHandler" />
<!-- Session Factory Declaration -->
<bean id="SessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="DataSource" />
<property name="annotatedClasses">
<list>
<value>net.test.entity.Employee</value>
<value>net.test.entity.Department</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.query.factory_class">org.hibernate.hql.internal.classic.ClassicQueryTranslatorFactory
</prop>
</props>
</property>
</bean>
<tx:annotation-driven transaction-manager="txManager" />
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="txManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="SessionFactory" />
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<!-- <tx:annotation-driven transaction-manager="txManager"/> -->
<context:annotation-config />
<bean id="hibernateStatisticsMBean" class="org.hibernate.jmx.StatisticsService">
<property name="statisticsEnabled" value="true" />
<property name="sessionFactory" value="#{entityManagerFactory.sessionFactory}" />
</bean>
<bean name="ehCacheManagerMBean"
class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" />
<bean id="mbeanServer" class="org.springframework.jmx.support.MBeanServerFactoryBean">
<property name="locateExistingServerIfPossible" value="true" />
</bean>
<bean id="jmxExporter" class="org.springframework.jmx.export.MBeanExporter"
lazy-init="false">
<property name="server" ref="mbeanServer" />
<property name="registrationBehaviorName" value="REGISTRATION_REPLACE_EXISTING" />
<property name="beans">
<map>
<entry key="SpringBeans:name=hibernateStatisticsMBean"
value-ref="hibernateStatisticsMBean" />
<entry key="SpringBeans:name=ehCacheManagerMBean" value-ref="ehCacheManagerMBean" />
</map>
</property>
</bean>
</beans>
发布于 2013-03-03 05:02:27
要真正回答这个问题,我们需要详细说明@Transactional的语义是如何配置的。例如,每个DAO最终将运行在一个单独的事务中,或者join在Java级别热切地连接在一起,在数据库级别上则懒洋洋地运行等等。
假设只有一个数据库的“公共”配置,以及连接作为服务懒洋洋地被重用,然后加入共享请求级别事务;那么,无论您使用一个服务还是两个服务,我都不会有太大的顾虑。
从性能的角度来看,对数据库的往返次数、数据库请求的工作负载以及事务在数据库级别上保持的时间等都将产生很大的影响。如果有一两个Java对象加入Java级别的事务,而这些事务可能或不受数据库连接(更不用说事务)的支持,那么性能数字就不会相形见绌。您可能会发现序列化多个单独请求所产生的延迟,在这种情况下,可能需要组合、批处理或缓存一些查询。这最好用一个DAO来完成;但是,只有当您有一个度量的性能问题时才这样做。
在这里,团队约定和交流设计/领域模型的意图将更加重要。因此,我认为你是最适合回答你自己的问题的人,不管是一份还是两份。
https://stackoverflow.com/questions/15185705
复制