JDBC是一种可用于执行SQL语句的Java API,是连接数据库和Java程序的纽带。JDBC全称是Java Database Connectivity,是一套面向对象的应用程序接口,指定了统一的访问各种关系型数据库的标准接口。JDBC是一种底层的API,因此访问数据库时需要再逻辑层中嵌入SQL语句。
需要注意:JDBC并不能直接访问数据库,必须依赖数据库厂商提供的JDBC驱动程序。
JDBC-ODBC桥
依靠ODBC驱动器和数据库通信。这种连接方式必须将ODBC二进制代码加载到使用该驱动程序的每台客户机上。
JDBC网络驱动
这种驱动程序将JDBC转换为与DBMS无关的网络协议,又被某个服务器转换为DBMS协议,是一种利用Java编写的JDBC驱动程序,也是最灵活的驱动程序。
本地协议驱动
这是一种纯Java驱动程序。这种驱动程序将JDBC调用直接转换为DBMS所使用的网络协议,允许从客户机上直接调用DBMS服务器,是一种很使用的访问Internet的解决方法。
常用的JDBC类和接口都在java.sql包中。
Connection接口代表与特定的数据库的连接,在连接上下文中执行SQL语句并返回结果。
| 方法 | 功能描述 |
| createStatement() | 创建Statement对象 |
| createStatement(int resultSetType, int resultSetConcurrency) | 创建一个Statement对象,该对象将生成具有给定类型、并发性和可保存性的ResultSet对象 |
| preparedStatement() | 创建预处理对象preparedStatement |
| isReadOnly() | 查看当前Connection对象的 读取模式是否为只读模式 |
| setReadOnly() | 设置当前Connection独享的读取模式为只读模式,默认为非只读模式 |
| commit() | 使所有上一次提交/回滚后进行的更改成为持久更改,并释放此Connection对象所持有的所有数据库锁 |
| roolback() | 取消当前事务中进行的所有更改,并释放此Connection对象所持有的所有数据库锁 |
| close() | 立即释放此Connection对象所持有的数据库和JDBC资源 |
Statement接口用于在已经建立Connection连接的基础上向数据库发送SQL语句。
在JDBC中有3种Statement对象:
Statement对象用于执行不带参数的简单SQL语句;
| 方法 | 功能描述 |
| execute(String sql) | 执行静态的SELECT语句,该语句可能返回多个结果集 |
| executeQuery(String sql) | 执行给定的SQL语句,该语句返回单个resultSet对象 |
| clearBatch() | 清空此Statement对象的当前SQL命令列表 |
| executeBatch() | 将一组命令提交给数据库来执行,如果命令全部执行成功,则返回一个更新计数组成的数组,数组元素的排序与SQL语句的添加顺序对应 |
| addBatch(String sql) | 将给定的SQL命令添加到此Statement对象的当前命令列表中,如果驱动程序不支持批量操作,将抛出异常 |
| close() | 释放Statement对象占用的数据库和JDBC资源 |
PreparedStatement继承了Statement,用来执行动态的SQL语句;通过PreparedStatement实例执行的动态SQL语句,将被预编译并保存到PreparedStatement实例中,从而可以反复地执行该SQL语句。
| 方法 | 功能描述 |
| setInt(int index, int k) | 将指定位置的参数设置为int值 |
| setFloat(int index, float f) | |
| setLong(int index, long l) | |
| setDouble(int index, double d) | |
| setBoolean(int index, boolean b) | |
| setDate(int index, date date) | |
| setString(int index, String s) | |
| setNull(int index, intsqlType) | 将指定位置的参数设置为SQL NULL |
| executeQuery() | 在此PreparedStatement对象中执行SQL查询,并返回该查询结果生成的ResultSet对象 |
| executeUpdate() | 执行前面包含参数的动态INSERT,UPDATE,DELETE语句 |
| clearParameters() | 清除当前所有参数的值 |
CallableStatement继承了PreparedStatement,用于执行对数据库的存储过程的调用。
同3.2.2
DriverManager类用来管理数据库中的所有驱动程序。它是JDBC的管理层,作用于用户和驱动程序之间,跟踪可用的驱动程序,并在数据库和驱动程序之间建立连接。
| 方法 | 功能描述 |
| getConnection(String url, String user, String password) | 指定3个入口参数,来获取与数据库的连接 |
| setLoginTimeout() | 设置驱动程序试图登录某数据库的最长等待时间,单位为秒 |
| println(String message) | 将一条消息打印到当前JDBC日志流中 |
ResultSet接口类似一个临时表,用来暂时存储数据库查询操作所获取的结果集。ResultSet实例具有指向当前数据行的指针,指针开始的位置在第一条记录的前面,通过next()方法可将指针向下移动。
| 方法 | 功能描述 |
| getInt() | 以int的形式获取此ResultSet对象的当前行的指定列的值。如果列值是NULL,则返回值是0 |
| getFloat() | |
| getDate() | |
| getBoolean() | |
| getString() | |
| getObject() | |
| first() | 将指针移动到当前记录的第一行 |
| last() | 将指针移动到当前记录的最后一行 |
| next() | 将指针向下移动一行 |
| beforeFirst() | 将指针移动到集合的开头(第一行位置) |
| afterLast() | 将指针移动到集合的尾部(最后一行位置) |
| absolute(int index) | 将指针移动到ResultSet给定编号的行 |
| isFirst() | 判断指针是否位于当前记录的第一行 |
| isLast() | |
| updateInt() | 用int值更新指定列 |
| updateFloat() | |
| updateLong() | |
| updateString() | |
| updateObject() | |
| updateNull() | |
| updateDate() | |
| updateDouble() | |
| getrow() | 查看当前行的索引号 |
| insertRow() | 将插入行的内容插入到数据库中 |
| updateRow() | 将当前行的内容更新到数据库表 |
| deleteRow() | 删除当前行,但不同步到数据库,而是执行close()方法后同步到数据库中 |
详见JDBC | mysql-connector jar包的加载_mysql-connector-java.jar-CSDN博客
- package db;
-
- import java.sql.*; //导入java.sql包
-
- public class Conn {
- Connection con; //声明Connection对象
-
- public Connection getConnection() { //建立返回值为Connection对象的方法
- try {
- // Class.forName("com.mysql.jdbc.Driver"); //deprecated
- Class.forName("com.mysql.cj.jdbc.Driver"); //加载数据库驱动类
- System.out.println("数据库驱动加载成功");
- } catch (ClassNotFoundException e) {
- e.printStackTrace();
- }
-
- try {
- //通过访问数据库的url,获取数据库连接对象con
- con = DriverManager.getConnection("jdbc:mysql:" + "//127.0.0.1:3306/debug", "root", "12345678");
- System.out.println("数据库连接成功");
- } catch (SQLException e) {
- e.printStackTrace();
- }
-
- return con; //返回Connection对象
- }
-
- public static void main(String[] args) {
- Conn c = new Conn(); //创建类对象
- c.getConnection(); //调用连接数据库的方法
- }
- }
-
- 输出:
- 数据库驱动加载成功
- 数据库连接成功
-
DriverManager中的getConnection()方法只是获取与数据库的连接,要执行SQL语句首先要获得Statement类对象,通过创建的数据库连接对象con的createStatement()方法可获得Statement对象
try{
Statement statement = con.createStatement();
}catch(SQLException e){
e.printStackTrace();
}
有了Statement对象,就可以调用这个对象的相应方法实现对象数据库的查询和修改,并将查询的结果放在ResultSet类的对象中:
String sql = "select * from xxx where xxx;";
ResultSet resultset = Statement.executeQuery(sql)
运行结果为返回的一个ResultSet对象,ResultSet对象一次只可以看到结果集中的一行数据,使用该对象的next()方法可以将光标从当前位置移动到下一行,返回一个boolean类型的数据,当游标移动到最后一行之后会返回false。
- package db;
-
- import java.sql.*;
-
- public class Gradation {
- static Connection con;
- static Statement statement;
- static ResultSet resultSet;
-
- public Connection getConnection() throws ClassNotFoundException, SQLException { //连接数据库的方法
- Class.forName("com.mysql.cj.jdbc.Driver");
- Connection con = DriverManager.getConnection("jdbc:mysql:" + "//localhost:3306/debug", "root", "12345678");
- return con;
- }
-
- public static void main(String[] args) throws SQLException, ClassNotFoundException {
- Gradation gra = new Gradation();
- con = gra.getConnection(); //建立与数据库的连接
- statement = con.createStatement(); //实例化一个用于执行SQL语句的Statement对象
- String sql = "select * from results limit 10;";
- resultSet = statement.executeQuery(sql); //执行sql语句
-
- while (resultSet.next()) {
- String id = resultSet.getString("id");
- String createTime = resultSet.getString(2); //createTime位于表中第二列,可以以这种方式获取对应字段值
- String endTime = resultSet.getString("end_time");
- String ProjectId = resultSet.getString("project_id");
- String receive_msg_count = resultSet.getString(5);
- String send_msg_count = resultSet.getString(6);
- String status = resultSet.getString(7);
- String strike = resultSet.getString(8);
- String suite_id = resultSet.getString(9);
- String suite_name = resultSet.getString(10);
-
- System.out.println("id:" + id + "; " + "createTime:" + createTime + "; " + "endTime:" + endTime + "; " + "ProjectId:" + ProjectId
- + "; " + "receive_msg_count:" + receive_msg_count + "; " + "send_msg_count:" + send_msg_count + "; " + "status:"
- + status + "; " + "strike:" + strike + "; " + "suite_id:" + suite_id + "; " + "suite_name:" + suite_name + "; ");
- }
- }
- }
-
- 输出:
- id:1234; createTime:2023-09-27 03:45:00; endTime:2023-09-27 03:51:41; ProjectId:1; receive_msg_count:12; send_msg_count:12; status:1; strike:SYSTEM; suite_id:20; suite_name:巡检;
- id:2582; createTime:2023-09-14 12:15:00; endTime:2023-09-14 12:17:09; ProjectId:1; receive_msg_count:3; send_msg_count:3; status:1; strike:SYSTEM; suite_id:19; suite_name:行情;
- id:2583; createTime:2023-09-14 12:30:00; endTime:2023-09-14 12:32:15; ProjectId:1; receive_msg_count:3; send_msg_count:3; status:1; strike:SYSTEM; suite_id:19; suite_name:行情;
- id:2584; createTime:2023-09-14 12:45:00; endTime:2023-09-14 12:47:14; ProjectId:1; receive_msg_count:3; send_msg_count:3; status:1; strike:SYSTEM; suite_id:19; suite_name:行情;
- id:2585; createTime:2023-09-14 13:00:00; endTime:2023-09-14 13:02:20; ProjectId:1; receive_msg_count:3; send_msg_count:3; status:1; strike:SYSTEM; suite_id:19; suite_name:行情;
- id:2586; createTime:2023-09-14 13:00:00; endTime:2023-09-14 13:07:01; ProjectId:1; receive_msg_count:9; send_msg_count:9; status:1; strike:SYSTEM; suite_id:20; suite_name:巡检;
- id:2587; createTime:2023-09-14 13:15:00; endTime:2023-09-14 13:17:15; ProjectId:1; receive_msg_count:3; send_msg_count:3; status:1; strike:SYSTEM; suite_id:19; suite_name:行情;
- id:2588; createTime:2023-09-14 13:30:00; endTime:2023-09-14 13:32:23; ProjectId:1; receive_msg_count:3; send_msg_count:3; status:1; strike:SYSTEM; suite_id:19; suite_name:行情;
- id:2589; createTime:2023-09-14 13:45:00; endTime:2023-09-14 13:47:20; ProjectId:1; receive_msg_count:3; send_msg_count:3; status:1; strike:SYSTEM; suite_id:19; suite_name:行情;
- id:2590; createTime:2023-09-14 14:00:00; endTime:2023-09-14 14:02:18; ProjectId:1; receive_msg_count:3; send_msg_count:3; status:1; strike:SYSTEM; suite_id:19; suite_name:行情;
statement = con.createStatement(); //实例化一个用于执行SQL语句的Statement对象 String sql = "select * from results where suite_name like '巡%' limit 10;"; resultSet = statement.executeQuery(sql); //执行sql语句
通过Connection对象的preparedStatement(String sql)方法对SQL语句进行预处理,生成数据库底层的内部命令,并将命令封装在PreparedStatement对象中,通过调用PreparedStatement对象相应的方法可以执行底层数据库命令,减轻数据库负担,提高性能。
sql = con.prepareStatement("select * from xx where id = ?");
sql.setInt(1,2);
1表示从左向右的第一个通配符,2表示设置的通配符的值,将通配符值设置为2后,功能等同于:
sql = con.prepareStatement("select * from xx where id = 2");
由上可知,使用预处理语句可以让程序动态地改变SQL语句中关于字段值的设定。
- package db;
-
- import java.sql.*;
-
- public class Prep {
- static Connection con;
- static PreparedStatement preparedState;
- static ResultSet resultSet;
-
- public Connection getcon() throws ClassNotFoundException, SQLException {
- Class.forName("com.mysql.cj.jdbc.Driver");
- con = DriverManager.getConnection("jdbc:mysql:" + "//127.0.0.1:3306/debug", "root", "12345678");
- return con;
- }
-
- public static void main(String[] args) throws SQLException, ClassNotFoundException {
- Prep prep = new Prep();
- con = prep.getcon();
- preparedState = con.prepareStatement("select * from results where id=?"); //使用通配符
- preparedState.setInt(1, 1234); //设置参数
- resultSet = preparedState.executeQuery(); //执行预处理语句
- //如果当前记录不是结果集中最后一行,则进入循环
- while (resultSet.next()) {
- String id = resultSet.getString("id");
- String createTime = resultSet.getString(2); //createTime位于表中第二列,可以以这种方式获取对应字段值
- String endTime = resultSet.getString("end_time");
- String ProjectId = resultSet.getString("project_id");
- String receive_msg_count = resultSet.getString(5);
- String send_msg_count = resultSet.getString(6);
- String status = resultSet.getString(7);
- String strike = resultSet.getString(8);
- String suite_id = resultSet.getString(9);
- String suite_name = resultSet.getString(10);
-
- System.out.println("id:" + id + "; " + "createTime:" + createTime + "; " + "endTime:" + endTime + "; " + "ProjectId:" + ProjectId
- + "; " + "receive_msg_count:" + receive_msg_count + "; " + "send_msg_count:" + send_msg_count + "; " + "status:"
- + status + "; " + "strike:" + strike + "; " + "suite_id:" + suite_id + "; " + "suite_name:" + suite_name + "; ");
- }
- }
- }
-
- 输出:
- id:1234;createTime:2023-09-27 03:45:00;endTime:2023-09-27 03:51:41;ProjectId:1;receive_msg_count:12;send_msg_count:12;status:1;strike:SYSTEM;suite_id:20;suite_name:巡检;
通过PreparedStatement类的指定参数,动态地对数据表中原有数据进行修改,并通过executeUpdate()方法执行更新语句操作;
- package db;
-
- import java.sql.*;
-
- public class Renewal {
- static Connection con;
- static PreparedStatement preparedState;
- static ResultSet resultSet;
-
- public Connection getCon() throws ClassNotFoundException, SQLException {
- Class.forName("com.mysql.cj.jdbc.Driver");
- con = DriverManager.getConnection("jdbc:mysql:" + "//127.0.0.1:3306/debug", "root", "12345678");
- return con;
- }
-
- public static void main(String[] args) throws SQLException, ClassNotFoundException {
- Renewal renewal = new Renewal();
- con = renewal.getCon();
- preparedState = con.prepareStatement("select * from modules");
- resultSet = preparedState.executeQuery();
- System.out.println("执行增删改查前的数据=========;");
- while (resultSet.next()) {
- String id = resultSet.getString(1);
- String name = resultSet.getString(2);
- String project_id = resultSet.getString(3);
- System.out.println("id:" + id + "; " + "name:" + name + "; " + "project_id:" + project_id + ";");
- }
-
- //预处理插入数据
- preparedState = con.prepareStatement("insert into modules values(?,?,?)");
- preparedState.setInt(1, 9); //数据已有数据的id最大为8,从9开始插入
- preparedState.setString(2, "jeanet测试");
- preparedState.setInt(3, 99);
- //执行插入数据到表
- preparedState.executeUpdate();
-
- //预处理更新数据
- preparedState = con.prepareStatement("update modules set name=? where id = ?");
- preparedState.setString(1, "春田");
- preparedState.setInt(2, 9);
- //执行更新数据到表
- preparedState.executeUpdate();
-
- //预处理删除数据
- preparedState = con.prepareStatement("delete from modules where id= ?");
- preparedState.setInt(1, 8);
- //执行表数据删除数据操作
- preparedState.executeUpdate();
-
- //查询增删改后的表数据
- preparedState = con.prepareStatement("select * from modules");
- resultSet = preparedState.executeQuery();
- System.out.println("执行增删改查后的数据=========;");
- while (resultSet.next()) {
- String id = resultSet.getString(1);
- String name = resultSet.getString(2);
- String project_id = resultSet.getString(3);
- System.out.println("id:" + id + "; " + "name:" + name + "; " + "project_id:" + project_id + ";");
- }
- }
- }
-
- 输出:
- 执行增删改查前的数据=========;
- id:1; name:首页; project_id:1;
- id:2; name:个人中心; project_id:1;
- id:3; name:行情; project_id:1;
- id:4; name:xx交易; project_id:1;
- id:5; name:xx交易; project_id:1;
- id:6; name:资产; project_id:1;
- id:7; name:特殊模块; project_id:1;
- id:8; name:公共元素; project_id:1;
- 执行增删改查后的数据=========;
- id:1; name:首页; project_id:1;
- id:2; name:个人中心; project_id:1;
- id:3; name:行情; project_id:1;
- id:4; name:xx交易; project_id:1;
- id:5; name:xx交易; project_id:1;
- id:6; name:资产; project_id:1;
- id:7; name:特殊模块; project_id:1;
- id:9; name:春田; project_id:99;