使用模板方法模式简化JDBC操作

在使用JDBC时,会重复的写很多重复的代码,例如 

                Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
                String sql="insert into t_user(username,brithday) values(?,?)";
        try {
            conn = JdbcUtils.getConnection();
            ps = conn.prepareStatement(sql);
            

        } catch (SQLException e) {
            throw new DaoException(e.getMessage(), e);
        } finally {
            JdbcUtils.free(rs, ps, conn);
        }
    

这部分代码在数据库操作方法中都会有。因此我们可以把这部分不变的内容提取出来,作为一个公用的方法。 

例如,我们的增,删,改操作可以这样写 

/**
     * 增,删,改方法
     * @param sql
     * @param args sql参数
     * @return
     */
    public int update(String sql, Object[] args) {
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            conn = JdbcUtils.getConnection();
            ps = conn.prepareStatement(sql);
            for (int i = 0; i < args.length; i++)
                ps.setObject(i + 1, args[i]);
            return ps.executeUpdate();
        } catch (SQLException e) {
            throw new DaoException(e.getMessage(), e);
        } finally {
            JdbcUtils.free(rs, ps, conn);
        }
    }

最麻烦的就是返回一个对象的操作了。因为我不知道要返回的对象是什么,所以在往对象里设值的时候就不确定了。因此我们可以在这个类里面定义一个抽象的方法,具体怎么实现,它的子类知道。 

因此我们的这个类就可以这样设计了

package com.zzg.jdbc.base;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import com.zzg.jdbc.exception.DaoException;
import com.zzg.jdbc.util.JdbcUtils;

public abstract class BaseDao {

    /**
     * 增,删,改方法
     * @param sql
     * @param args sql参数
     * @return
     */
    public int update(String sql, Object[] args) {
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            conn = JdbcUtils.getConnection();
            ps = conn.prepareStatement(sql);
            for (int i = 0; i < args.length; i++)
                ps.setObject(i + 1, args[i]);
            return ps.executeUpdate();
        } catch (SQLException e) {
            throw new DaoException(e.getMessage(), e);
        } finally {
            JdbcUtils.free(rs, ps, conn);
        }
    }

    /**
     * 返回一个对象
     * @param <T>
     * @param sql
     * @param args
     * @return
     */
    public <T> T find(String sql, Object[] args) {
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            conn = JdbcUtils.getConnection();
            ps = conn.prepareStatement(sql);
            for (int i = 0; i < args.length; i++)
                ps.setObject(i + 1, args[i]);
            rs = ps.executeQuery();
            T t = null;
            if (rs.next()) {
                t = rowMapper(rs);
            }
            return t;
        } catch (SQLException e) {
            throw new DaoException(e.getMessage(), e);
        } finally {
            JdbcUtils.free(rs, ps, conn);
        }
    }

    /**
     * 返回一个List
     * @param <T>
     * @param sql
     * @param args
     * @return
     */
    public <T> List<T> list(String sql, Object[] args) {
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            conn = JdbcUtils.getConnection();
            ps = conn.prepareStatement(sql);
            for (int i = 0; i < args.length; i++)
                ps.setObject(i + 1, args[i]);
            rs = ps.executeQuery();
            T t = null;
            List<T> list = new ArrayList<T>();
            while (rs.next()) {
                t = rowMapper(rs);
                list.add(t);
            }
            return list;
        } catch (SQLException e) {
            throw new DaoException(e.getMessage(), e);
        } finally {
            JdbcUtils.free(rs, ps, conn);
        }
    }

    abstract protected <T> T rowMapper(ResultSet rs) throws SQLException;

}

在使用时我们的类只需要继承上面那个类就可以了。

package com.zzg.jdbc.dao.impl;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

import com.zzg.jdbc.base.BaseDao;
import com.zzg.jdbc.dao.UserDao;
import com.zzg.jdbc.domain.User;

public class UserDaoImpl extends BaseDao implements UserDao {

    @Override
    public User findUser(int id) {
        String sql = "select *from t_user where id=?";
        Object[] args = new Object[] { id };
        User user = super.find(sql, args);
        return user;
    }

    @Override
    public List<User> listUser(String username) {
        String sql = "select *from t_user where username=?";
        Object[] args = new Object[] { username };
        List<User> list = super.list(sql, args);
        for (User u : list) {
            System.out.println(u.getId());
        }
        return list;
    }

    @Override
    protected Object rowMapper(ResultSet rs) throws SQLException {
        User user = new User();
        user.setId(rs.getInt("id"));
        user.setUsername(rs.getString("username"));
        user.setBrithday(rs.getDate("brithday"));
        return user;
    }

}

附加分页的方法:

/**
     * 分页
     * @param tableName
     * @param PK
     * @param methodPageNum
     * @param methodNumPerPage
     * @param conditions
     * @param <T>
     * @return
     * @throws SQLException
     */
    public <T> List<T> getPageListResultSet(String tableName,String PK,int methodPageNum,int methodNumPerPage,Map<String,String> conditions) throws SQLException{
        int pageNum = methodPageNum==0?DEFAULT_PAGE_NUM:methodPageNum;
        int numPerPage = methodNumPerPage==0?DEFAULT_NUM_PER_PAGE:methodNumPerPage;
        List<T> list = null;
        DataSetOp dataSetOp = null;
        try {
           dataSetOp = new  DataSetOp();
            String PAGE_SQL_PREFIX = " SELECT * FROM (SELECT ROW_NUMBER() OVER(ORDER BY t1.ID DESC) AS ROW_NUM, t1.* FROM  ";
            String PAGE_SQL_END = " ) TT WHERE TT.ROW_NUM >? AND TT.ROW_NUM <= ? ";
            if(StringUtil.isNotBlank(PK)){
                PAGE_SQL_PREFIX = PAGE_SQL_PREFIX.replace("ID",PK);
            }
            StringBuffer sql = new StringBuffer(PAGE_SQL_PREFIX);
            sql.append(tableName).append(" t1 WHERE 1=1 ");
            //设置条件
            if(conditions!=null && conditions.size()>0){
                Set<String> key = conditions.keySet();
                for (Iterator it = key.iterator(); it.hasNext();) {
                    String column = (String) it.next();
                    //System.out.println(conditions.get(s));
                    StringBuffer cd = new StringBuffer(" and t1.");
                    cd.append(column).append("='").append(conditions.get(column)).append("' ");
                    sql.append(cd);
                }
            }
            sql.append(PAGE_SQL_END);
            System.out.println(sql);
            PreparedStatement ps = dataSetOp.getConnection().prepareStatement(sql.toString());
            ps.setInt(1, (pageNum - 1) * numPerPage);
            ps.setInt(2, pageNum*numPerPage);
            ResultSet rs = ps.executeQuery();
            T t = null;
            list = new ArrayList<T>();
            while (rs.next()) {
                t = rowMapper(rs);
                list.add(t);
            }
        } catch (DataException e) {
            e.printStackTrace();
        }finally{
            if(dataSetOp != null) dataSetOp.close();
        }
        return list;
    }
原文地址:https://www.cnblogs.com/winkey4986/p/4269524.html