DAO层基础设计原理

    在实际的开发中有一种项目的程序组织架构方案叫做MVC模式,按照程序 的功能将他们分成三个层,如下图

Modle层(模型层)、View层(显示层)、Controller层(控制层)。

Modle层:可以分两层,DAO层、service层,基文本功能 如下

service层:主要去负责一些业务处理,比如取得连接、关闭数据库连接、事务回滚,一些复杂的逻辑业务处理就放到service层

DAO层:负责访问数据库进行数据的操作,取得结果集,之后将结果集中的数据取出封装到VO类对象之后返回给service层

Cotroller层:叫做控制层,主要的功能是处理用户发送的请求。

View层:叫做显示层,主要是负责现实数据。

在实际开发中dao层要先定义出自己的操作标准即标准接口,就是为了解耦合。

Modle层(DAO层和service层)的设计如下。

 

//BasDaoUtil.java代码,共7个方法
package com.sxt.mvcpro.dao.impl;
import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class BaseDAOUtil {
    private static PreparedStatement pst;
    private static ResultSet rst;
    /**
     * 
     * @param conn 
     * @param sql
     * @param clz
     * @param vo
     * @return
     * @throws Exception
     */
    public <T> int save(Connection conn, String sql, Class<T> clz, T vo) throws Exception {
        //取得预编译对象
        pst = conn.prepareStatement(sql);
        // 为sql设置占位符内容(insert into 表(字段1,字段2,字段3,字段4)VALUES(?,?,?,?))
        String[] coulums = sql.split("\\(")[1].split("\\)")[0].split(",");
        for (int i = 0; i < coulums.length; i++) {
            Field f = vo.getClass().getDeclaredField(coulums[i]);
            // 取消私有封装访问限制
            f.setAccessible(true);
            //取得字段对应的属性的值
            Object fvalue = f.get(vo);
            pst.setObject(i + 1, fvalue);
        }
        return pst.executeUpdate();
    }
    /**
     * 
     * @param conn
     * @param sql
     * @param vo
     * @return
     * @throws Exception
     */
    public <T> int edit(Connection conn,String sql,T vo) throws Exception{
        // update emp SET sal=?,job=?,comm=? WHERE empno=? AND  ...  ;
        //取得预编译对象
        pst=conn.prepareStatement(sql);
        String[] strs = sql.split("SET")[1].split("WHERE")[0].split(",");
        int i=0;
        for(i=0;i<strs.length;i++) {
            //取得要修改的字段名称
            String column=strs[i].split("=")[0];
            //通过反射取得column对应在vo中的属性对象(就是拿vo的变量,比如ename)
            Field f = vo.getClass().getDeclaredField(column.trim());
            // 取消私有封装访问限制
            f.setAccessible(true);
            //取得该字段在vo对象中的值
            Object fvalue=f.get(vo);
            //为占位符设置具体的内容
            pst.setObject(i+1, fvalue);
        }
        String coditions = sql.split("WHERE")[1].split("=")[0];
        Field f = vo.getClass().getDeclaredField(coditions.trim());
        f.setAccessible(true);
        Object fvalue=f.get(vo);
        pst.setObject(i+1, fvalue);
        return pst.executeUpdate();
    }
    /**
     * 
     * @param conn
     * @param sql
     * @param id
     * @return
     * @throws Exception
     */
    public  int  removeById(Connection conn,String sql,Object id) throws Exception{
        //取得预编译对象
        pst=conn.prepareStatement(sql);
        pst.setObject(1, id);
        return pst.executeUpdate();
    }
    /**
     * 
     * @param conn
     * @param sql
     * @param ids
     * @return
     * @throws Exception
     */
    public  int removeBatch(Connection conn,StringBuffer sql,List<Object> ids) throws Exception{
        Iterator<Object> iter=ids.iterator();
        while (iter.hasNext()) {
            sql.append(iter.next()+",");
        }
        sql.delete(sql.length()-1, sql.length());
        sql.append(")");
        pst=conn.prepareStatement(sql.toString());
        return pst.executeUpdate();
    }
    /**
     * 
     * @param conn
     * @param sql
     * @param clz
     * @param id
     * @return
     * @throws Exception
     */
    public <T> T selectOne(Connection conn,String sql,Class<T> clz,Object id) throws Exception{
        //取得预编译对象
        pst=conn.prepareStatement(sql);
        pst.setObject(1, id);
        //执行sql语句
        rst=pst.executeQuery();
        T t=null;
        if (rst.next()) {
            t=clz.newInstance();
            //取得所有属性
            Field[] fs = clz.getDeclaredFields();
            for (Field f : fs) {
                //为属性取消私有封装
                f.setAccessible(true);
                //取得属性名
                String fname=f.getName();
                //使用该属性名称从结果集中取得数据
                Object fvalue=rst.getObject(fname);
                //将取得的值保存t对象的属性
                f.set(t, fvalue);
            }
            return t;
        }
        return null;
    }
    /**
     * 
     * @param conn
     * @param sql
     * @param clz
     * @param params
     * @return
     * @throws Exception
     */
    public <T> List<T> selectList(Connection conn,String sql,Class<T> clz,Object...params) throws Exception{
        List<T> list= new ArrayList<T>();
        pst=conn.prepareStatement(sql);
        for(int i=0;i<params.length;i++) {
            pst.setObject(i+1, params[i]);
        }
        //执行sql语句
        rst=pst.executeQuery();
        T t=null;
        while (rst.next()) {
            t=clz.newInstance();
            //取得所属性
            Field[] fs = clz.getDeclaredFields();
            for (Field f : fs) {
                //为属性取消私有封装
                f.setAccessible(true);
                //取得属性名
                String fname = f.getName();
                //使用该属性名称从结果集中取得数据
                Object fvalue=rst.getObject(fname);
                //将取得的值保存给t对象的属性
                f.set(t, fvalue);
            }
            list.add(t);
        }
        return list;
    }
    /**
     * 
     * @param conn
     * @param sql
     * @param params
     * @return
     * @throws Exception
     */
    public int selectCount(Connection conn,String sql,Object...params) throws Exception{
        pst=conn.prepareStatement(sql);
        for(int i=0;i<params.length;i++) {
            pst.setObject(i+1, params[i]);
        }
        //执行sql语句
        rst=pst.executeQuery();
        rst.next();//让指针往下移动
        return rst.getInt(1);
    }
}

 

posted @ 2019-04-17 14:41  上下平中  阅读(10460)  评论(0编辑  收藏  举报