• ExtJS实战(3)spring


    上一篇文章我们看到了hibernate的作用,但是我们并没有贴出具体的数据访问层的代码,这是因为我们既然要使用这么多框架,当然就希望它们能够“黏合”的很好,譬如,我们不想使用代码处理事务,也就是说想使用声明式事务。这当然就是Spring大显身手的地方了。我们来看一看数据访问层的代码,还是面向接口编程:

    1.下面是一个接口,它告诉外界可以做哪些事情,譬如按条件分页查询房屋信息,增加,修改,删除房屋信息,得到符合条件的房屋总数等!

    package org.leno.houseHire.dao;

    import java.util.List;

    import org.leno.houseHire.action.Condition;

    import org.leno.houseHire.dao.House;

    public interface IHouseDAO {

        public List<House> findAllHouse(Condition cond,final int start ,final int limit);

        public House findById(int id);

        public void addHouse(House house);

        public void editHouse(House house);

        public int delHouse(List<String> ids);

        public long getTotalNums(Condition cond);

        public List<Area> getAllAreas();

        public List<Street> getAllStreets(int aid);

        public String getAreaNameById(int id);

        public String getStreetNameById(int id);

        public User getUserById(int id);

        public Street getStreetById(int id);

    }

    2.下面是一个利用Hibernate访问数据库的DAO实现,我们看到,它还继承了HibernateDaoSupport这个类,这是Spring对Hibernate提供的一个帮助支持类,它不仅封装了Hiberntate的实现,还对Hibernate操作涉及的事务进行统一管理。

    package org.leno.houseHire.dao;

    import java.sql.SQLException;

    import java.text.ParseException;

    import java.text.SimpleDateFormat;

    import java.util.ArrayList;

    import java.util.Date;

    import java.util.List;

    import org.hibernate.Criteria;

    import org.hibernate.HibernateException;

    import org.hibernate.Query;

    import org.hibernate.Session;

    import org.hibernate.criterion.Order;

    import org.hibernate.criterion.Projections;

    import org.hibernate.criterion.Restrictions;

    import org.leno.houseHire.action.Condition;

    import org.leno.houseHire.dao.House;

    import org.springframework.orm.hibernate3.HibernateCallback;

    import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

    public class HouseDAOImpl extends HibernateDaoSupport implements IHouseDAO {

        public void addHouse(House house) {

            getHibernateTemplate().save(house);

        }

        public void editHouse(House house) {

            getHibernateTemplate().update(house);

        }

        @SuppressWarnings("unchecked")

        public List<House> findAllHouse(Condition cond, final int start,

                final int limit) {

            final String title = cond.getTitle();

            final int room = cond.getRoom();

            final int ting = cond.getTing();

            final int areaId = cond.getAreaId();

            final int streetId = cond.getStreetId();

            final double priceStart = cond.getPriceStart();

            final double priceEnd = cond.getPriceEnd();

            final String booktime = cond.getBooktime();

            final String sort = cond.getSortCond();

            // 更通用可以换成DetachedCriteria

            return (List<House>) getHibernateTemplate().execute(

                    new HibernateCallback() {

                        public Object doInHibernate(Session session)

                                throws HibernateException, SQLException {

                            Criteria cr = session.createCriteria(House.class)

                                    .setFirstResult(start).setMaxResults(limit);

                            if (title != null && !title.trim().equals("")) {

                                cr.add(Restrictions

                                        .like("title", "%" + title + "%"));

                            }

                            if (room != 0) {

                                cr.add(Restrictions.eq("room", room));

                            }

                            if (ting != 0) {

                                cr.add(Restrictions.eq("ting", ting));

                            }

                            if (streetId == 0) {

                                if (areaId != 0) {

                                    cr.createCriteria("street").createCriteria(

                                            "area").add(

                                            Restrictions.eq("aid", areaId));

                                }

                            }

                            if (streetId != 0) {

                                cr.createCriteria("street").add(

                                        Restrictions.eq("sid", streetId));

                            }

                            if (priceEnd > 0) {

                                cr.add(Restrictions.between("hireprice",

                                        priceStart, priceEnd));

                            }

                            if (booktime != null && !booktime.trim().equals("")) {

                                String sda = booktime + " " + "00:00:00";

                                String eda = booktime + " " + "23:59:59";

                                SimpleDateFormat sdf = new SimpleDateFormat(

                                        "yyyy-MM-dd HH:mm:ss");

                                try {

                                    Date start_date = sdf.parse(sda);

                                    Date end_date = sdf.parse(eda);

                                    cr.add(Restrictions.between("booktime",

                                            start_date, end_date));

                                } catch (ParseException e) {

                                    // TODO Auto-generated catch block

                                    e.printStackTrace();

                                }

                            }

                            if (sort != null && sort.equals("desc")) {

                                cr.addOrder(Order.desc("booktime"));

                            }

                            List<House> list = cr.list();

                            return list;

                        }

                    });

        }

        /**

         * 在Hibernate3中,对Criteria又增添了新功能,可以支持分组与统计功能,在Hibernate3中增加了Projections以及ProjectionList类,这两个类对分组与统计功能进行了封装

         */

        public long getTotalNums(Condition cond) {

            final String title = cond.getTitle();

            final int room = cond.getRoom();

            final int ting = cond.getTing();

            final int areaId = cond.getAreaId();

            final int streetId = cond.getStreetId();

            final double priceStart = cond.getPriceStart();

            final double priceEnd = cond.getPriceEnd();

            final String booktime = cond.getBooktime();

            return (Integer) getHibernateTemplate().execute(

                    new HibernateCallback() {

                        public Object doInHibernate(Session session)

                                throws HibernateException, SQLException {

                            Criteria cr = session.createCriteria(House.class);

                            if (title != null && !title.trim().equals("")) {

                                cr.add(Restrictions

                                        .like("title", "%" + title + "%"));

                            }

                            if (room != 0) {

                                cr.add(Restrictions.eq("room", room));

                            }

                            if (ting != 0) {

                                cr.add(Restrictions.eq("ting", ting));

                            }

                            if (streetId == 0) {

                                if (areaId != 0) {

                                    cr.createCriteria("street").createCriteria(

                                            "area").add(

                                            Restrictions.eq("aid", areaId));

                                }

                            }

                            if (streetId != 0) {

                                cr.createCriteria("street").add(

                                        Restrictions.eq("sid", streetId));

                            }

                            if (priceEnd > 0) {

                                cr.add(Restrictions.between("hireprice",

                                        priceStart, priceEnd));

                            }

                            if (booktime != null && !booktime.trim().equals("")) {

                                String sda = booktime + " " + "00:00:00";

                                String eda = booktime + " " + "23:59:59";

                                SimpleDateFormat sdf = new SimpleDateFormat(

                                        "yyyy-MM-dd HH:mm:ss");

                                try {

                                    Date start_date = sdf.parse(sda);

                                    Date end_date = sdf.parse(eda);

                                    cr.add(Restrictions.between("booktime",

                                            start_date, end_date));

                                } catch (ParseException e) {

                                    // TODO Auto-generated catch block

                                    e.printStackTrace();

                                }

                            }

                            // return cr.list().size();

                            cr.setProjection(Projections.count("hid"));

                            return cr.uniqueResult();

                        }

                    });

        }

        @SuppressWarnings("unchecked")

        public List<House> findAllHouse2(Condition cond, final int start,

                final int limit) {

            String hql = "select h from House h where 1=1";

            String title = cond.getTitle();

            int room = cond.getRoom();

            int ting = cond.getTing();

            int areaId = cond.getAreaId();

            int streetId = cond.getStreetId();

            double priceStart = cond.getPriceStart();

            double priceEnd = cond.getPriceEnd();

            String booktime = cond.getBooktime();

            String sort = cond.getSortCond();

            if (title != null && !title.trim().equals("")) {

                hql = hql + " and h.title like '%" + title + "%'";

            }

            if (room != 0) {

                hql = hql + " and h.room=" + room;

            }

            if (ting != 0) {

                hql = hql + " and h.ting=" + ting;

            }

            if (areaId != 0) {

                hql = hql + " and h.street.area.aid=" + areaId;

            }

            if (streetId != 0) {

                hql = hql + " and h.street.sid=" + streetId;

            }

            if (priceEnd > 0) {

                hql = hql + " and h.hireprice between " + priceStart + " and "

                        + priceEnd;

            }

            if (booktime != null && !booktime.trim().equals("")) {

                // 用到sqlserver日期转化成字符串的函数

                hql = hql + " and  convert(char,h.booktime,23)='" + booktime + "'";

            }

            if (sort != null && sort.equals("desc")) {

                hql = hql + " order by h.booktime desc";

            }

            System.out.println(hql);

            final String finalHql = hql;

            // Spring的HibernateTemplate提供了Hibernate的完美封装,即通过匿名类实现回调,来保证Session的自动资源管理和事务的管理。

            return (List<House>) getHibernateTemplate().execute(

                    new HibernateCallback() {

                        public Object doInHibernate(Session session)

                                throws HibernateException, SQLException {

                            Query query = session.createQuery(finalHql)

                                    .setFirstResult(start).setMaxResults(limit);

                            return query.list();

                        }

                    });

        }

        public long getTotalNums2(Condition cond) {

            String hql = "select count(h) from House h where 1=1";

            String title = cond.getTitle();

            int room = cond.getRoom();

            int ting = cond.getTing();

            int areaId = cond.getAreaId();

            int streetId = cond.getStreetId();

            double priceStart = cond.getPriceStart();

            double priceEnd = cond.getPriceEnd();

            String booktime = cond.getBooktime();

            if (title != null && !title.trim().equals("")) {

                hql = hql + " and h.title like '%" + title + "%'";

            }

            if (room != 0) {

                hql = hql + " and h.room=" + room;

            }

            if (ting != 0) {

                hql = hql + " and h.ting=" + ting;

            }

            if (areaId != 0) {

                hql = hql + " and h.street.area.aid=" + areaId;

            }

            if (areaId != 0) {

                hql = hql + " and h.street.area.aid=" + areaId;

            }

            if (streetId != 0) {

                hql = hql + " and h.street.sid=" + streetId;

            }

            if (priceEnd > 0) {

                hql = hql + " and h.hireprice between " + priceStart + " and "

                        + priceEnd;

            }

            if (booktime != null && !booktime.trim().equals("")) {

                // 用到sqlserver日期转化成字符串的函数

                hql = hql + " and  convert(char,h.booktime,23)='" + booktime + "'";

            }

            System.out.println(hql);

            final String finalHql = hql;

            return (Long) getHibernateTemplate().execute(new HibernateCallback() {

                public Object doInHibernate(Session session)

                        throws HibernateException, SQLException {

                    return session.createQuery(finalHql).uniqueResult();

                }

            });

        }

        @SuppressWarnings("unchecked")

        public List<Area> getAllAreas() {

            return (List<Area>) getHibernateTemplate().execute(

                    new HibernateCallback() {

                        public Object doInHibernate(Session session)

                                throws HibernateException, SQLException {

                            Query query = session.createQuery("from Area");

                            return query.list();

                        }

                    });

        }

        @SuppressWarnings("unchecked")

        public List<Street> getAllStreets(final int aid) {

            return (List<Street>) getHibernateTemplate().execute(

                    new HibernateCallback() {

                        public Object doInHibernate(Session session)

                                throws HibernateException, SQLException {

                            Query query = session.createQuery(

                                    "from Street s  where s.area.aid=?")

                                    .setInteger(0, aid);

                            return query.list();

                        }

                    });

        }

        public int delHouse(List<String> ids) {

            int len = 0;

            if (ids == null || ids.size() == 0) {

                return len;

            }

            len = ids.size();

            System.out.println("del........" + len);

            List<House> list = new ArrayList<House>();

            for (int i = 0; i < len; i++) {

                House house = findById(Integer.parseInt(ids.get(i)));

                list.add(house);

            }

            getHibernateTemplate().deleteAll(list);

            return len;

        }

        public House findById(int id) {

            House house = (House) getHibernateTemplate().get(House.class, id);

            return house;

        }

        public String getAreaNameById(int id) {

            return ((Area) getHibernateTemplate().get(Area.class, id)).getAname();

        }

        public String getStreetNameById(int id) {

            return getStreetById(id).getSname();

        }

        public Street getStreetById(int id) {

            return (Street) getHibernateTemplate().get(Street.class, id);

        }

        public User getUserById(int id) {

            return (User) getHibernateTemplate().get(User.class, id);

        }

    }

           上面的DAO实现代码非常重要,因为数据库的操作就靠它了。对于复杂的表单查询,我这里使用了些技巧,大家可以借鉴。一个是将所有的查询条件封装成了一个Condition类,这样接口中复杂查询方法的设计就很简洁。再就是我提供了拼凑HQL和QBC两种查询的实现,大家可以对比一下,特别是对于日期字段,这两种方式是如何处理的,好好参考一下。每个框架基本上都有自己核心的基于XML格式的配置文件,我们来看看Spring的核心配置文件:

    <?xml version="1.0" encoding="UTF-8"?>

    <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

    <beans>

        <bean id="sessionFactory"

            class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">

            <property name="configLocation"

                value="classpath:hibernate.cfg.xml">

            </property>

        </bean>

        <!-- Hibernate 事务管理  -->

        <bean id="transactionManager"

            class="org.springframework.orm.hibernate3.HibernateTransactionManager">

            <property name="sessionFactory" ref="sessionFactory" />

        </bean>

        <bean id="baseTransactionProxy"

            class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"

            abstract="true">

            <property name="transactionManager" ref="transactionManager" />

            <property name="transactionAttributes">

                <props>

                    <prop key="persist*">

                        PROPAGATION_REQUIRED,-Exception

                    </prop>

                    <prop key="remove*">

                        PROPAGATION_REQUIRED,-Exception

                    </prop>

                    <prop key="insert*">PROPAGATION_REQUIRED</prop>

                    <prop key="save">PROPAGATION_REQUIRED</prop>

                    <prop key="update*">PROPAGATION_REQUIRED</prop>

                    <prop key="edit*">PROPAGATION_REQUIRED</prop>

                    <prop key="del*">PROPAGATION_REQUIRED</prop>

                    <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>

                    <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>

                    <prop key="query*">PROPAGATION_REQUIRED,readOnly</prop>

                    <prop key="disPlay*">PROPAGATION_REQUIRES_NEW</prop>

                </props>

            </property>

        </bean>

       

        <!-- login module -->

        <bean name="/login" class="org.leno.houseHire.action.LoginAction">

            <property name="loginService" ref="loginService"></property>

        </bean>

        <bean id="loginService"

            class="org.leno.houseHire.service.LoginServiceImpl">

            <property name="loginDAO" ref="loginDAO"></property>

        </bean>

        <bean id="loginDAO" class="org.leno.houseHire.dao.LoginDAOImpl">

            <property name="sessionFactory" ref="sessionFactory"></property>

        </bean>

    <!-- hosue module -->

       

        <bean name="/house" class="org.leno.houseHire.action.HouseSearchAction" lazy-init="true"

            singleton="true">

        <property name="houseService">

        <ref bean="houseService"/>

        </property>

        </bean>

       

         <bean name="/houseExport" class="org.leno.houseHire.action.HouseExportAction">

         <property name="houseService">

        <ref bean="houseService"/>

        </property>

        </bean> 

       

        <bean name="/houseHandler" class="org.leno.houseHire.action.HouseHandlerAction" lazy-init="true"

            singleton="true">

        <property name="houseService">

        <ref bean="houseService"/>

        </property>

        </bean>

        <bean id="houseServiceTarget" class="org.leno.houseHire.service.HouseServiceImpl" >

        <property name="houseDAO">

        <ref bean="houseDAO"/>

        </property>

        </bean>

        <bean id="houseService" parent="baseTransactionProxy">

            <property name="target">

            <ref bean="houseServiceTarget"/>

            </property>

            </bean>

        <bean id="houseDAO" class="org.leno.houseHire.dao.HouseDAOImpl" lazy-init="true"

            singleton="true">

        <property name="sessionFactory">

        <ref bean="sessionFactory"/>

        </property>

        </bean>

        </beans>

    我们可以看到,在上面IOC和AOP的概念都得到了强有力的体现。怎么说呢?上面所有bean以及bean之间的依赖关系都是由Spring的IOC容器来管理的,譬如我们上面主要配置了四种bean:Action->Service->DAO->SessionFactory,后面的bean做前面bean的属性,也就是前面的bean依赖于后面的bean,而我们在代码中使用前面bean实例的时候,是不需要主动去寻找所依赖的后面bean的实例的,因为容器已经帮我们把依赖关系设置好了。这就是IOC(也叫DI,依赖注入),那么,AOP是怎么体现的呢?大家仔细分析上面的配置,我们发现Service除了有一个目标对象houseServiceTarget,还有一个代理对象houseService,而在Action里我们使用的是代理对象。咿,我们为什么要做这样一个代理对象呢?回想我们前面提到的事务管理,哦,明白了。Spring对Service层中的方法做了声明式事务管理。也就是说,当Service层调用DAO层对数据库进行操作时,根本不需要显式地写JAVA代码来开启或提交事务,而只需要利用Spring的配置文件就可以将Service层中的方法调用置身在事务管理中!嘿,这是一个非常强大的信号!有了AOP,意味这以后我们可以将一些系统级的服务,譬如日志处理,性能监控,安全管理,异常处理,事务管理等都单独地抽离处理,当业务模块需要这些服务的时候,我们要做的并不是修改代码,而是修改配置文件!这样,我们就可以做出更加松耦合的应用!

  • 相关阅读:
    Java 9将采用新的版本字符串格式
    Hadoop单机伪分布式
    Hadoop JAVA 开发说明
    Java 批量插入数据(Oracle)
    Myeclipse 的hadoop环境搭建
    [LeetCode] 136. Single Number 单独数
    [LeetCode] 89. Gray Code 格雷码
    [LeetCode] 209. Minimum Size Subarray Sum 最短子数组之和
    [LeetCode] 211. Add and Search Word
    [LeetCode] 152. Maximum Product Subarray 求最大子数组乘积
  • 原文地址:https://www.cnblogs.com/hannover/p/1563656.html
Copyright © 2020-2023  润新知