4.1 DriverManager 和DataSource
- DataSource驱动管理类,⽤于管理JDBC驱动程序,可以从驱动程序中获取数据库连接,始于JDK1.1。
- DataSource数据源是DriverManager的替代⽅案,始于JDK1.4,是获取数据库连接的首选方法,推荐使用。
4.2 DriverManager 与DataSource的区别
- DriverManager和DataSource都可以获取到数据库连接,但它们之间存着着⼀些区别,主要在于连接的管理方式和资源利用效率
- 连接管理方式不同:
①DriverManager每次调用getConnection方法都会初始化⼀个新的连接(上文Driver类中,我们注意到过源码中就有new Driver()),使用完成后会关闭真实连接,导致资源浪费
②DataSource使用了连接池的技术,会在初始化时创建⼀定数量的数据库连接,这些连接可以重复使用,关闭时并不是真正关闭连接,而是将连接归还给连接池,以供后续使用,有效地提高资源利用率和和性能
4.3 Connection 数据库连接
数据库连接(会话)对象,在连接的上下文中执行SQL语句并返回结果
4.3.1 Statement对象
- ⽤于执⾏静态SQL语句并返回执⾏结果,由于只能执⾏静态语句,所以这⾥会有⼀个问题,假设⼀个语句中需要动态的参数,⽐如where⼦句中的条件,那么只能通过字符串拼接的⽅式组装完成的SQL语句,比如:
String sql = "select * from student where name = '" + name + "' and class_id =
" + classId;
- 字符串拼接形式构造SQL语句时,如果不处理参数中的特殊字符就会造成SQL注⼊,这是⼀个非常严重的安全性问题。
4.3.2 SQL注入
4.3.3 PreparedStatement
- 预编译SQL语句对象,SQL语句被预编译并存储在PreparedStatement对象中,可以使用该对象多次执行SQL语句,同时可以解决SQL注入问题。
示例:通过Connection对象获取到PreparedStatement对象,需要传⼊SQL模板,动态参数用占位符?
表示
// 获取了个处理SQL的PrepareStatement对象
PreparedStatement preparedStatement = connection.prepareStatement("select id,
name, sno, age, gender, enroll_date, class_id from student where name = ? and
class_id = ?");
- 为动态参数设置真实值,下标从1开始
// ⽤真实值去替换占位符
preparedStatement.setString(1, "宋江");
preparedStatement.setLong(2, 2);
- 执行SQL语句
// select 操作
ResultSet resultSet = statement.executeQuery();
// insert, update, delete操作
//増 删 改 返回的是受影响的行数
int result = statement.executeUpdate();
//1 表示插入成功,0表示错误
4.3.4 CallableStatement
用于执行SQL存储过程的接⼝。
4.3.5 executeQuery()
执行结果返回的是⼀个结果集,通常⽤于select操作
4.3.6 executeUpdate()
执行结果返回的是⼀个整形,通常用于insert,update,delete操作
4.3.7 ResultSet结果集
- 是⼀个查询结果集的数据表,通常由执行查询操作的语句生成。
- ResultSet对象维护了⼀个指向当前数据行的游标,最初游标位于第⼀行之前,调用next方法将游标移动到下⼀行,当ResultSet中没有更多的数据行时返回false,所以可以在while循环中使用它来遍历结果集。
- ResultSet接⼝提供了getter方法(getBoolean、getLong等),用于从当前行检索列值,可以使用列的索引号或列的名称来检索值。⼀般来说,使用列索引会更有效率,索引编号从1开始,按照从左到右的顺序读取。