Java之JDBC技术详解

16 篇文章 1 订阅

一、简介

1. 什么是JDBC

JDBC (Java Date Base Connectivity),指 Java 数据库连接,是一种标准Java应用编程接口 (Java API),用来连接Java编程语言和广泛的数据库。

JDBC API 库包含下面提高的每个任务,都是与数据库相关的常用用法。

  • 制作到数据库的连接
  • 创建 SQL 或 MySQL 语句
  • 创建 SQL 或 MySQL 查询数据库
  • 查看和修改所产生的记录

从根本上来说,JDBC 是一种规范,它提供了一套完整的接口,允许便携式访问到底层数据库,因此可以用 Java 编写不同类型的可执行文件,例如:

  • Java 应用程序
  • Java Applets
  • Java Servlets
  • Java ServerPages (JSPs)
  • Enterprise JavaBeans (EJBs)

所有这些不同的可执行文件就可以使用JDBC驱动程序来访问数据库,这样可以方便的访问数据。

JDBC 具有 ODBC 一样的性能,允许 Java 程序包含与数据库无关的代码。

2. 先决条件

为了更好的理解本教程,需要对以下两个主题内容很好的理解:

  • 核心 Java 编程
  • SQL 或 MySQL 数据库

3. JDBC 架构

JDBC 的 API 支持两层和三层处理模式进行数据库访问,但一般的 JDBC 架构由两层处理模式组成:

  • JDBC API:提供了应用程序对 JDBC 管理器的连接
  • JDBC DRIVER API:提供了 JDBC 管理器对驱动程序连接

JDBC API 使用驱动程序管理器和数据库特定的驱动程序来提供异构 (heterogeneous) 数据库的透明连接。

JDBC 驱动程序管理器可确保正确的驱动程序来访问每个数据源。该驱动程序管理器能够支持连接到多个异构数据库的多个并发的驱动 程序。

以下是结构图,其中显示了驱动程序管理器相对于在 JDBC 驱动程序和 Java 应用程序所处的位置。

以上引自 JDBC 简介_w3cschool

二、常用接口

在开发 JDBC 程序前,首先了解一下 JDBC 常用的 API。JDBC API主要位于 java.sql 包中,该包定义了一系列访问数据库的接口和类,具体如下:

  1. Driver 接口

Driver 接口由数据库厂家提供,作为 Java 开发人员,只需要使用 Driver 接口就可以了。在编程中要连接的数据库,必须先装载特定厂商的数据库驱动程序,不同的数据库有不同的装载方法。如:

​ 装载 MySQL 驱动:Class.forName ( "ciom.mysql.jdvc.Driver" );

​ 装载 Oracle 驱动:Class.forName ( "oracle.jdbc.driver.OracleDriver" );

  1. Connection 接口

Connection 与特定数据库的连接(会话),在连接上下文中执行 sql 语句并返回结果。

DriverManager.getConnection ( url ,user ,password )方法建立在 JDBC URL 中定义的数据库 Connection 连接上。

连接 MySQL 数据库:

Connection conn = DriverManager.getConnection ( "jdbc:mysql://host:port/database" , "user" , "password");

连接 Oracle 数据库:

Connection conn = DriverManager.getConnection ( "jdbc:oracle:thin:@host:port:database" , "user" , "password");

连接 SqlServer 数据库:

Connection conn = DriverManager.getConnection ( "jdbc:microsoft:sqlsever://host:port;DatabaseName=database" , "user" , "password");

常用方法:

  • createStatement():创建向数据库发送 sql 的 statement 对象。
  • prepareStatement (sql):创建向数据库发送预编译 sql 的 PrepareSatement 对象。
  • prepareCall (sql):创建执行存储过程的 callableStatement 对象。
  • setAutoCommit (boolean autoCommit):设置事物是否自动提交。
  • commit():在链接上提交事物。
  • rollback():在此链接上回滚事物。
  1. Statement 接口

用于执行静态 SQL 语句并返回它所生成结果的对象

三种 Statement 类:

  • Statement:由 createStatement 创建,用于发送简单的 SQL 语句 (不带参数)。
  • PreparedStatement:继承自Statement接口,由 preparedStatement 创建,用于发送含有一个或多个参数的 SQL 语句。PreparedStatement 对象比 Startement 对象的效率更高,并且可以防止 SQL 注入,所以一般我们都使用 PreparedStatement
  • CallableStatement:继承自 PreparedStatement 接口,由方法 prepareCall 创建,用于调用 存储过程。

常用Statement 方法:

  • execute (String sql):运行语句,返回是否有结果集
  • executeQuery (String sql):运行select语句,返回 ResultSet 结果集。
  • executeUpdate (String sql):运行insert/update/delete操作,返回更新的行数。
  • addBatch (String sql):把多条 sql 语句放到一个批处理中。
  • executeBatch():向数据库发送一批 sql 语句并执行。
  1. ResultSet 接口

ResulttSet 提供检索不同类型字段的方法,常用的有:

  • getString (int index)、getString (String columnName):获得在数据库里是varchar、char等类型的数据对象。
  • getFloat (int index)、getFloat (String columnName):获得在数据库里是Float类型的数据对象。
  • getDate (int index)、getDate (String columnName):获得在数据库里是Date类型的数据。
  • getBoolean (int index)、getBoolean (String columnName):获得在数据库里是Boolean类型的数据。
  • getObject(int index)、getObject(String columnName):获取在数据库里任意类型的数据。

ResultSet还提供了对结果集进行滚动的方法:

  • next ():移动到下一行
  • Previous ():移动到前一行
  • absolute (int row):移动到指定行
  • beforeFirst ():移动resultSet的最前面。
  • afterLast ():移动到resultSet的最后面。

**使用后依次关闭对象及连接:**ResultSet → Statement →Connection

三、使用JDBC的步骤

加载JDBC驱动程序 → 建立数据库连接Connection → 创建执行SQL的语句Statement → 处理执行结果ResultSet → 释放资源

  1. 注册驱动 (只做一次)

方式一:Class.forName(“com.MySQL.jdbc.Driver”);   推荐这种方式,不会对具体的驱动类产生依赖。

方式二:DriverManager.registerDriver(com.mysql.jdbc.Driver);   会造成DriverManager中产生两个一样的驱动,并会对具体的驱动类产生依赖。

  1. 建立连接
 Connection conn = DriverManager.getConnection(url, user, password); 

​ URL用于标识数据库的位置,通过URL地址告诉JDBC程序连接哪个数据库,URL的写法为:

  

​ 其他参数如:useUnicode=true&characterEncoding=utf8

  1. 创建执行SQL语句的statement
//Statement  
String id = "5";
String sql = "delete from table where id=" +  id;
Statement st = conn.createStatement();  
st.executeQuery(sql);  
//存在sql注入的危险
//如果用户传入的id为“5 or 1=1”,那么将删除表中的所有记录
//PreparedStatement 有效的防止sql注入(SQL语句在程序运行前已经进行了预编译,当运行时动态地把参数传给PreprareStatement时,即使参数里有敏感字符如 or '1=1'也数据库会作为一个参数一个字段的属性值来处理而不会作为一个SQL指令)
String sql = “insert into user (name,pwd) values(?,?)”;  
PreparedStatement ps = conn.preparedStatement(sql);  
ps.setString(1, "col_value");  //占位符顺序从1开始
ps.setString(2, "123456");     //也可以使用setObject
ps.executeQuery(); 
  1. 处理执行结果(ResultSet)
ResultSet rs = ps.executeQuery();  
While(rs.next()){  
    rs.getString("col_name");  
    rs.getInt(1);  
    //…
}  
  1. 释放资源
// 数据库连接(Connection)非常耗资源,尽量晚创建,尽量早的释放 //都要加try catch 以防前面关闭出错,后面的就不执行了  
try {
     if (rs != null) {
         rs.close();
     }
} catch (SQLException e) {
     e.printStackTrace();
} finally {
	try {
         if (st != null) {
             st.close();
         }
     } catch (SQLException e) {
         e.printStackTrace();
     } finally {
         try {
             if (conn != null) {
                 conn.close();
             }
         } catch (SQLException e) {
             e.printStackTrace();
         }
     }
} 

上文引自 JDBC详解 - ErBing - 博客园 (cnblogs.com) ,如有侵权请通知。

三、PreparedStatement 接口的解释和用法

PreparedStatement 是 Statement 接口的子接口

优点:

  1. 使用 PreparedStatement 接口可以防止 SQL 注入
  2. PreparedStatement 是预编译(Statement 每次执行sql语句,都要执行相关数据库的编译,而 PreparedStatement 的sql是一个模板 (可以类比函数),编译过程与执行是分开的,当为其参数赋予值时,实际上只是将值给传入进去,放进模板中,需要时取出插入数据即可,不需要继续编译。)的,对于批量处理可以大大提高效率。总的来说,区别在于前者编译执行一体化,后者属于先编译后执行。
  3. 可以重复使用同一SQL模板,给予其不同的参数来重复的使用。

第二点也就是为什么预编译能够防止SQL注入。

创建 PreparedStatement 对象

PreparedStatement ps = null;
try{
    ……
    String sql = "select studentNo from student where studentName = ?";
    ps = connection.prepareStatement(sql);
    ……
} catch (SQLException e) {
    ……
} finally {
    ps.close();
}

在使用 PreparedStatement 对象的同时,所有的参数都被用 ?符号表示,而为其参数赋值则需要用到 setXXX() 方法将值绑定到参数,其中 XXX 表示参数的数据类型

当你没有给参数赋予值,你会收到一个 SQLException

setXXX (int parementerIndex , XXX类型变量) ,每个参数的起始下标为1。

Statement 和 PreparedStatement 执行SQL语句方法的区别

PreparedStatement对象独有的executeQuery()方法是没有参数的,而Statement的executeQuery()是需要参数(SQL语句)的。因为在创建PreparedStatement对象时已经让它与一条SQL模板绑定在一起了,所以在调用它的executeQuery()和executeUpdate()方法时就不再需要参数了。

总结

  • JDBC 由一组使用 Java 语言编写的类和接口组成,可以为多种关系型数据库提供统一的访问方式。
  • JDBC API 是一套接口规范,数据库厂商或第三方中间件厂商根据这套接口规范提供针对不同数据库的数据库驱动
  • JDBC操作步骤
    • 加载JDBC驱动
    • 获取数据库连接
    • 创建SQL语句集,发送SQL语句,并得到返回结果
    • 处理返回结果
  • 每个JDBC驱动只对应一种数据库,甚至只对应某个版本的数据库
  • 数据库操作结束后,应该关闭数据库连接,释放系统资源。为了确保程序的执行,关闭数据库连接语句要放到 finally 语句块中
  • Connection 接口负责连接数据库并担任传达数据库的任务
  • Statement 接口负责执行 SQL 语句
  • ResultSet 接口负责保存和处理 Statement 接口执行后所产生的查询结果
  • SQL 注入是通过提交一段 SQL 代码,执行超出用户权限的数据库操作的攻击行为
  • PreparedStatement 接口能够提高代码的可读性、可维护性、SQL语句的执行性能和安全性

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
JDBCJava Database Connectivity)是一种Java语言访问数据库的标准API,它提供了一组用于访问关系型数据库的类和接口。在使用JDBC时,我们需要进行一些配置,下面是jdbc配置的详解: 1. 导入jdbc驱动:在项目中引入对应数据库jdbc驱动包,这个驱动包通常由数据库厂商提供,也可以在Maven或Gradle中添加对应的依赖。 2. 加载驱动类:使用Class.forName()方法加载JDBC驱动程序类,加载后会自动注册到DriverManager中。 3. 建立数据库连接:使用DriverManager.getConnection()方法建立与数据库的连接,需要传递数据库连接URL、用户名和密码等参数。 4. 创建Statement对象:使用Connection对象的createStatement()方法创建Statement对象,用于发送SQL语句到数据库执行。 5. 执行SQL语句:使用Statement对象的execute()、executeQuery()、executeUpdate()等方法执行SQL语句,获取结果集或影响的行数。 6. 处理结果集:如果执行的SQL语句返回了结果集,可以使用ResultSet对象进行遍历和获取数据。 7. 关闭资源:在使用完JDBC后,需要释放资源,包括ResultSet对象、Statement对象和Connection对象等,可以使用close()方法进行释放。 下面是一个简单的JDBC配置示例: ```java import java.sql.*; public class JdbcDemo { public static void main(String[] args) { String url = "jdbc:mysql://localhost:3306/test"; String user = "root"; String password = "123456"; Connection conn = null; Statement stmt = null; ResultSet rs = null; try { // 加载MySQL驱动 Class.forName("com.mysql.jdbc.Driver"); // 建立连接 conn = DriverManager.getConnection(url, user, password); // 创建Statement对象 stmt = conn.createStatement(); // 执行SQL语句 rs = stmt.executeQuery("SELECT * FROM users"); // 处理结果集 while (rs.next()) { int id = rs.getInt("id"); String name = rs.getString("name"); int age = rs.getInt("age"); System.out.println("id=" + id + ", name=" + name + ", age=" + age); } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } finally { // 关闭资源 try { if (rs != null) rs.close(); if (stmt != null) stmt.close(); if (conn != null) conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } } ``` 在这个示例中,我们使用了MySQL数据库,首先通过Class.forName()方法加载MySQL驱动类,然后使用DriverManager.getConnection()方法建立与数据库的连接,使用Connection对象的createStatement()方法创建Statement对象,使用executeQuery()方法执行SQL语句,再使用ResultSet对象处理结果集。最后在finally块中关闭资源。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小简(JanYork)

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值