目录
·前言
一、JDBC概述
二、准备工作
1.下载MySQL的JDBC驱动包
2.把jar引入到项目中
三、JDBC编程
1.插入操作
2.查询操作
·尾声
·前言
本篇文章主要介绍如何利用Java代码进行操作数据库,在实际开发中,绝大多数对数据库的操作我们都是通过代码进行操作,而不是在控制台手动输入SQL语句进行操作数据库,通过代码操作数据库使我们对数据库的操作更方便,使我们程序的可移植性更强,本篇文章使用的是Java的JDBC来对数据库进行操作,下面进入本篇文章的学习吧。
一、JDBC概述
JDBC,即Java Database Connectivity,在Java中操作数据库最基础的方式就是JDBC,为什么是最基础呢,因为现在出现了很多框架技术,他们在JDBC的基础上进行了封装,使JDBC用起来更方便。
数据库是一个“级别”,有很多数据库,如:MySQL、Oracle、Sql Server等,那么通过代码操作数据库的前提,就是数据库要提供 api ,我们调用api才能完成代码操作数据库,这里 api 全称是 Application Programming Interface应用程序编程接口,这是一个通用术语,只要是基于这个东西进行编程,就需要这个东西提供api,然而各个数据库的api并不相同,因此Java站了出来,提供了一套api标准,保证各个数据库原有的api不变,在这个基础上加个封装层,适配到JDBC这一套接口上。
二、准备工作
1.下载MySQL的JDBC驱动包
前面说到,每个数据库都有自己本身的一套api,在这个api基础上,重新封装,封装得到的就是JDBC的驱动包,这种驱动包属于“第三方库”,并不是JDK里原生就有的,就需要通过其他途径下载下来并引入到项目中,在咱们Java的世界中,有一个东西叫做“中央仓库”,这是一群大佬,把第三方库收集起来,统一放到一个服务器上,这样就可以通过这个服务器来获取到了,后续一些新的开发者做的一些新的第三方库也会上架到这个“中央仓库”上,这个中央仓库的连接如下:
Java中心仓库 打开可能会有一点慢,这种情况很正常。
主界面如下:
由于我使用的MySQL版本是5.7.27,所以此处也需要使用5系列的驱动包,选择上述两个仓库的第二个仓库,当然8版本的MySQL服务器,只要去下对应版本的驱动包即可。
下载的是一个.jar这样的文件,jar本质上是一个类似于rar这样的压缩包,里面主要是.class文件, .class文件可能会有很多,每个类都会有一个.class文件,因此Java官方给出了解决方案,把这些 .class文件打成了.jar压缩包,在我们实际使用的时候,不需要对jar进行解压缩,只要把jar导入我们自己的项目中即可,使用jar包发布Java程序,是当前既定的一种方式。
2.把jar引入到项目中
先在编译器中新建一个项目,然后创建一个目录,把刚才下载好的jar包拷贝进去。
此时,编译器就可以解析到我们导入的jar包了,下面进行JDBC编程的介绍。
三、JDBC编程
在这里,我们利用JDBC主要介绍两个数据库相关操作,一个是插入操作,一个是查询操作,其中插入操作与修改删除操作原理是一致的,所以只介绍插入这一种。在进行JDBC相关代码编写前,先打一个预防针,如果你是初次接触,可能会感觉有些麻烦,这是正常现象,因为这里涉及到了很多新的类和新的方法,不用担心,只要多敲几次代码,熟悉之后就会感觉很简单。
1.插入操作
在进行完上述的导入jar包的操作后,我们开始编写JDBC的代码对数据库进行插入操作。
第一步:创建数据源(数据源描述了你要操作的数据库在哪里)
数据库是一个服务器,这个服务器可能在你这个主机上,也可能在其他主机上,为了明确这个服务器的位置,我们通常用以下方式来进行定位:
ip地址 + 端口号 + 数据库名
ip地址:用来描述一个主机在网络上的位置,往往是一串数字构成
端口号:一个主机上同时有很多服务器程序,使用端口号来区分不同的服务器程序
这里我们使用的ip地址是一个特殊的ip地址“127.0.0.1”,这个ip地址也叫做“环回ip”,表示本机,因为我这里使用的数据库服务器与Java代码是在同一个主机上的,然后这里的端口号使用的是3306,(这是MySQL服务器默认的端口号)。具体代码,与详细介绍如下:
到此,数据源就准备就绪了。
第二步:和数据库服务器建立连接
代码如下:
Connection connection = dataSource.getConnection();
这个代码就会和数据库服务器之间建立连接,建立好连接后,这过程可能会出错(抛出异常),比如:ip,port,数据库名,user,password……当出现错误的时候,异常信息中就会告诉我们错误原因。
第三步:构造SQL语句
代码如下:
String sql = "insert into people values (1,'张三');";
//需要把String sql 转换成 语句对象
PreparedStatement statement = connection.prepareStatement(sql);
这里的字符串sql中可以写任意的SQL语句,PreparedStatement 意思为预处理的语句,每条要执行的SQL语句是需要进行语法解析的,语法解析也是有一定开销的,通过控制台写SQL语句,都是把原始的SQL发给服务器,服务器负责解析SQL并执行,使用PreparedStatement这个类,就可以在客户端这边提前把SQL解析好,把解析后的结果发给服务器,这样服务器解析的开销就大幅度降低了,直接执行即可。
上面构造SQL语句是将代码写“死”的,如果想要插入其他数据,就需要修改代码,重新编译,关于重新编译这种操作,代价可能会非常大,我们期望在执行过程中,可以自己输入要插入的数据,所以我们可以用以下这种写法:
Scanner scanner = new Scanner(System.in);
System.out.print("请输入id->: ");
int id = scanner.nextInt();
System.out.print("请输入姓名->: ");
String name = scanner.next();
String sql = "insert into people values (" + id + ",'" + name + "');";
上述这种代码是通过简单的字符串拼接来构造的SQL,虽然是可以自己输入要插入的数据了,但是还有三个问题:
- 代码太乱,这里稍微构造错了一点,都会使SQL无法正确执行;
- 代码太丑(代码丑是一个很大的问题,这是一个看脸的世界);
- 代码存在SQL注入攻击的风险。
这里简单介绍一下SQL注入攻击是什么,首先你要明确,永远不要预期你的用户会按照你的要求来输入内容,比如上述代码中,让输入name时,他不正常输入name,而是输入了‘);drop database .......这样的内容,此时上述代码就会把用户输入的内容构建到SQL语句中了,我们以为执行的只是一条insert,实际上已经带上了 drop database这样的操作了,当然这里只是举了个例子,真正的SQL注入攻击还是不太一样,但也差不多,为了解决上述的问题,真正的方案,是使用 PreparedStatement 提供的一个替换占位符的功能,代码如下:
Scanner scanner = new Scanner(System.in);
System.out.print("请输入id->: ");
int id = scanner.nextInt();
System.out.print("请输入姓名->: ");
String name = scanner.next();
String sql = "insert into people values (?,?)";
PreparedStatement statement = connection.prepareStatement(sql);
statement.setInt(1,id);
statement.setString(2,name);
? 作为占位符,占位的目的就是为了进行“替换”,通过上述代码中setInt()和setString()这个方式,也能够起到刚才动态构造SQL的效果,当然,这里是方法还有很多种,不同的方法就是对应到不同类型的参数:
第四步:把构造好的SQL发给服务器去执行
代码如下:
int n = statement.executeUpdate();
System.out.println("n = " + n);
在 PreparedStatement 这个类包含了以下两个方法:
这里代码主要介绍的是插入操作,所以选择方法是executeUpdate()方法。此时,代码就会构造一个网络请求,发送给MySQL服务器(我写的这个代码就扮演了MySQL客户端的角色,相当于cmd一样),并且等待服务器响应数据,把得到的响应最终显示到控制台上。
第五步: 最后一步,释放必要的资源
代码如下:
statement.close();
connection.close();
内存,创建个变量之类的,也是一种重要的资源,之所以没有去手动释放,是因为JVM帮我们做了自动回收(垃圾回收,GC),然而我们在创建下面这俩对象的时候,是需要我们进行释放的,这两个对象内部都持有一些计算机重要的软/硬件资源,DataSource不需要释放,因为这里就只是单纯的保存了几个信息(URL,user,password),释放资源的顺序,和创建的顺序是相反的,我们先创建的connection,后创建的statement,所以先释放的是statement,再释放connection。
完整的代码如下:
import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Scanner;
public class TestJDBCInsert {
public static void main(String[] args) throws SQLException {
//1.创建数据源,数据源描述了你要操作的数据库在哪里
DataSource dataSource = new MysqlDataSource();
((MysqlDataSource) dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/bite?characterEncoding=utf8&useSSL=false");
((MysqlDataSource) dataSource).setUser("root");
((MysqlDataSource) dataSource).setPassword("111111");
//2.和数据库服务器建立连接
Connection connection = dataSource.getConnection();
//3.构造SQL语句
Scanner scanner = new Scanner(System.in);
System.out.print("请输入id->: ");
int id = scanner.nextInt();
System.out.print("请输入姓名->: ");
String name = scanner.next();
String sql = "insert into people values (?,?)";
//需要把String sql 转换成 语句对象
PreparedStatement statement = connection.prepareStatement(sql);
statement.setInt(1,id);
statement.setString(2,name);
//4.把构造好的SQL发送给服务器去执行
int n = statement.executeUpdate();
System.out.println("n = " + n);
//5.最后一步,释放必要的资源
statement.close();
connection.close();
}
}
运行结果如下:
插入,修改和删除,这些操作JDBC代码其实完全一样,唯一区别就是构造的SQL语句不一样。
2.查询操作
查询这里的代码,和上面插入的代码就有些差别了,查询,会有一个返回的“结果集合”(临时表),查询操作中有三步:创建数据源、和数据库服务器建立连接、释放必要的资源,操作与上面查询操作一致,这里不再进行介绍,此处我们从不一样的地方开始进行介绍:
构造SQL:
代码如下:
String sql = "select * from people";
PreparedStatement statement = connection.prepareStatement(sql);
这里的操作和上面查询操作也比较类似,也可以使用占位符。
执行SQL:
这里的操作与查询就截然不同了,代码如下:
//4.执行SQL
ResultSet resultSet = statement.executeQuery();
while (resultSet.next()){
int id = resultSet.getInt("id");
String name = resultSet.getString("name");
System.out.println("id ->: " + id);
System.out.println("name ->: " + name);
}
这里ResultSet就是结果集合,代表了查询返回的临时表,利用循环,遍历ResultSet,将结果集中的数据打印出来。
完整代码如下:
import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class TestJDBCSelect {
public static void main(String[] args) throws SQLException {
//1.构造 DataSource
DataSource dataSource = new MysqlDataSource();
((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/bite?characterEncoding=utf8&useSSL=false");
((MysqlDataSource)dataSource).setUser("root");
((MysqlDataSource)dataSource).setPassword("111111");
//2.建立连接
Connection connection = dataSource.getConnection();
//3.构造SQL
String sql = "select * from people";
PreparedStatement statement = connection.prepareStatement(sql);
//4.执行SQL
ResultSet resultSet = statement.executeQuery();
while (resultSet.next()){
int id = resultSet.getInt("id");
String name = resultSet.getString("name");
System.out.print("id ->: " + id);
System.out.println(" name ->: " + name);
}
//5.释放必要资源
statement.close();
connection.close();
}
}
运行结果如下:
·尾声
文章到这就要结束了,本篇文章介绍了什么是JDBC,如何下载并引用jar包,如何进行JDBC编程,当然这里针对JDBC编程只是编写了一个最简单的代码,由JDBC提供的API是有很多具体的方法的,所以在进行JDBC编程时也衍生出了不同的写法,本篇文章使用的是DataSource这一套写法,但是不只有这一种写法,这里只介绍这一种了,框架和技术都是在不断更迭的,有些东西是比较固定的,JDBC就是属于基本不变的技术,介绍JDBC也是为了在后面使用相关框架时能更好理解相关框架的底层的原理,如果读完本篇文章感觉有所收获,希望可以点赞收藏支持一下啦~~您的支持是我最大的动力,当然如果有什么问题欢迎在评论区进行留言,我们下一篇文章再见~~