0
点赞
收藏
分享

微信扫一扫

Spring-学习笔记06【spring_day02资料_dbutils】

目录

01_分析jdbc中操作问题-抽取增删改方法的通用方法

1.1、DBAssit.java

02_抽取查询方法-编写封装一个实体对象的结果集处理器

2.1、BeanHandler.java

03_实现查询所有的封装以及dbutils介绍

04_dbutils的使用


01_分析jdbc中操作问题-抽取增删改方法的通用方法

1.1、DBAssit.java

package com.itheima.dbassit;

import com.itheima.handler.ResultSetHandler;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.ParameterMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

/**
 * 封装的工具类
 */
public class DBAssit {
    private DataSource dataSource;

    public DBAssit(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    /**
     * 执行增删改的方法
     *
     * @param sql
     * @param params
     * @return
     */
    public int update(String sql, Object... params) {
        Connection conn = null;
        PreparedStatement pstm = null;
        try {
            //1.得到连接
            conn = dataSource.getConnection();
            //2.使用连接和参数的sql语句创建预处理对象
            pstm = conn.prepareStatement(sql);
            //3.得到sql语句参数的源信息(有几个参数,都什么类型等等)
            ParameterMetaData pmd = pstm.getParameterMetaData();
            //4.判断语句中参数的个数和方法参数params的个数是否一致,不一致肯定没法执行
            int parameterCount = pmd.getParameterCount();//参数的个数(问号的个数)
            if (parameterCount > 0) {
                if (params == null) {
                    throw new NullPointerException("没有sql语句执行必须的参数");
                }
                if (params.length != parameterCount) {
                    throw new RuntimeException("传入的参数个数和语句所需的参数个数不一致,语句无法执行");
                }
            }
            //5.给sql语句的参数赋值
            for (int i = 0; i < parameterCount; i++) {
                pstm.setObject(i + 1, params[i]);
            }
            //6.执行语句
            int res = pstm.executeUpdate();
            //7.返回执行结果
            return res;
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            release(conn, pstm, null);
        }
    }

    public Object query(String sql, ResultSetHandler rsh, Object... params) {
        Connection conn = null;
        PreparedStatement pstm = null;
        ResultSet rs = null;
        try {
            //1.得到连接
            conn = dataSource.getConnection();
            //2.使用连接和参数的sql语句创建预处理对象
            pstm = conn.prepareStatement(sql);
            //3.得到sql语句参数的源信息(有几个参数,都什么类型等等)
            ParameterMetaData pmd = pstm.getParameterMetaData();
            //4.判断语句中参数的个数和方法参数params的个数是否一致,不一致肯定没法执行
            int parameterCount = pmd.getParameterCount();//参数的个数(问号的个数)
            if (parameterCount > 0) {
                if (params == null) {
                    throw new NullPointerException("没有sql语句执行必须的参数");
                }
                if (params.length != parameterCount) {
                    throw new RuntimeException("传入的参数个数和语句所需的参数个数不一致,语句无法执行");
                }
            }
            //5.给sql语句的参数赋值
            for (int i = 0; i < parameterCount; i++) {
                pstm.setObject(i + 1, params[i]);
            }
            //6.执行语句
            rs = pstm.executeQuery();
            //7.返回执行结果
            return rsh.handle(rs);
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            release(conn, pstm, rs);
        }
    }


    private void release(Connection conn, PreparedStatement pstm, ResultSet rs) {
        if (rs != null) {
            try {
                rs.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        if (pstm != null) {
            try {
                pstm.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        if (conn != null) {
            try {
                conn.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

02_抽取查询方法-编写封装一个实体对象的结果集处理器

2.1、BeanHandler.java

package com.itheima.handler.impl;

import com.itheima.handler.ResultSetHandler;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;

/**
 * 结果集封装的具体实现类。
 * 此类实现的是把一个结果集rs的内容封装到一个指定的实体类对象中
 * 使用要求:实体类中的属性必须和表中的列名一致(sql语句查询出来的列名一致)
 *
 * @param <T>
 */
public class BeanHandler implements ResultSetHandler {
    private Class domainClass;

    public BeanHandler(Class domainClass) {
        this.domainClass = domainClass;
    }

    /**
     * 把rs的内容封装到domainClass所表示的类中
     *
     * @param rs
     * @return
     */
    @Override
    public Object handle(ResultSet rs) {
        try {
            //1.创建一个实体类对象
            Object bean = domainClass.newInstance();
            //2.判断是否有结果集
            if (rs.next()) {
                //3.得到结果集rs中所有的列名
                //要想得到列名,得先得到结果集的源信息
                ResultSetMetaData rsmd = rs.getMetaData();
                //得到源信息之后,还要得到有多少列
                int columnCount = rsmd.getColumnCount();
                //遍历列数
                for (int i = 1; i <= columnCount; i++) {
                    //得到每列的名称
                    String columnName = rsmd.getColumnName(i);
                    //列名其实就是实体类的属性名称,于是就可以使用列名得到实体类中属性的描述器
                    PropertyDescriptor pd = new PropertyDescriptor(columnName, domainClass);//实体类中定义的私有类成员和它的get以及set方法
                    //获取属性的写入方法(set方法)
                    Method method = pd.getWriteMethod();
                    //获取当前列名所对应的值
                    Object columnValue = rs.getObject(columnName);
                    //通过执行写方法把得到的值给属性赋上
                    method.invoke(bean, columnValue);
                }
            }
            //4.返回
            return bean;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

03_实现查询所有的封装以及dbutils介绍

04_dbutils的使用

举报

相关推荐

0 条评论