JDBC入门

[1]快速了解JDBC

JDBC(Java Database Connectivity)的缩写,Java连接数据库。
JDBC是java程序连接数据库的技术统称。
JDBC由java语言的规范(接口)和各个数据库厂商的实现驱动(jar)(jar里包含第三方对于接口的实现类)组成。
JDBC是一种典型的面向接口编程。
JDBC优势:
1)只需要学习了JDBC规范接口的方法,即可操作所有的数据库软件。
2)项目中期切换数据库软件,只需要更换对应的数据库驱动jar包,不需要更改代码。

[2]java语言的规范接口和各个数据库厂商的实现驱动jar包

-jdk下jdbc规范接口,存储在java.sql和javax.sql包中的api
-各个数据库驱动jar包由各个数据库厂商自己编写jdbc的实现类然后压缩成jar包并导入工程下,即可连接该数据库厂商的DBMS软件。

[3]jdbc涉及具体核心类和接口

1)DriverManager
-1.将第三方数据库厂商的实现驱动jar注册到程序中
-2.可以根据数据库连接信息获取connection
2) Connection
-和数据库建立的连接,在连接对象上,可以多次执行数据库的CURD动作
-可以获取statement和preparedstatement,callablestatement对象
3) Statement | PreparedStatement | CallableStatement
-具体发送SQL语句到数据库管理软件的对象
-不同发送方式稍有不同!perparedstatement使用为重点!!!
4) Result
-面向对象思维的产物(抽象成数据库的查询结果表)
-存储DQL查询数据库结果的对象
-需要我们进行解析,获取具体的数据库数据

[4]JDBC API使用路线

Alt text

JDBC使用步骤

[1]引入mysql-jdbc驱动jar

从官网下载mysql connector/J ,他会自动选择最新版本的connect jar包,然后选择platform independent 随便选择一个下载即可。

[2]jdbc基本使用步骤分析

1)注册驱动
2)获取连接
3)创建发送sql语句对象statement()
4)发送sql语句,并获取返回结果
5)结果集resultset解析
6)资源关闭/释放资源

[3]Idea代码块

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public class StatementQueryPart {
public static void main(String[] args) throws SQLException {

//1.注册驱动
DriverManager.registerDriver(new Driver());

//2.获取连接
Connection connection=DriverManager.
getConnection("jdbc:mysql://192.168.xx.xxx:3306/atguigu","root","填自己设定的密码");

//3.创建statement
Statement statement=connection.createStatement();

//4.发送SQL语句,并且获取返回结果
String sql="select * from t_user;";
ResultSet resultSet=statement.executeQuery(sql);

//5.进行结果集解析
while(resultSet.next()){
int id=resultSet.getInt("id");
String account = resultSet.getString("account");
String password = resultSet.getString("password");
String nickname = resultSet.getString("nickname");
System.out.println(id+"--"+account+"--"+password+"--"+nickname);
}

//6.关闭资源
resultSet.close();
statement.close();
connection.close();
}
}

JDBC优化:

//1.注册驱动方式的优化

需要优化的方面:
Alt text
优化方法:
Alt text
实际使用迭代过程:
Alt text

//2.获取数据库连接详解

连接方法有三个:Alt text
允许开发者,以不同的形式传入数据库连接的核心参数!(方法重载)

核心属性:
-数据库软件所在的主机的ip地址:localhost | 127.0.0.1(我自己是linux虚拟机的mysql,ip为192.168.xx.xxx)
-数据库软件所在的主机的端口号:3306
-连接的具体数据库名称:atguigu
-连接的账号:root
-连接的密码:填自己设定的密码
-可选的信息:无

三个参数连接方法:
String url:数据库软件所在的信息,连接的具体库,以及其他可选信息
语法:jdbc:数据库管理软件名称mysql/oracle://ip地址|主机名:port端口号/数据库名?key=value&key=value
具体:jdbc:mysql://192.168.xx.xxx:3306/atguigu
如果是装在本机上且没调整端口号的话,可以省略默认的本机IP地址和3306端口号,可以简写为——jdbc:mysql:///atguigu
String user:数据库账号 root
String password:数据库密码 填自己设定的密码

两个参数的连接方法
String url:此url和三个参数的url作用一样! 传递数据库ip,端口号,具体的连接数据库名和可选信息
Properties info: 至少存储账号和密码
Properties类似于map ,只不过key=value都是字符串形式的。
Alt text

一个参数的连接方法
String url:同上, 传递数据库ip,端口号,具体的连接数据库名和可选信息(通过可选信息来传递数据库账号和密码)
携带固定的参数名user 和 password
具体:jdbc:mysql://192.168.xx.xxx:3306/atguigu?user=root&password=填自己设定的密码
三种连接方式的代码写法:(账号密码都为root)
Alt text
url的路径属性可选信息:
Alt text

//3.创建发送SQL语句的statement对象且优化为preparedstatement

Statement statement=connection.createStatement();
以上方式适合执行静态sql语句但是有sql注入攻击的问题
建议之后使用preparedstatement,能安全防止sql注入攻击。
Alt text
preparedstatement和statement的执行流程区别
Alt text

//4.发送SQL语句(1.编写SQL语句 2.发送SQL语句)

详解:根据sql语句分类选择发送方法!
非DQL使用executeUpdae(sql)
DQL使用executeQuery(sql)
Alt text

//5.结果集解析

Java是一种面向对象的思维,将查询结果封装成了resultset对象,我们应该理解,内部一定也是有行和有列的!
因此:解析结果集的思路是:resultSet ——> 逐行获取数据, 行——> 获取当前行的的列数据

Alt text
想要进行数据解析,我们需要进行两件事情:1.移动光标指定获取数据行 2.获取指定数据行的列数据即可

1.光标移动问题
resultSet内部包含一个光标,指定当前行数据!
默认光标指定的是第一行数据之前!
我们可以调用next()方法向后移动一行光标!如果有数据返回true并向下移动一行,无数据返回false。
如果有很多行数据,我们可以使用while(resultSet.next()){获取每一行的数据}
移动光标的方法还有很多,有兴趣可以自己了解。但是必须要会next()结合while循环遍历resultSet.

2.获取列的数据(获取光标指定的行的列的数据)
有两套方法:
-resultSet.get类型(int columnindex)根据列索引获取列数据,索引从1开始
-resultSet.get类型(String columnlabel)根据列名称(有别名可以写别名)获取列数据

//6.关闭资源

resultSet.close();
statement.close();
connection.close();

JDBC优化后使用步骤

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
   //1.注册驱动
-Class.forName("com.mysql.cj.jdbc.Driver");

//2.获取连接
-Connection connection = DriverManager.getConnection("jdbc:mysql://192.168.xx.xxx:3306/atguigu",
"root", "填自己设定的密码");

//3.编写SQL语句结构
-String sql="delete from t_user where id=?;"; 动态值用?代替

//4.创建preparedStatement对象并且传入SQL语句结构
-PreparedStatement preparedStatement = connection.prepareStatement(sql);

//5.占位符赋值
-preparedStatement.setObject(1,3);

//6.发送SQL语句,并且获取结果。
-DQL语句使用int rows=preparedstatement.executeQuery()
-非DQL语句使用ResultSet resultSet=preparedstatement.executeUpdate()

//7.结果集解析(DQL语句才有,非DQL语句返回的是影响的行数
移动光标执行下一行数据 next(); ——> if(next()) ——>while(next())
获取列的数据 get类型(columnIndex or columnLabel)索引从1开始
获取列的信息 getMetadata(); ResultsetMetaData对象 包含的就是列的信息
获取列的数量和名称 getColumnCount | getColumnLabel(Index)

//8.关闭资源
关闭顺序:结果集——>preparedStatement对象——>connection
-resultSet.close();
-preparedStatement.close();
-connection.close();

JDBC扩展

1.主键回显
即通过preparestatement对象获取回显的主键
获取装主键的结果集对象,一行一列 id=值

Alt text
关键点一:
Alt text
关键点二:
Alt text

2.批量插入
即高效执行批量插入。

-路径后面添加?rewriteBatchedStatement=true 允许批量插入
Alt text-insert into values(必须写)语句不能添加;结束
Alt text
-不是执行语句每条,是批量添加addBatch();
Alt text
-遍历添加完毕以后,统一批量执行executeBatch();
Alt text

3.jdbc中数据库实现事务

Alt text
实现银行转账业务
Alt text

思路:在Dao层封装操作数据库的方法——>而在Service业务层执行Dao层的方法,在Service层注册驱动和获取连接然后将Connection连接传入到Dao层,使其顺利执行业务(记住不要close(),Service层还要connection来进行事务,close()由Service层来做),并融入try(开启事务——>执行业务方法——>事务提交)…..catch(出异常就rollback()回滚即可)…..finally(关闭资源connection.close)来实现数据库的事务。为什么要将connection传入Dao层在执行,因为实现事务的最基本要求,必须是同一个connection连接对象!!!

Dao层封装方法
Alt text

Service层负责执行开启事务和执行业务!Alt text

Druid连接池

Druid连接池是针对connection的一种连接池技术,它会创建一个容器池然后里面装入connection连接,每次需要使用可以进入容器池获取连接,使用结束后可以回收connection连接,可以实现connection的复用,从而改善原来每次创建新连接使用完然后关闭资源这种用完即弃的低效率且浪费资源做法。相当于线程池一样复用线程的概念节约资源概念。
Alt text

市面连接池对比Alt text

#Druid连接池使用步骤

//1.导入druid工具类jar包

Alt text

添加为库
Alt text

//2.连接池使用方法

1.硬编码方式
Alt text

-思路:
Alt text
-代码:
Alt text

2.软编码方式
-思路:创建properties文件,通过properties文件来传输需要的配置参数,灵活实例化druid连接池

-创建properties文件并填写配置参数
Alt text

-代码
Alt text

#JDBC使用优化以及工具类封装

//1.jdbc工具类封装v1.0

-思路:
Alt text

-代码
Alt text

-使用
Alt text

//2.jdbc工具类封装v 2.0

优化工具类v1.0版本,考虑事务的情况下!如何一个线程的不同的方法获取同一个连接。
Alt text

思路:有ThreadLocal对象来管理连接,在类里设置一个静态ThreadLocal变量,创建连接时从ThreadLocal变量里面获取,进行判断当前有误连接,有则返回连接,没有就创建新的返回给ThreadLocal存储,然后返回连接给调用者,使用完毕后使用回收方法里先在ThreadLocal里获取连接,如果有连接,在ThreadLocal里移除连接,并设置事务自动提交为True,然后回收线程。如果没有连接

-完整代码:Alt text
Alt text

-关键点1
Alt text

-关键点2
Alt text

-关键点3
Alt text

调用和回收的话直接再Service层和Dao层使用以下代码:
调用:
Connection connection=JdbcUtilsV2.getConnection()
回收:
JdbcUtilsV2.freeConnection()

//3.高级应用层封装BaseDao

思路:Alt text

按照发送SQL语句方法封装2个方法并给其他类继承:1.简化非DQL 2.简化DQL
1)简化非DQL语句
-需要外部传入SQL语句结构(创建statement用)和可变参数(给占位符赋值用)
思想:封装操作数据库方法,让其他类继承,大大简化代码。
-代码
Alt text
Alt text

-实际调用:大大简化代码,只要保留动态的sql语句和需要传入的values
Alt text

2)简化DQL语句
-思路:Alt text

-实现思路:反射+泛型
Alt text

-代码:
Alt text
Alt text