day38_JDBC

今日内容

上课同步视频:CuteN饕餮的个人空间_哔哩哔哩_bilibili
同步笔记沐沐霸的博客_CSDN博客-Java2301
零、 复习昨日
一、数据库连接池
二、反射
三、封装DBUtil

零、 复习昨日

SQL注入

预处理语句

String sql = "select * from user where id = ?";
PreparedStatement ps = conn.preparedStatement(sql);
ps.setInt(1,id);
// ps.setDate(1,new java.sql.Date(user.getDate().getTime()))
ps.executeQuery();

DBUtil

一、数据库连接池

目前数据库连接是使用是建立连接,用完直接关闭连接.即需要不断创建和销毁连接.就会消耗系统资源.借鉴线程池的思想,设计出数据库连接池.

在程序初始时,预先创建好指定数量的数据库连接对象,存储连接池。需要用时就去取,用完就放回去即可。就会不会频繁创建和销毁,从而节省系统资源。

使用上的线程池有很多

  • druid (德鲁伊)
  • c3p0
  • dbcp

1.1 Druid数据库连接池

Druid是阿里开源技术,性能很好

使用步骤

  • 导入依赖druid.jar包

  • 创建一个db.properties

    # 必须是driverClass,不是jdbc.driverClass,否则创建DataSource失败
    driverClass=com.mysql.jdbc.Driver
    url=jdbc:mysql://localhost:3306/database?useSSL=false
    username=root
    password=123456
    # ----- 加入druid的一些连接配置
    #<!-- 初始化连接 -->
    initialSize=10
    #最大连接数量
    maxActive=50
    #<!-- 最小空闲连接 -->
    minIdle=5
    #<!-- 超时等待时间以毫秒为单位 60000毫秒/1000等于60秒 -->
    maxWait=5000
    
  • 修改之前的DBUtil

    public class DBUtil {
    
        // 创建Properties类对象,专用于操作properties文件
        private static final Properties properties = new Properties();
        // 声明Druid连接池的连接池对象
        // 数据连接,一般称作数据源 dataSource
        private static DruidDataSource dataSource;
    
  static {

      try {
          InputStream inputStream = DBUtil.class.getResourceAsStream("/db.properties");
          properties.load(inputStream);
          // 不需要由我们加载驱动
          // 需要给dataSource赋值
          dataSource = (DruidDataSource) DruidDataSourceFactory.createDataSource(properties);

      } catch (Exception e) {
          System.out.println("加载驱动异常!!" );
          e.printStackTrace( );
      }
  }

  public static Connection getConnection() {
      Connection conn = null;
      try{
          // 不需要我们获得连接
          // 而是通过Druid获得
          conn = dataSource.getConnection();
      } catch (Exception e) {
          System.out.println("获得连接出异常!!!" );
          e.printStackTrace();
      }
      return conn;
  }
 // 后续正常...跟之前一样

}

  • 开始使用

    • 跟之前一样使用

二、反射

JAVA反射(reflect)机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法,对于任意一个对 象,都能够调用它的任意一个方法和属性

这种动态获取的信息以及动态调用对象的方法的功能称为java 语言的反射机制。

反射是在程序运行过程中拿到类的字节码文件,进而获得类中的属性,方法等.

2.1 获得类的字节码文件

  • Object类的方法 getClass()
  • 类的静态属性 Xxx.class
  • Class类的静态方法Class.forName(“xxx”)
   /**
     * 演示获取字节码文件
     */
    public static void getClassFile() throws ClassNotFoundException {
        // 方式1
        Class<?> clazz = Class.forName("com.qf.model.User");

        // 方式2
        Class<User> clazz2 = User.class;

        // 方式3
        User user = new User( );
        Class<? extends User> clazz3 = user.getClass( );

        if (clazz.equals(clazz2) && clazz2.equals(clazz3)) {
            System.out.println("是同一个字节码文件" );
        } else {
            System.out.println("不是" );
        }
    }

2.2 获得并设置属性(Field)

API
image-20230322084435433
    /**
     * 获得字节码中的属性并操作
     */
    public static void getAndSetFields() throws Exception {
        Class<User> clazz = User.class;
        /**
         * Filed getField(String name)
         *       通过属性名获得属性对象(只能获得public修饰的属性的属性对象)
         * Filed getDeclaredField()
         *       通过属性名获得属性对象(获得任意修饰符修饰的属性对象)
         */
        // Field id = clazz.getField("id");
        // System.out.println(id );

        Field id1 = clazz.getDeclaredField("id");
        System.out.println(id1 );

        /**
         * Filed[]  getFields( ) 获得public修饰所有属性对象,返回数组
         * Filed[] getDeclaredFields( )  获得所有属性对象,返回数组
         */
        Field[] fields = clazz.getFields( );
        System.out.println(fields.length );
        Field[] declaredFields = clazz.getDeclaredFields( );
        System.out.println(declaredFields.length );

        // =============================================
        // 获得属性名
        String name = id1.getName( );
        System.out.println("name = "+ name );

        // 获得属性访问修饰符
        int modifiers = id1.getModifiers( );
        System.out.println("访问修饰符: " + modifiers );

        // 获得属性值
        // 获得哪个对象的该属性值
        // 但是不能获得私有属性的值
        // 可以通过设置,就可以访问,
        id1.setAccessible(true);
        User user = new User( );
        int value = id1.getInt(user);
        System.out.println("id = " + value );

        // 设置属性值
        // 设置哪个对象的该属性值
        id1.setInt( user,11);

        System.out.println(user );

    }

2.3 获得并设置方法(Method)

API
image-20230322084508059
    /**
     *  获得字节码中的方法
     */
    public static void getAndSeMethod() throws Exception {
       Class<User> clazz = User.class;
       // 方法有重载,需要通过参数来确定获得哪个方法
       Method m1 = clazz.getMethod("m1"); // 获得无参的m1方法
       Method m1_ = clazz.getMethod("m1",int.class); // 获得有参的m1(int)方法

        // 获得关于方法的所有信息
        int count = m1.getParameterCount( );// 参数个数
        int count_ = m1_.getParameterCount( );// 参数个数

        // 操作方法,让方法执行
        // 参数1: 哪个对象的该方法执行
        // 参数2: 该方法执行时的参数
        Object ret = m1.invoke(new User( ));
        System.out.println("m1()执行后的返回值:" + ret );
        m1_.invoke(new User(),222);

    }

2.4 获得并设置构造方法(Constructor)

API
image-20230322084547730
    /**
     *  获得字节码中的构造方法
     */
    public static void getAndSeConstructor() throws Exception {
        Class<User> clazz = User.class;

        // 通过参数来获得有参还是无参构造
        Constructor<User> constructor = clazz.getConstructor( );

        // 构造方法执行,创建对象
        User user = constructor.newInstance( );

        System.out.println(user );

        // 创建字节码的对象,还有另外方法
        // 可以通过字节码,直接创建
        User user1 = clazz.newInstance( );
    }

三、使用反射封装DBUtil

能利用反射封装DBUtil的前提是,一定是完全按照ORM设计的类.

即 表名即类名,字段名即属性名

package com.qf.util;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;

import java.io.File;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

/**
 * --- 天道酬勤 ---
 *
 * @author QiuShiju
 * @desc
 */
public class DBUtil {

    // 创建Properties类对象,专用于操作properties文件
    private static final Properties properties = new Properties( );
    // 声明Druid连接池的连接池对象
    // 数据连接,一般称作数据源 dataSource
    private static DruidDataSource dataSource;


    static {

        try {
            InputStream inputStream = DBUtil.class.getResourceAsStream("/jdbc.properties");
            properties.load(inputStream);
            // 不需要由我们加载驱动
            // 需要给dataSource赋值
            dataSource = (DruidDataSource) DruidDataSourceFactory.createDataSource(properties);

        } catch (Exception e) {
            System.out.println("加载驱动异常!!");
            e.printStackTrace( );
        }
    }

    public static Connection getConnection() {
        Connection conn = null;
        try {
            // 不需要我们获得连接
            // 而是通过Druid获得
            conn = dataSource.getConnection( );
        } catch (Exception e) {
            System.out.println("获得连接出异常!!!");
            e.printStackTrace( );
        }
        return conn;
    }


    /**
     * 关闭所有流
     */
    public static void closeAll(Connection conn, Statement s) {
        if (conn != null) {
            try {
                conn.close( );
            } catch (SQLException throwables) {
                throwables.printStackTrace( );
            }
        }

        if (s != null) {
            try {
                s.close( );
            } catch (SQLException throwables) {
                throwables.printStackTrace( );
            }
        }
    }

    public static void closeAll(Connection conn, Statement s, ResultSet rs) {
        if (conn != null) {
            try {
                conn.close( );
            } catch (SQLException throwables) {
                throwables.printStackTrace( );
            }
        }

        if (s != null) {
            try {
                s.close( );
            } catch (SQLException throwables) {
                throwables.printStackTrace( );
            }
        }

        if (rs != null) {
            try {
                rs.close( );
            } catch (SQLException throwables) {
                throwables.printStackTrace( );
            }
        }
    }


    /**
     * 封装查询方法,返回一个对象
     * 参数1 执行查询的SQL,预处理的,条件用?占位
     * select * from tb_user where id = ? and username = ? and password = ?
     * 参数2 结果要封装的类
     * 参数3 给?赋值,不定长参数,是数组
     * 1,admin,123456
     */
    public static <T> T selectOne(String sql, Class<T> t, Object... args) {
        Connection conn = getConnection( );
        PreparedStatement ps = null;
        ResultSet rs = null;
        T target = null;
        try {
            ps = conn.prepareStatement(sql);
            for (int i = 0; args != null && i < args.length; i++) {
                ps.setObject(i + 1, args[i]);
            }

            rs = ps.executeQuery( );
            /**
             * 创建对象
             * 从数据库取出数据,并设置对象属性
             */
            while (rs.next( )) {
                target = t.newInstance( );
                Field[] declaredFields = t.getDeclaredFields( );
                for (int i = 0; i < declaredFields.length; i++) {
                    Field field = declaredFields[i];
                    Object value = rs.getObject(field.getName( ));

                    // 破解私有
                    field.setAccessible(true);

                    // 给对象的该字段赋值
                    field.set(target, value);
                }

            }
        } catch (Exception e) {
            e.printStackTrace( );
        } finally {
            closeAll(conn, ps, rs);
        }
        return target;
    }

    public static <T> List<T> selectAll(String sql, Class<T> t, Object... args) {
        Connection conn = getConnection( );
        PreparedStatement ps = null;
        ResultSet rs = null;
        T target = null;
        ArrayList<T> list = new ArrayList<>( );
        try {
            ps = conn.prepareStatement(sql);
            for (int i = 0; args != null && i < args.length; i++) {
                ps.setObject(i + 1, args[i]);
            }

            rs = ps.executeQuery( );
            /**
             * 创建对象
             * 从数据库取出数据,并设置对象属性
             */
            while (rs.next( )) {
                target = t.newInstance( );
                Field[] declaredFields = t.getDeclaredFields( );
                for (int i = 0; i < declaredFields.length; i++) {
                    Field field = declaredFields[i];
                    Object value = rs.getObject(field.getName( ));

                    // 破解私有
                    field.setAccessible(true);

                    // 给对象的该字段赋值
                    field.set(target, value);
                }
                list.add(target);

            }
        } catch (Exception e) {
            e.printStackTrace( );
        } finally {
            closeAll(conn, ps, rs);
        }
        return list;
    }

    /**
     * 增删改方法一样
     */
    public static boolean update(String sql, Object... args) {
        Connection conn = getConnection( );
        PreparedStatement ps = null;
        int num = 0;
        try {
            ps = conn.prepareStatement(sql);
            for (int i = 0; args != null && i < args.length; i++) {
                ps.setObject(i + 1, args[i]);
            }
            num = ps.executeUpdate( );
        } catch (Exception e) {
            e.printStackTrace( );
        } finally {
            closeAll(conn, ps);
        }
        return num > 0 ? true : false;
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/2879.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

企业微信中如何拉黑?拉黑个人和群成员有什么区别?

企业微信既可以拉黑个人好友&#xff0c;又可以拉黑群好友。 1. 拉黑个人好友 拉黑好友通俗来说就是不想再接收到对方的信息&#xff0c;企业微信可以通过设置消息免打扰的方式来屏蔽对方的消息。 【客户聊天界面】-【右上角的小人标志】-【第一栏名称进入】-【右上角三点】…

C语言——动态内存管理 malloc、calloc、realloc、free的使用

目录 一、为什么存在动态内存分配 二、动态内存函数的介绍 2.1malloc和free 2.2calloc 2.3realloc 三、常见的动态内存错误 3.1对NULL指针的解引用操作 3.2对动态开辟空间的越界访问 3.3对非动态开辟的内存使用free释放 3.4使用free释放一块动态开辟内存的一部分 3.5…

奇安信_防火墙部署_透明桥模式

奇安信_防火墙部署_透明桥模式一、预备知识二、项目场景三、拓扑图四、基本部署配置1. 登录web控制台2.连通性配置3.可信主机配置4.授权导入5.特征库升级6.安全配置文件五、透明桥配置1. 创建桥2. 端口绑定桥3. 创建桥端口六、结语一、预备知识 安全设备接入网络部署方式 二、…

运算放大器:电压比较器

目录一、单限电压比较器二、滞回电压比较器三、窗口电压比较器最近在学习电机控制&#xff0c;遇到了与运算放大电路相关的知识&#xff0c;然而太久没有接触模拟电路&#xff0c;对该知识已经淡忘了&#xff0c;及时温故而知新&#xff0c;做好笔记&#xff0c;若有错误、不足…

字节跳动测试岗面试记:二面被按地上血虐,所幸Offer已到手...

在互联网做了几年之后&#xff0c;去大厂“镀镀金”是大部分人的首选。大厂不仅待遇高、福利好&#xff0c;更重要的是&#xff0c;它是对你专业能力的背书&#xff0c;大厂工作背景多少会给你的简历增加几分竞争力。 但说实话&#xff0c;想进大厂还真没那么容易。最近面试字…

3分钟阐述这些年我的 接口自动化测试 职业生涯经验分享

接口自动化测试学习教程地址&#xff1a;https://www.bilibili.com/video/BV1914y1F7Bv/ 你好&#xff0c;我是凡哥。 很高兴能够分享我的接口自动化测试经验和心得体会。在我目前的职业生涯中&#xff0c;接口自动化测试是我经常进行的一项任务。通过不断地学习和实践&#xf…

【C++】map 和 set

文章目录一、关联式容器与键值对1、关联式容器2、键值对 pair3、树形结构的关联式容器二、set1、set 的介绍2、set 的使用三、multiset四、map1、map 的介绍2、map 的使用五、multimap一、关联式容器与键值对 1、关联式容器 在C初阶的时候&#xff0c;我们已经接触了 STL 中的…

基于SpringBoot的酒店管理系统

系统环境 开发语言&#xff1a;Java 框架&#xff1a;springboot JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09; 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclipse/i…

matplotlib参数详解

文章目录一、简介二、安装与调用三、绘图与风格设置3.1、绘图标记3.1.1、标记类型&#xff08;marker*&#xff09;3.1.2、标记大小、内部和边框颜色&#xff08;ms10、mfcr、mecg&#xff09;3.2、绘图线3.2.1、线类型&#xff08;linestyle--&#xff09;3.2.2、线宽&#xf…

C++入门教程||C++ 字符串||

C 字符串C 字符串C 提供了以下两种类型的字符串表示形式&#xff1a;C 风格字符串C 引入的 string 类类型C 风格字符串C 风格的字符串起源于 C 语言&#xff0c;并在 C 中继续得到支持。字符串实际上是使用 null 字符 终止的一维字符数组。因此&#xff0c;一个以 null 结尾的…

大文件上传

上图就是大致的流程一、标题图片上传课程的标题图片Ajax发送请求到后端后端接收到图片使用IO流去保存图片&#xff0c;返回图片的信息对象JS回调函数接收对象通过$("元素id").val(值)&#xff0c;方式给页面form表达img标签src属性值&#xff0c;达到上传图片并回显二…

若依微服务(ruoyi-cloud)保姆版容器编排运行

一、简介 项目gitee地址&#xff1a;https://gitee.com/y_project/RuoYi-Cloud 由于该项目运行有很多坑&#xff0c;大家可以在git克隆拷贝到本地后&#xff0c;执行下面的命令使master版本回退到本篇博客的版本&#xff1a; git reset --hard 05ca78e82fb4e074760156359d09a…

扒一扒抖音是如何做线程优化的

背景 最近在对一些大厂App进行研究学习&#xff0c;在对某音App进行研究时&#xff0c;发现其在线程方面做了一些优化工作&#xff0c;并且其解决的问题也是之前我在做线上卡顿优化时遇到的&#xff0c;因此对其具体实现方案做了深入分析。本文是对其相关源码的研究加上个人理…

人员玩手机离岗识别检测系统 yolov5

人员玩手机离岗识别检测系统根通过pythonyolov5网络模型识别算法技术&#xff0c;人员玩手机离岗识别检测算法可以对画面中人员睡岗离岗、玩手机打电话、脱岗睡岗情况进行全天候不间断进行识别检测报警提醒。Python是一种由Guido van Rossum开发的通用编程语言&#xff0c;它很…

【2023.3.18 美团校招】

文章目录1. 小美剪彩带2. 最多修改两个字符&#xff0c;生成字典序最小的回文串1. 小美剪彩带 题意&#xff1a;找出区间内不超过k种数字子数组的最大长度 使用双指针的方式&#xff0c;用哈希表来统计每个数出现次数。在双指针移动的过程中&#xff0c;动态的维护区间内不同数…

难以置信,已经有人用 ChatGPT 做 Excel 报表了?

要问2023年初科技领域什么最火&#xff0c;那自然是 ChatGPT。 ChatGPT 由人工智能研究实验室 OpenAI 于2022年11月30日推出。上线短短5天&#xff0c;用户数量已突破100万&#xff0c;在今年2月份&#xff0c;用户数量已经突破1亿。 ChatGPT 是一个超级智能聊天机器人&#…

【java】笔试强训Day4【计算糖果、进制转换】

目录 ⛳一、单选题 1.下列与队列结构有关联的是&#xff08; &#xff09; 2.类所实现接口的修饰符不能为&#xff08; &#xff09; 3.下列关于栈叙述正确的是&#xff08; &#xff09; 4.下面关于abstract关键字描述错误的是&#xff08; …

9.0 自定义SystemUI下拉状态栏和通知栏视图(十五)之悬浮通知布局

1.前言在进行9.0的系统rom产品定制化开发中&#xff0c;在9.0中针对systemui下拉状态栏和通知栏的定制UI的工作开发中&#xff0c;原生系统的下拉状态栏和通知栏的视图UI在产品开发中会不太满足功能&#xff0c;所以根据产品需要来自定义SystemUI的下拉状态栏和通知栏功能&…

【jenkins部署】一文弄懂自动打包部署(前后台)

这里写目录标题序言软件安装jdkmaven配置maven阿里镜像以及本地库位置git安装安装jenkins插件安装环境配置创建项目配置gitee生成gitee WebHookmaven打包验证是否打包成功连接远程服务器并重启服务远程服务器生成私钥配置ssh项目配置ssh脚本vue项目打包nodejs安装下载配置环境变…

【C++进阶】位图和布隆过滤器

文章目录位图位图概念位图使用场景位图的结构构造setresettest完整代码布隆过滤器布隆过滤器概念布隆过滤器结构构造setresettest完整版代码位图 位图概念 所谓位图&#xff0c;就是用每一位来存放某种状态&#xff0c;适用于海量数据&#xff0c;数据无重复的场景。通常是用…