来了解JDBC的运行过程
发表于 2019-08-04 20:35
JDBC的作用
JDBC的全称是Java DataBase Connection,它是一个Java数据库连接,我们可以使用它来操作关系数据库。JDBC接口和相关类都在java中。sql包和javax。sql包。我们可以使用它连接到数据库,执行SQL查询,存储过程,并处理返回的结果。
JDBC接口允许Java程序和JDBC驱动程序松散耦合,从而更容易在不同的数据库之间切换。
JDBC
JDBC的连接步骤
执行JDBC连接需要六个步骤:
1. 导入包
在程序中包含数据库编程所需的JDBC类。在大多数情况下,使用import java.sql。*就足够了
2. 注册JDBC驱动程序
需要初始化驱动程序,以便能够打开与数据库的通信。
3. 打开一个连接
使用DriverManager.getConnection()方法创建表示数据库物理连接的连接对象。
4. 执行一个查询
需要使用Statement或PreparedStatement类型的对象(两者之间的区别),并向数据库提交一条SQL语句来执行查询。
5. 从结果集中提取数据
此步骤演示如何从数据库获取查询结果的数据。使用ResultSet.getXXX()方法检索数据结果
6. 清理环境资源
在使用JDBC与数据库中的数据交互之后,应该显式地关闭所有数据库资源,以减少资源浪费。本文使用try with resources来关闭资源,这是JDK7的语法糖,读者可以自己搜索。
完整代码如下。
//STEP 1. 导入包
import java.sql.*;
class JDBCExample {
// JDBC驱动包名和数据库的URL
static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
static final String DB_URL = "jdbc:mysql://localhost/test";
// 数据库名和密码自己修改
static final String USER = "username";
static final String PASS = "password";
public static void main(String[] args) {
String sql = "SELECT id, first, last, age FROM Employees";
//STEP 2: 注册JDBC驱动程序
try {
Class.forName(JDBC_DRIVER);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
// try with resources方式关闭资源。
//STEP 6: 清理环境资源
try (Connection conn = DriverManager.getConnection(DB_URL, USER, PASS);
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql)) {
//STEP 3: 打开一个连接
System.out.println("Connecting to database...");
// Connection conn = DriverManager.getConnection(DB_URL, USER, PASS);
//STEP 4: 执行一个查询
System.out.println("Creating statement...");
// Statement stmt = conn.createStatement();
// ResultSet rs = stmt.executeQuery(sql);
//STEP 5: 从结果集中提取数据
while (rs.next()) {
// 根据列名获取数据
int id = rs.getInt("id");
int age = rs.getInt("age");
String first = rs.getString("first");
String last = rs.getString("last");
// 显示结果
System.out.print("ID: " + id);
System.out.print(", Age: " + age);
System.out.print(", First: " + first);
System.out.println(", Last: " + last);
}
} catch (SQLException se) {
// 处理可能出现的错误
se.printStackTrace();
}
System.out.println("Goodbye!");
}
}
JDBC的最佳实践
数据库资源非常昂贵,应该在耗尽时立即关闭。Connection、Statement、ResultSet和其他JDBC对象都有一个close方法,只需调用它。
在代码中必须显式关闭ResultSet、语句、连接,如果使用连接池,连接将在使用后放回池中,但是不关闭ResultSet和语句将导致资源泄漏。
关闭finally块中的资源,以确保即使发生异常,它也会关闭。
大量类似的查询应该使用批处理来完成。
尝试使用PreparedStatement而不是Statement来避免SQL注入,并通过预编译和缓存机制提高执行效率。
如果希望将大量数据读入ResultSet,应该合理地设置fetchSize以提高性能。
您使用的数据库可能不支持所有隔离级别,请在使用前仔细确认。
数据库隔离级别越高,性能越差,从而确保数据库连接设置的隔离级别是最佳的。
如果需要长时间操作ResultSet,请尝试使用脱机行集。
FAQ
JDBC是如何实现Java程序和JDBC驱动的松耦合?
JDBC API使用Java的反射机制来实现Java程序和JDBC驱动程序之间的松散耦合。查看上面的JDBC示例,您会发现所有操作都是通过JDBC接口完成的,只有通过类加载驱动程序时才会出现。forName反射机制。
这是Java core库中用于反射的最佳实践之一,它将应用程序与驱动程序隔离开来,使迁移数据库的任务更加容易。
Statement和PreparedStatement区别
关系:PreparedStatement继承自Statement,两者都是接口
区别:PreparedStatement可以使用占位符,并且是预编译的,批处理比语句更有效
预编译
创建时的区别:
Statement statement = conn.createStatement();
PreparedStatement preStatement = conn.prepareStatement(sql);
执行时的区别:
ResultSet rSet = statement.executeQuery(sql);
ResultSet pSet = preStatement.executeQuery();
从上面可以看出,PreparedStatement有一个预编译的进程,已经绑定到sql,无论执行多少次,都不会再编译,语句是不同的。如果它被执行多次,它会被编译多少次?从这个角度来看,PreparedStatement比Statement更有效。PreparedStatement是预编译的,因此它可以有效地防止SQL注入等问题。
占位符
PrepareStatement可以替换变量在SQL语句中可以包含?,可以用?替换成变量。
ps = conn.prepareStatement("select * from Employees where id=?");
int sid = 1001;
ps.setInt(1, sid);
rs = ps.executeQuery();
而Statement只能用字符串拼接。
int sid = 1001;
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("select * from Employees where id=" + sid);
JDBC的ResultSet
查询数据库之后,它返回一个ResultSet,类似于查询结果集的数据表。
ResultSet对象维护指向当前数据行的游标。在开始时,光标指向第一行。如果调用ResultSet的next()方法,光标将向下移动一行。如果没有更多的数据,next()方法将返回false。它可以在for循环中用于遍历数据集。
不能更新默认的ResultSet,光标只能向下移动。换句话说,您只能从第一行遍历到最后一行。不过,您还可以创建一个可以回滚或更新的ResultSet,如下所示。
Statement stmt = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
当生成结果集的语句对象关闭或重新执行或检索下一个结果集时,结果集对象也会自动关闭。
列数据可以通过getSet的getter方法获得,该方法传入列名或从1开始的序列号。
ResultSet的不同类型
根据创建语句时的输入参数,将会有不同类型的resultset。如果查看连接方法,您会发现createStatement和prepareStatement方法被重载,以支持不同的结果集和并发类型。
ResultSet对象有三种类型。
ResultSet.TYPE_FORWARD_ONLY:这是默认类型,它的光标只能向下移动。
ResultSet.TYPE_SCROLL_INSENSITIVE:光标可以上下移动。创建之后,数据库中的数据将再次修改,这对它是透明的。
ResultSet.TYPE_SCROLL_SENSITIVE:光标可以上下移动。如果在生成数据库之后对其进行了修改,则可以感知它。
ResultSet有两种并发类型。
ResultSet.CONCUR_READ_ONLY:ResultSet是只读的,这是默认类型。
ResultSet.CONCUR_UPDATABLE:我们可以使用ResultSet的update方法来更新其中的数据。
评论 (0人参与)
最新评论