JDBC:提取重复代码进行重构

  当我们在写 JDBC 代码连接数据库进行交互的时候,因为要写很多个增删改查的方法,有很多代码是重复的,而且这些代码必须但又不是主要业务,所以会造成代码的冗余,不利于后期的维护。所以我们必须把相同的代码抽取出来形成一个方法,在需要的时候直接调用这个方法就行了。那么在这中我们可以抽取四份不同的重复代码形成四个方法:

  1.数据库的连接

    每次进行对数据库的增删改查,都需要先连接数据库,所以我们可以把连接数据库这部分代码抽取出来。

  public static Connection getConnection() {
        Connection conn = null;
        try {
            conn = DriverManager.getConnection(url,username,password);    //jdbc4 之后不再需要显式声明注册驱动,在调用getConnection()方法的时候,
                                                                        //底层会通过url自动查找相应的驱动注册
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return conn;
    }

  2.相应接口对象的关闭

    在进行数据库连接进行增删改查的时候,通常会进行打开连接Connection,创建声明Statement,返回结果集ResultSet这样的操作,在使用完毕后通常是需要放在 finally 中关闭的。这些写起来繁琐且重复的代码也需要被抽取出来。

  /**
     * 只要是实现了AutoCloseable接口的实现类,都可以使用 此方法进行关闭
     * @param auto
     */
    public static void close(AutoCloseable auto) {
        if(auto != null) {            //判断是否关闭,未关闭则进行关闭
            try {
                auto.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

  3.增删改的抽取

    在数据库增删改查这四种基本操作中,增删改这三种操作是可以不需要有返回值的,所以也可以抽取出来。

  /**
     * 
     * @param sql    传入要进行执行的 sql 语句
     * @param obj    可变参数,可以传入0-n个参数,使用Object类型可以传入任意类型的参数
     */
    public static void executeSQL(String sql,Object...obj) {
        Connection conn = getConnection();            //获取数据库连接
        PreparedStatement ps = null;
        try {
            ps = conn.prepareStatement(sql);        //预编译sql语句
            for(int i = 0; i < obj.length; i++) {    //对预编译的sql语句中的占位符?进行传参
                ps.setObject(i+1, obj[i]);            //占位符?从1开始,变参数组从0开始
            }
            ps.execute();                            //执行sql语句
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            close(ps);                                //关闭接口对象
            close(conn);
        }
    }

  4.查询的抽取

    增删改查这四种操作中,查询是有返回结果集的,所以要抽取相同代码形成一个通用方法是一件相对较麻烦的事情,但是重复的查询代码写多了也不利于维护,所以还是有必要抽取一下。

  /**
     * 
     * @param sql    传入要执行的sql语句
     * @param obj    可变参数,可以传入0-n个参数,使用Object类型可以传入任意类型的参数
     * @return        返回一个List结果集
     */
    public static List<Map<String,Object>> executeQuery(String sql,Object...obj){
        //声明一个List用来存储每一条记录,每一条记录相当于一个Map
        //Map用来存储每条记录中的各字段的值,key:字段名;value:字段值
        List<Map<String,Object>> list = new ArrayList<Map<String,Object>>();
        
        Connection conn = getConnection();        //获取连接            
        PreparedStatement ps = null;
        ResultSet rs = null;
        
        try {
            ps = conn.prepareStatement(sql);        //预编译sql语句
            for(int i = 0; i < obj.length; i++) {    //对预编译的sql语句中的占位符?进行传参
                ps.setObject(i+1, obj[i]);            //占位符?从1开始,变参数组从0开始
            }
            rs = ps.executeQuery();                    //执行查询语句
            ResultSetMetaData rsmd = rs.getMetaData();    //通过结果集获取对应的元数据
            
            //遍历结果集
            while(rs.next()) {
                Map<String,Object> map = new HashMap<String,Object>();
                
                //遍历获取的所有字段,把字段名和值存入map
                for(int i = 1; i <= rsmd.getColumnCount(); i++) {
                    map.put(rsmd.getColumnLabel(i), rs.getObject(i));
                }
                list.add(map);            //把每条记录map存入list
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            close(rs);                    //关闭接口对象
            close(ps);
            close(conn);
        }
        return list;
    }

  通过重复代码的抽取形成通用方法之后,在进行对数据库的增删改查操作也变得简洁、更容易了:

public class PersonDaoImpl implements PersonDao {

    @Override
    public void insert(Person person) {
        DBUtil.executeSQL("insert into person values(null,?,?,?,?)", person.getPersonname(),
                person.getDegree(),person.getBirth(),person.getSal());
    }

    @Override
    public void update(Person person) {
        DBUtil.executeSQL("update person set personname=?,degree=?,birth=?,sal=? where personid=?", person.getPersonname(),
                person.getDegree(),person.getBirth(),person.getSal(),person.getPersonid());
    }

    @Override
    public void delete(int[] ids) {
        for(int i = 0; i < ids.length; i++) {
            DBUtil.executeSQL("delete from person where personid=?", ids[i]);
        }
    }

    @Override
    public List<Person> getAll() {
        String sql = "select personid,personname,degree,birth,sal from person";
        return this.convert(DBUtil.executeQuery(sql));
    }

    @Override
    public List<Person> getPersonForPage(int pageSize, int pageOrder) {
        String sql = "select personid,personname,degree,birth,sal from person limit ?,?";
        return this.convert(DBUtil.executeQuery(sql,(pageOrder-1)*pageSize,pageSize));
    }

    @Override
    public Person getPersonById(int id) {
        String sql = "select personid,personname,degree,birth,sal from person where personid=?";
        List<Person> list = this.convert(DBUtil.executeQuery(sql,id));
        return list.isEmpty() ? null : list.get(0);
    }
    
    
    public List<Person> convert(List<Map<String,Object>> list){
        List<Person> pList = new ArrayList<Person>();
        for(Map<String,Object> map:list) {
            Person p = new Person();
            p.setPersonid((Integer)map.get("personid"));
            p.setPersonname( map.get("personname").toString());
            p.setDegree( map.get("degree").toString());
            p.setBirth((Date) map.get("birth"));
            p.setSal( (double) map.get("sal"));
            pList.add(p);
        }
        return pList;
    }

}

 

转载于:https://www.cnblogs.com/zincpool/p/7748323.html

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值