一、前言
之前学过一点jdbc,但后来会了Mybatis,就放弃了JDBC的记忆,这两天将JDBC重新学习了一遍,现在记录一下学习的内容
二、什么是JDBC?
JDBC的全称是Java DataBase Connection,也就是Java数据库连接,是应用于Java编程语言去连接数据库的一个技术。它为Java开发者使用数据库提供了统一的编程接口,是Java程序与数据库通信的标准API,可以使开发人员使用纯java的方式来连接数据库,并且操作数据库。
三、来源
Sun公司不知道当时的各个主流厂商用数据库的程序代码,因为无法自己写代码连接各个数据库,所以Sun公司决定,自己提供一套API,凡是数据库想与Java进行连接的,数据库厂商自己必须实现JDBC这套接口。而数据库厂商的JDBC实现,我们就叫它使此数据库的数据库驱动。
四、驱动接口
①Driver接口由数据库厂商提供,对于开发者而言,只需要使用Driver接口就可以了。
②在编程中要连接数据库,必须先装载特定厂商的数据库驱动程序,不同的数据库有不同的装载方法。
③驱动就是各个数据库厂商实现Sun公司提供的JDBC接口,即对Connection等接口的实现类的jar文件。
⑤装载Mysql驱动 ——Class.forName("com.mysql.jdbc.Driver")。
⑥装载Oracle驱动 ——Class.forName("oracle.jdbc.driver.OracleDriver");
⑦可能会抛出一个异常为ClassNotFoundException
五、Connection接口
①Connection与特定数据库的连接(会话),在连接上下文中执行SQL语句并返回结果。
②DriverManager的getConnection()方法建立在JDBC URL中定义的数据库Connection连接上。
③连接Mysql数据库:
-Connection conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/test/database","user","password");
-Connection conn=DriverManager.getConnection("jdbc:oracle:thin:@host:port:database","user","password");
④可能会抛出一个异常为SQLException
六、Statement(声明)接口
①用于执行静态SQL语句并返回它所生成结果的对象。
②三种Statement类:
Statement:
- 由createStatement创建,用于发送简单的SQL语句。(不带参数的)
PreparedStatement(预编译声明):
- 继承自Statement接口,由prepareStatement创建,用于发送含有一个或多个输入参 数的sql语句。PreparedStatement对象比Statement对象的效率更高,并且可以防止SQL注入,一般会用PreparedStatment,并且它的赋值下标是从1开始的。
CallableStatement:
- 继承自PreparedStatement。由方法PrePareCall创建,用于调用储存过程。
③常用的Statement方法:
execute():运行语句,返回是否有结果集。
executeQuery():运行select语句,返回ResultSet结果集。
executeUpdate():运行insert/update/delete操作,返回更新的行数。
注意:使用Statement会带来一些不便,比如:对于含有参数的sql语句需要进行字符串的拼接,还有就是Sql注入的问题。解释什么是SQL注入问题,现在需要执行一个"delete from user where id = "+"3 or 1=1";后面是拼接的语句,那么此时数据库中的数据将会全部删除。所以我们一般不会使用Statement。
而为什么PreparedStatement能够防止sql注入呢?因为sql语句是预编译的,而且语句中使用占位符,规定了sql语句的结构。用户可以设置"?"的值,但是不能改变sql语句的结构,因此想在sql语句后加上如"or 1=1"实现sql注入是行不通的,开发中都是使用PreparedStatement,它不仅能防止sql注入,还是预编译的(不用改变一次参数就要重新编译整个sql语句,效率高),此外,它执行查询语句得到的结果集是离线的,连接关闭后,仍然可以访问结果集。
七、ResultSet接口
①Statement执行SQL语句时返回ResultSet结果集。
②ResultSet提供的检索不同类型字段的方法,常用的有:
·getString():获得在数据库里是varchar、char等数据类型的对象;
·getFloat():获得在数据库里是Float类型的对象;
·getDate():获得在数据库里面是Date类型的数据;
·getBoolean():获得在数据库里面是Boolean类型的数据。
八、依序关闭使用对象及连接
ResultSet ➡ Statement ➡ Connection,注意一定要将三个try catch块分开写,如果ResultSet在关闭的时候抛出异常,那么接下来的Statement与Connection就不会关闭了。
九、批量处理数据
关键语句:
connection.setAutoCommit(false);
st.addBatch("insert into user(user_id,user_name,`password`,sex,age) values ('"+i+"','hcj"+i+"','123456','男','23')");
st.executeBatch();
connection.commit();
这里使用的是Statement接口,防止预编译接口的空间不够,造成异常。
十、事务基本概念
①一组要么同时执行成功,要么同时执行失败的SQL语句。是数据库操作的一个执行单元!
②事务开始于:
连接到数据库上,并执行一条DML语句(INSERT、UPDATE或DELETE)。
前一个事务结束后,又输入了另外一条DML语句。
③事务结束于:
执行COMMIT或ROLLBACK语句
执行一条DDL语句,例如CREATE TABLE语句;在这种情况下,会自动执行COMMIT语句。
断开与数据库的连接
执行了一条DML语句,该语句却失败了;在这种情况中,会为这个无效的DML语句执行 ROLLBACK语句。
注意:DML语句——Data Manipulation Language,是SQL语言中负责对数据库对象运行数据访问工作的指令集,以INSERT、UPDATE、DELETE三种指令为核心,分别代表插入,更新与删除,是开发以数据为中心的应用程序必定会使用到的指令,因此很多开发人员都把加上SQL的SELECT语句的四大指令以“CRUD”来称呼(Create、Read、Update、Delete)
DDL语句——Data Definition Language,是用于描述数据库中要存储的现实世界实体的语言。
十一、事务的四大特性(ACID)
——atomicity(原子性)
表示一个事务内的所有操作是一个整体,要么全部成功,要么全部失败;
——consistency(一致性)
表示一个事务内有一个操作失败时,所有的更改过的数据都必须回滚到修改前的状态;
——isolation(隔离性)
事务查看数据时数据所处的状态,要么是另一并发事务修改它之前的状态,要么是另一事务修改它之后的状态,事务不会查看中间状态的数据。
——durability(持久性)
持久性事务完成之后,它对于系统的影响是永久性的。
十二、JDBC连接数据的流程
①加载数据库连接驱动:
Class.forName("com.mysql.cj.jdbc.Driver");
注意:这是Mysql连接驱动6.0版本以上使用的,区别可参考此文献https://www.cnblogs.com/liaojie970/p/8916568.html
②连接数据库:
DriverManager.getConnection("URL","USERNAME","PASSWORD");
建立连接的对象内部其实包含了Socket对象,是一个远程的连接,比较耗时,这是Connection对象管理的一个要点,通常我们会使用连接池来管理连接对象。可参考此文献https://blog.youkuaiyun.com/lmy86263/article/details/76165714
③创建PrepareStatement对象:
④编写SQL语句,使用占位符来代替参数;
⑤给占位符赋值,下标从1开始;
⑥执行语句,使用execute():运行语句,返回是否有结果集;executeQuery():运行select语句,返回ResultSet结果集;executeUpdate():运行insert/update/delete操作,返回更新的行数。
⑦如果返回的是结果集,则执行遍历;
while(rs.next()){
syso(rs.getString("数据库列名"));
}
⑧关闭资源,后创建的对象先关闭。