SSH(二)——實現DAO層和部署DAO層

1.

在Hibernate持久層之上,可使用DAO組件在此封裝數據庫操作,這也是Java EE應用裏常用的DAO模式。當使用DAO模式時,既體現了業務邏輯組件封裝DAO組件的門面模式,也可分離業務邏輯組件和DAO組件的功能:業務邏輯組件負責業務邏輯的變化,而DAO組件負責持久化技術的變化,這正是橋接模式的引用。

2.

引入DAO模式後,每個DAO組件包含了數據庫的訪問邏輯;每個DAO組件可對一個數據庫表完成基本的CRUD操作。

3.

DAO模式的實現至少需要如下三個部分。
    一、DAO工廠類
    二、DAO接口
    三、DAO接口的實現類

4.

DAO模式是一種更符合軟件工程的開發方式,使用DAO模式有如下理由:
    一、DAO模式抽象出數據訪問方式,業務邏輯組件無須理會底層的數據庫訪問細節,而只專注於業務邏輯的實現,業務邏輯組件只負責業務功能的改變。
    二、DAO將數據訪問集中在獨立的一層,所有的數據訪問都由DAO對象完成,這層獨立的DAO分離了數據訪問的實現與其他業務邏輯,使得系統更具可維護性。
    三、DAO還有助於提升系統的可移植性。獨立的DAO層使得系統能在不同的數據庫之間輕易切換,底層的數據庫實現對於業務邏輯是透明的。數據庫移植時僅僅影響DAO層,不同數據庫的切換不會影響業務邏輯組件,因此提高了系統的可複用性。
    四、對於不同的持久層技術,Spring的DAO提供了一個DAO模板,將通用的操作放在模板裏完成,而對於特定的操作,則通過回調接口完成。

5.

幾個通用的方法:
    get(Serializable id);根據主鍵加載持久化實例
    save(Object entity)保存持久化實例
    update(Object entity);更新持久化實例
    delete(Object entity);刪除持久化實例
    delete(Serializable id);根據主鍵刪除持久化實例
    findAll();獲取數據表中全部的持久化實例

6.DAO定義接口
BaseDao.java接口定義如下。

    package org.coolerwu.common.dao;

    import java.io.Serializable;
    import java.util.List;

    public interface BaseDao<T>{

        /**
         * 根據ID加載實體
         */
        T get(Class<T> entityClazz, Serializable id);

        /**
         * 保存實體
         */
        Serializable save(T entity);

        /**
         * 更新實體
         */
        void update(T entity);

        /**
         * 刪除實體
         */
        void delete(T entity);

        /**
         * 根據ID刪除實體
         */
        void delete(Class<T> entityClazz, Serializable id);

        /**
         * 獲取所有實體
         */
        List<T> findAll(Class<T> entityClazz);

        /**
         * 獲取實體總數
         */
        long findCount(Class<T> entityClazz);

        /**
         * 根據HQL語句查詢實體
         */
        List<T> query(String hql);

        /**
         * 根據帶佔位符參數HQL語句查詢實體
         */
        List<T> query(String hql, Object ... args);
    }

EmployeeDao.java接口定義如下。

    package org.coolerwu.mydo.dao;

    import java.util.List;

    import org.coolerwu.common.dao.BaseDao;
    import org.coolerwu.mydo.domain.Employee;

    public interface EmployeeDao extends BaseDao<Employee>{

        /**
         * 
         * @param user 賬號
         * @param password 密碼
         * @return 查詢到返回true,否則false
         */
        List<Employee> queryEmployee(String user, String password);

    }

ManagerDao.java接口定義如下。

    package org.coolerwu.mydo.dao;

    import org.coolerwu.common.dao.BaseDao;
    import org.coolerwu.mydo.domain.Manager;

    public interface ManagerDao extends BaseDao<Manager>{

    }

7.實現DAO組件
BaseDaoImpl.java實現類的源代碼。

    package org.coolerwu.common.dao.impl;

    import java.io.Serializable;
    import java.util.List;

    import org.coolerwu.common.dao.BaseDao;
    import org.hibernate.Query;
    import org.hibernate.SessionFactory;

    public class BaseDaoImpl<T> implements BaseDao<T>{

        /**
         * DAO組件進行持久化操作底層依賴的SessionFactory組件
         */
        private SessionFactory sessionFactory;

        /**
         * 依賴注入SessionFactory所需的setter方法
         * @param sessionFactory
         */
        public void setSessionFactory(SessionFactory sessionFactory) {
            this.sessionFactory = sessionFactory;
        }

        /**
         * 
         * @return
         */
        public SessionFactory getSessionFactory() {
            return sessionFactory;
        }

        @SuppressWarnings("unchecked")
        @Override
        public T get(Class<T> entityClazz, Serializable id) {
            return (T) getSessionFactory().getCurrentSession().get(entityClazz, id);
        }

        @Override
        public Serializable save(T entity) {
            return getSessionFactory().getCurrentSession().save(entity);
        }

        @Override
        public void update(T entity) {
            getSessionFactory().getCurrentSession().saveOrUpdate(entity);
        }

        @Override
        public void delete(T entity) {
            getSessionFactory().getCurrentSession().delete(entity);
        }

        @Override
        public void delete(Class<T> entityClazz, Serializable id) {
            getSessionFactory().getCurrentSession()
                .createQuery("select en from " + entityClazz.getSimpleName() 
                    + " en where en.id = ?0")
                .setParameter("0", id)
                .executeUpdate();
        }

        @Override
        public List<T> findAll(Class<T> entityClazz) {
            return  query("select en from " + entityClazz.getSimpleName() 
                + " en"); 
        }

        @Override
        public long findCount(Class<T> entityClazz) {
            List<?> l = query("select count(*) from " + entityClazz.getSimpleName());

            if(l != null && l.size() == 1)
                return (long)l.get(0);

            return 0;
        }

        @SuppressWarnings("unchecked")
        @Override
        public List<T> query(String hql) {
            return (List<T>)getSessionFactory().getCurrentSession()
                    .createQuery(hql)
                    .list();
        }

        @SuppressWarnings("unchecked")
        @Override
        public List<T> query(String hql, Object... args) {
            Query query = getSessionFactory().getCurrentSession()
                .createQuery(hql);

            for(int i = 0; i < args.length; i++){
                query.setParameter(i + "", args[i]);
            }

            return (List<T>)query.list();
        }

    }

EmployeeDaoImpl.java實現類的源代碼。

    package org.coolerwu.mydo.dao.impl;

    import java.util.List;

    import org.coolerwu.common.dao.impl.BaseDaoImpl;
    import org.coolerwu.mydo.dao.EmployeeDao;
    import org.coolerwu.mydo.domain.Employee;

    public class EmployeeDaoImpl extends BaseDaoImpl<Employee> implements EmployeeDao{

        @Override
        public List<Employee> queryEmployee(String user, String password) {

            List<Employee> l = query("select a from Employee as a where a.user = ?0 "
                    + "and a.password = ?1", user, password);

            return l;
        }

    }

ManagerDaoImpl.java實現類的源代碼。

    package org.coolerwu.mydo.dao.impl;

    import org.coolerwu.common.dao.impl.BaseDaoImpl;
    import org.coolerwu.mydo.dao.ManagerDao;
    import org.coolerwu.mydo.domain.Manager;

    public class ManagerDaoImpl extends BaseDaoImpl<Manager> implements ManagerDao{

    }

8.部署DAO層
1.DAO組件運行的基礎

    應用的DAO組件以Hibernate和Spring爲基礎,由Spring容器負責生成並管理DAO組件。Spring容器複製爲DAO組件注入所需要的基礎SessionFactory。

daoContext.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:aop="http://www.springframework.org/schema/aop"
            xmlns:p="http://www.springframework.org/schema/p"
            xmlns:tx="http://www.springframework.org/schema/tx"
            xsi:schemaLocation="http://www.springframework.org/schema/beans 
            http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
            http://www.springframework.org/schema/tx 
            http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
            http://www.springframework.org/schema/aop 
            http://www.springframework.org/schema/aop/spring-aop-4.0.xsd">

            <!-- 定義數據源Bean,使用C3P0數據源實現 -->
            <!-- 並設置連接數據庫的驅動、URL、用戶名、密碼,
            連接池最大連接數、最小連接數、初始連接數等參數  -->
            <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
                destroy-method="close" 
                p:driverClass="com.mysql.jdbc.Driver"
                p:jdbcUrl="jdbc:mysql://localhost:3306/test?useSSL=false" 
                p:user="root"
                p:password="wulang" 
                p:maxPoolSize="200" 
                p:minPoolSize="2"
                p:initialPoolSize="2" 
                p:maxIdleTime="20" />

            <!-- 定義Hibernate的SessionFactory,並依賴注入數據源,注入上面定義的dataSource -->
            <bean id="sessionFactory"
                class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"
                p:dataSource-ref="dataSource" >
                <!-- annotatedClasses屬性用於列出全部持久化類 -->
                <property name="annotatedClasses">
                    <list>
                        <value>org.coolerwu.mydo.domain.Employee</value>
                        <value>org.coolerwu.mydo.domain.Manager</value>
                    </list>
                </property>
                <!-- 定義Hibernate的SessionFactory的屬性 -->
                <property name="hibernateProperties">
                    <!-- 指定數據庫方言、是否自動建表、是否生成SQL語句等  -->
                    <value>
                        hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
                        hibernate.hbm2ddl.auto=update
                        hibernate.show_sql=true
                        hibernate.format_sql=true
                        #開啓二級緩存
                        hibernate.cache.use_second_level_cache=true
                        #設置二級緩存的提供者
                        hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.EhCacheRegionFactory
                    </value>
                </property>
            </bean>

            <!-- 配置DAO組件的模板 -->
            <bean id="daoTemplate" abstract="true" lazy-init="true"
                p:sessionFactory-ref="sessionFactory"/>

            <bean id="employeeDao" class="org.coolerwu.mydo.dao.impl.EmployeeDaoImpl"
                parent="daoTemplate"/>

            <bean id="managerDao" class="org.coolerwu.mydo.dao.impl.ManagerDaoImpl"
                parent="daoTemplate"/>      

        </beans>

配置文件先配置了一個DAO組件的模板,配置文件爲改模板注入量SessionFactory,而其他DAO組件都繼承了該DAO模板,因此,其他實際的DAO組件也會被注入SessionFactory對象。系統的各具體DAO組件實現類中並未提供setSessionFactory()方法,該方法由其父類BaseDaoImpl提供,用於依賴注入SessionFactory對象。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章