1. 程式人生 > >基於Spring4+Hibernate4的通用資料訪問層(Dao層)設計與實現!

基於Spring4+Hibernate4的通用資料訪問層(Dao層)設計與實現!

基於泛型的依賴注入。當我們的專案中有很多的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 orderby)
14.getScrollData(int firstResult, int maxResult, String where, Object[] params)
15.getScrollData(int firstResult, int maxResult, String where, Object[] params, LinkedHashMap 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

<span><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></span>


##Spring.xml

<span><?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></span>


##Spring-hibernate.xml

<span><?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></span>


後面到了重點了!!!

#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
<span class="pln">public interface DriverDaoInter extends BaseDaoInter</span><span class="tag"><Integer</span><span class="pln">,</span><span class="atn">Driver</span><span class="tag">></span><span class="pln">{

}</span>
#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);
	}
	
}

#BaseService.java
<span class="tag"></span><span class="pln"></span><span class="tag"></span>
#CarService.java
public interface CarServiceInter extends BaseServiceInter<Integer,Car>{
	
}

#DriverService.java
public interface DriverServiceInter extends BaseServiceInter<Integer,Driver>{
	
}

#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);
	}
	
}

#BaseService

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);

}


#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方法】
}


相關推薦

基於Spring4+Hibernate4通用資料訪問Dao設計實現

基於泛型的依賴注入。當我們的專案中有很多的Model時,相應的Dao(DaoImpl),Service(ServiceImpl)也會增多。而我們對這些Model的操作很多都是類似的,下面是我舉出的一些(見名知意,其它自行腦補): 1.save 2.saveAll 3.fin

基於架構下的公共資料訪問方法Sqlite資料庫

作者總結了一下,使用Winform的三層架構做窗體應用程式,在資料訪問方面,有用到純sql語句方法、引數方法、儲存過程方法。 那麼什麼是三層架構呢? UI---存放Form窗體---(使用者所關心的) 業務邏輯層----存放業務傳遞(BLL) 資料訪問層----底層的資料處理方法(DAL) 資料公共

應用http協議 httphttps區別

在協議分層的TCP/IP(或四層)通訊協議採用了5層的層級結構,5層分別包括:應用層、傳輸層、網路層、資料鏈路層、物理層。5層一些簡單功能和著名協議可參考這篇部落格:https://blog.csdn.net/sophia__yu/article/details/82717115 一.應用層

【強烈推薦】:關於系統學習資料探勘Data Mining的一些建議

微信公眾號 關鍵字全網搜尋最新排名 【機器學習演算法】:排名第一 【機器學習】:排名第一 【Python】:排名第三 【演算法】:排名第四 關於資料探勘 提到收據挖掘(Data Mining, DM),很多想學習的同學大多數都會問我: 什麼是資料探勘? 怎麼培養資料分析的能力? 如何成為一名資料科學家? (

java資料結構演算法之棧Stack設計實現

關聯文章:   本篇是java資料結構與演算法的第4篇,從本篇開始我們將來了解棧的設計與實現,以下是本篇的相關知識點: 棧的抽象資料型別   棧是一種用於儲存資料的簡單資料結構,有點類似連結串列或者順序表(統稱線性表),棧與線性表的最大區別是

關於音訊PCM資料2位元組16位byte64位double之間的轉換

1 致謝 2 問題描述 今天遇到一個問題 讀取了WAV檔案的PCM資料 PCM資料是以byte[]型別儲存的 而在一般的FFT變換庫函式中一般使用的是浮點型資料 (Youki此處使用的是dou

DeepLearning深度學習原理實現

經過三年的狂刷理論,覺得是時候停下來做些有用的東西了,因此決定開博把他們寫下來,一是為了整理學過的理論,二是監督自己並和大家分享。先從DeepLearning談起吧,因為這個有一定的實用性(大家口頭傳的“和錢靠的很近”大笑),國內各個大牛也都談了不少,我儘量從其他方面解釋一下。

Agora 聲網簡介實現音視訊通話

Agora (聲網)簡介 一個專注移動端的高清實時通話雲服務解決方案。 SD-RTN(Software Defined Real-time Network) SD-RTN(Software Defin

目標檢測Object Detection原理實現(一)

基於閾值影象處理的目標檢測           從今天起開始要寫一些關於目標檢測的文章,涵蓋從簡單的閾值影象處理檢測、霍夫變換(hough transform)檢測、模版匹配檢測(剛體匹配)、AAM+ASM+ACM(非剛體)匹配檢測到近代機器學習方法檢測,儘量貼一些程式碼,

目標檢測Object Detection原理實現(六)

基於形變部件模型(Deformable Part Models)的目標檢測         上節說了基於cascade的目標檢測,cascade的級聯思想可以快速拋棄沒有目標的平滑窗(sliding window),因而大大提高了檢測效率,但也不是沒缺點,缺點就是它僅僅

目標檢測Object Detection原理實現(五)

基於Cascade分類器的目標檢測        從今天開始進入基於機器學習的目標檢測,前幾節雖然也接觸了一些機器學習的方法,但它主要是做輔助工作,機器學習的方法和非機器學習的方法結合在一起使用,說到這想起來前幾天看到一位博士師兄發的笑話,說的是百度實驗室:     

目標檢測Object Detection原理實現

基於形變部件模型(Deformable Part Models)的目標檢測         上節說了基於cascade的目標檢測,cascade的級聯思想可以快速拋棄沒有目標的平滑窗(sliding window),因而大大提高了檢測效率,但也不是沒缺點,缺點就是它僅僅是

影象目標檢測Object Detection原理實現(三)

基於霍夫森林的目標檢測        上節說了霍夫變換(HT)和廣義霍夫變換(GHT),今天就接著廣義霍夫變換說下去,在廣義霍夫變換中,每個投票元素(比如邊緣畫素中的點)在霍夫空間中累加投票的權重是相等的,每個元素投票的權重互不影響,這其實是假設了影象空間中的每個畫

DeepLearning深度學習原理實現

       經過三年的狂刷理論,覺得是時候停下來做些有用的東西了,因此決定開博把他們寫下來,一是為了整理學過的理論,二是監督自己並和大家分享。先從DeepLearning談起吧,因為這個有一定的實用性(大家口頭傳的“和錢靠的很近”),國內各個大牛也都談了不少,我儘量從其他

維諾圖Voronoi Diagram分析實現

一、問題描述 1.Voronoi圖的定義 又叫泰森多邊形或Dirichlet圖,它是由一組由連線兩鄰點直線的垂直平分線組成的連續多邊形組成。 2.Voronoi圖的特點 (1)每個V多邊形內有一個生成元;  (2)每個V多邊形內點到該生成元距離短於到其它生成元距離

影象目標檢測Object Detection原理實現(一)

基於閾值影象處理的目標檢測           從今天起開始要寫一些關於目標檢測的文章,涵蓋從簡單的閾值影象處理檢測、霍夫變換(hough transform)檢測、模版匹配檢測(剛體匹配)、AAM+ASM+ACM(非剛體)匹配檢測到近代機器學習方法檢測,儘量貼一些程式

資料知識工程大作業——goodu搜尋引擎設計實現

前言 很長一段時間沒有寫部落格,因為最近在忙一些學校的事情,在資料知識工程這門課上,老師留了一個大作業,是做一個簡單的搜尋引擎,功能需求如下: 要求: 使用者可指定返回結果數 顯示查詢的響應時間 排序結果中提取文件中包含查詢關鍵詞的片段 支援短語(2單詞)查詢 按照功能的

命令模式Command pattern-- 請求實現的解耦

[align=center][size=x-large]PART 1 請求與實現[/size][/align] [b]什麼叫請求:[/b]使用者選中一行文字,點選複製按鈕,意圖將文字複製到剪貼簿,這個意圖就叫做請求,但具體到程式中,這個請求被具象化為一個複製按鈕

計算機網路- 可靠資料傳輸協議-停等協議的設計實現

一、所實現停等協議簡介 我設計的程式實現的是rdt3.0版本的停等協議,傳送端將資料包以0、1交替的順序傳送資料包,當傳送0資料包之後開始計時,只有接收到ack0才能繼續傳送1資料包,如果在沒有接收到ack0的時候已經超時,這時候需要重傳資料包0; 接收方按照所收到的資料包

寫了個基於sqlhelper和oracleHelper的通用資料訪問

不久前做了個.net平臺上用oracle做後臺資料庫的小b/s,c/s混合專案. 之前做的專案用的是sqlserver資料庫,用的是微軟的sqlhelper作為資料訪問層. 到網上搜索了一遍,沒有找到微軟關於oracle的資料訪問層,下載一個petshop3.0,終於找到了