目录
1.1 前言
JDBC 是 Java 用于连接数据库的标准 API,全称是 java database connectivity。JDBC 包括哪些步骤,为什么是这些步骤,完成这些步骤需要哪些类和方法,这些方法会抛出哪些异常,一起来看看。
1.2 示例
public class Test {
static Connection connection;
public static void main(String args[]) {
try {
Class.forName("com.mysql.jdbc.Driver");
}
catch (ClassNotFoundException e) {
System.out.println(e.toString());
}
Statement statement = null;
ResultSet resultSet = null;
try {
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/bankingSystem?characterEncoding=utf8","UserName","password");
try {
statement = connection.createStatement();
}
catch (SQLException e) {
System.out.println(e.toString());
}
try {
resultSet = statement.executeQuery("select * from atm");
if (resultSet.next()) {
String cardID = resultSet.getString("cardID");
String password = resultSet.getString("password");
Double money = resultSet.getDouble("money");
System.out.println(cardID + '\t' + password + '\t' + money);
}
}
catch (SQLException e) {
System.out.println(e.toString());
}
finally {
resultSet.close();
statement.close();
}
}
catch (SQLTimeoutException e) {
System.out.println(e.toString());
}
catch (SQLException e) {
System.out.println(e.toString());
}
finally {
try {
connection.close();
}
catch (SQLException e) {
System.out.println(e.toString());
}
}
}
}
运行结果:
1001 1001 1000.0
1.3 基本流程
注册驱动程序类 —— Class.forName(“com.mysql.jdbc.Driver”);
建立连接 —— Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/DatabaseName?characterEncoding=utf8","root","password");
建立 Statement —— Statement statement = connection.createStatement();
执行 SQL 语句 —— resultSet = statement.executeQuery("select * from atm");
关闭连接 —— connection.close();
1.4 注册驱动程序类
Class.forName();
- 注册驱动程序类实际上就是加载你想要连接的数据库(如 MySQL,Oracle)的驱动类;
- 每种数据库都有各自的驱动程序类,每次加载都是根据你使用的数据库随心所欲地加载,也就是说加载数据库驱动类是根据实际情况实时加载的。因此需要使用类的动态加载,即 Class 类中的 forName() 方法;
- 实时加载可能会加载不到相关类,因此使用 Class.forName() 要求抛出一个异常 —— ClassNotFoundException(找不到相关类异常);
- JDBC 加载各种数据库的驱动程序类实例:
MySQL:
Class.forName("com.mysql.jdbc.Driver");
Oracle:
Class.forName("oracle.jdbc.driver.OracleDriver");
SQL Server:
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
Access:
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
DB2:
Class.forName("com.ibm.db2.jdbc.net.DB2Driver");
PostgreSQL:
Class.forName("org.postgresql.Driver");
1.5 建立连接
Connection connection = DriverManager.getConnection("特定数据库网址 (url)","用户名 (root)","密码 (password)");
- 接口 Connection 可连接一个特定数据库;
- DriverManager 是一个存放了 JDBC 驱动程序基本服务的类,调用其中的 getConnection 方法可建立给定的数据库网址的连接,可能建立成功,也可能建立失败;
- 建立连接失败有两个原因,所以会抛出两种异常:
- 第一种:发生数据库访问错误或网址为 null ,抛出 SQLException;
- 第二种:连接超时,抛出 SQLTimeoutException,它是 SQLException 的子类所以要写在 SQLException 之前;
- 不同数据库建立连接示例:
(注:1. 例中的 DatabaseName 是你创建的数据库并想要连接的数据库名;2. 网址需要添加与编译器相应的字符集格式,由于使用 UTF-8 字符集,所以 characterEncoding=utf8 )
MySQL:
Connection connection = DriverManager.getConnection( "jdbc:mysql://localhost:3306/DatabaseName?characterEncoding=utf8","UserName","password");
Oracle:(附:使用JDBC连接ORACLE的三种URL格式)
Connection connection = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:DatabaseName?characterEncoding=utf8","UserName","password");
SQL Server:
Connection connection = DriverManager.getConnection("jdbc:sqlserver://127.0.0.1:1433;databaseName=DatabaseName;user=sa;password=******");
Access:
Connection connection = DriverManager.getConnection(""jdbc:Access:///c:/a/DatabaseName.mdb","UserName","password");
DB2:
Connection connection = DriverManager.getConnection("JDBC:db2://localhost:5000/DatabaseName?characterEncoding=utf-8","UserName","password");
PostgreSQL:
Connection connection = DriverManager.getConnection("jdbc:postgresql://localhost:5432/DatabaseName?characterEncoding=utf-8", "UserName", "password");
1.6 创建 Statement
Statement statement = connection.createStatement();
PreparedStatement pStatement = connection.preparedStatement("insert into tableName(column1,column2) values(?,?);
pStatement.setString(1,values);
pStatement.setString(2,values);
CallableStatement cStatement = connection.prepareCall("{call revise_total(?)}");
- Statement 是一个接口用于将静态 SQL 语句发送到数据库并返回其产生的结果;
- 使用 Connection 类中的 createStatement 方法来创建 Statement;
- Statement 有两个子接口 PreparedStatement 和 CallableStatement。准确的说,CallableStatement 继承自PreparedSatement,PreparedStatement 继承自 Statement。
-
PreparedStatement 和 Statement 能够完成相同的功能,但 PreparedStatement 由于具有编译效率高,可读性,可维护性和安全性好等特点,在三个接口用的最多。
-
如果需要批量执行 SQL 语句,使用 Statement 更好。
-
CallableStatement 用来调用存储过程,它提供了对输出和输入/输出参数的支持;
- 由于可能发生数据库访问错误或者 Connection 已经关闭,可能抛出 SQLException 异常;
1.7 执行 SQL 语句
resultSet = statement.executeQuery(String sql);
statement.executeUpdate(String sql);
- 使用 Statement 接口执行 SQL 语句会使用到 Statement 中的四个方法,分别是:boolean execute(String sql),int[] executeBatch(),ResultSet executeQuery(String sql),int executeUpdate(String sql),它们都可以执行 SQL 语句只是返回的数据类型不同;
- boolean execute(String sql):执行 SQL 语句,返回布尔值,提示是否执行成功;
- int[] executeBatch():批量(通常在循环语句中)执行插入,更新和删除语句,但不可执行查询语句,如果所有命令执行成功,则返回每次被执行的行数(每执行一次就将得到执行的行数放到数组中)。executeBatch() 的作用是将语句提交给数据库,还需要搭配 void addBatch(String sql) 来对 Statement 设置 SQL 语句和 void clearBatch() 来清空 Statement 已发送的 SQL 语句;
- ResultSet executeQuery(String sql):通常执行查询语句,并返回 ResultSet(数据库结果集的数据表)。ResultSet 是通过指向当前行的光标来维护的,当光标指向下一行(ResultSet.next()) 时,意味着数据已经进入 ResultSet;
- int executeUpdate(String sql):执行插入,更新,删除语句和 DDL(创建,修改,删除数据库和表)语句,返回数据库中被执行的行数;
- 虽然到了可以给数据库发送 SQL 语句的地步,但仍可能出现数据库断连,重连超时两个异常,所以仍会抛出 SQLException 和 SQLTimeoutException;
1.8 关闭连接
resultSet.close();
statement.close();
connection.close();
- JDBC 中与数据库的连接数量是有限的,如果不在使用后将连接关闭和释放,当连接数量不够时,需要长时间的等待;
- 除了关闭连接,Statement 和 ResultSet 会占用着数据库的游标(游标是一种对从表中检索出的数据进行操作的机制),长期运行就有可能报 ” 游标超出数据库允许的最大值 “ 的错误。所以 Statement 和 ResultSet 也是要关闭的;
- 调用各自的 void close() 方法进行关闭;
- 如果前面的数据库连接失败,就谈不上关闭连接,void close() 也要抛出 SQLException;
1.9 总结