JDBC详解
简介
JDBC 指 Java 数据库连接,是一种标准Java应用编程接口( JAVA API),用来连接 Java 编程语言和广泛的数据库。从根本上来说,JDBC 是一种规范,它提供了一套完整的接口,允许便携式访问到底层数据库,因此可以用 Java 编写不同类型的可执行文件。
执行流程:
连接数据源,如:数据库。
为数据库传递查询和更新指令。
处理数据库响应并返回的结果。
所需的接口和类
1.Connection接口
Connection 对象的数据库能够提供信息描述其表、所支持的 SQL 语法、存储过程和此连接的功能等。默认情况下,Connection 对象处于自动提交模式下,这意味着它在执行每个语句后都会自动提交更改。如果禁用自动提交模式,为了提交更改,必须显式调用 commit 方法;否则无法保存数据库更改。
createStatement()方法:
创建一个 Statement 对象来将 SQL 语句发送到数据库。没有参数的 SQL 语句通常使用 Statement 对象执行。如果多次执行相同的 SQL 语句,使用 PreparedStatement 对象可能更有效。
getMetaData()方法:
获取 DatabaseMetaData 对象,该对象包含关于 Connection 对象连接到的数据库的元数据。元数据包括关于数据库的表、受支持的 SQL 语法、存储过程、此连接的功能等信息。
rollback(Savepoint savepoint) 方法:
取消在当前事务中进行的所有更改,并释放此 Connection 对象当前保存的所有数据库锁定。此方法应该只在已禁用自动提交模式时使用。
setAutoCommit(boolean autoCommit) 方法:
将此连接的自动提交模式设置为给定状态。如果连接处于自动提交模式下,则将执行其所有 SQL 语句,并将这些语句作为单独的事务提交。否则,其 SQL 语句将成组地进入通过调用 commit 方法或 rollback 方法终止的事务中。默认情况下,新的连接处于自动提交模式下。
Savepoint setSavepoint(String name)方法:
添加事务回滚的点,在当前事务中创建一个具有给定名称的保存点,并返回表示它的新 Savepoint 对象。
2. Statement接口
用于执行静态 SQL 语句并返回它所生成结果的对象。
在默认情况下,同一时间每个 Statement 对象在只能打开一个 ResultSet 对象。因此,如果读取一个 ResultSet 对象与读取另一个交叉,则这两个对象必须是由不同的 Statement 对象生成的。如果存在某个语句的打开的当前 ResultSet 对象,则 Statement 接口中的所有执行方法都会隐式关闭它。
executeUpdate(String sql) 方法:
执行给定 SQL 语句,该语句可能为 INSERT、UPDATE 或 DELETE 语句,或者不返回任何内容的 SQL 语句(如 SQL DDL 语句)。
executeQuery(String sql) 方法:
执行给定的 SQL 语句,该语句返回单个 ResultSet 对象。
3.ResultSet接口
表示数据库结果集的数据表,通常通过执行查询数据库的语句生成。
ResultSet 对象具有指向其当前数据行的指针。最初,指针被置于第一行之前。next 方法将指针移动到下一行;因为该方法在 ResultSet 对象中没有下一行时返回 false,所以可以在 while 循环中使用它来迭代结果集。
默认的 ResultSet 对象不可更新,仅有一个向前移动的指针。因此,只能迭代它一次,并且只能按从第一行到最后一行的顺序进行。可以生成可滚动和/或可更新的 ResultSet 对象。以下代码片段(其中 con 为有效的 Connection 对象)演示了如何生成可滚动且不受其他更新影响的、可更新的结果集。请参阅 ResultSet 字段以了解其他选项。
Statement stmt = con.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE);
ResultSet rs = stmt.executeQuery("SELECT a, b FROM TABLE2");
// rs will be scrollable, will not show changes made by others,
// and will be updatable
next() 方法:
判断resultset的接受结果,采用循环遍历,查询结果!在知道数据库表里参数类型的情况下,采用resultset的getint方法。
Properties类(父类是hashtable)
Properties 类表示了一个持久的属性集。Properties 可保存在流中或从流中加载。属性列表中每个键及其对应值都是一个字符串。
一个属性列表可包含另一个属性列表作为它的“默认值”;如果未能在原有的属性列表中搜索到属性键,则搜索第二个属性列表。
因为 Properties 继承于 Hashtable,所以可对 Properties 对象应用 put 和 putAll 方法。但强烈反对使用这两个方法,因为它们允许调用方插入其键或值不是 Strings 的项。相反,应该使用 setProperty 方法。如果在“有危险”的 Properties 对象(即包含非 String 的键或值)上调用 store 或 save 方法,则该调用将失败。
load 和 store 方法按下面所指定的、简单的面向行的格式加载和存储属性。此格式使用 ISO 8859-1 字符编码。可以使用 Unicode 转义符来编写此编码中无法直接表示的字符;转义序列中只允许单个 ‘u’ 字符。可使用 native2ascii 工具对属性文件和其他字符编码进行相互转换。
作用:
Properties(Java.util.Properties),该类主要用于读取Java的配置文件,不同的编程语言有自己所支持的配置文件,配置文件中很多变量是经常改变的,为了方便用户的配置,能让用户够脱离程序本身去修改相关的变量设置。就像在Java中,其配置文件常为.properties文件,是以键值对的形式进行参数配置的。
getProperty(String key) 方法:
用指定的键在此属性列表中搜索属性。
setProperty(String key, String value) 方法:
调用 Hashtable 的方法 put。
DataSource类
该工厂用于提供到此 DataSource 对象表示的物理数据源的连接。作为 DriverManager 设施的替代项,DataSource 对象是获取连接的首选方法。实现 DataSource 接口的对象通常在基于 JavaTM Naming and Directory Interface (JNDI) API 的命名服务中注册。
DataSource 接口由驱动程序供应商实现。共有三种类型的实现:
1.基本实现 - 生成标准 Connection 对象
2.连接池实现 - 生成自动参与连接池的 Connection 对象。此实现与中间层连接池管理器一起使用。
3.分布式事务实现 - 生成一个 Connection 对象,该对象可用于分布式事务,并且几乎始终参与连接池。此实现与中间层事务管理器一起使用,并且几乎始终与连接池管理器一起使用。
DataSource 对象的属性在需要时可以修改。例如,如果将数据源移动到另一个服务器,则可更改与服务器相关的属性。其优点是,因为可以更改数据源的属性,所以任何访问该数据源的代码都无需更改。
通过 DataSource 对象访问的驱动程序不会向 DriverManager 注册。通过查找操作检索 DataSource 对象,然后使用该对象创建 Connection 对象。使用基本的实现,通过 DataSource 对象获取的连接与通过 DriverManager 设施获取的连接相同。
getConnection() 方法:
尝试建立与此 DataSource 对象表示的数据源的连接。
DriverManager类
管理一组 JDBC 驱动程序的基本服务。
注:DataSource 接口是 JDBC 2.0 API 中的新增内容,它提供了连接到数据源的另一种方法。使用 DataSource 对象是连接到数据源的首选方法。
getConnection(String url) 方法:
试图建立到给定数据库 URL 的连接。
PreparedStatement接口(Statement的子接口)
表示预编译的 SQL 语句的对象。
SQL 语句被预编译并且存储在 PreparedStatement 对象中。然后可以使用此对象高效地多次执行该语句。
注:用来设置 IN 参数值的 setter 方法(setShort、setString 等等)必须指定与输入参数的已定义 SQL 类型兼容的类型。例如,如果 IN 参数具有 SQL 类型 INTEGER,那么应该使用 setInt 方法。
如果需要任意参数类型转换,使用 setObject 方法时应该将目标 SQL 类型作为其参数的类型。
在以下设置参数的示例中,con 表示一个活动连接:
PreparedStatement pstmt = con.prepareStatement("UPDATE EMPLOYEES
SET SALARY = ? WHERE ID = ?");
pstmt.setBigDecimal(1, 153833.00)
pstmt.setInt(2, 110592)
executeQuery() 方法:
在此 PreparedStatement 对象中执行 SQL 查询,并返回该查询生成的 ResultSet 对象。
getMetaData() 方法:
检索包含有关 ResultSet 对象的列消息的 ResultSetMetaData 对象,ResultSet 对象将在执行此 PreparedStatement 对象时返回。
基础版的JDBC
作为简单功能的实现,并不是通用的方法每次实现功能单一,没有实现功能统一。
package jdbc;
import java.sql.*;
public class Connect {
public static void main(String [] args) throws Exception{
//Class.forName("com.mysql.cj.jdbc.Driver");
//1.注册jdbc驱动
String driverName="com.mysql.cj.jdbc.Driver";
//2.获取连接对象
String dbURL="jdbc:mysql://127.0.0.1:3306/mytest?useSSL=false&serverTimezone=UTC";
String userName="root";
String userPwd="123456";//数据库密码(自己设置的)
try{
Class.forName(driverName);
System.out.println("加载驱动成功!");
}catch(Exception e){
e.printStackTrace();
System.out.println("加载驱动失败!");
}
try{
Connection dbConn=DriverManager.getConnection(dbURL,userName,userPwd);
System.out.println("连接数据库成功!");
}catch(Exception e){
e.printStackTrace();
System.out.print("MySQL80连接失败!");
}
Connection Conn=DriverManager.getConnection(dbURL,userName,userPwd);
Statement stat=Conn.createStatement();
String sql = "select * from tb1";
ResultSet result = stat.executeQuery(sql);
while(result.next()) {
System.out.print("username:"+result.getString("username")+"|");
System.out.println("age:"+result.getInt("age"));
}
result.close();
stat.close();
Conn.close();
}
}
通用版本的JDBC(采用Statement)
1.JDBCUtils通用抽象类:
package mysql.jdbc;
import fs.反射.ReflectionUtils;
import org.apache.commons.dbcp.BasicDataSourceFactory;
import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties