JDBC编程
前言:
你是否见过用Java连接数据库的操作,对没错,今天我们要讲的就是这个“高级”操作,做好准备全程高速。
API:
什么是API?我喜欢先把它的全称说一下:Application Programming Interface。简称 API 函数。
Windows 这个多作业系统除了协调应用程序的执行、分配内存、管理资源之外,它同时也是一个很大的服务中心,调用这个服务中心的各种服务(每一种服务就是一个函数),可以帮应用程序达到开启视窗、描绘图形、使用周边设备等目的,由于这些函数服务的对象是应用程序(Application),所以便称之为 Application Programming Interface,简称 API 函数。WIN32 API 也就是 Microsoft Windows 32 位平台的应用程序编程接口。
说人话就是函数,我们能直接使用(应该就是使用Windows系统都可以使用这些函数)。
因为我们用的是Java,所以要是用这些方法需要导入包,才能使用这些方法。
JDBC:
在此之前我么先说一下什么是JDBC:JDBC是Java Database Connectivity的缩写,是一种用于Java程序访问关系型数据库的API。它允许Java程序员使用标准的SQL语句来访问和操作数据库。JDBC提供了一种标准的方式来连接到不同数据库的驱动程序,并且是Java EE平台上进行数据访问的基础。它提供了许多接口和类,使Java应用程序可以通过他们来访问和管理关系型数据库。
JDBC的好处:
API既然叫做程序应用接口,这里面的程序你可以理解为软件,因为操作系统也是软件。那么也就说明每个软件可能都有不同的API。我们刚才又说了,API可以理解为函数,既然不同软件可能有不同的API,那么说明他们的方法可能都不一样。
比如你平时用的API是MySQL的,此时你领导让你使用oracle的API,此时你就傻眼了,因为你几乎不可能同时记得两种相同作用但不相同名字的API。
这时候,Java就站出来了,像秦始皇一样进行了车同轨,书同文一样,它让所有的API都进行了统一。 也就是JDBC,它统一了Java程序访问关系型数据库的API。
通过JDBC,开发人员可以使用标准的SQL雨具来操作数据库。
JDBC写操作:
1、准备工作:
要想在程序中操作MySQL,就需要先安装MySQL的驱动包。
这里我们给出官方链接:https://mvnrepository.com/search?q=MySQL
当然我们要根据当前版本(MySQL版本)进行选择下载那个驱动包,如果MySQL是5,驱动包也要使用5系列。
至于如何得知自己的MySQL版本,当我们登录MySQL时输入密码,里面会显示;也可以输入select version(); 来查看。
.jar 是Java中常见的后缀类型,Java写的程序会有很多.class文件,当我们要发文件给别人时,我们就会把这些文件打包成.jar包发给别人。
jar如何引入到项目中?
先把jar复制到当前项目目录中
之后创建Java项目之后:
之后要把这个目录标记成库:
此时准备工作完成,就可以编写代码了。记住,每次创建项目,都需要把这个jar包导入,javax.sql 就是JDBC的包。
2、创建DataSource
在此之前,我们先介绍一下什么是耦合和内聚:
内聚:把相同的功能放在一起
耦合:两个模块之间关联关系不是非常密切,也就是这边变换会影响到另一边。
所以我们写代码要追求高内聚,低耦合。
这里我们要建立DataSource,还需要一个前置知识,就是什么是url。
url 表示网络上的资源位置,MySQL是一个客户端服务器结构的程序,通过网络进行交互的。说人话也就是:url也可以称作网址。
我们来图解一个url:
哎~先不要着急,这里有可能不是完整的url,可能到你的电脑上运行不了(因为我的就是,这里需要在添加一个地区),我在上海,所以要完整语句为:
jdbc:mysql://127.0.0.1:3306/java109?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
这个错误是由于 MySQL 服务器的时区设置不被识别或表示多个时区。你需要在连接 URL 中指定 serverTimezone 参数来解决这个问题。因为这可能导致你所在的地区和应用程序所期望的时区不一致,所以谨慎处理,可以加上。
?后面,表示访问资源的时候,需要哪些参数。这里我们举一个例子更好的理解:
开店://上海电机学院1食堂:3楼/烧饼?豆腐串=要&鸡蛋=要
所以此时我们此时完整语句为:
// 1.先创建 DataSource 也就是数据源头
DataSource dataSource = new MysqlDataSource();((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/java109?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai");
但是DataSource只写url只是找到了MySQL服务器,还得认证(用户名、密码):
((MysqlDataSource)dataSource).setUser("root");((MysqlDataSource)dataSource).setPassword("123456");
root是管理员,MySQL默认自带的用户。
此时只是准备工作,还没有实现与MySQL通信。
3、 和数据库建立连接
这里没什么好说的:
// 2.建立和数据库服务器之间的连接 连接之后才能进行后续的 请求-响应 交互
Connection connection = dataSource.getConnection();
这个是JDBC中的异常,如果执行sql或者操作数据库过程中出现问题,一般会抛出这个异常。
4、构造SQL(增、删、改)
//3.构造 sql 注意:代码中的 sql 不需要写 ;
String sql = "insert into student values(1, '张三')";
PreparedStatement statement = connection.prepareStatement(sql);
构造sql (代码中的sql不需要写语句末尾的";"。
当然我们可以自己写入id和姓名:
Scanner scanner = new Scanner(System.in);
System.out.println("请输入学生学号:");
int id = scanner.nextInt();
System.out.println("请输入学生姓名:");
String name = scanner.next();
之后这样编写SQL语句:
String sql = "insert into student values(" + id + ",'" + name + "'" + ")";
但是各位感觉这样写怎么样?是不是很傻很复杂?确实,而且很不安全,举个栗子:
此时就可以攻击数据库,所以提供了另一种写法:
//3.构造 sql 注意:代码中的 sql 不需要写 ;
String sql = "insert into student values(?, ?)";
//引入 '?' 做占位符
PreparedStatement statement = connection.prepareStatement(sql);
statement.setInt(1, id);
statement.setString(2, name);
里面的数字是替换第几个"?",这里是从第一个开始,不是从0开始。
5、把SQL发给服务器
因为数据库我们平时操作的时候会返回两种结果,一种是影响的行数,一种是查询的结果,所以有两种方法:
此时我们是写操作:
//4.把 sql 发送给服务器 返回值是一个整数,表示影响到的行数
int n = statement.executeUpdate();
System.out.println("影响的行数:" + n);
注意这个方法返回的是一个整数,所以我们可以打印一下。
6、关闭资源
//5.关闭资源,释放资源 释放顺序 后获取的资源先释放
statement.close();
connection.close();
释放顺序为:后获得的资源先释放。
7、写操作整体效果:
此时我们先给出整体代码,之后从数据库中管材结果:
import com.mysql.cj.jdbc.MysqlDataSource;import javax.sql.ConnectionEvent;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Scanner;// 通过这个代码 往数据库中插入一条记录public class Dome {public static void main(String[] args) throws SQLException {Scanner scanner = new Scanner(System.in);System.out.println("请输入学生学号:");int id = scanner.nextInt();System.out.println("请输入学生姓名:");String name = scanner.next();//1.先创建 DataSource 也就是数据源头DataSource dataSource = new MysqlDataSource();((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/java109?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai");((MysqlDataSource)dataSource).setUser("root");((MysqlDataSource)dataSource).setPassword("123456");//2.建立和数据库服务器之间的连接 连接之后才能进行后续的 请求-响应 交互Connection connection = dataSource.getConnection();//3.构造 sql 注意:代码中的 sql 不需要写 ;String sql = "insert into student values(?, ?)";//引入 '?' 做占位符PreparedStatement statement = connection.prepareStatement(sql);statement.setInt(1, id);statement.setString(2, name);//4.把 sql 发送给服务器 返回值是一个整数,表示影响到的行数int n = statement.executeUpdate();System.out.println("影响的行数:" + n);//5.关闭资源,释放资源 释放顺序 后获取的资源先释放statement.close();connection.close();}
}
此时我们执行代码,并输入学号为6,姓名为李四的学生并在MySQL中查看:
JDBC读操作:
这个单独介绍一下,其实区别也不大。
为了更好的理解,我们再创建一个类,除了SQL语句不一样和把SQL发给服务器不一样,其他都是一样的流程。这里我们只介绍区别:
String sql = "select * from student";
PreparedStatement statement = connection.prepareStatement(sql);// 遍历结果集合
// 通过 next 方法可以获取每一行数据 最后一行再执行返回 false
while(resultSet.next()) {// 这对这一行输出int id = resultSet.getInt("id");String name = resultSet.getString("name");System.out.println("id = " + id + ", name = " + name);
}
这里遍历类似于迭代器,但是略有差异。hasNext方法初始情况写指向第一个元素,但是这个next方法初始指向第一个元素前一个位置。
hasNext是判断有没有下一个,里面还需要调用next方法移动光标。
完整代码:
// jdbc 查询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 Demo2 {public static void main(String[] args) throws SQLException {// 1.创建 DataSourceDataSource dataSource = new MysqlDataSource();((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/java109?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai");((MysqlDataSource)dataSource).setUser("root");((MysqlDataSource)dataSource).setPassword("123456");// 2.建立连接Connection connection = dataSource.getConnection();// 3.构造sqlString sql = "select * from student";PreparedStatement statement = connection.prepareStatement(sql);// 4.执行sql// ResultSet 就表示查询的结果集合(集合表)ResultSet resultSet = statement.executeQuery(); //返回的是 ResultSet(结果集合)// 5.遍历结果集合// 通过 next 方法可以获取每一行数据 最后一行再执行返回 falsewhile(resultSet.next()) {// 这对这一行输出int id = resultSet.getInt("id");String name = resultSet.getString("name");System.out.println("id = " + id + ", name = " + name);}// 6.释放资源resultSet.close();statement.close();connection.close();}
}
运行结果:
读操作就是多了一个遍历结果集的过程。
总结:
这里我们可以发现,其实我们之前学习的SQL语句都是很重要的。
你可能会有点反应不过来,这里面这么多类和方法,但实际就是这样,我们没有必要去学习所有的知识的原理,尤其是这些东西,而且真的很难记住,我们只需要大致学会使用,使用的时候去查看也是无可厚非的。
但是JDBC的API还是太过复杂,我们以后可能会学习其他更好的框架进行使用,但是毕竟这是元老级别,我们必须了解并且掌握使用。