JDBC
JDBC
JDBC:Java Database Connectity,意为Java数据库连接
java提供了接口规范,由各个数据库厂商提供了接口的实现,厂商提供的实现类封装成jar文件
这充分的体现了面向接口编程的好处,程序员只关心标准和规范,而无需关注实现过程
JDBC的核心组成
接口储存在java.sql,javax.sql包下
厂商提供了这两个接口的实现类,并封装成jar包给程序员使用
JDBC搭建步骤
JDBC下载链接:MySQL :: Download MySQL Connector/J (Archived Versions)
选择对应MySQL版本后,选择Platform Independent(独立于平台)
快速入门
package com.xiaobai.base;
import java.sql.*;
public class JDBCQuick {
public static void main(String[] args) throws Exception {
//1. 注册驱动(缺省)
//Class.forName("com.mysql.cj.jdbc.Driver");
//DriverManager.registerDriver(new Driver());
//2. 获取连接对象
String url = "jdbc:mysql://192.168.2.2:3306/xiaobai";
String user = "root";
String password = "Zhuwenxue2002";
Connection connection = DriverManager.getConnection(url, user, password);
//3. 获取执行SQL语句的对象
Statement statement = connection.createStatement();
//4. 编写SQL语句并执行,接收返回的结果集
String sql = "select * from user";
ResultSet resultSet = statement.executeQuery(sql);
//5. 处理结果,遍历结果集
while (resultSet.next()) {
int id = resultSet.getInt("u_id");
String name = resultSet.getString("u_name");
double salary = resultSet.getDouble("u_salary");
int age = resultSet.getInt("u_age");
System.out.println(id + "\t" + name + "\t" + salary + "\t" + age);
}
//6. 释放资源(先开后关的原则)
resultSet.close();
statement.close();
connection.close();
}
}
JDBC核心API
驱动的注册
Class.forName("com.mysql.cj.jdbc.Driver");//通过加载类来注册驱动
DriverManager.registerDriver(new Driver());//手动注册驱动,这个类的包别导错了
***在JDK6之后,java中会自动检索驱动是否存在,所以现在不用注册驱动了(白学)***😓
Connection
创建与数据库的连接,
Connection connection = DriverManager.getConnection(url, user, password);
通过DriverManager调用静态方法getConnection即可获得数据库连接
当我们想在url后接参数时,使用以下格式:
String url = "jdbc:mysql://192.168.2.2:3306/xiaobai?key1=value1&key2=value2";
jdbc:mysql://为固定格式,只要连接的是MySQL的数据库都要这么写
-
connection还负责管理事务,提供了commit和rollback方法,用于提交事务和回滚事务
-
connection可以创建一个发送语句的对象statement,用于执行SQL语句并与数据库进行交互
-
在使用JDBC技术时,必须要先获取Connection对象,使用完毕后,要释放资源,避免资源占用浪费以及泄露
Statement
由connection对象获得,可以向数据库发送SQL语句并获取执行结果
Statement英文释义:陈述
结果可以是一个或多个结果
- 增删改:受影响行数的单个结果
- 查询:单行单列、多行多列、单行多列等结果
动态查询
String s = new Scanner(System.in).nextLine();
String sql = "select * from user where u_name='" + s + "'";
我们如果通过拼接字符串的方式来对SQL语句实现动态查询,就会产生SQL注入攻击问题
比如,我们在以上代码输入 abc' or '1' = '1 就会将SQL语句拼接为 select * from user where u_name='abc' or '1' = '1'
这样就会遍历整个数据表,这是十分危险的
PreparedStatement
PreparedStatement是Statement的子接口,用于执行预编译的SQL查询
-
防止SQL注入:PreparedStatement支持参数化查询,就是将参数作为参数传递到SQL语句中,采用?占位符的方式,将传入的参数用一对单引号包裹起来,无论传递什么都作为值,有效防止传入关键字导致SQL注入问题
-
性能提升:PreparedStatement时预编译SQL语句,可以代码复用,效率更高
后续的学习我们都是基于PreparedStatement进行实现🙃
-
PreparedStatement是通过connection调用prepareStatement方法获得,这个方法不支持无参构造
-
通过setString()方法传入参数,注:这里的索引不再是从零开始,1即为第一个参数
-
调用executeQuery(),传入SQL语句到数据库,获得结果集
String s = new Scanner(System.in).nextLine();
PreparedStatement preparedStatement = connection.prepareStatement("select * from user where u_name=?");
preparedStatement.setString(1, s);
ResultSet resultSet = preparedStatement.executeQuery();
executeQuery中文释义:执行查询
ResultSet
ResultSet用于从数据库中执行查找语句接收结果集,它提供了用于遍历和访问查询结果的方式
- 遍历结果:ResultSet可以使用next()方法将游标移动到结果集的下一行,逐行遍历数据库查询的结果,返回值为boolean类型true代表有下一行结果,false则代表没有
- 获取单列结果:可以通过getXxx的方法获取单列的数据,该方法为重载方法,支持索引和列名进行获取