今天是刘小爱自学Java的第66天。
感谢你的观看,谢谢你。
话不多说,开始今天的学习:
很多优秀的框架中都封装有jdbc,可以直接使用,都不用我们自己写的,特别方便。
但本着学习的原则:知其然也要知其所以然。
所以决定还是学一下jdbc具体是如何写的?以及是如何一步步封装的?其中JDBC一共有6步:
- 注册驱动
- 获取连接
- 创建执行语句
- 执行语句
- 处理结果集
- 释放资源
一、注册驱动、获取连接详解
注册驱动:
①看下Driver源码
该Driver类是mysql编写的一个实现类,用来实现Java中规定的Driver接口。
②静态代码块
Driver类中有一个静态代码块,已经写出了注册驱动这个步骤,并且静态代码块是随着类的加载而加载的。
也就是说我们第一步注册驱动其实是多余的,只需要让Driver类加载就好了。
如何加载?
前面学反射的时候就接触过,每一个类都有其唯一对应的Class对象。做一个回顾,Class对象的获取有三种方式:
①通过对象调用getClass()方法
将注册驱动这个步骤替换成这一步,会发现运行Java程序,照样能得到一样的结果。
但是这个步骤有一个问题就是driver对象根本就没用到。要知道对象是要进堆内存的,那为何还要它进堆占用内存呢?
②通过类名.class也可以获取Class对象
这个呢也是可以的,但是要保证Driver是mysql中的Driverl类。
③用Java中的Class类调用forName()方法
这种是最稳妥的,不用担心出错。
“com.mysql.jdbc.Driver”这个是全限定名,也就是包名+类名。通俗一点理解就是:
- com是一个文件夹
- mysql是com下的一个文件夹
- jdbc是mysql下的一个文件夹
- Driver是jdbc下面的一个文件
这样理解下来也就很好记下来了。
值得注意的是:
注册驱动这个步骤其实都不用写的、因为MySQL驱动3.0之后就实现自动注册驱动了。
但是3.0之前是需要我们自己实现注册的。
要知道也有很多企业喜欢用旧的版本。
现在jdk都更新到14了,还不是有那么多用jdk8的,有的银行还用jdk6呢。
所以了解一下肯定是没问题的。
- 就算有自动注册,这样写的话也不会错。
- 但是不写的话,如果遇到旧版本没法自动注册的就会报错。
说完注册驱动,再仔细讲讲获取连接。
①jdbc:mysql
这个就有点类似于http,所以后面要接“://”
其中jdbc是一个协议,mysql是jdbc的子协议。
②ip+端口
因为是本地主机,数据库就在我自己的电脑上。
所以ip为127.0.0.1,其中用localhost也就是本地主机,效果是一样的。
③liuxiaoai
这是我MySQL里创建的一个数据库名。
以上3点组成的就是url,也就是知道了我想访问的数据库在哪儿了。
而想要访问数据库,还要知道用户名和密码,这也就是另外两个参数。
二、statement和resultSet详解
statement就相当于是连接Java程序和数据库的一个通道,通过它来传输sql语句,也就是IO流?
sql语句可以用来增删改查。
①executeQuery()方法
当sql为查询语句时,就用该方法。
其返回值是一个结果集,我们可以遍历这个结果集得到我们想要的数据。
②executeUpdate()方法
当sql为增删改语句时,就用该方法。
其返回值是updateCount,也就是sql语句执行影响了几行数据:
- ②中增加了1行数据,所以返回值为1;
- ③中删除了2行数据,所以返回值为2。
④execute()方法
这个方法是用来判断sql语句的。
其返回值是一个boolean值:
- 如果为查询语句,则执行executeQuery()方法;
- 如果为增删改语句,则执行executeUpdate()方法。
但是该方法不怎么实用,原因很简单:
其返回值是不确定的,所以很难将该方法封装。
resultSet结果集
其本质上其实就是集合中的迭代器:
①next()方法
用于判断下一行是否有数据
- 如果下一行有数据,就继续循环;
- 如果下一行没有数据了,就停止循环。
②getString()方法
- 参数可以填数据表中的列名,那么得到的结果就是列名对应的具体值。
- 参数也可以填数字,如果是1就是第一个列名也就是id,这样依次往下推。
但是一般都是填列名,这样阅读性强,直接就知道获取的是什么数据。
如果填数字,要对数据表了如指掌,不然时常会搞不清楚数字具体对应的是哪一列。
三、JDBC的封装
将jdbc封装到一个工具类JdbcUtil中,我们使用时直接可以用工具类获取连接,会方便很多。
jdbc中牵扯到如下变量:
- Driver:com.mysql.jdbc.Driver
- url:jdbc:mysql://localhost:3306/liuxiaoai
- user:root
- password:root
封装分析一:
这些变量并不是一成不变的,数据库不一样Driver就不一样,url、user以及password更是各不相同。
那根据代码的可拓展性原则:出现变化,要保证修改的代码越少越好。
那该怎么办是好?
编写一个配置文件即可。
①jdbc.properties文件
将这些变量抽取出来,放入配置文件中。
这样做有什么好处?
以后换数据库软件了,换数据库名了,数据库账号密码变了,都只需要修改配置文件就好了,代码都不用动。
②加载配置文件
在Java里有一个类叫Properties。
其有一个load()方法,可以用来加载对应的配置文件。
参数为一个输入流,将我们配置文件所在的路径填写进去即可。我这边的路径是在项目src文件夹下。
③获取配置文件信息
其中有一个getProperty()方法。
看方法名就知道该方法可以获取配置文件中对应的属性。
封装分析二:
这些配置文件需要获取几次?
只需要一次就够了的。
同样的道理,驱动注册也只需要一次就够了。
在一个类中,什么东西只随着类的加载而加载一次?
答案是:静态代码块。
所以封装如下:
static{"静态代码块"};即为静态代码块。
其中异常要try……catch,在静态代码块中也没法throws。
封装分析三:
既然获取连接需要的三个参数都被封装起来了,那么该方法也可以封装在工具类JdbcUtil中;
并且每次我们都需要释放资源,也就是关流,同样也可以将其封装起来。
代码如下:
①获取连接方法
工具类中的方法一般都是静态方法。
这里将getConnection()方法封装成一个静态方法,实际使用时直接用JdbcUtil类调用即可。
②释放资源
也就是close方法关流,其中的三个参数都为Java中对应的参数。
都要进行try…catch处理异常,前面为了方便直接抛异常了(为了省事、不然代码太多也不好截图)。
但实际上大多数时候都是需要try…catch处理的。
四、JDBC测试
先直接用工具类JdbcUtil调用封装的方法即可获取连接。
当JdbcUtil类加载的时候,静态代码块就会执行,同时配置文件信息会被获取,驱动也会注册。
然后再就是具体的执行语句以及处理结果,就不再赘述。
最后释放资源直接调用封装的release方法即可。
以上就是对JDBC的封装以及测试。
我不清楚框架中是如何封装JDBC的,肯定没我这想的这么简单,但是我觉得思想上应该是大同小异。并且学习的过程本身也就是不断优化的过程。
最后
谢谢你的观看。
如果可以的话,麻烦帮忙点个赞,谢谢你。