JDBC编程,SQL注入与连接池

2023-05-16

JDBC概念

JDBC(Java Data Base Conection)是java中提供的一套标准的应用编程接口,用来连接Java编程语言和数据库

JDBC常用组件:

  • DriverManger:数据库驱动程序的管理类,匹配java程序到数据库的驱动的协议(mysql,sqlerver...),识别出某个子协议与数据库服务器进行通信
  • Driver:处理与数据库服务器通信的,主要是DriverManger管理的对象,指具体的连接驱动(MYSQL驱动)
  • Connection:接口形式,接触数据库的所有的方法,以及数据库对象的上下文
  • Statement:创建用于这个接口的对象将所有的SQL提交的数据库(SQL操作都是通过该对象)
  • ResultSet:使用SQL语句执行查询后,返回的结果都是保存在该对象中
  • SqlExeption:这个类是数据库应用程序中的任何错误

注意:JDBC是第三方提供的库,要使用JDBC必须先引入jdbc相关jar包(mysql-connection-jave)

idea上直接编写(ArrayList等)等可以直接使用,这是JDK提供的工具类

 

使用maven来构建程序,主要作用用来统一管理第三方依赖jar,包括jar下载,更新...等操作使用maven可以更加的方便

mybatis,spring,springMVC,springboot框架都需要通过maven来管理

JDCB的使用

通过maven引入依赖

        <!--mysql依赖-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.39</version>
        </dependency>

核心信息

  • 驱动包路径
  • url:  jdbc:子协议(mysql)://ip+端口/数据库名
  • 账号
  • 密码

JDBC编程流程

  • 1、引入驱动包路径 Class.fromName
  • 2、连接数据库 DriverManager.getConnection(url,name,passwd)获取Connection对象
  • 3、获取Statement对象,通过Connection对象来获取
  • 4、通过Statement执行SQL
  • 5、查询操作会获取ResultSet结果集对象
  • 6、关闭资源
public class JDBCDemo {
    public static void main(String[] args) {
        //加载MYSQL驱动 com.mysql.jdbc.Driver
        try {
            Class.forName("com.mysql.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        try {
        //连接MYSQL数据库
        /**
         * 连接数据库的信息:
         * url:jdbc:mysql://localhost:3306/ssms
         * username:用户名
         * password:密码
         */
           //获取Connection
            Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/ssms", "root", "123456");

            //获取Statement对象
            Statement statement = connection.createStatement();


            String sql = "select * from user ";
            //查询操作使用executeQuery
            ResultSet resultSet = statement.executeQuery(sql);


            //处理result结果集
            /**
             * resultSet对象返回的是一个结果集,可以包含多个对象
             * 多个对象中,每调用next()方法处理结果集中的一行数据
             *
             */
            while (resultSet.next()) {
                Integer id = resultSet.getInt("id");
                resultSet.getI
                String account = resultSet.getString("account");
                String name = resultSet.getString("name");
                System.out.println("Id:"+id+",name:"+name);
            }

            //关闭资源
            connection.close();


        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

SQL注入问题

通过输入的参数和SQL进行拼接的查询数据库,为了绕开正常SQL逻辑而添加一些额外的SQL信息来来达到访问数据库的目的,以登陆为例:

 public static  String login(String name ,String passwd){
        getConnetion();
        try {
            Statement statement = connection.createStatement();
            String sql = "select * from user where name = "+name+" and password = "+passwd;
            // select * from user where name = XXX and password =XXX
            //select * from user where name = XXX or 1=1  and password =XXX
            ResultSet resultSet = statement.executeQuery(sql);
            if (resultSet.next()) {
                return "success";
            } else {
                return "fail";
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        close();
        return "fail";
    }

正常登陆通过name(2555)和passwd(111111)能够正常登陆

但是现在name= "2555 or 1=1"或者"2555 # XXX"(#后面变成注释了) 和passwd(错误信息)是可以完成登陆的,当前拼接的SQL信息为select * from user where name = XXX or 1=1  and password =XXX,改变SQL意义

String name = "2555 or 1=1";

String passwd = "11111";

String login = login(name, passwd);

 

如何解决SQL注入问题

使用PreparedStatement来解决SQL注入的问题,

将sql和参数分别传给数据库服务端,会先进行预编译,会先进行SQL语法的检查,在语法检测成功后才进行执行,如果语法检查不通过则无法执行

 public static  String login1(String name ,String passwd){
        getConnetion();
        try {
            //使用prepareStatement来实现 ,其中SQL中参数用"?"占位符
            String sql = "select * from user where name = ? and password = ?";
            PreparedStatement statement = connection.prepareStatement(sql);
            //往SQL中占位符给定数据  setString第一参数指的是占位符的位置,第一个位置为1
            statement.setString(1,name);
            statement.setString(2,passwd);

            ResultSet resultSet = statement.executeQuery(sql);
            if (resultSet.next()) {
                return "success";
            } else {
                return "fail";
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        close();
        return "fail";
    }

PreparedStatement和Statement区别点

 

  • SQL注入问题(安全性问题)

Statement是将拼接的SQL在服务端直接执行,无法避免的SQL注入问题,PreparedStatement将SQL和参数分别传递给服务单,先进行预编译,可以检查SQL语法,可以避免SQL注入问题

  • 效率不同

PreparedStatement先编译,在讲编译结果拿来执行,Statement是在服务端需要进行编译执行,PreparedStatement效率高于Statement

事务

JDBC同样支持事务,在JDBC下和事务相关的额操作都封装在Connection提供的相应操作

            /**
             * jdbc操作事务在Connection实例下提供的方法来进行事务相关操作
             */
            connection.commit();//提交事务
            connection.rollback();//事务回滚
            connection.setSavepoint();//保存点
            Savepoint point1 = connection.setSavepoint("point1");
            connection.rollback(point1);//回滚到指定的保存点

连接池

在JDBC的操作过程中,每次进行SQL操作都需要先进行连接操作,SQL执行完毕后需要关闭连接,在数据库的并发量比较高的情况下,频繁的进行数据库的连接和关闭是比较消耗系统性能。为了解决对资源的频繁的连接关闭问题,可以通过连接复用来解决,那么就引入了连接池的概念

连接池的原理

在创建连接池时,就先初始化指定数量的连接(initnum),将建立的连接放入到池中,当有新的SQL操作请求时,可以在池中获取一个空闲的连接来执行SQL操作,当SQL执行完成后将连接放入池中重复使用,最大连接数(maxNum),当池中的连接都在使用时,而且连接数没有到达最大的时候,就可以新创建一个连接来执行新的SQL请求操作,如果已经达到了最大的连接数且所有的连接都在使用时可以将新连接进行拒绝或者是通过缓存先存储等有空闲连接在此执行,有空闲时间阈值,当一个连接空闲的时间超过阈值,就自动进行销毁

连接池的优势

1、复用资源

2、对资源的进行统一的管理

3、提高了系统资源的利用率

 

连接池:c3p0,Druid,dbcp...连接池

引入依赖

配置连接池

使用连接池

 

C3p0连接池

引入依赖

  <!--c3p0连接池-->
        <dependency>
            <groupId>com.mchange</groupId>
            <artifactId>c3p0</artifactId>
            <version>0.9.5.2</version>
        </dependency>

创建c3p0-config.xml配置文件

在resources资源路径下增加c3p0的配置

<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
    <!--配置连接池mysql-->
    <named-config name="mysql">
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/ssms</property>
        <property name="user">root</property>
        <property name="password">123456</property>
        <!-- 初始化连接数 -->
        <property name="initialPoolSize">10</property>
        <!--最大空闲时间,多少秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 -->
        <property name="maxIdleTime">30</property>
        <!--连接池中保留的最大连接数。Default: 15 -->
        <property name="maxPoolSize">100</property>
        <!-- 最小连接数 -->
        <property name="minPoolSize">10</property>
    </named-config>
    
</c3p0-config>

连接池的使用

 //设置数据源DataSource
        ComboPooledDataSource dataSource = new ComboPooledDataSource("mysql");

        try {
            //获取Connection
            Connection connection = dataSource.getConnection();

            //获取Statement对象
            Statement statement = connection.createStatement();

            String sql = "select * from user where id = 25";
            ResultSet resultSet = statement.executeQuery(sql);

            while (resultSet.next()) {
                Integer id1 = resultSet.getInt("id");
                String account = resultSet.getString("account");
                String name = resultSet.getString("name");
                System.out.println("Id:" + id1 + ",name:" + name);
            }


        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

 

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JDBC编程,SQL注入与连接池 的相关文章

  • 这个 SQL DELETE FROM 语法有什么问题?

    我正在尝试删除 96k 记录 删除表 xoops bb posts text 页面中没有与 xoops bb posts 匹配的 post id 的所有记录 此查询返回 91k 条记录 SELECT FROM xoops bb posts
  • 在 jdbc 程序中使用时,通过 SQL 客户端插入表中的记录未显示

    我使用 SQL 客户端和 JDBC 程序将几行插入到我的表 EMP 中 使用 SQL 客户端插入的记录不会显示在 Java 的输出控制台中 我正在使用 Java 8 和 oracle 11g 数据库来插入和读取数据库 除了通过 SQL 客户
  • 如果列有多个逗号分隔值,如何过滤 mysql 数据?

    我想问如果检查条件以查找具有多个逗号分隔值的列 如何过滤 mysql 数据 我给你举个例子 我有下表说 tbitems id item names item types item features 1 item 1 8 6 10 5 4 9
  • CROSS APPLY 不适用于 SQL SERVER 2000?

    如何在 SQL Server 2000 中使用与 CROSS APPLY 等效的功能 我有一个函数返回传递的 id 的顶级父级 ALTER Function dbo fn GetTopParentRiskCategory RctId int
  • Postgres - 如何在插入时自动调用 ST_SetSRID(ST_MakePoint(lng, lat), 4326)?

    我正在使用postGIS 并且我对SQL不是很熟悉 我可以成功插入到我的markers表只要我做这样的事情 伪代码 INSERT INTO markers created by title description lat lng geogr
  • SQL Server 将一个表中的所有行复制到另一个表中,即重复表

    我想保留一张桌子作为历史并用空桌子替换它 我如何通过 Management Studio 执行此操作 将您的表复制到要存档的表中 SELECT INTO ArchiveTable FROM MyTable 删除表中的所有条目 DELETE
  • 如何使用 SQL 查询在 Access 中的字段上设置验证规则?

    我正在使用 MS Access 2016 Office 365 目前遇到问题 下面是一个演示此问题的示例 这里我创建了一个表 名为节点家庭链接 由两个字段组成 NodeID 和 FamilyID 如下所示 现在 NodeID 是从另一个表
  • 插入后用触发器更新多行(sql server)

    我有一个表 orderDetails 包含订单的产品 产品编号 color size quantity 和一个表库存 产品编号 size color stock 订单完成后 我使用此查询将项目插入表中orderDetails INSERT
  • 为什么此 SQL 更新失败(“列名无效”)?

    我有一个 SQL Server CE 表 如下所示 我正在尝试像这样更新其唯一记录 update workTables set fileType INV 但我得到 Why UPDATE 请查看相关问题here https stackover
  • SqlCommand 参数与 String.Format [重复]

    这个问题在这里已经有答案了 我一直在互联网上搜索 但似乎找不到任何可以解释我的问题的内容 可能是我没有使用正确的搜索字符串 所以我在这里发帖希望有人可以帮助我有了这个 我的程序是使用Visual Studio 2010用C 编写的 我注意到
  • 使用 WHILE 创建虚拟数据

    我尝试使用 a 在表中插入一些虚拟数据WHILE 但它运行得非常非常慢 我在想也许我写的代码不正确 你能看一下并确认一下吗 Insert dummy data DECLARE i int Content int SET i 5001 WHI
  • 如何以最少的查询次数获取帖子列表和关联标签

    我的表格结构如下 标签 更多的是一个类别 id 标签名称 描述 slug POSTS ID 标题 网址 邮戳 id idPost idTag USERS ID 用户名 userSlug VOTES id idPost idUser 每个帖子
  • Glassfish 4 - JDBC 领域

    Glassfish 4 中的密码加密算法和摘要算法有什么区别 因为Password加密算法不能为空 所以我使用了MD5 Encoding使用了Hex 摘要算法为空 因此默认为 SHA 256 但是 如果我使用 JAAS 制作一个简单的登录应
  • 插入多行并返回主键时 Sqlalchemy 的奇怪行为

    插入多行并返回主键时 我注意到一些奇怪的事情 如果我在 isert 查询中添加使用参数值 我会得到预期的行为 但是当将值传递给游标时 不会返回任何内容 这可能是一个错误还是我误解了什么 我的sqlachemy版本是0 9 4 下面如何重现错
  • Oracle 中的 SQL 调优 [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 是否有任何文章 链接可以让我找到 SQL 调优 Oracle 的示例 如果能用例子来解释那就太好了 我需
  • 对于数据库来说,选择正确的数据类型会影响性能吗?

    如果是这样 为什么 我的意思是 tinyint 的搜索速度比 int 快吗 如果是这样 性能上的实际差异是什么 是的 根据数据类型 它确实有所不同 int vs tinyint不会在速度上产生明显的差异 但会在数据大小上产生差异 假设tin
  • 使用Powershell访问远程Oracle数据库

    我需要能够连接到我的网络上基于 Windows 7 的 Oracle 服务器 32 位 Oracle XE 我需要连接的机器运行 Windows 7 64 位 两台机器上都安装了 Powershell 我已在 64 位计算机上安装了 Ora
  • SQL参数化查询不显示结果

    我的 DataAcess 类中有以下函数 但它没有显示任何结果 我的代码如下 public List
  • 查询中列的顺序重要吗?

    当从 MySQL 表中选择列时 与表中的顺序相比 选择列的顺序是否会影响性能 不考虑可能覆盖列的索引 例如 您有一个包含行 uid name bday 的表 并且有以下查询 SELECT uid name bday FROM table M
  • SQLite HAVING 比较错误

    我有一个测试 SQLite 表 用于存储带有值的报告数据 CREATE TABLE IF NOT EXISTS test fact daily revenue date TEXT revenue NUMERIC product TEXT I

随机推荐

  • EBYTE E103-W02 WIFI模块配置总结(TCP+UDP+HTTP+云透传)

    目录 1 硬件配置 1 1 原理图 1 2 管脚配置 2 AT指令集 3 AP模式配置 3 1AP介绍 3 2 AP配置TCP通信 3 3 AP配置UDP通信 4 STA模式配置 4 1STA介绍 4 2配置过程 4 3网页配置 5 基于亿
  • JavaSE-自定义单链表

    目录 1 自定义链表实现 2 基础操作 2 1 链表打印操作 2 2 链表逆序打印 2 3 链表逆置 3 进阶操作 3 1查找倒数第K个结点 3 2 不允许遍历链表 xff0c 在pos结点之前插入 3 3两个链表相交 xff0c 输出相交
  • SRGAN实现超分辨率图像重建之模型复现

    1 论文介绍 1 1简介 论文名称 Photo Realistic Single Image Super Resolution Using a Generative Adversarial Ledig C Theis L Huszar F
  • JavaSE-自定义队列+两栈实现队列+两队列实现栈

    1 顺序队列实现 与栈一样 xff0c 队列也是一种操作受限制的线性表 xff0c 但与栈不同的是 xff0c 栈是后进先出 xff0c 队列的特点是先进先出 实现与栈类似 xff0c 队列有一个队头指针和一个队尾指针 xff0c 入队的时
  • JavaSE-八大经典排序算法及优化算法思路与实现

    目录 1 冒泡排序 1 1算法思想 1 2 算法实现 1 3 算法优化 1 4 算法分析 2 简单选择排序 2 1 算法思想 2 2 算法实现 2 3 算法优化 2 4 算法分析 3 直接插入排序 3 1 算法思想 3 2 算法实现 3 3
  • 快速超分辨率重建卷积网络-FSRCNN

    1 网路结构图 2 改进点 SRCNN缺点 xff1a SRCNN将LR送入网络前进行了双三次插值上采样 xff0c 产生于真实图像大小一致的图像 xff0c 会增加计算复杂度 xff0c 因为插值后图像更大 xff0c 输入网络后各个卷积
  • PriorityQueue(优先级队列)的解读与底层实现

    目录 1 什么是优先级队列 xff1f 2 优先级队列的特性 3 如何使用优先级队列 4 JDK源码分析 4 1类的继承关系 4 2类的属性 4 3常用的方法 5 自定义优先级队列实现 5 1 优先级队列类定义 5 2 add 方法 5 3
  • HashMap的使用与底层结构剖析

    目录 一 基础概念 二 先使用再了解 三 底层结构 1 HashMap结构 xff08 JDK1 8以前 xff09 2 HashMap结构 xff08 JDK1 8以后 xff09 四 HashMap实现 1 成员变量 2 put实现 3
  • 线程基础与使用测试

    目录 一 进程和线程 二 线程的创建 1 继承Thread类 xff0c 重写run 方法 2 实现Runnable接口 xff0c 重写run方法 3 匿名线程 xff0c 匿名内部类 4 实现Callable接口 xff0c 重写cal
  • 线程生命周期及常用方法的使用

    一 守护线程 守护线程是什么 xff1f 守护线程是一类比较特殊的线程 xff0c 一般用于处理后台的工作 xff0c 比如JDK的垃圾回收线程 守护线程的作用 xff1f JVM xff08 Java Virtual Machine xf
  • git合并被fork的仓库的远程分支

    如果你 fork 了一个仓库并在自己的 forked 仓库中进行了更改 xff0c 而原始仓库也有一些更新 xff0c 此时想将原始仓库的更新合并到你的 forked 仓库 xff0c 可以按照以下步骤 xff1a 1 将原始仓库添加为远程
  • Linux-基础知识及常见操作命令汇总

    目录 1 终端操作 2 命令手册 3 关机重启 4 runlevel 5 目录结构 6 文件属性 7 Linux文件属主和属组 8 目录常用命令 9 VIM命令 10 进程管理命令 1 进程状态 2 ps命令 3 pstree命令 jobs
  • 关键字synchronized与volatile详解

    在多线程并发编程中synchronized和volatile都扮演着重要的角色 xff0c synchronized一直是元老级角色 xff0c 很多人都会称呼它为重量级锁 但是 xff0c 随着Java SE 1 6对synchroniz
  • 迁移学习与Transformer架构

    迁移学习 迁移学习干什么的 xff1f 迁移学习是通过从已学习的相关任务中转移知识来改进学习的新任务 Eg xff1a 学习识别苹果可能有助于识别梨 xff0c 学习骑自行车可能有助于学习骑摩托车 xff0c 学习打羽毛球可能有助于学习打网
  • 生产者消费者模型分析与实现

    生产者消费者模式就是通过一个容器来解决生产者和消费者的强耦合问题 生产者和消费者彼此之间不直接通讯 xff0c 而通过阻塞队列来进行通讯 xff0c 所以生产者生产完数据之后不用等待消费者处理 xff0c 直接扔给阻塞队列 xff0c 消费
  • ConcurrentHashMap优点与源码剖析

    哈希表是中非常高效 xff0c 复杂度为O 1 的数据结构 xff0c 在Java开发中 xff0c 我们最常见到最频繁使用的就是HashMap和HashTable xff0c 但是在线程竞争激烈的并发场景中使用都不够合理 HashMap
  • IO-字节流

    文件 amp File类的使用 1 文件的概念 文件可以分为文本文件 二进制文件 2 IO流的概念 流是有顺序 有起点和终点的集合 xff0c 是对数据传输的总称 流的本质就是用来对数据进行操作 IO是我们实现的目的 xff0c 实现这个目
  • STM32F407的TCP编程出现客户端无法连接上服务器,DHCP获取IP失败,服务器重启客户端无法自动重连问题解决方案

    单写一篇文章记录这些问题 xff0c 因为有的问题实在是困扰了我太久太久了 xff0c 终于解决了 xff01 xff01 xff01 1 STM32F407的TCP编程 xff0c TCP SERVER测试完全正常 xff0c TCP C
  • SQL练习汇总(查询“01“课程比“02“课程成绩高的学生的信息及课程分)

    1 学生表 Student SID Sname Sage Ssex SID 学生编号 Sname 学生姓名 Sage 年龄 Ssex 学生性别 编号 姓名 年龄 性别 1 赵雷 20 男 2 钱电 20 男 3 孙风 21 男 4 吴兰 1
  • JDBC编程,SQL注入与连接池

    JDBC概念 JDBC Java Data Base Conection 是java中提供的一套标准的应用编程接口 xff0c 用来连接Java编程语言和数据库 JDBC常用组件 xff1a DriverManger xff1a 数据库驱动