SSH的Dao层封装

来源:互联网 发布:信捷plc的编程方法 编辑:程序博客网 时间:2024/06/05 04:13

一、先来看代码


1.准备好所需要的Jar包

antlr-2.7.6.jar
aopalliance-1.0.jar
c3p0-0.9.1.2.jar
commons-collections-3.2.1.jar
commons-logging.jar
dom4j-1.6.1.jar
ejb3-persistence.jar
hibernate-jpa-2.0-api-1.0.0.Final.jar
hibernate3.jar
javassist-3.11.0.GA.jar
jta-1.1.jar
ojdbc6.jar
slf4j-api-1.6.1.jar
spring-aop-3.2.4.RELEASE.jar
spring-beans-3.2.4.RELEASE.jar
spring-context-3.2.4.RELEASE.jar
spring-core-3.2.4.RELEASE.jar
spring-expression-3.2.4.RELEASE.jar
spring-jdbc-3.2.4.RELEASE.jar
spring-orm-3.2.4.RELEASE.jar
spring-tx-3.2.4.RELEASE.jar

2.准备数据库

create table USER_INFO(id number(8,0) primary key,USERNAME varchar2(32),PASSWORD varchar2(32));

3.配置Spring配置文件

<?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"    xmlns:aop="http://www.springframework.org/schema/aop"     xmlns:tx="http://www.springframework.org/schema/tx"    xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-3.2.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-3.2.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsdhttp://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">    <context:component-scan base-package="net.csdn" />    <bean id="datasource" class="com.mchange.v2.c3p0.ComboPooledDataSource"        destroy-method="close">        <property name="driverClass" value="oracle.jdbc.driver.OracleDriver" />        <property name="jdbcUrl" value="jdbc:oracle:thin:@localhost:1521:orcl" />        <property name="user" value="CNDS" />        <property name="password" value="CNDS" />        <property name="autoCommitOnClose" value="true" />        <property name="checkoutTimeout" value="10000" />        <property name="initialPoolSize" value="10" />        <property name="minPoolSize" value="3" />        <property name="maxPoolSize" value="20" />        <property name="maxIdleTime" value="30000" />        <property name="acquireIncrement" value="3" />        <property name="maxIdleTimeExcessConnections" value="1800" />    </bean>    <bean id="sessionFactory"        class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">        <property name="dataSource" ref="datasource" />        <property name="packagesToScan">            <list>                <value>net.csdn.model</value>            </list>        </property>        <property name="hibernateProperties">            <value>                hibernate.dialect=org.hibernate.dialect.OracleDialect            </value>        </property>    </bean>    <bean id="txManager"        class="org.springframework.orm.hibernate3.HibernateTransactionManager">        <property name="sessionFactory" ref="sessionFactory" />    </bean>    <tx:annotation-driven transaction-manager="txManager" /></beans>

4.准备对应的实体类

package net.csdn.model;import javax.persistence.Entity;import javax.persistence.Id;import javax.persistence.Table;import org.springframework.stereotype.Component;/** * 对应数据库中的USER_INFO表的实体类 * @author Bowen * */@Entity@Table(name="USER_INFO")@Component("userInfoEntity")public class UserInfoEntity {    /** ********** 成员变量 ********** **/    //映射表中的id字段    private int id;    //映射表中的username字段    private String username;    //映射表中的password字段    private String password;    /** ********** Get方法 ********** **/    @Id    public int getId() {        return id;    }    public String getUsername() {        return username;    }    public String getPassword() {        return password;    }    /** ********** Set方法 ********** **/    public void setId(int id) {        this.id = id;    }    public void setUsername(String username) {        this.username = username;    }    public void setPassword(String password) {        this.password = password;    }}

5.设计Dao层通用类的接口

package net.csdn.dao.inter;import java.io.Serializable;import java.util.List;import java.util.Map;/** * 封装的Dao层通用的接口 这里用到了泛型 *  * @author Bowen *  * @param <T> */public interface CommonlyDaoInter<T> {    /**     * 保存     *      * @param entity     */    public void save(T entity);    /**     * 根据主键删除     *      * @param ids     */    public void deleteByIds(Serializable... ids);    /**     * 根据集合删除     *      * @param list     */    public void deleteByList(List<T> list);    /**     * 修改     *      * @param entity     */    public void update(T entity);    /**     * 更具主键查询     *      * @param id     * @return     */    public T queryById(Serializable id);    /**     * 查询全部     *      * @return     */    public List<T> queryAll();    /**     * 根据条件查询 并且按照指定的排序方式排序     *      * @param condition     * @param params     * @param orderby     * @return     */    public List<T> queryCondition(String condition, Object[] params,            Map<String, String> orderby);    /**     * 分页查询全部     *      * @param offset     * @param length     * @return     */    public List<T> queryAllPage(int offset, int length);}

6.设计Dao层通用实现类的常用功能

package net.csdn.dao.impl;import java.io.Serializable;import java.lang.reflect.ParameterizedType;import java.lang.reflect.Type;import java.sql.SQLException;import java.util.List;import java.util.Map;import javax.annotation.Resource;import org.hibernate.HibernateException;import org.hibernate.Query;import org.hibernate.SessionFactory;import org.springframework.orm.hibernate3.HibernateCallback;import org.springframework.orm.hibernate3.support.HibernateDaoSupport;import net.csdn.dao.inter.CommonlyDaoInter;/** * 封装Dao层的实现类 *  * @author Bowen *  * @param <T> */public class CommonlyDaoImpl<T> extends HibernateDaoSupport implements        CommonlyDaoInter<T> {    /**     * 注入SessionFactory     *      * @param sessionFactory     */    @Resource(name = "sessionFactory")    public final void setSessionFactoryDi(SessionFactory sessionFactory) {        this.setSessionFactory(sessionFactory);    }    /**     * 保存方法     */    @Override    public void save(T entity) {        this.getHibernateTemplate().save(entity);    }    /**     * 利用可变参数的形式来达到可以根据id同时删除一个或多个对象的目的 这里参数的类型为Serializable     */    @Override    public void deleteByIds(Serializable... ids) {        if (ids != null && ids.length > 0) {            for (Serializable key : ids) {                Object entity = this.queryById(key);                if (entity != null) {                    this.getHibernateTemplate().delete(entity);                }            }        }    }    /**     * 通过集合来删除多个对象 这种方法是为了便于使用deleteAll()方法     */    @Override    public void deleteByList(List<T> list) {        this.getHibernateTemplate().deleteAll(list);    }    /**     * 更新方法     */    @Override    public void update(T entity) {        this.getHibernateTemplate().update(entity);    }    /**     * 这是一个获取当前元素真实类的方法 原理是通过反射机制 在下面的各项查找方法中都有应用     *      * @return     */    @SuppressWarnings({ "rawtypes" })    public Class getEntityClass() {        Type type = this.getClass().getGenericSuperclass();        ParameterizedType pt = (ParameterizedType) type;        return (Class) pt.getActualTypeArguments()[0];    }    /**     * 根据Id查找对象是最为应用普遍的     */    @SuppressWarnings("unchecked")    public T queryById(Serializable id) {        return (T) this.getHibernateTemplate().get(this.getEntityClass(), id);    }    /**     * 查找所有对象     */    @SuppressWarnings("unchecked")    @Override    public List<T> queryAll() {        // 注意这里的from后面一定要多加一个空格        return this.getHibernateTemplate().find(                "from " + this.getEntityClass().getName());    }    /**     * 根据条件查找多个对象并按照一定规则排序 这个方法拼接了一个HQL语句,要注意HQL语句的格式 参数介绍 String condition     * 是预设的筛选条件的属性名 Object[] params 是对应预设的筛选条件的属性值,这里设置为Object数组是为了方便传参     * Map<String, String> orderby 是存储设置的排序方式的信息的Map集合     */    @SuppressWarnings("unchecked")    @Override    public List<T> queryCondition(String condition, Object[] params,            Map<String, String> orderby) {        // 编写的HQL语句头部        // 这里要注意where后面的1=1属性        // 之所以设置这样一个属性是为了保证语HQL语句的完整性        String hqlHead = "from " + this.getEntityClass().getName()                + " where 1=1 ";        // 创建一个StringBuffer用来存储遍历Map的数据        StringBuffer buffer = new StringBuffer("");        // 判断Map是否为空        if (orderby != null && orderby.size() > 0) {            // 向StringBuffer添加 order by 字符串用于设置排序            buffer.append(" order by ");            // 遍历Map            for (Map.Entry<String, String> map : orderby.entrySet()) {                buffer.append(" " + map.getKey() + " " + map.getValue() + ",");            }            // 遍历Map之后要删除最后一个逗号            buffer.deleteCharAt(buffer.length() - 1);        }        // 拼接成完整的HQL语句        String wholeHql = hqlHead + condition + buffer.toString();        // 执行查询        return this.getHibernateTemplate().find(wholeHql, params);    }    /**     * 分页查询 参数介绍 final int offset 起始查询的位置,从0开始 final int length 查询的步长     */    @SuppressWarnings({ "unchecked", "rawtypes" })    @Override    public List<T> queryAllPage(final int offset, final int length) {        // 获取类的名字        final String className = this.getEntityClass().getName();        return this.getHibernateTemplate().executeFind(new HibernateCallback() {            public Object doInHibernate(org.hibernate.Session session)                    throws HibernateException, SQLException {                Query query = session.createQuery("from " + className);                query.setFirstResult(offset);                query.setMaxResults(length);                return query.list();            }        });    }}

7.创建对应实体类的Dao层操作接口

package net.csdn.dao.inter;import net.csdn.model.UserInfoEntity;/** * 这里要注意定义Dao层接口的时候要继承通用Dao接口 * 并且要在原有的泛型位置上传入对应的实体类 * @author Bowen * */public interface UserInfoDaoInter extends CommonlyDaoInter<UserInfoEntity>{}

8.创建对应实体类的Dao层实现类

package net.csdn.dao.impl;import org.springframework.stereotype.Component;import net.csdn.dao.inter.UserInfoDaoInter;import net.csdn.model.UserInfoEntity;/** * 定义Dao层实现类实现了对应的接口 * 并且继承Dao层的通用实现类,同样也要在原有的泛型上传入对应的实体类 * @author Bowen * */@Component("userInfoDaoImpl")public class UserInfoDaoImpl extends CommonlyDaoImpl<UserInfoEntity> implements UserInfoDaoInter{}

9.创建测试类

package net.csdn.test;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import net.csdn.dao.inter.UserInfoDaoInter;import net.csdn.model.UserInfoEntity;import org.junit.Before;import org.junit.Test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;/** * 测试类 通过Junit单元测试功能来实现测试 *  * @author Bowen *  */public class TestClass {    private ApplicationContext context;    private UserInfoEntity userInfoEntity;    private UserInfoDaoInter userInfoDaoInter;    /**     * 在测试前先注入     */    @Before    public void init() {        context = new ClassPathXmlApplicationContext("applicationContext.xml");        userInfoEntity = (UserInfoEntity) context.getBean("userInfoEntity");        userInfoDaoInter = (UserInfoDaoInter) this.context                .getBean("userInfoDaoImpl");    }    /**     * 测试保存     */    @Test    public void testSave() {        for (int i = 10000; i < 10010; i++) {            this.userInfoEntity.setId(i);            this.userInfoEntity.setUsername("cnds");            this.userInfoEntity.setPassword("cnds");            this.userInfoDaoInter.save(userInfoEntity);        }    }    /**     * 测试根据ID删除     */    @Test    public void testDeleteByIds() {        this.userInfoDaoInter.deleteByIds(10000, 10001);    }    /**     * 测试根据集合删除     */    @Test    public void testDeleteByList() {        // 创建一个集合        List<UserInfoEntity> list = new ArrayList<UserInfoEntity>();        // 获取Id为10002的数据        this.userInfoEntity = this.userInfoDaoInter.queryById(10002);        // 向集合添加数据        list.add(this.userInfoEntity);        // 获取Id为10003的数据        this.userInfoEntity = this.userInfoDaoInter.queryById(10003);        // 向集合添加数据        list.add(this.userInfoEntity);        // 删除数据        this.userInfoDaoInter.deleteByList(list);    }    /**     * 测试更新数据     */    @Test    public void testUpate() {        // 获取原有数据        this.userInfoEntity = this.userInfoDaoInter.queryById(10004);        System.out.println("更新前用户名:" + this.userInfoEntity.getUsername());        this.userInfoEntity.setUsername("cnds.net");        // 更新数据        this.userInfoDaoInter.update(this.userInfoEntity);        // 查看更新后的数据        this.userInfoEntity = this.userInfoDaoInter.queryById(10004);        System.out.println("更新后用户名:" + this.userInfoEntity.getUsername());    }    /**     * 测试根据ID查询     */    @Test    public void testQueryById() {        this.userInfoEntity = this.userInfoDaoInter.queryById(10004);        System.out.println("更新前用户名:" + this.userInfoEntity.getUsername());    }    /**     * 测试查询所有     */    @Test    public void testQueryAll() {        List<UserInfoEntity> list = this.userInfoDaoInter.queryAll();        for (UserInfoEntity userInfo : list) {            System.out.println("用户名:" + userInfo.getUsername());        }    }    /**     * 测试根据条件查询     */    @Test    public void testQueryCondition() {        // 这里注意设置条件的时候一定要加有and        String condition = " and username=? ";        Object[] params = { "cnds.net" };        Map<String, String> orderby = new HashMap<String, String>();        orderby.put(" id ", " DESC ");        List<UserInfoEntity> list = this.userInfoDaoInter.queryCondition(                condition, params, orderby);        for (UserInfoEntity userInfo : list) {            System.out.println("用户名:" + userInfo.getUsername());        }    }    /**     * 测试分页查询     */    @Test    public void testQueryAllPage() {        for (int i = 0; i < 10; i++) {            List<UserInfoEntity> list = this.userInfoDaoInter.queryAllPage(                    i * 2, 2);            if (list.size() == 0) {                break;            } else {                System.out.println("第 " + (i + 1) + " 页");                for (UserInfoEntity userInfo : list) {                    System.out.println(userInfo.getUsername());                }            }        }    }}

10.最终目录结构图

SSH的Dao层封装目录结构图

二 、原理分析与实际应用

这种封装的好处能够大大的解决了Dao层代码的重复性。因为在Dao层中基本都是增删改查的操作。所以代码重复性很高。通过继承和泛型的应用来实现一劳永逸的方法

Created with Raphaël 2.1.0UserInfoDaoImplUserInfoDaoImplUserInfoDaoInterUserInfoDaoInterCommonlyDaoImplCommonlyDaoImplCommonlyDaoInterCommonlyDaoInter实现(implements)继承(extends)实现(implements)继承(extends)
1 0
原创粉丝点击