JDBC
JDBC简介
JDBC概念
- JDBC就是使用java语言操作关系型数据库的一套API
- 全称:(Java DataBase Connectivity)Java数据库连接
Jdbc本质
官方(sun公司)定义的一套操作所有关系型数据库的规则,即接口
各个数据库厂商去实现这套接口,提供数据库驱动jar包
我们可以使用这套接口(JDBC)编程,真正执行的代码是驱动jar包中的实现类
JDBC好处
- 各数据库厂商使用相同的接口,Java代码不需要针对不同数据库分别开发
- 可随时替换底层数据库,访问数据库的Java代码基本不变
JDBC快速入门
- 创建工程,导入驱动jar包
- 注册驱动
Class.forName("com.mysql.cj.jdbc.Driver")
- MySQL 5之后的驱动包,可以省略注册驱动的步骤
- 自动加载jar包中META-INF/services/java.sql.Driver文件中的驱动类
- 获取连接
String url = "jdbc:mysql://127.0.0.1:3306/db1";
String username = "root";
String password = "123";
Connection conn = DriverManager.getConnection(url, username, password);
- 定义SQL语句
String sql = "update...";
- 获取执行SQL对象
Statement stmt = conn.createStatement();
- 执行SQL
int count = stmt.executeUpdate(sql);//返回受影响的行数
- 处理返回结果
System.out.println(count);
- 释放资源
stmt.close();
conn.close();
JDBC API
DriverManager
-
驱动管理类
-
作用
- 注册驱动
- 获取数据库连接
-
static void registerDriver(Driver driver)- 注册驱动
- 在上面我们并没有使用使用这个静态方法来注册驱动,而是通过
Class.forName("com.mysql.cj.jdbc.Driver")将这个Dreiver类加载进内存的 - 看一下
Driver类的源码
//类中的静态代码块 static { try { DriverManager.registerDriver(new Driver()); } catch (SQLException var1) { throw new RuntimeException("Can't register driver!"); } }- 可以看到,随着类的加载,自动调用了
DriverManager.registerDriver()这个方法
-
static Connection getConnection(String url, String user, String password)-
获取数据库连接
-
参数
-
url:连接路径
- 语法:
jdbc:mysql://ip地址(域名):端口号/数据库名称?参数键值对1&参数键值对2... - 示例:
jdbc:mysql://127.0.0.1:3306/db1 - 细节:
- 如果连接的是本机mysql服务器,并且mysql服务默认端口是3306,则url可以简写为
jdbc:mysql:///数据库名称?参数键值对1&参数键值对2... - 配置
?useSSL=false参数,禁用安全连接方式,解决警告提示
- 如果连接的是本机mysql服务器,并且mysql服务默认端口是3306,则url可以简写为
- 语法:
-
user:用户名
-
password:密码
-
-
Connection
-
数据库连接对象
-
作用
- 获取执行SQL对象
- 管理事务
-
获取执行SQL对象
- 普通执行SQL对象
Statement creatStatement()- 预编译SQL的执行SQL对象:防止SQL注入
PreparedStatement prepareStatement(sql)- 执行存储过程的对象
CallableStatement prepareCall(sql) -
事务管理
-
MySQL事务管理
- 开启事务:
BEGIN; / START TRANSACTION; - 提交事务:
commit; - 回滚事务:ROLLBACK
- MySQL默认自动提交事务
- 开启事务:
-
JDBC事务管理:Connection接口中定义了3个对应的方法
-
开启事务:
setAutoCommit(bollean autoCommit)- true:自动提交事务
- false:手动提交事务,即为开启事务
-
提交事务:
commit() -
回滚事务:
rollback()
-
-
使用try..catch语句控制事务,同时执行完毕才算成功,否则回滚事务
try { //开启事务 conn.setAutoCommit(false); //执行sql int count1 = stmt.executeUpdate(sql1); //处理结果 System.out.println(count1); //执行sql int count2 = stmt.executeUpdate(sql2); //处理结果 System.out.println(count2); //提交事务 conn.commit(); } catch (Exception throwables) { //回滚事务 conn.rollback(); throwables.printStackTrace(); } -
Statement
- 作用
- 执行SQL语句
int executeUpdate(sql):执行DML、DDL语句- 返回值
- DML语句影响的行数,通过返回值是否大于0来判断语句是否执行成功
- DDL语句执行后,执行成功也可能返回0
- 返回值
ResultSet executeQuery(sql):执行DQL语句- 返回值:ResultSet结果集对象
ResultSet
-
结果集对象
-
作用
- 封装了DQL查询语句的结果
-
ResultSet executeQuery(sql):执行DQL语句,返回ResultSet对象 -
获取查询结果
boolean next()- 将光标从当前位置向前移动一行
- 判断当前行是否为有效行
- 返回值
- true:有效行,当前行有数据
- false:无效行,当前行没有数据
xxx getXxx(参数)- 获取数据
- xxx:数据类型,如:
int getInt(参数),String getString(参数) - 参数
- int:列的编号,从1开始
- String:列的名称
//循环判断游标是否是最后一行末尾
while(rs.nest()) {
//获取数据
rs.getXxx(参数);
}
PreparedStatement
- 作用
- 预编译SQL语句并执行:预防SQL注入问题
- SQL注入
- SQL注入是通过操作输入来修改事先定义好的SQL语句,用以达到执行代码对服务器进行攻击的方法
步骤
- 获取PreparedStatement对象
//SQL语句中的参数值,使用?占位符替代
String sql = "select * from user where username = ? and password = ?";
//通过Connection对象获取,并传入对应的sql语句
PreparedStatement pstmt = comm.prepareStatement(sql);
- 设置参数值
- 给?赋值
- 参数
- 参数1:?的位置编号,从1开始
- 参数2:?的值
PreparedStatement对象.setXxx(参数1, 参数2)
- 执行SQL
- 不需要再传递sql
executeUpdate();
//或
excuteQuery();
- 好处
- 预编译SQL,性能更高
- 防止SQL注入:将敏感字符进行转义
- PrepareStatement预编译功能开启:在url的后面加
&useServerPreStmts=true - PrepareStatement原理
- 在获取PrepareStatement对象时,将sql语句发送给mysql服务器进行检查,编译(这些步骤很耗时)
- 执行时就不用再进行这些操作了,速度更快
- 如果sql模板一样,则只需要进行一次检查、编译