什么是JDBC
- JDBC:Java Database Connectivity,Java 数据库连接。
- JDBC 是 Java 语言访问关系型数据库的标准 API。
- JDBC 是 Java 官方(Sun公司) 定义的一套操作数据库的规范,即定义了一组接口和类。
- 各数据库厂商实现 JDBC 接口,提供数据库驱动 jar 包。
- Java 程序员面向 JDBC 接口编程,真正执行代码时使用的是数据驱动 jar 包中的实现类。
Java 程序员面向 JDBC 接口编程,Java代码与具体的数据软件是解耦合的,将来切换底层数据库软件,Java代码可以基本不变。
JDBC入门程序
- 引入 MySQL 驱动 jar 包依赖
- 注册驱动
- 获取连接
- 定义 SQL 语句
- 执行SQL 语句
- 释放资源
JDBC入门程序 – 注册驱动
- 使用 Class.forname 加载类,注册驱动。
- 类加载会执行类的 static 代码块,在Driver 类的 static 代码块中注册驱动。
- jdbc4.0不再需要显示调用Class.forName()注册驱动而是自动调用驱动jar包下META-INF\services\java .sql.Driver文本中的类名完成注册
JDBC入门程序 – 获取连接
- url 的格式
- 语法 jdbc:mysql://ip地址(域名):端口号/数据库名称?参数名称1=参数值1&参数名称2=参数值2
- 例子,以下两个例子中,域名 localhost 和 IP地址 127.0.0.1 都指向本机
- jdbc:mysql://localhost:3306/school
- jdbc:mysql://127.0.0.1:3306/school
JDBC入门程序 – 定义SQL语句
JDBC入门程序 – 执行SQL语句
- 调用 Connection 的 createStatement 方法 获取 Statement
- 使用 Statement 执行 SQL 语句
JDBC入门程序 – 释放资源
- 关闭 Statement
- 关闭 Connection
JDBC API - DriverManager
DriverManager 的作用
- 注册驱动
- 获取数据库连接
JDBC API - Connection
Connection(数据库连接) 的作用
- 获取执行 SQL 的对象,包括:普通执行 SQL 对象,预编译 SQL 的执行 SQL 对象(防止 SQL 注入)。
- 进行事务管理
- 开启事务:
setAutoCommit(false);
- 提交事务:
commit();
- 回滚事务:
rollback();
- 开启事务:
JDBC API - Statement
Statement 的作用
- 执行 SQL 语句,可以执行 DDL、DML、DQL。
- executeUpdate 执行 DDL 和 DML(插入数据、更新数据、删除数据)
- executeQuery 执行 DQL,查询数据
JDBC API - ResultSet
ResultSet(结果集)的作用
- 封装了select语句的查询结果,我们从结果集中获取查询到的数据结果。
ResultSet 的核心方法,next 和 getXxx
- next(),ResultSet 读取数据的方式类型迭代器,next 将光标从当前行向后移一位,返回结果表示当前行是否为有效行。
- getXxx(参数),获取数据,Xxx表示数据类型,例如 getInt, 有两种参数类型
- String columLabel, columLabel 是列的名称
int columnIndex, columnIndex 是返回列(不是数据库中列的顺序)的编号,从1开始
从 ResultSet 中读取结果代码示例
输出结果
JDBC API - PreparedStatement
PreparedStatement的作用:
- 预编译SQL语句并执行,预防SQL注入问题
什么是 SQL 注入问题?
- 攻击者通过在应用程序中注入恶意的SQL代码来执行未经授权的数据库操作。
SQL 注入演示
SQL注入分析:为什么输出了错误的密码数据库仍能返回数据?
- 打印最终执行的 SQL
or 本来是参数值字符串的一部分,SQL注入攻击者让它成为了 SQL 语句的一部分。
- 由于最终执行的 SQL where 条件后永远为 true,相当于没有 where 条件,会返回表中所有数据。
- 注入让用户名密码校验失效了,
使用 PreparedStatement 解决 SQL 注入问题
- 第一步:获取 PrepareStatement 对象,从 Connection 获取,需要传入待执行 SQL
- 第二步:为 PrepareStatement 对象赋值:用数值替换 SQL 中的占位符?, setXxx(参数1, 参数2)
- 参数1:? 位置的编号,从1开始
- 参数2:替换?的数值
- 第三步:执行 SQL,不需要传入待执行 SQL
PreparedStatement 解决 SQL 注入问题的原理
- 预编译:在创建PreparedStatement对象时,数据库会对SQL语句进行预编译,将SQL语句解析为一个执行计划,这个执行计划中包含了SQL语句的结构和参数的占位符。
- 参数绑定:通过调用PreparedStatement对象的setXXX()方法,将参数值绑定到SQL语句的占位符上。这里的XXX表示参数的数据类型,例如setString()、setInt()等。
- 参数转义:在绑定参数的过程中,PreparedStatement会自动对参数值进行转义处理,将特殊字符进行转义,从而避免了恶意输入中的特殊字符对SQL语句的影响。
- 执行SQL语句:当执行PreparedStatement对象的executeQuery()或executeUpdate()方法时,数据库会使用预编译的执行计划和绑定的参数值来执行SQL语句,而不是直接拼接用户输入的数据。
由于执行了参数转义,实际执行的 SQL 发生了变化,不会发生SQL注入问题
数据库连接池
- 数据库连接池(Database Connection Pool)是一种管理和复用数据库连接的技术,它可以提高数据库访问的性能和效率。每次与数据库建立连接都需要进行网络通信、身份验证等操作,这些操作会消耗较多的时间和资源。而数据库连接池通过预先创建一定数量的数据库连接,并将这些连接保存在连接池中,应用程序在需要访问数据库时,从连接池中获取一个可用的连接,使用完毕后归还给连接池,而不是每次都重新建立连接。
- 数据库连接池的主要优势包括:
- 提高性能:连接池中的连接可以被多个线程共享,避免了频繁创建和销毁连接的开销,减少了数据库连接的建立时间,提高了数据库访问的性能和效率。
- 资源管理:连接池可以限制同时打开的连接数量,避免了过多的连接占用数据库资源,保护数据库的稳定性和可用性。
- 连接复用:连接池会复用已有的连接,避免了频繁的连接建立和断开操作,减少了网络通信和身份验证的开销。
- 连接管理:连接池可以对连接进行管理,包括连接的创建、销毁、超时检测等操作,确保连接的可用性和稳定性。
- 常用的数据库连接池有 C3P0、Druid(德鲁伊) 等。
- 下面介绍 Druid 连接池的使用方式
- 导入 druid 依赖 jar 包
- 配置连接池参数
- 创建连接池对象
- 从连接池中获取数据库连接