基于Spring4+Hibernate4的通用数据访问层+业务逻辑层(Dao层+Service层)设计与实现!
基于泛型的依赖注入。当我们的项目中有很多的Model时,相应的Dao(DaoImpl),Service(ServiceImpl)也会增多。
而我们对这些Model的操作很多都是类似的,下面是我举出的一些(见名知意,其它自行脑补):
1.save
2.saveAll
3.findById
4.update
5.saveOrUpdate
6.delete
7.deleteAll
8.deleteById
9.loadAll
10.load(int page,int rows)
11.getTotalCount
12.getScrollData(int firstResult, int maxResult)
13.getScrollData(int firstResult, int maxResult, LinkedHashMap<String, String> orderby)
14.getScrollData(int firstResult, int maxResult, String where, Object[] params)
15.getScrollData(int firstResult, int maxResult, String where, Object[] params, LinkedHashMap<String, String> orderby)
如果我们在每个Dao(DaoImpl),Service(ServiceImpl)中都定义这些方法,我们来算一下。假如有20个Model,那么:
20*15*(2+2)= 1200。纳里,这么一堆破东西就花了1200个方法!!!!(下次可以用这个凑代码量了。。。。)平均每个方法实现了20次,平均每个方法复制了不下40次。还要保证不出任何错误,这个还真是个苦力活。下面是我们更先进的方法。【注:此方法必须将spring更新到4,Spring3还不支持泛型注入!】
我们在Dao(DaoImpl),Service(ServiceImpl)中定义BaseDao(BaseDaoImpl),BaseService(BaseServiceImpl),然后由于ORM使用的是hibernate,我们在操作一个实体的时候其实只需要知道两个属性{Model.id.class(主键类型),Model.class(实体类类型)},好吧其实都是Class类型,还是可序列化的。这样我们的BaseDao在实现的时候不需要关注具体是哪个实体类,根据Model.id.class和Model.class即可获取操作的一切【就CURD操作来说】。然后每个具体的Dao继承BaseDao,就可以拥有BaseDao中定义的十多个方法(不需重复复制代码),还可以根据业务需求扩展具体Dao中的方法,做到了很大程度的解耦(基础操作和特殊操作的解耦)。然后具体的DaoImpl首先继承自BaseDaoImpl(这样那十多个基础方法的实现就又可以省去了)再实现自己Dao的特殊业务逻辑方法。解耦很到位!【当然既然是基于泛型的那么别传错了Model类!!!】,Service(ServiceImpl)层也是一样的!!!
下面是包的结构:
com.xy.model
{Car,Driver,Passenger}
com.xy.dao
{BaseDao,CarDao,DriverDao,PassengerDao}
com.xy.dao.impl
{BaseDaoImpl,CarDaoImpl,DriverDaoImpl,PassengerDaoImpl}
com.xy.service
{BaseService,CarService,DriverService,PassengerService}
com.xy.service.impl
{BaseServiceImpl,CarServiceImpl,DriverServiceImpl,PassengerServiceImpl}
下面是配置文件信息:【本来觉得这个不是重点,没有必要填上来的,不过还是贴了】
##web.xml
<listener> <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class> </listener> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring.xml,classpath:spring-hibernate.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class> </listener> <filter> <filter-name>openSessionInViewFilter</filter-name> <filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class> <init-param> <param-name>singleSession</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>openSessionInViewFilter</filter-name> <url-pattern>*.action</url-pattern> </filter-mapping>
##Spring.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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/context http://www.springframework.org/schema/context/spring-context-3.0.xsd "> <!-- 引入属性文件,config.properties位于src/main/resources目录下 --> <context:property-placeholder location="classpath:config.properties" /> <!-- 自动扫描dao和service包(自动注入) --> <context:component-scan base-package="com.xy.dao.**,com.xy.service.**" /> </beans>
##Spring-hibernate.xml
<?xml version="1.0" encoding="UTF-8"?> <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:aop="http://www.springframework.org/schema/aop" 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/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd "> <!-- 配置数据源 --> <bean name="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"> <property name="url" value="${jdbc_url}" /> <property name="username" value="${jdbc_username}" /> <property name="password" value="${jdbc_password}" /> <!-- 初始化连接大小 --> <property name="initialSize" value="0" /> <!-- 连接池最大使用连接数量 --> <property name="maxActive" value="20" /> <!-- 连接池最小空闲 --> <property name="minIdle" value="0" /> <!-- 获取连接最大等待时间 --> <property name="maxWait" value="60000" /> <property name="validationQuery" value="${validationQuery}" /> <property name="testOnBorrow" value="false" /> <property name="testOnReturn" value="false" /> <property name="testWhileIdle" value="true" /> <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 --> <property name="timeBetweenEvictionRunsMillis" value="60000" /> <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 --> <property name="minEvictableIdleTimeMillis" value="25200000" /> <!-- 打开removeAbandoned功能 --> <property name="removeAbandoned" value="true" /> <!-- 1800秒,也就是30分钟 --> <property name="removeAbandonedTimeout" value="1800" /> <!-- 关闭abanded连接时输出错误日志 --> <property name="logAbandoned" value="true" /> <!-- 监控数据库 --> <!-- <property name="filters" value="stat" /> --> <property name="filters" value="mergeStat" /> </bean> <!-- 配置hibernate session工厂 --> <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="hibernateProperties"> <props> <!-- web项目启动时是否更新表结构 --> <prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop> <!-- 系统使用的数据库方言,也就是使用的数据库类型 --> <prop key="hibernate.dialect">${hibernate.dialect}</prop> <!-- 是否打印Hibernate生成的SQL到控制台 --> <prop key="hibernate.show_sql">${hibernate.show_sql}</prop> <!-- 是否格式化打印出来的SQL --> <prop key="hibernate.format_sql">${hibernate.format_sql}</prop> </props> </property> <!-- 自动扫描注解方式配置的hibernate类文件 --> <property name="packagesToScan"> <list> <value>com.xy.model</value> </list> </property> <!-- 自动扫描hbm方式配置的hibernate文件和.hbm文件 --> <!-- <property name="mappingDirectoryLocations"> <list> <value>classpath:me/gacl/model/hbm</value> </list> </property> --> </bean> <!-- 配置事务管理器 --> <bean name="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory"></property> </bean> <!-- 注解方式配置事物 --> <tx:annotation-driven transaction-manager="transactionManager" /> </beans>
#BaseDao.Java
public interface BaseDaoInter<K extends Serializable ,T extends Serializable> { /** * 由session工厂获取当前session对象 * @return */ public Session getSession(); /** * 将实体对象保存到数据库中 * @param t 待保存的实体对象 * @return 实体对象的ID */ public K save(T t); /** * 将实体对象【集合】保存到数据库中 * @param ct 实体对象【集合】 */ public void saveAll(Collection<T> ct); /** * 根据Id查询实体对象 * @param id 表记录中的对应的id字段 * @return 对应的实体对象 */ public T findById(K id); /** * 更新一条记录 * @param t 待更新记录对应的实体对象 * @return 更新后的实体对象 */ public T update(T t); /** * 保存或更新一个实体对象到表记录中 * @param t 待更新的实体对象 * @return 更新后的实体对象 */ public T saveOrUpdate(T t); /** * 删除一个实体对象对应的表记录 * @param t 待删除的实体对象 */ public void delete(T t); /** * 删除一组记录 * @param ct 待删除记录集合 */ public void deleteAll(Collection<T> ct); /** * 根据id删除一条记录 * @param id 待删除记录id * @return 是否删除成功(id是否有效) */ public boolean deleteById(K id); /** * 加载所有记录集合 * @return 所有记录集合 */ public QueryResult<T> loadAll(); /** * 分页加载记录集合 * @param page 当前第多少页 * @param rows 每页最多多少行数据 * @return 第page页的数据集合 */ public QueryResult<T> load(int page,int rows); /** * 获取总记录数 * @return 总数 */ public long getTotalCount(); /******************************HQL******************************/ /** * 分页获取所有记录 * @return */ public QueryResult<T> getScrollData(); /** * 分页获取记录 * @param firstResult 开始索引,如果输入值为-1,即获取全部数据 * @param maxResult 每页获取的记录数,如果输入值为-1,即获取全部数据 * @return */ public QueryResult<T> getScrollData(int firstResult, int maxResult); /** * 分页获取记录 * @param firstResult 开始索引,如果输入值为-1,即获取全部数据 * @param maxResult 每页获取的记录数,如果输入值为-1,即获取全部数据 * @param orderby 排序,Key为排序属性,Value为asc/desc,如: * LinkedHashMap<String, String> orderby = new LinkedHashMap<String, String>(); orderby.put("email", "asc"); orderby.put("password", "desc"); * @return */ public QueryResult<T> getScrollData(int firstResult, int maxResult, LinkedHashMap<String, String> orderby); /** * 分页获取记录 * @param firstResult 开始索引,如果输入值为-1,即获取全部数据 * @param maxResult 每页获取的记录数,如果输入值为-1,即获取全部数据 * @param where 条件语句,不带where关键字,条件语句只能使用位置参数,位置参数的索引值以1开始,如:o.username=?1 and o.password=?2 * @param params 条件语句出现的位置参数值 * @return */ public QueryResult<T> getScrollData(int firstResult, int maxResult, String where, Object[] params); /** * 分页获取记录 * @param firstResult 开始索引,如果输入值为-1,即获取全部数据 * @param maxResult 每页获取的记录数,如果输入值为-1,即获取全部数据 * @param where 条件语句,不带where关键字,条件语句只能使用位置参数,位置参数的索引值以1开始,如:o.username=?1 and o.password=?2 * @param params 条件语句出现的位置参数值 * @param orderby 排序,Key为排序属性,Value为asc/desc,如: * LinkedHashMap<String, String> orderby = new LinkedHashMap<String, String>(); orderby.put("email", "asc"); orderby.put("password", "desc"); * @return */ public QueryResult<T> getScrollData(int firstResult, int maxResult, String where, Object[] params, LinkedHashMap<String, String> orderby); }
#CarDao.java
public interface CarDaoInter extends BaseDaoInter<Integer,Car>{ //定义扩展的方法 }
#DriverDao.java
public interface DriverDaoInter extends BaseDaoInter<Integer,Driver>{ //定义扩展的方法 }
#PassengerDao.java
public interface PassengerDaoInter extends BaseDaoInter<Integer,Passenger>{ //定义扩展的方法 }
#BaseDaoImpl.java
/** * 不一定必须是abstract类型的, 请不要对BaseDaoImpl使用@Repository注解,因为无法直接指定clatt属性值 * class值由继承类来指定 * * @author BearSmall * * @param <T> */ public abstract class BaseDaoImpl<K extends Serializable, T extends Serializable> implements BaseDaoInter<K, T> { @Autowired private SessionFactory sessionFactory; // 从容器中注入session工厂【无需get,set方法】 private Class<T> clatt; // 【实体类对应的Class对象】 /** * //向子类暴露的接口获用来获取sessionFactory * * @return sessionFactory */ public SessionFactory getSessionFactory() { return sessionFactory; } /** * 保留指定clatt值的接口【通过子类显示调用父类的构造函数来指定】 * * @param clatt */ public BaseDaoImpl(Class<T> clatt) { this.clatt = clatt; } // @SuppressWarnings("unchecked") // public BaseDaoImpl() {//另外一种方式指定clatt值,要求类必须是abstract类型 // ParameterizedType parameterizedType = // (ParameterizedType)this.getClass().getGenericSuperclass(); // clatt= (Class<T>)(parameterizedType.getActualTypeArguments()[0]); // } @Override public Session getSession() { return getSessionFactory().getCurrentSession(); } @SuppressWarnings("unchecked") @Override public K save(T t) { Session session = getSession(); return (K) session.save(t); } @Override public T findById(K id) { Session session = getSession(); @SuppressWarnings("unchecked") T t = (T) session.get(clatt, id); return t; } @Override public void saveAll(Collection<T> ct) { Session session = getSession(); for (T t : ct) { session.save(t); } } @Override public T update(T t) { Session session = getSession(); session.update(t); return t; } @Override public void deleteAll(Collection<T> ct) { Session session = getSession(); for (T t : ct) { session.delete(t); } } @Override public T saveOrUpdate(T t) { Session session = getSession(); session.saveOrUpdate(t); return t; } @Override public void delete(T t) { Session session = getSession(); session.delete(t); } @Override public boolean deleteById(K id) { Session session = getSession(); @SuppressWarnings("unchecked") T t = (T) session.get(clatt, id); if (t == null) return false; session.delete(t); return true; } @SuppressWarnings("unchecked") @Override public QueryResult<T> loadAll() { Session session = getSession(); Criteria criteria = session.createCriteria(clatt); QueryResult<T> result = new QueryResult<>(); result.setDatas(criteria.list()); result.setTotalCount(Long.parseLong(criteria .setProjection(Projections.rowCount()).uniqueResult() .toString())); return result; } @SuppressWarnings("unchecked") @Override public QueryResult<T> load(int page, int rows) { Session session = getSession(); Criteria criteria = session.createCriteria(clatt); criteria.setFirstResult((page - 1) * rows); criteria.setMaxResults(rows); QueryResult<T> result = new QueryResult<>(); result.setDatas(criteria.list()); result.setTotalCount(Long.parseLong(criteria .setProjection(Projections.rowCount()).uniqueResult() .toString())); return result; } @Override public long getTotalCount() { Session session = getSession(); Criteria criteria = session.createCriteria(clatt); Object object = criteria.setProjection(Projections.rowCount()) .uniqueResult(); long totalCount = 0; if (object != null) { totalCount = Long.parseLong(object.toString()); } return totalCount; } /****************************** HQL ******************************/ @Override public QueryResult<T> getScrollData() { return getScrollData(-1, -1, null, null, null); } @Override public QueryResult<T> getScrollData(int firstResult, int maxResult) { return getScrollData(firstResult, maxResult, null, null, null); } @Override public QueryResult<T> getScrollData(int firstResult, int maxResult, LinkedHashMap<String, String> orderby) { return getScrollData(firstResult, maxResult, null, null, orderby); } @Override public QueryResult<T> getScrollData(int firstResult, int maxResult, String where, Object[] params) { return getScrollData(firstResult, maxResult, where, params, null); } @Override @SuppressWarnings("unchecked") public QueryResult<T> getScrollData(int firstResult, int maxResult, String where, Object[] params, LinkedHashMap<String, String> orderby) { String entityName = clatt.getSimpleName(); String whereql = where != null && !"".equals(where.trim()) ? " where " + where : ""; Session session = getSession(); Query query = session.createQuery("select o from " + entityName + " o" + whereql + buildOrderby(orderby)); if (firstResult != -1 && maxResult != -1) query.setFirstResult(firstResult).setMaxResults(maxResult); setQueryParameter(query, params); QueryResult<T> qr = new QueryResult<T>(); // qr.setResultlist(query.getResultList()); Query queryCount = session.createQuery("select count(o) from " + entityName + " o" + whereql); setQueryParameter(queryCount, params); long count = (Long) queryCount.uniqueResult(); qr.setTotalCount(count); qr.setDatas(query.list()); return qr; } /** * 设置查询参数 * * @param query * 查询对象 * @param params * 参数值 */ public static void setQueryParameter(Query query, Object[] params) { if (params != null) { for (int i = 0; i < params.length; i++) { query.setParameter(i, params[i]); } } } /** * 构建排序语句 * * @param orderby * 排序属性与asc/desc, Key为属性,Value为asc/desc * @return */ public static String buildOrderby(LinkedHashMap<String, String> orderby) { StringBuilder sb = new StringBuilder(); if (orderby != null && !orderby.isEmpty()) { sb.append(" order by "); for (Map.Entry<String, String> entry : orderby.entrySet()) { sb.append("o.").append(entry.getKey()).append(" ") .append(entry.getValue()).append(','); } sb.deleteCharAt(sb.length() - 1); } return sb.toString(); } }
#CarDaoImpl.java
@Repository("carDao") public class CarDaoImpl extends BaseDaoImpl<Integer,Car> implements CarDaoInter{ //通过调用父类的构造函数指定clazz值,即实体类的类类型 public CarDaoImpl() { super(Car.class); } /*****************************************扩展的方法的实现****************************************/ }
#DriverDaoImpl.java
@Repository(value="driverDao") public class DriverDaoImpl extends BaseDaoImpl<Integer,Driver> implements DriverDaoInter{ //通过调用父类的构造函数指定clazz值,即实体类的类类型 public DriverDaoImpl() { super(Driver.class); } /*****************************************扩展的方法的实现****************************************/ }
#PassengerDaoImpl.java
@Repository("passengerDao") public class PassengerDaoImpl extends BaseDaoImpl<Integer,Passenger> implements PassengerDaoInter { //通过调用父类的构造函数指定clazz值,即实体类的类类型 public PassengerDaoImpl() { super(Passenger.class); } /*****************************************扩展的方法的实现****************************************/ }
#BaseService.java
public interface BaseServiceInter<K extends Serializable,T extends Serializable> { /** * 将实体对象保存到数据库中 * @param t 待保存的实体对象 * @return 实体对象的ID */ public K save(T t); /** * 将实体对象【集合】保存到数据库中 * @param ct 实体对象【集合】 */ public void saveAll(Collection<T> ct); /** * 根据Id查询实体对象 * @param id 表记录中的对应的id字段 * @return 对应的实体对象 */ public T findById(K id); /** * 更新一条记录 * @param t 待更新记录对应的实体对象 * @return 更新后的实体对象 */ public T update(T t); /** * 保存或更新一个实体对象到表记录中 * @param t 待更新的实体对象 * @return 更新后的实体对象 */ public T saveOrUpdate(T t); /** * 删除一个实体对象对应的表记录 * @param t 待删除的实体对象 */ public void delete(T t); /** * 删除一组记录 * @param ct 待删除记录集合 */ public void deleteAll(Collection<T> ct); /** * 根据id删除一条记录 * @param id 待删除记录id * @return 是否删除成功(id是否有效) */ public boolean deleteById(K id); /** * 加载所有记录集合 * @return 所有记录集合 */ public QueryResult<T> loadAll(); /** * 分页加载记录集合 * @param page 当前第多少页 * @param rows 每页最多多少行数据 * @return 第page页的数据集合 */ public QueryResult<T> load(int page,int rows); /** * 获取总记录数 * @return 总数 */ public long getTotalCount(); /******************************HQL******************************/ /** * 分页获取所有记录 * @return */ public QueryResult<T> getScrollData(); /** * 分页获取记录 * @param firstResult 开始索引,如果输入值为-1,即获取全部数据 * @param maxResult 每页获取的记录数,如果输入值为-1,即获取全部数据 * @return */ public QueryResult<T> getScrollData(int firstResult, int maxResult); /** * 分页获取记录 * @param firstResult 开始索引,如果输入值为-1,即获取全部数据 * @param maxResult 每页获取的记录数,如果输入值为-1,即获取全部数据 * @param orderby 排序,Key为排序属性,Value为asc/desc,如: * LinkedHashMap<String, String> orderby = new LinkedHashMap<String, String>(); orderby.put("email", "asc"); orderby.put("password", "desc"); * @return */ public QueryResult<T> getScrollData(int firstResult, int maxResult, LinkedHashMap<String, String> orderby); /** * 分页获取记录 * @param firstResult 开始索引,如果输入值为-1,即获取全部数据 * @param maxResult 每页获取的记录数,如果输入值为-1,即获取全部数据 * @param where 条件语句,不带where关键字,条件语句只能使用位置参数,位置参数的索引值以1开始,如:o.username=?1 and o.password=?2 * @param params 条件语句出现的位置参数值 * @return */ public QueryResult<T> getScrollData(int firstResult, int maxResult, String where, Object[] params); /** * 分页获取记录 * @param firstResult 开始索引,如果输入值为-1,即获取全部数据 * @param maxResult 每页获取的记录数,如果输入值为-1,即获取全部数据 * @param where 条件语句,不带where关键字,条件语句只能使用位置参数,位置参数的索引值以1开始,如:o.username=?1 and o.password=?2 * @param params 条件语句出现的位置参数值 * @param orderby 排序,Key为排序属性,Value为asc/desc,如: * LinkedHashMap<String, String> orderby = new LinkedHashMap<String, String>(); orderby.put("email", "asc"); orderby.put("password", "desc"); * @return */ public QueryResult<T> getScrollData(int firstResult, int maxResult, String where, Object[] params, LinkedHashMap<String, String> orderby); }
#CarService.java
public interface CarServiceInter extends BaseServiceInter<Integer,Car>{ //定义扩展的方法 }
#DriverService.java
public interface DriverServiceInter extends BaseServiceInter<Integer,Driver>{ //定义扩展的方法 }
#PassengerService.java
public interface PassengerServiceInter extends BaseServiceInter<Integer,Passenger>{ //定义扩展的方法 }
#BaseServiceImpl.java
@Transactional(propagation=Propagation.REQUIRED) public abstract class BaseServiceImpl<K extends Serializable,T extends Serializable> implements BaseServiceInter<K,T> { @Autowired private BaseDaoInter<K,T> baseDao; //从容器中注入session工厂【无需get,set方法】 @Override public K save(T t) { return baseDao.save(t); } @Override public void saveAll(Collection<T> ct) { baseDao.saveAll(ct); } @Override public T findById(K id) { return baseDao.findById(id); } @Override public T update(T t) { return baseDao.update(t); } @Override public T saveOrUpdate(T t) { return baseDao.saveOrUpdate(t); } @Override public void delete(T t) { baseDao.delete(t); } @Override public void deleteAll(Collection<T> ct) { baseDao.deleteAll(ct); } @Override public boolean deleteById(K id) { return baseDao.deleteById(id); } @Override public QueryResult<T> loadAll() { return baseDao.loadAll(); } @Override public QueryResult<T> load(int page, int rows) { return baseDao.load(page, rows); } @Override public long getTotalCount() { return baseDao.getTotalCount(); } /******************************HQL******************************/ @Override public QueryResult<T> getScrollData() { return baseDao.getScrollData(); } @Override public QueryResult<T> getScrollData(int firstResult, int maxResult) { return baseDao.getScrollData(firstResult, maxResult); } @Override public QueryResult<T> getScrollData(int firstResult, int maxResult, LinkedHashMap<String, String> orderby) { return baseDao.getScrollData(firstResult, maxResult, orderby); } @Override public QueryResult<T> getScrollData(int firstResult, int maxResult, String where, Object[] params) { return baseDao.getScrollData(firstResult, maxResult, where, params); } @Override public QueryResult<T> getScrollData(int firstResult, int maxResult, String where, Object[] params, LinkedHashMap<String, String> orderby) { return baseDao.getScrollData(firstResult, maxResult, where, params, orderby); } }
#CarServiceImpl.java
@Service("carProxy") public class CarServiceImpl extends BaseServiceImpl<Integer,Car> implements CarServiceInter { @Autowired private CarDaoInter carDao; //从容器中注入session工厂【无需get,set方法】 /*****************************************扩展的方法的实现****************************************/ }
#DriverServiceImpl.java
@Service("driverProxy") public class DriverServiceImpl extends BaseServiceImpl<Integer,Driver> implements DriverServiceInter { @Autowired private DriverDaoInter driverDao; //从容器中注入session工厂【无需get,set方法】 /*****************************************扩展的方法的实现****************************************/ }
#PassengerServiceImpl.java
@Service("passengerProxy") public class PassengerServiceImpl extends BaseServiceImpl<Integer,Passenger> implements PassengerServiceInter { @Autowired private PassengerDaoInter passengerDao; //从容器中注入session工厂【无需get,set方法】 /*****************************************扩展的方法的实现****************************************/ }
Plus:源代码传送门:https://github.com/bearsmall/BASESSH2
原文地址:http://blog.csdn.net/u014424628/article/details/51560256