4、API详解
4.1、DriverManager
JDBC步骤二:注册驱动->DriverManager
4.1.1、注册方式
注册驱动的两种方式:
①静态注册:Class.forName("com.mysql.jdbc.Driver");
②动态注册:DriverManager.registerDriver(new Driver());
实际注册方式为方式二,但实际代码编写为方式一。
理由:
两种注册方式都可以,但是静态注册方式更稳定,因为它在程序启动前就注册了驱动,没有因为网络问题等导致无法加载驱动的风险,所以推荐使用静态注册方法。
4.1.2、源码分析
DriverManager.registerDriver(new Driver());
--->
Class.forName("com.mysql.jdbc.Driver");
--->
可以看出,静态注册方式采用的是反射机制,获取了MySQL驱动包中的Driver对象
重温反射知识:
查看com.mysql.jdbc.Driver源码,可以看到在Driver中静态加载了DriverManager.registerDriver(new Driver());,所以两种注册方式在源码上本质并无区别。只是静态注册更安全更稳固,且只会随着类加载一次,不会出现重复注册或者因网络问题进而出现注册问题的情况出现。
4.1.3、🔺🔺MySQL5
MySQL 5之后的驱动包,可以省略注册驱动的步骤,
自动加载jar包中META-INF/services/java.sql.Driver文件中的驱动类
4.2、Connection
Connection(数据库连接对象)作用:
获取执行 SQL 的对象
管理事务
4.2.1、DriverManager.getConnection
JDBC步骤三:获取连接->Connection connection = DriverManager.getConnection(url, username, password);
参数说明:
①url : 连接路径
语法:jdbc:mysql://ip地址(域名):端口号/数据库名称[?参数键值对1&参数键值对2… ]
示例:jdbc:mysql://127.0.0.1:3306/student
②user :用户名
③poassword :密码
4.2.2.1、⭐注意事项:useSSL
如果连接的是本机mysql服务器,并且mysql服务默认端口是3306,
则url可以简写为:jdbc:mysql:///数据库名称?参数键值对
配置 useSSL=false 参数,禁用安全连接方式,解决警告提示
Ex: jdbc:mysql://127.0.0.1:3306/student?useSSL=false
false前:
false后:
警告内容为:
Tue Jan 31 20:57:02 CST 2023 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
简单来说就是:
不建议在没有服务器身份验证的情况下建立 SSL 连接。
需要设置 useSSL=false 来显式禁用 SSL,或设置 useSSL=true 并为服务器证书验证提供信任库。
4.2.2、connection.createStaterment()
JDBC步骤五:获取执行SQL对象->Statement statement = connection.createStatement();
三种获取方式:
①普通执行SQL对象:Statement createStatement()
②预编译SQL的执行SQL对象:PreparedStatement prepareStatement(sql)->防止SQL注入
③执行存储过程的对象:CallableStatement prepareCall(sql)
通过方式③获取的 CallableStatement 执行对象是用来执行存储过程的,而存储过程在MySQL中不常用
4.2.2.1、 🔺🔺PreparedStatement
PreparedStatement作用: 预编译SQL语句并执行:预防SQL注入问题
sql语句中参数使用"?"进行占位,在执行SQL之前要设置这些"?"的值。
PreparedStatement对象方法:setXxx(参数1,参数2)->给SQL中的"?"赋值
Xxx:数据类型 ; 如 setInt (参数1,参数2)
参数:
参数1: ?的位置编号,从1 开始
参数2: ?的值
注意:
调用执行SQL语句的方法时不需要传递SQL语句,
因为获取SQL语句执行对象时已经对SQL语句进行预编译了。
代码改进如下:
改前:
1. package com.xzl; 2. 3. import java.sql.Connection; 4. import java.sql.DriverManager; 5. import java.sql.Statement; 6. 7. public class jdbc { 8. public static void main(String[] args) throws Exception { 9. //1、注册驱动 10. Class.forName("com.mysql.jdbc.Driver"); 11. //2、获取连接 12. String url = "jdbc:mysql://127.0.0.1:3306/student?useSSL=false"; 13. String username = "root"; 14. String password_P = "xzlXZGK680"; 15. Connection connection = DriverManager.getConnection(url,username,password); 16. 17. String sql = "update stu set gender='女' where name='李四' and gender='男'"; 18. //4. 获取执行sql的对象Statement 19. Statement statement = connection.createStatement(); 20. //此时需要开启事务之后再执行 21. try { 22. //禁用自动提交模式:false 23. connection.setAutoCommit(false); 24. //5、执行SQL->此处需要开启事务之后再执行 25. int count = statement.executeUpdate(sql); 26. System.out.println(count); 27. 28. //6、处理结果 29. // ============提交事务========== 30. //程序运行到此处,说明没有出现任何问题,则需提交事务 31. connection.commit(); 32. }catch (Exception e){ 33. //事务程序出错,回滚事务 34. connection.rollback(); 35. e.printStackTrace(); 36. }finally { 37. //7、释放资源 38. statement.close(); 39. connection.close(); 40. } 41. } 42. }
改后:
1. package com.xzl; 2. 3. import java.sql.*; 4. 5. public class jdbc { 6. public static void main(String[] args) throws Exception { 7. //1、注册驱动 8. Class.forName("com.mysql.jdbc.Driver"); 9. //2、获取连接 10. String url = "jdbc:mysql://127.0.0.1:3306/student?useSSL=false"; 11. String username = "root"; 12. String password_P = "xzlXZGK680"; 13. Connection connection = DriverManager.getConnection(url,username,password); 14. //3、定义sql 15. String sql = "update stu set gender='女' where name=? and gender=?"; 16. //4、获取预编译SQL的执行SQL对象:PreparedStatement 17. PreparedStatement preparedStatement = connection.prepareStatement(sql); 18. //设置参数值 19. preparedStatement.setString(1,"李四"); 20. preparedStatement.setString(2,"男"); 21. //此时需要开启事务之后再执行 22. try { 23. //禁用自动提交模式:false 24. connection.setAutoCommit(false); 25. //5、执行SQL->此处需要开启事务之后再执行 26. int count = preparedStatement.executeUpdate(); 27. System.out.println(count); 28. 29. //6、处理结果 30. // ============提交事务========== 31. //程序运行到此处,说明没有出现任何问题,则需提交事务 32. connection.commit(); 33. }catch (Exception e){ 34. //事务程序出错,回滚事务 35. connection.rollback(); 36. e.printStackTrace(); 37. }finally { 38. //7、释放资源 39. preparedStatement.close(); 40. connection.close(); 41. } 42. } 43. }
4.2.3、事务管理
4.2.3.1、MySQL事务管理
回顾MySQL事务管理的操作:
①开启事务 : BEGIN; 或者 START TRANSACTION;
②提交事务 : COMMIT;
③回滚事务 : ROLLBACK;
MySQL默认是自动提交事务
4.2.3.2、⭐JDBC事务管理信息
JDBC事务管理的方法:Connection接口中定义了3个对应的方法:
方法 |
说明 |
|
开启事务 |
void setAutoCommit (boolean autoCommit) |
将次连接的自动提交模式设置为给定状态 |
提交事务 |
void commit() |
使自上次提交/回滚以来所做的所有更改成为永久更改,并释放此Connection对象当前特有的所有数据库锁 |
回滚事务 |
void rollback() |
撤销当前事务中所做的所有更改,并释放此Connection对象当前特有的所有数据库锁 |
代码如下: