在实际开发中,SQL很少是手动输入的,绝大多数的SQL都是通过代码,自动执行的。这个时候就需要其他编程语言来操作数据库服务器。
自己写一个数据库客户端是非常容易的,各种数据库本身就提供了一系列的API,但是自己写一个数据库服务器就非常困难了。Java中,就出现了JDBC。
JDBC就是一种用于执行SQL语句的Java API,可以为多种关系型数据库提供统一访问,它是由一组用Java语言编写的类和接口组成的。
JDBC的作用:可以通过java代码操作数据库,同时各种数据库厂商,都提供了能够适应JDBC相关的驱动包。只要掌握了这套API,无论操作哪个数据库,操作的代码都是基本相同的。JDBC屏蔽了不同数据库原生API之间的差异,使用同一套API接口来规范了所有数据库的编程操作。
目录
JDBC的使用
驱动包查找
导入jar包
编写JDBC代码
创建数据源
和数据库建立连接
构造SQL语句
执行SQL语句
断开连接
SQL动态语句
查找
总结
JDBC的使用
驱动包查找
先能够安装对应数据库的驱动包,以我使用的mysql 5.7为例,通过Maven Repository: Search/Browse/Explore (mvnrepository.com)来找到所需要的驱动包。
因为我的mysql版本是5.7,所以我们选择任何5.1的版本都可以
我们下载的是一个jar文件,jar是一个java格式的压缩包,类似于.rar .zip一样。
.jar中有很多的.class文件,.java编译生成的二进制字节码文件,同时我们写一个程序发布出去,主要就是通过.jar的形式。
导入jar包
(1)在项目中创建目录,把.jar复制进来
(2)右键这个目录,然后点击Add as Library,此时idea就可以解析出jar包里面包含的内容
编写JDBC代码
创建数据源
在创建好类文件和主函数后,我们首先要创建一个DataSource
DataSource dataSource = new MysqlDataSource();
DataSource是java自带的包中的类,而MysqlDataSource是驱动包里面具体提供的类,这里是向上转型。
((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/lzx?characterEncoding=utf8&useSSL=false");
((MysqlDataSource)dataSource).setUser("root");
((MysqlDataSource)dataSource).setPassword("123456");
后面的具体的代码我们先不关注,我们看到 ((MysqlDataSource)dataSource),这里是向下转型。
后续代码使用DataSource类型的实例,避免MysqlDataSource这个名字扩散到代码的各种地方(高内聚),未来要是交换数据库,只需要动这一个数据库即可。
当然也可以不做任何转型,
MysqlDataSource mysqlDataSource = new MysqlDataSource();
在当前的简单的实例代码中,向上转型/向下转型和直接写相比,没有任何优势,但一但涉及到数据库的切换问题,就会知道高内聚的代码更有优势。
我们往下看:
.setURL("jdbc:mysql://127.0.0.1:3306/lzx?characterEncoding=utf8&useSSL=false");
.setUser("root");
.setPassword("123456");
这个代码是固定写法,URL是唯一资源地址符,也就是网址
上面的数据源的创建操作,只是描述了服务器在哪,并没有进行真正的访问,紧接着的连接操作才是真正开始通过网络进行通信。
和数据库建立连接
Connection connection = dataSource.getConnection();
通过Connection新建一个对象,
但是我们发现,getConnection报错了,这里是一个异常,我们要处理这个异常
处理好了之后就算和数据库建立了连接,但是真正的执行还没开始
构造SQL语句
SQL语句,我们用String类型来表示
String sql = "insert into student values(1,'张三')";
但是JDBC中还需要搭配一个特定的对象,来描述这里的sql的情况
PreparedStatement statement = connection.prepareStatement(sql);
PreparedStatement背后做了很多事情,比如会对SQL语句进行一些预处理(对语法进行解析之类的),以前通过cmd输入的sql,都是把sql直接发给服务器,让服务器来解析,一个服务器是要做很多的事情的,要对应很多客户端的。
执行SQL语句
针对增,删,改,使用executeUpdate 来执行.
针对查,使用executeQuery 来执行
执行就是给服务器发送网络请求
具体的代码:
int ret = statement.executeUpdate();
System.out.println("ret = " + ret);
这个ret就是executeUpdate的返回结果,是一个整数,代表着代码操作了几行数据,跟cmd客户端中返回的结果是一样的
断开连接
statement.close();
connection.close();
当连接不再使用的时候,就需要释放连接。
同时注意到:资源释放的顺序和创建的顺序是相反的,后出创建的statement,那么就先关闭它。
JDBC支持两种风格的代码,一种是DriverManager,一种是DataSource。
1.DriverManager使用的时候,需要借助反射.咱们不喜欢。
反射不属于常规编程手段,特殊情况下的特殊手段。
2.DataSource相比于DriverManager,内置了数据量连接池可以重复利用连接。
SQL动态语句
String sql = "insert into student values("+ id +",' " + name + " ')";
在前面的构造sql语句中,这段代码比较丑,也不方便阅读,同时还容易引起SQL注入攻击,更靠谱的方案,是使用PreparedStatement来通过占位符替换的方式,来实现动态sql的构造。
通过占位符,然后再通过statement引用替换,可以把具体的值修改。
查找
刚刚演示的是插入的代码,修改和删除几乎一模一样,下面我们重点说一下查找,和上面的曹锁相比,查找还需要遍历结果集
ResultSet resultset = statement.executeQuery();
while (resultSet.next()){
//next相当于移动一下光标,光标指向下一行.然后移动到结尾,就返西false
//使用 getXX方法获取到每一列.
//获取 int,就使用getInt,获取String,使用getString
//这里的参数,就是数据库表的列名.
int id = resultSet.getInt("id"));
String name = resultSet.getString("name");
System.out.println(id + ": " + name);
}
并且最后断开连接的时候也需要多加一个步骤:
resultSet.close();
statement.close();
connection.close();
总结
如果一个SQL代码一天要执行一万次,那么JDBC就可以让Java程序快速的把这一万次执行完毕。
借助代码自动的完成重复劳动,代码写一次。就可以自动的执行很多次,提高效率,解放生产力
JDBC 实际工作中,可能并不会直接使用,因为JDBC代码写起来有点麻烦。
因此就有一些库和框架,对JDBC进行了进一步的封装,让我们用起来更方便,Mybatis,或者JPA这种,让我们写起来非常方便。但是学习JDBC是仍然有巨大的意义的,框架一直在变更,但是JDBC是恒定,框架也都是基于JDBC的。如果你发现现有的框架,难以满足你的需求,就可以基于JDBC来进行框架魔改或者自定义。