一、什么是JDBC
- JDBC(Java Database Connectivity) 是由SUN公司提出来的一组规范,主要作用是使用Java程序访问关系型数据库系统 。
- JDBC的组成:
2.1 组成 : 接口 + 各个数据库厂商提供的实现
- 接口: 是SUN公司提出来的规范。
- 实现类: 各个数据库生产厂商自己提供实现类, 他们将编好的实现类打成jar包,发布到自己的官网上。 比如 : oracle的数据库驱动jar 叫 ojdbc5.jar 或ojdbc6.jar 。
二、JDBC编程的核心
- JDBC编程的核心思想
- JDBC核心API
| API名称 | 作用 |
|---|---|
| DriverManager 工具类 | 帮助我们管理不同的数据库驱动jar, 实现Connection的创建,我们只需要提供 url、username、password即可 |
| Connection (接口) | 一个connection代表与数据库建立的一个连接 |
| Statement (接口)(PreparedStatement是Statement的子接口 ) | statement主要负责发送SQL语句到数据库执行, 如果执行的是查询返回结果集(ResultSet), 如果执行的是增删改返回影响数据的行数 |
| ResultSet(接口) | 封装了从数据库查询返回的数据结果集 |
三、使用JDBC开发第一个应用
- 搭建开发环境
1.1 引入数据库驱动jar : ojdbc6.jar - 编码 【重点】
2.1 加载驱动
Class.forName(“oracle.jdbc.OracleDriver”);
2.2 创建连接 - Connection
Connection conn = DriverManager.getConnection(url,username,password);
url = jdbc:oracle:thin:@localhost:1521:xe // xe是数据库实例名(SID),在系统服务列表中找到Oracle数据库的服务, 去掉OracleService 剩下的就是SID
username = 你数据库的用户
password = 你数据库的密码
2.3 编写SQL
String sql = “insert/update/delete/select”; (增/改/删/查)
2.4 创建Statement执行SQL
Statement stm = conn.createStatement();
int i = stm.executeUpdate(sql); // 执行增删改,返回值代表执行SQL影响数据的行数
ResultSet rs = stm.executeQuery(sql); // 执行查询,返回值是一个结果集对象
2.5 处理结果集 - 如果执行的是查询
ResultSet的特点: 这个结果集对象里有一个游标,初始在结果集第一条数据的上一行,通过调用rs.next()方法移动游标, rs.next()返回值代表游标指向的当前行是否有数据, 可以使用while循环遍历取出结果集中的数据。
ResultSet取数据: 通过调用rs.getXXX(columnIndex)系列方法取出数据。
rs.getInt(columnIndex) - 对应表字段类型 number(n)
rs.getDouble(columnIndex) - 对应表字段类型 number(m,n)
rs.getString(columnIndex) - 对应表字段类型 varchar2 和 char
注意: columnIndex 代表列的下标, 从1开始。(这个下标对应的列是当前返回结果集中包含列的下标)
2.6 释放资源 - 先创建后关闭的原则
stm.close();
conn.close();
注意: Statement存在SQL注入的风险,SQL注入是指一些黑客或非法分子,通过字符串拼接的形式将非法的字符注入到系统原有的SQL语句中,进而威胁到系统数据安全的一种现象 。
四、PreparedStatement 的使用【重点】
-
PreparedStatement是Statement的子接口, 作用与Statement一样, 也是用于执行SQL语句的。但是PreparedStatement可以执行参数化的SQL语句。
比如: 它可以接收 insert into account values(account_seq.nextval,?,?,?,?);
SQL语句中的? 号,表示一个占位符,一个占位符对应一个列。 -
PreparedStatement的使用:
2.1 创建:
String sql = “insert into account values(account_seq.nextval,?,?,?,?)”;
PreparedStatement pstm = conn.prepareStatement(sql);
2.2 执行SQL:
① 给占位符赋值 : 调用pstm.setXXX(parameterIndex,value) 系列方法。
参数parameterIndex :对应SQL语句中的占位符下标,从1开始。
参数value: 给对应占位符位置设置的值。
pstm.setString(int parameterIndex, String value); - 对应占位符的字段 char 和varchar2类型
pstm.setInt(int parameterIndex, int value); - 对应占位符字段 number(n)类型
pstm.setDouble(int parameterIndex, int value);- 对应占位符字段 number(m,n)类型
② 在最终执行SQL
int i = pstm.executeUpdate(); // 执行增删改
ResultSet rs = pstm.executeQuery(); //执行查询 -
Statement与PreparedStatement对比
| API名称 | 创建 | 使用 | SQL注入问题 |
|---|---|---|---|
| Statement | conn.createStatement(); | stm.executeUpdate(sql) stm.executeQuery(sql) | 存在 |
| PreparedStatement 是Statement的子接口 | // 可以接收一个参数化的SQL语句conn.prepareStatement(sql); | // 执行之前需要给占位符赋值pstm.executeUpdate(); pstm.executeQuery(); | 不存在 |
- PreparedStatement 的执行原理 【了解】
4.1 数据库执行一条SQL语句的过程: 检查权限 -> 检查语法 -> 值注入 - >最后执行
4.2 PreparedStatement执行过程:
① 当创建PreparedStatement的时候, 先将SQL语句发送到数据库进行预编译。预编译阶段要执行检查权限和检查语法。 然后将编译好的SQL结构放在数据库。
② 当调用executeUpdate()/executeQuery()方法的时候,再将给占位符的赋值一次性发送到数据库,注入到编译好的SQL中,然后执行。
4.3 在批处理上,PreparedStatement的效率要高于Statement;
五、JDBC编程常见错误
-
错误类型:
排除错误思路: 类找不到异常,检查类全限定名是否有误。 -
错误类型:
排除错误思路: 无效的用户名和密码, 检查数据库用户名密码是否正确 -
错误类型:
排除错误思路: 第一种情况: 数据库URL写错了,检查url. 第二种情况: 数据库服务出现错误,需要重新启动数据库服务。 -
错误类型:
排除错误思路: 检查 结果集ResultSet的处理下标是否正确, 或检查PreparedStatement下标处理是否正确。