JDBC编程
一、概述
1.1 概念介绍
- JDBC:Java Databases Connectivity——Java语言连接数据库
- Java通过JDBC这样的技术连接MySQL数据库,MySQL是一个基于C/C++实现的数据库,本身也提供了一系列的API,从而可以通过代码操作数据库
- API: Application Programming Interface——应用程序编程接口,这是一个通用的概念,不仅仅局限于Java当中;可以把这个词理解为“一组类”/“一组方法”,都是现成的,可以直接调用实现一些功能;对于Java来说,Java提供了“标准库”,只要安装了Java,此时就能使用标准库中的类和方法(标准库API),也可以使用别人写的类和方法(第三方API);有的库,提供的API非常多,形成了一系列体系.这种情况也可以称为“SDK”(软件开发工具包)——Software development kit;Java中用到的JDK就是一个SDK,只不过起了个专属的名字Java开发工具包
- 不同数据库提供的API不同(功能上大同小异,细节上存在很大差异),那么在项目中使用到不同的数据库时,就需要掌握多分api的使用,非常麻烦,这时候Java出版了一套API接口标准,使他们都按照该标准适配过来(每个数据库厂商只需要额外写一些代码,能够按照Java提供的标准把原有的API封装一下),后续仅需掌握Java这一套API(JDBC),就可以切换各种数据库了,如下图:
- JDBC是Java标准库提供的,只要装了JDK就自带JDBC,但是使用JDBC操作MySQL需要安装并导入MySQL的驱动包(数据库驱动)
1.2 驱动包下载
中央仓库:https://mvnrepository.com/
-
搜索MySQL
-
找到与MySQL对应的版本(只要大版本相同即可,比如我的MySQL版本是8.0.34,驱动包只要是8开头的版本都行)
如果你的MySQL是比较新的就点击新版本,否则就点击旧版本
在central中查看版本
- 选择版本后,点击jar下载即可
.jar文件就是类似于.rar文件的压缩包,是最常见的一种发布Java程序方式,其中包含了很多的.class(Java编译生成的字节码文件)文件
或者在项目中配置pom文件,使用maven下载
1.3 导入驱动包
这里我使用的是IDEA编译器
- 创建一个Java项目
- 在项目中随便创建一个目录
- 把jar文件拷贝到刚刚创建的目录(lib)中,
- 右键目录,选择Add as library
告诉IDEA,这个目录存放的是第三方库,此时IDEA就能识别拷贝进来的驱动包了
添加完上述,可以看到这个jar文件可以展开了,说明能被识别
上述操作是JDBC程序的准备操作,接下来就可以写代码了
二、通过Java程序操作数据库
2.1 通过 JDBC 进行 插入数据 操作
先在数据库新建一张表,虽然通过JDBC也能进行建表操作,一般都是提前建好表的
接下来准备往people这张表来插入数据
2.1.1 创建“数据源(DataSource)——描述要操作的数据库、数据是在哪”
在MySQL中,要设定好MySQL服务器的位置,访问数据库的用户名、用户密码以及数据库名
以上要包含的是JDBC自带的interface(接口),而接口是不能直接new的,所以需要new一个实现该接口的类的实例
因为需要操作MySQL数据库,所以new一个MySQL提供的类MysqlDataSource,这就是MySQL厂商提供的驱动包里面的类,需要包含信息
//向上转型
DataSource dataSource = new MysqlDataSource();
以上过程就是数据库厂商(MySQL)和JDBC进行对接,就是让数据库厂商实现JDBC中提供的接口,进一步的实现其中约定好的抽象方法
//向下转型,并且设置url
((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/learn_db?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai");
Url:唯一资源定位符;MySQL是一个 客户端—服务器 的程序,服务器是保存数据的本体,当前写的 jdbc 代码,就是在写一个 mysql 客户端;之前的cmd黑框是MySQL自带的客户端,这里可以通过Java代码通过JDBC自己实现客户端,然后客户端通过网络访问到数据库服务器(不是cmd黑框启动的那个),才能进一步的进行数据库操作;要想访问服务器,就需要知道服务器所在位置,这里的Url就是描述服务器以及服务器上的资源在网络上所在的位置,
其中jdbc:mysql:
代表给jdbc中的MySQL使用的url,127.0.0.1
代表ip地址(描述的是一个主机/电脑在网络上的位置,这里本地ip默认为127.0.0.1),3306
端口号(区分了主机上的应用程序,这里是MySQL默认的端口号),learn_db
为即将要操作的数据库的名字,characterEncoding=utf8
表示指定字符集为utf8,useSSl=false
表示关闭加密通信,不写的话可能会由于依赖程序有问题导致数据库连接失败,serverTimezone=Asia/Shanghai
表示配置数据库时间,确保其正确
除了设置Url之外,还需要设置用户名和密码
((MysqlDataSource)dataSource).setUser("root");
((MysqlDataSource)dataSource).setPassword("123456");
其中root为默认用户名,密码为123456
DataSource需要对接不同的数据库,对于MySQL来说,设置的为url,user,password;对于其他数据库就不一定了,所以需要向下转型为MysqlDataSource
2.1.2 与服务器建立连接
进行 客户端—服务器 之间通信的时候,一般两种通信模式:
(1)有连接 (类似于打电话,对方必须接通才能进行通话)
(2)无连接 (类似于发短信,不需要对方操作,直接可以发送成功)
这里的JDBC就属于“有连接”的这种模式,则需要先进行“拨号”——dataSource.getConnection();
写完之后,发现报错了,这里查看信息后发现没有处理异常,这里使用throws关键字显式处理该受查异常
处理后就不报错了
下面使用Connection(选择java.sql包中的Connection)来进行接收
Connection connection= dataSource.getConnection();
做到这一步后,如果能够编译成功说明可以与MySQL服务器进行连接了,后面就可以写sql语句了
2.1.3 构造sql语句,并且对字符串类型的sql进行识别和编译
虽然是通过Java来操作数据库,但是核心还是需要通过执行sql语句来操作数据库,只不过是把sql嵌入Java中了
String sql = "insert into people values(1,'小明')";
预编译sql语句
以上是字符串结构的sql语句,还需要构造语句对象,使JDBC能够识别
有两种方法:使用Statement或者PrepareStatement
其中Statement是一个普通的语句对象,而PrepareStatement则是带有预编译(一个字符串sql发送到MySQL服务器上,是要先对sql进行解析,然后进行各种校验,之后才能执行——这个操作需要花费一定开销的,虽然开销不大,但是MySQL服务器要同时给多个客户端提供服务,为了减轻服务器的负担,这里现在客户端预编译好,把解析后的数据交给服务器,服务器可以立即执行) 功能的语句对象;
所以下面推荐使用PrepareStatement
PreparedStatement preparedStatement = connection.prepareStatement(sql);
2.1.4 将编译好的sql语句传给服务器,并且执行sql
对于insert、update、delete(对数据库进行改动的操作)都是使用executeUpdate方法
对于select则是使用executeQuery方法
int n = preparedStatement.executeUpdate(); //返回结果为整数,表示当前操作影响到了几行数据
System.out.println("n="+n); //查看影响行数
执行这个方法,就在内部会向服务器发送请求,请求中就是包含了解析后的sql语句
等待数据库执行sql;执行完成就会返回响应,这个方法再获取到响应,并且把数据库返回的结果通过返回值体现出来
2.1.5 释放前面占用的各种资源
注意:释放 语句对象 和 连接对象 dataSource不必释放
释放顺序和创建顺序相反
preparedStatement.close();
connection.close();
完成以上操作就可以运行代码了,运行前,people表中数据为空
运行后,n=1说明1行受影响
再次查询people表后发现数据添加成功
2.1.6 完整代码
import com.mysql.cj.jdbc.MysqlDataSource;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
public class JDBCDemo {
public static void main(String[] args) throws SQLException {
//接下来通过 JDBC 进行一个简单的插入数据的操作
//JDBC 步骤比较多,每个步骤都不难,都是固定讨论
//1.创建“数据源(DataSource)
DataSource dataSource = new MysqlDataSource(); //向上转型
//向下转型
((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/learn_db?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai");
((MysqlDataSource)dataSource).setUser("root");
((MysqlDataSource)dataSource).setPassword("123456");
//2. 和MySQL服务器建立连接
Connection connection= dataSource.getConnection();
//3.构造sql语句,并且对字符串类型的sql进行识别和编译(PrepareStatement才能编译,Statement不能编译)
String sql = "insert into people values(1,'小明')";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
//4. 将编译好的sql语句传给服务器,并且执行sql
int n = preparedStatement.executeUpdate(); //返回结果为整数,表示当前操作影响到了几行数据
System.out.println("n="+n);
//5. 释放前面占用的各种资源
preparedStatement.close();
connection.close();
}
}
手动输入的代码:
import com.mysql.cj.jdbc.MysqlDataSource;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Scanner;
public class JDBCDemo {
public static void main(String[] args) throws SQLException {
//接下来通过 JDBC 进行一个简单的插入数据的操作
//JDBC 步骤比较多,每个步骤都不难,都是固定讨论
//1.创建“数据源(DataSource)
DataSource dataSource = new MysqlDataSource(); //向上转型
//向下转型
((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/learn_db?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai");
((MysqlDataSource)dataSource).setUser("root");
((MysqlDataSource)dataSource).setPassword("123456");
//2. 和MySQL服务器建立连接
Connection connection= dataSource.getConnection();
//手动输入信息
System.out.println("请输入id");
Scanner scanner = new Scanner(System.in);
int id = scanner.nextInt();
System.out.println("请输入姓名");
String name = scanner.next();
//3.构造sql语句,并且对字符串类型的sql进行识别和编译(PrepareStatement才能编译,Statement不能编译)
String sql = "insert into people values(?,?)";//?代表占位符
PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.setInt(1,id);
preparedStatement.setString(2,name);
//4. 将编译好的sql语句传给服务器,并且执行sql
int n = preparedStatement.executeUpdate(); //返回结果为整数,表示当前操作影响到了几行数据
System.out.println("n="+n);
//5. 释放前面占用的各种资源
preparedStatement.close();
connection.close();
}
}
System.out.println("n="+n);
//5. 释放前面占用的各种资源
preparedStatement.close();
connection.close();
}
}
2.2 通过 JDBC 进行 查询数据 操作
查询操作由于要在idea里面返回结果,所以不同于增删改操作;
代码如下:
import com.mysql.cj.jdbc.MysqlDataSource;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class JDBCDemo2 {
public static void main(String[] args) throws SQLException {
DataSource dataSource = new MysqlDataSource();
((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/learn_db?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai");
((MysqlDataSource)dataSource).setUser("root");
((MysqlDataSource)dataSource).setPassword("123456");
Connection connection = dataSource.getConnection();
String sql = "select * from people";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
ResultSet resultSet=preparedStatement.executeQuery();
while(resultSet.next()){
int id = resultSet.getInt("id");
String name = resultSet.getString("name");
System.out.println(id+" "+name);
}
resultSet.close();
preparedStatement.close();
connection.close();
}
}