DAO的设计模式

来源:互联网 发布:软件开发报价方案模板 编辑:程序博客网 时间:2024/05/17 18:19

在我们做J2EE应用,或者其他的Java web 项目,基于SSH的MVC设计,我们都会提到DAO这个概念,那么DAO到底是什么?他能做什么?他是怎么实现的?下面我们就围绕这三个方面来了解一下DAO。前面我们进行了数据库的连接。JDBCTools

1.什么是DAO?

DAO:数据访问接口(Data Access Object)。顾名思义就是与数据库打交道。夹在业务逻辑与数据库资源中间。(百度百科)他是一个面向对象的数据库接口。DAO可以被子类继承或直接使用

2.他能做什么?

  DAO模式是标准的J2EE设计模式之一.开发人员使用这个模式把底层的数据访问操作和上层的商务逻辑分开. 实现功能的模块化 访问数据信息的类,包含了对数据的CRUD(create,read,update,delete)

3.DAO的实现。

      DAO是一组接口,里面封装了数据库操作的一些方法。一个实现DAO接口的具体类;

我们通过两种方法来实现DAO的设计模式
1.普通的方法。即先定义一组接口,再写他的实现类。(为了方便,我将他们写在一个类里面)

import java.lang.reflect.InvocationTargetException;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.ResultSetMetaData;import java.sql.SQLException;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;/**     * java类的属性      * 1).实际上在javaEE中,java类的属性通过getter,setter来定义。     *  2).而以前叫的那个属性,既成员变量,称之为字段。     *  一般情况下,字段名和属性名一致。     * 3).操作java类的属性有一个工具包,beanUtils(setProperty(),getProperty())     */public class DAO {    public void updata(String sql,Object...args){        JDBCUtils JDBCUtil=new JDBCUtils();        Connection connection =null;        PreparedStatement preparedStatement=null;        try{            connection=JDBCUtil.getConnection();            preparedStatement =connection.prepareStatement(sql);            for(int i=0;i<args.length;i++){                preparedStatement.setObject(i+1,args[i]);            }            preparedStatement.executeUpdate();        }catch(Exception e){            e.printStackTrace();        }finally{            JDBCUtil.release(null,preparedStatement,connection);        }    }    //查询一条记录。返回对应的对象    public  <T> T get(Class<T> clazz,String sql,Object...args){        T entity=null;        Connection connection =null;        PreparedStatement preparedStatement =null;        ResultSet resultSet=null;        JDBCUtils JDBCUtil=new JDBCUtils();        try{            //1.获取connection            connection=JDBCUtil.getConnection();            //2.获取PrepareStatement            preparedStatement =connection.prepareStatement(sql);            //3.填充占位符            for(int i=0;i<args.length;i++){                preparedStatement.setObject(i+1,args[i]);            }            //4.进行查询得到ResultSet            resultSet=preparedStatement.executeQuery();            //5.若其中有记录            if(resultSet.next()){                //准备一个Map<String,Object>:键:存放列的别名。值:存放列的值                Map<String,Object> values=new HashMap<String, Object>();                //6.得到ResultSetMetaData对象                ResultSetMetaData rsmd=resultSet.getMetaData();                //7.处理ResultSet对象,把指针向下移动一个位置                //8.由ResultSetMetaData得到结果集中有多少列                int columnCount=rsmd.getColumnCount();                //9.由ResultSetMetaData得到每一列的别名,由ResultSet得到每一列的集体值。                for(int i=0;i<columnCount;i++){                    String columnLabel=rsmd.getColumnLabel(i+1);                    Object columnValue=resultSet.getObject(i+1);                    //10.填充Map对象                    values.put(columnLabel, columnValue);                }                //11.利用反射创建Class对应的对象                Object object=clazz.newInstance();                //12.遍历Map对象,用反射填充对象的属性值。属性名为Map中的key                for(Map.Entry<String, Object> entry:values.entrySet()){                    String propertyName=entry.getKey();                    Object value=entry.getValue();                    //通过反射来赋值,可行但不正宗的 做法                    ReflectionUtils.setFieldValue(object, propertyName, value);                    //通过BeanUtlis赋值                    BeanUtlis.setProperty(entry,propertyName,value);                }                System.out.println(object);            }        }catch(Exception e){            e.printStackTrace();        }finally{            JDBCUtil.release(rs, statement);        }    }    //查询多条记录,返回对应对象的集合    public  <T> List<T> getForList(Class<T> clazz,String sql,Object...args){        T entity=null;        Connection connection =null;        PreparedStatement preparedStatement =null;        ResultSet resultSet=null;        JDBCUtils JDBCUtil=new JDBCUtils();        List<T> list=new ArrayList<T>();        try{            //1.获取connection            connection=JDBCUtil.getConnection();            //2.获取PrepareStatement            preparedStatement =connection.prepareStatement(sql);            //3.填充占位符            for(int i=0;i<args.length;i++){                preparedStatement.setObject(i+1,args[i]);            }            //4.进行查询得到ResultSet            resultSet=preparedStatement.executeQuery();            //5.准备多个List<Map<String,Object>>:键:存放列的别名。值:存放列的值            List<Map<String,Object>> values=new ArrayList<Map<String, Object>>();            ResultSetMetaData rsmd=resultSet.getMetaData();            Map<String,Object> map=null;                //6.得到ResultSetMetaData对象                //7.处理ResultSet,使用while循环                while(resultSet.next()){                    map=new HashMap<String, Object>();                //8.由ResultSetMetaData得到结果集中有多少列                    int columnCount=rsmd.getColumnCount();                //9.由ResultSetMetaData得到每一列的别名,由ResultSet得到每一列的集体值。                for(int i=0;i<columnCount;i++){                    String columnLabel=rsmd.getColumnLabel(i+1);                    Object columnValue=resultSet.getObject(i+1);                    //10.填充Map对象                    map.put(columnLabel, columnValue);                }                //11.吧一条记录的一个Ma放入5准备的List中                values.add(map);                }                //12.判断List是否为空,若不为空                //则遍历List,得到一个一个Map对象,再把一个Map对象转为一个Class参数对应的Object类                Object bean=null;                if(list.size()>0){                    for(Map<String,Object> m:values){                        for(Map.Entry<String, Object> entry:map.entrySet()){                            String propertyName=entry.getKey();                            Object value=entry.getValue();                            //通过反射来赋值,可行但不正宗的 做法                            ReflectionUtils.setFieldValue(object, propertyName, value);                            //通过BeanUtlis赋值                            BeanUtlis.setProperty(entry,propertyName,value);                        }                        //13.把Object对象放入List中                        list.add((T) bean);                    }                }                System.out.println(object);            }        catch(Exception e){            e.printStackTrace();        }finally{            JDBCUtil.release(rs, statement);        }    }    //返回某条记录的某一个字段的值或一个统计的值(一共多少条记录)    public  <E> E getForValue(String sql,Object...args){        return null;    }}

2.通过DBUtils的方法来实现

import java.sql.Connection;import java.sql.SQLException;import java.util.List;/** * 访问数据的 DAO 接口.  * 里边定义好访问数据表的各种方法 * @param T: DAO 处理的实体类的类型.  */public interface DAO<T> {    /**     * 批量处理的方法     * @param connection     * @param sql     * @param args: 填充占位符的 Object [] 类型的可变参数.     * @throws SQLException      */      void batch(Connection connection,             String sql, Object [] ... args) throws SQLException;    /**     * 返回具体的一个值, 例如总人数, 平均工资, 某一个人的 email 等.     * @param connection     * @param sql     * @param args     * @return     * @throws SQLException      */    <E> E getForValue(Connection connection,            String sql, Object ... args) throws SQLException;    /**     * 返回 T 的一个集合     * @param connection     * @param sql     * @param args     * @return     * @throws SQLException      */    List<T> getForList(Connection connection,            String sql, Object ... args) throws SQLException;    /**     * 返回一个 T 的对象     * @param connection     * @param sql     * @param args     * @return     * @throws SQLException      */    T get(Connection connection, String sql,             Object ... args) throws SQLException;    /**     * INSRET, UPDATE, DELETE     * @param connection: 数据库连接     * @param sql: SQL 语句     * @param args: 填充占位符的可变参数.     * @throws SQLException      */    void update(Connection connection, String sql,             Object ... args) throws SQLException;}

DAO的实现

import java.sql.Connection;import java.sql.SQLException;import java.util.List;import org.apache.commons.dbutils.QueryRunner;import org.apache.commons.dbutils.handlers.BeanHandler;import org.apache.commons.dbutils.handlers.BeanListHandler;import org.apache.commons.dbutils.handlers.ScalarHandler;/** * 使用 QueryRunner 提供其具体的实现 * @param <T>: 子类需传入的泛型类型.  */public class JdbcDaoImpl<T> implements DAO<T> {    private QueryRunner queryRunner = null;    private Class<T> type;    public JdbcDaoImpl() {        queryRunner = new QueryRunner();        type = ReflectionUtils.getSuperGenericType(getClass());    }    @Override    public void batch(Connection connection, String sql, Object[]... args) throws SQLException {        queryRunner.batch(connection, sql, args);    }    @Override    public <E> E getForValue(Connection connection, String sql, Object... args) throws SQLException {        return (E) queryRunner.query(connection, sql, new ScalarHandler(), args);    }    @Override     public List<T> getForList(Connection connection, String sql, Object... args)             throws SQLException {        return queryRunner.query(connection, sql,                 new BeanListHandler<>(type), args);    }    @Override    public T get(Connection connection, String sql, Object... args) throws SQLException {         return queryRunner.query(connection, sql,                 new BeanHandler<>(type), args);    }    @Override    public void update(Connection connection, String sql, Object... args) throws SQLException {        queryRunner.update(connection, sql, args);    }}
1 0
原创粉丝点击