DBUtil基于反射的进化版本

news/2024/5/19 2:10:21 标签: java, jdbc, 反射, jsp

JavaWeb学习大纲传送门

本章学习目录

  • 问题的引出:往日的工具类需要针对不同的环境做出适当的改变,这里由于,增删改已经实现通用,那么对于查询是否可以一个工具类多用呢?(之前细讲过普通的DBUtil设置,传送门:普通DBUtil工具类)
  • 问题的解决反射机制能让我们动态的获得类中的属性或者方法,从而实现多用性
  • 页内目录
    一,构建建立连接和释放资源的方法
    二,思考需要建立的通用工具类需要哪些参数
    三,建立连接获得预处理对象设置?占位符
    四,获得查询结果的元数据和表结构
    五,依靠反射机制循环遍历结果集并放入集合
    六,释放资源
    七,展示整体流程(本方法适用于查询)

一,构建建立连接和释放资源的方法(将异常都try catch了)

  • 为连接属性,预处理对象属性,结果集对象提升作用域:
java">    protected Connection conn = null;
    protected PreparedStatement ps = null;
    protected ResultSet rs = null;
  • 建立连接的方法:
java">    protected Connection getConn() throws ClassNotFoundException, SQLException {
        Class.forName("com.mysql.jdbc.Driver");
        conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/goods?useSSL=true","root","root");
        return conn;
    }
  • 释放数据库相关资源的方法:
java">    protected void closeAll(){
        try { if(rs != null){ rs.close(); }
              if(ps != null){ ps.close(); }
              if(conn != null){ conn.close(); }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            conn = null;
            ps = null;
            rs = null;
        }
    }

二,建立的通用工具类的方法需要哪些参数

  • 少不了的sql语句
  • 既然是动态的那就少不了反射中的Class
  • ?占位符的不定长设置
java">public <T>List<T> excuteQuery(String sql,Class<T> cla,Object...params){}

三,建立连接获得预处理对象设置?占位符

  • 建立连接
java">this.getConn();
  • 获得预处理对象
java">ps=conn.prepareStatement(sql);
  • 设置?占位符(有?才设置,这里进行判断)
java">if (params!=null&&params.length!=0){
                for (int i=0;i<params.length;i++){
                    ps.setObject(i+1,params[i]);
                }
            }

四,获得查询结果的元数据和表结构

  • 获得结果集
java">rs=ps.executeQuery();
  • 通过结果集获得查询结果的元数据(也可称为表结构)
java">ResultSetMetaData rsmt= rs.getMetaData();
  • 获得查询结果集的列数方便便利
java">int columnCount = rsmt.getColumnCount();

五,依靠反射机制循环遍历结果集并放入集合

  • 定义用于存储的集合
java">List<T> list=new ArrayList<>();
  • while循环遍历
java">while (rs.next()){
  • 创建类的对象
java">T t = cla.newInstance();
  • for循环获取每一列数据
java">for (int i = 1; i <=columnCount; i++) {
  • 根据列编号获取每一列数据
java">Object value = rs.getObject(i);
  • 获得当前列的列名
java">String columnName = rsmt.getColumnName(i);
  • 运用反射根据列名获得属性对象
java">Field field = cla.getDeclaredField(columnName);
  • 拼凑set方法
java">String methodName="set"+columnName.substring(0,1).toUpperCase()+columnName.substring(1);
  • 运用反射根据set方法名和参数类型获取方法对象(因为方法名和参数可以唯一确定一个方法)
java">Method method = cla.getDeclaredMethod(methodName, field.getType());
  • 运用反射调用方法并统一类型
java">method.invoke(t, ConvertUtils.convert(value,field.getType()));
  • for循环完毕
  • while循环完毕
  • 将对象添加到集合内
java">list.add(t);

六,释放资源

  • 因为资源必须释放,否则占用内存,所以在最后执行的finally里释放资源
java">finally {
            this.closeAll();
        }

七,展示整体流程

java">    public <T>List<T> excute(String sql,Class<T> cla,Object...params){
        try {
            this.getConn();
            ps=conn.prepareStatement(sql);
            if (params!=null&&params.length!=0){
                for (int i=0;i<params.length;i++){
                    ps.setObject(i+1,params[i]);
                }
            }
            rs=ps.executeQuery();
            //获得查询结果的元数据(查询结果的表结构)
            //通过结果集获得查询结果的元数据
            ResultSetMetaData rsmt= rs.getMetaData();
            //获得查询结果集的列数方便遍历
            int columnCount = rsmt.getColumnCount();
            //用于存储对象的list集合
            List<T> list=new ArrayList<>();
            //遍历结果集,先将结果集中的对象封装到对象中,再将对象封装到list集合中
            while (rs.next()){
                //创建类的对象(实体对象)
                T t = cla.newInstance();
                //循环获取每一列数据
                for (int i = 1; i <=columnCount; i++) {
                    //根据列编号获取一列数据
                    Object value = rs.getObject(i);
                    //获得当前类所对应的实体类中的set方法,并调用
                    //获得当前列的列名
                    String columnName = rsmt.getColumnName(i);
                    //根据列名(属性名)属性field对象
                    Field field = cla.getDeclaredField(columnName);
                    //根据列名获取set方法,当前属性的方法=set+属性首字母大写
                    String methodName="set"+columnName.substring(0,1).toUpperCase()+columnName.substring(1);
                    //根据方法名和参数类型获取Method对象,因为方法名和参数可以唯一确定一个方法
                    Method method = cla.getDeclaredMethod(methodName, field.getType());
                    System.out.println(value);
                    //得到了set方法就可以调用了
                    //ConvertUtils.convert(value,field.getType())将值按照属性的类型进行转换
                    method.invoke(t, ConvertUtils.convert(value,field.getType()));
                }
                //将t添加到集合里
                list.add(t);
            }
            return list;
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } finally {
            this.closeAll();
        }
        return null;
    }

http://www.niftyadmin.cn/n/1674810.html

相关文章

oracle如果插入id重复不进行操作_动态SQL不绑定变量的影响

ORACLE可以用EXECUTE IMMEDIATE来执行动态SQL&#xff0c;但在动态SQL中如果涉及到变量&#xff0c;一定要使用USING方法来绑定变量&#xff0c;不能直接把变量拼接到SQL执行&#xff0c;否则会严重影响执行的性能。动态SQL不绑定变量&#xff0c;即直接拼接变量到SQL&#xff…

APUE读书笔记-18终端输入输出-03特殊输入字符

转载于:https://blog.51cto.com/quietheart/881097

浏览器界面下的基于JSP和servlet的数据的增删改查

JavaWeb学习大纲传送门 本章学习目录 问题的引出&#xff1a;学了提升作用域request篇和response篇&#xff0c;EL表达式&#xff0c;jsp标签库&#xff0c;反射我们怎样去应用呢&#xff1f; 问题的解决&#xff1a;针对于数据的增删改查的浏览器界面化&#xff0c;我们对它…

php : 文件及文件夹操作(创建、删除、移动、复制)

Talk is cheap, show you the code : <?php/*** 操纵文件类* */ class FileUtil {/*** 建立文件夹** param string $aimUrl* return viod*/function createDir($aimUrl) {$aimUrl str_replace(, /, $aimUrl);$aimDir ;$arr explode(/, $aimUrl);$result true;foreach …

python匹配规则_兄弟连学Python(06)---- 正则表达式匹配规则

正则表达式 - 匹配规则基本模式匹配一切从最基本的开始。模式&#xff0c;是正则表达式最基本的元素&#xff0c;它们是一组描述字符串特征的字符。模式可以很简单&#xff0c;由普通的字符串组成&#xff0c;也可以非常复杂&#xff0c;往往用特殊的字符表示一个范围内的字符、…

android textview设置背景颜色图片

为什么80%的码农都做不了架构师&#xff1f;>>> 第一&#xff0c;使用背景&#xff0c;在做项目的时候&#xff0c;有时候需要单击一个TextView时改变其背景颜色&#xff0c;或者图片&#xff0c;或者文字颜色 第二&#xff0c;解决办法&#xff1a;Drawable drawa…

python编程多久能学会_零基础小白多久能学会python

学习任何一门编程语言&#xff0c;都是为了去实现一个个项目&#xff0c;来解决实际的问题。无论项目是大还是小&#xff0c;都关联着许多知识与技能。例如要写一个「文件资源管理器」的应用&#xff0c;就需要MVC设计模式、组件化构建、对象集合及操作、打包与部署、多线程遍历…

mysql into 变量_mysql实例 select into设置变量的方法

mysql实例&#xff0c;select into设置变量&#xff0c;代码&#xff1a;mysql> CREATE TABLE Employee( //创建雇员表-> id int,-> first_name VARCHAR(15),-> last_name VARCHAR(15),-> start_date DATE,-> end_date DATE,-> salary FLOAT(8,2),-> c…