JAVA SE自学 基础篇 JDBC
目标
- DriverManager
- Driver
- Connection
- Statement
- PreparedStatement
- ResultSet
- 获取AUTO_INCREMENT值
- JDBC级别的事务控制
什么是jdbc
JDBC ( Java Data Base Connectivity ) , Java的数据库连接技术
工作方式:
但是, Java程序运行过程中, 只有接口没有其实现类是不行的 ! 所以开发时, 我们需要把厂商提供的驱动程序 ( 如: mysqlconnectorjava5.1.18.jar ) 加入到项目的Build Path中.
JDBC API中的主要类和接口:
- DriverManager类 – 驱动管理器, 通过它可以创建数据库连接
- Connection接口 – 表示到数据库的连接, 基于connection可以创建SQL语句
- Statement接口 -- 封装了SQL语句的各种方法, 如: 查询, 增删改
- ResultSet接口 -- 封装了对结果集的操作, 如: 后移一行, 读取某一列的值
JDBC通用步骤
- [可选] 加载驱动程序
1 Class.forName("驱动程序名称");
- 创建数据库连接
1 Connection conn = DriverManager.getConnection(url, user, password);
- 创建Statement
1 Statement stmt = conn.createStatement();
- 执行SQL ( 本质上是通过网络发送SQL语句给数据库服务进程, 由服务器来执行 )
1 int rowAffected = stmt.executeUpdate(用于增删改的SQL); // 返回数据库受影响的行数
2 ResultSet rs = stmt.executeQuery(用于查询的SQL); // 返回的是结果集
- 如果是查询, 需要解析结果集
1 while(rs.next()){ // next()用于后移一行
2 String dname = rs.getString("dname"); // 读取当前行dname列的值 3 }
- 释放资源
1 rs.close();
2 stmt.close();
3 conn.close();
JDBC API主要方法
DriverManager类
- getConnection( url, user, password ) : Connection
Connection接口
- createStatement( ) : Statement
- close()
Statement接口
- executeUpdate( sql ) : int
- executeQuery ( sql ) : ResultSet
- close()
ResultSet接口
- next() : boolean , 在结果集中后移一行
- getXxx( int 列索引 | String 列名 ) : Xxx , 在当前行中读取某一列的值, Xxx表示数据类型
- close()
注意
开发中使用的Connection , Statement, ResultSet均位于包 java.sql下!
URL格式
url实际上是告诉驱动管理器: 我要连接到哪台服务器的哪个端口, 我要使用哪个数据库
协议://数据库服务器的地址:端口/目标数据库
jdbc:mysql://localhost:3306/example
如果数据库默认编码是utf8, java程序连接数据库时出现了乱码, 可以写成这样:
jdbc:mysql://localhost:3306/example?useUnicode=true&characterEncoding=UTF8
有时候也可以把user和password写在url中:
jdbc:mysql://localhost:3306/example?user=root&password=root
PreparedStatement
普通的Statement不会编译SQL语句, 也容易发生SQL注入 ( 具体见示例 )
为了防止SQL注入以及提高SQL语句的执行效率, JDBC API提供了预编译的PreparedStatement.
用法:
- SQL语句中用 ? 表示动 态参数, 不要用字符串拼接 , 注意?两侧不要添加单引号
- 创建PreparedStatement要这样:
PreparedStatement stmt = conn.prepareStatement(sql);
- 传入 sql中的?表示的动态参数 ( 索引从 1 开始 )
1 stmt.setXxx(1, 参数值);
2 stmt.setXxx(2, 参数值);
3 ...
- 执行SQL语句时, 不要再次传入sql
1 stmt.executeUpdate();
2 stmt.executeQuery();
事实上, 在实际工作中, 所有场景都可以用PreparedStatement来替代Statement!
获取AUTO_INREMENT自动生成的值
方案一
方案二
要注意的是: SELECT LAST_INSERT_ID()必须和INSERT语句在同一个Connection上执行 ( 同一会话内 ).
事务处理
事务, Transaction, 它表示不可分割的一系列操作.
事务为数据操作提供"后悔药".
事务一旦开启, 对数据的更改处于临时状态(可撤销/回滚), 可以后悔.
提交事务指的是让更改正式生效.
回滚事务指的是撤销更改.
事实上, 每个SQL都自动开启了一个隐性事务, 一旦出错, 自动回滚; 一旦没有错误产生, 自动提交; 在MySQL数据库级别, 例如存储过程中, 可以用以下语法控制事务流程:
1 START TRANSACTION //开启事务
2 SET AUTOCOMMIT = FALSE // 同上
1 COMMIT // 提交事务
1 ROLLBACK // 回滚事务
在默认情况下, MySQL的AUTOCOMMIT为TRUE
在JDBC级别, 也可以控制事务流程:
1 connection.setAutoCommit( false ) // 设置不自动提交, 相当于开启事务
1 connection.commit() // 提交事务
1 connection.rollback() // 回滚事务
要注意的是: 一个事务的多个操作(INSERT, UPDATE, DELETE .) 必须在同一个Connection上执行, 事务 才能起作用!