目录
1.数据库编程的必备条件
PS:程序是怎么操作数据库的?
2.什么是JDBC?
2.1.JDBC定义
2.2.JDBC工作原理
3.JDBC使用
3.1.创建项目并添加MySQL驱动包
3.2.使用代码操作数据库
3.2.1.获得数据源
3.2.2.获得连接
3.2.3.获得执行器
3.2.4.查询或操作数据库
3.2.5.关闭数据库连接
执行代码——插入
执行代码——修改、删除
执行代码——查询
PS:使用DriverManager实现查询
1.数据库编程的必备条件
- 编程语言,如Java,C、C++、Python等。
- 数据库,如Oracle,MySQL,SQL Server等。
- 数据库驱动包:不同的数据库,对应不同的编程语言提供了不同的数据库驱动包,如:MySQL提供了Java的驱动包mysql-connector-java,需要基于Java操作MySQL即需要该驱动包。同样的, 要基于Java操作Oracle数据库则需要Oracle的数据库驱动包ojdbc。
PS:程序是怎么操作数据库的?
实际开发中,SQL很少是手动输入的,绝大多数的SQL都是通过代码,自动执行的。重复执行同一条SQL,且不确定执行多少次?就需要让其他编程语言程序来操作数据库服务器。
- 自己实现数据库客户端很容易,因为各种数据库本身提供了一系列操作的API。官方维护——Oracle。
- 自己实现数据库服务器就很难了,因为包含存储引擎、使用啥样的数据结构来组织数据,存储数据、SQL执行引擎、基于编译原理能对SQL进行解析和优化。
API:Application Program Interface,好比拿到个啥东西,这个东西能提供哪些功能/服务。
- Java标准库就提供一些API:这个API里有一些随机数、scanner、集合类等(一组类/方法);
- C标准库的API:#include<stdio.h>、scanf、printf、fopen、fclose。
- 操作系统也提供一些API:操作硬盘的文件、访问一下内存的内容、重置一下网卡的状态......包括模拟鼠标事件、模拟硬盘事件(以类/方法提供的);
- MySQL也会提供一些API(最初是C语言,为了使用广泛,提供了多个其他语言版本的API,其他语言版本的API本质还是调用C的API,跨语言调用)用来操作数据库,完成各种增删改查操作了。
使⽤程序之所以能操作数据库,主要是因为数据库⼚商提供了操作的 API,也就是数据库驱动,驱使数据库⾏动起来。不光是程序,像我们之所以能通过命令⾏操作 MySQL,也是因为 MySQL 的数据库驱动,对于操作界⾯来说,数据库驱动就是:
输⼊的命令就是 MySQL 数据驱动的⼀部分。
数据库驱动包含了数据库操作 API,它们的关系如下:
2.什么是JDBC?
在了解 JDBC 概念之前,先来想⼏个问题:
- 不同数据库⼚商的数据库驱动⼀样吗?
- 不同数据库⼚商的 API 调⽤⼀样吗?
- 使⽤ Java 程序只操作 MySQL 吗?还是有可能操作 Oracle、Sql Server、DB2 等数据库?
以上的答案都是否定的,也就是说不同⼚商提供了不同的数据库驱动,提供了不同的 API 接⼝,那 Java 程序要怎么实现? 难道是针对⼀个数据库写⼀套调⽤的⽅法吗?因为驱动和 API 完全不同,所以不同的数据操作也是不同的,要针对每种数据库写⼀套调⽤代码就太麻烦了,那要怎么办? 解决以上问题的办法就是使⽤ JDBC。
2.1.JDBC定义
JDBC,即 Java Database Connectivity,Java 数据库连接。是⼀种⽤于执⾏ SQL 语句的 Java API, 它是 Java 中的数据库连接规范。这个 API 由 java.sql.*、javax.sql.* 包中的⼀些类和接⼝组成,它为 Java 开发⼈员操作数据库提供了⼀个标准的 API,可以为多种关系数据库提供统⼀访问。
简单来说,使⽤了 JDBC 之后,不管是什么数据库与什么数据库驱动,只需要使⽤⼀套标准代码就可以实现对不同数据库进⾏统⼀操作(添加、修改、删除、查询),也就解决了上⾯说的那些问题了。
C++操作哪个数据库,就使用哪个API。
Java运行在JVM上,C++运行在CPU上。
2.2.JDBC工作原理
JDBC 为多种关系数据库提供了统⼀访问⽅式,作为特定⼚商数据库访问 API 的⼀种⾼级抽象, 它主要包含⼀些通⽤的接⼝类。 JDBC 访问数据库层次结构:
JDBC 优势:
- Java 语⾔访问数据库操作完全⾯向抽象接⼝编程。
- 开发数据库应⽤不⽤限定在特定数据库⼚商的 API。
- 程序的可移植性⼤⼤增强。
3.JDBC使用
3.1.创建项目并添加MySQL驱动包
Oracle官网特别难用,去Maven这个版本的中央仓库下载驱动包:
选择时大版本是5.1即可~和数据库服务器版本对应。
- 黑客(黑帽子)发现一些软件漏洞(相当于是代码里的bug),对系统进行攻击,进一步入侵操控你的电脑。
- 白客(白帽子)发现软件漏洞后,通知开发者,赶紧修复。
- 红客:2001年,中美黑客大战,中国一群黑客入侵美国政府网站,给网站上插红旗,称为红客。
新建文件夹lib。复制刚才下载的jar包,粘贴到lib下。
此时idea就可以解析jar包里包含的内容了。
3.2.使用代码操作数据库
操作数据库 MySQL 提供了两种操作 API:
- DriverManager
- DataSource(推荐使⽤)
接下来咱们使⽤ DataSource 来实现操作数据库。 使⽤代码操作数据库分为以下 5 个步骤:
- 获取数据源(准备⼯作,点击 MySQL 连接⼯具,并输⼊⽤户名、密码)
- 获取连接(敲击回⻋试图建⽴客户端和服务器端的连接)
- 获取执⾏器(连接到服务器并切换到数据库)
- 查询或操作数据库(输⼊命令,并得到结果)
- 关闭连接(关闭客户端)
3.2.1.获得数据源
不同的数据库,对于数据源的描述,是存在差异的!有的数据库是通过用户名、密码来认证,有的不是,比如SQLLite。
URL:
- jdbc:mysql - 这个url是给idbc中的mysql来使用的。
- 127.0.0.1 - 数据库服务器所在的IP地址,换回IP,表示主机自己(相当于java中的this)只要数据库服务器和jdbc程序是在同一台电脑上,就可以使用这个IP地址。
- 3306 - 端口号,mysql安装时配置的默认端口号。
- java106 - 访问的数据库名。
- characterEncoding=utf8 - 描述了请求的字符编码方式,一般都设置为utf8。
- useSSL=false - 关闭数据库加密功能,此处没必要加密,手动关了,如果不关,有些可能会连接失败。
//使用 jdbc 往数据库中,插入一个记录
//需要提前准备好数据库(java106)和数据表(student)
//1.创建数据源,描述了数据库服务器在哪
DataSource dataSource = new MysqlDataSource(); //向上转型
//设置数据库所在的地址和端口以及数据库名,当前是固定写法
((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/java106?characterEncoding=utf8&useSSL=false"); //向下转型
//这样写的好处是后续代码使用DataSource类型的实例,避免MysqlDataSource这个名字扩散到代码的各个地方(高内聚),未来要是换数据库,只改动这一个代码即可
// //也可以不做任何转型
// MysqlDataSource mysqlDataSource = new MysqlDataSource();
// mysqlDataSource.setURL();
//指定数据库登录的用户:root,这是mysql自带的用户,也可配置别的,但基本用不到((MysqlDataSource)dataSource).setUser("root");
//指定数据库登录的密码,密码就是安装数据库的时候,手动设置的密码((MysqlDataSource)dataSource).setPassword("12345678");
3.2.2.获得连接
- Connection是网络通信中的核心概念,叫“连接”。
- Link是“链接”。
//2.和数据库建立网络连接,写的 jdbc 代码本质上是实现一个 mysql 客户端,要通过网络和服务器进行通信
Connection connection = dataSource.getConnection();
//通过控制台,来输入用户的信息
Scanner scanner = new Scanner(System.in);
System.out.println("请输入学号:");
int id = scanner.nextInt();
System.out.println("请输入姓名:");
String name = scanner.next();
3.2.3.获得执行器
执⾏器是⽤来执⾏ SQL 命令的,执⾏器有三种:
- Statement
- PreparedStatement
- CallableStatement
实际开发中最常⽤的是 PreparedStatement 对象,PreparedStatement 优点如下:
PreparedStatement 有主要两种重要的⽅法:
- executeQuery():⽅法执⾏后返回单个结果集的,通常⽤于 select 语句。
- executeUpdate():⽅法返回值是⼀个整数,指示受影响的⾏数,通常⽤于 update、insert、 delete 语句。
//3.构造一个sql语句,来完成插入操作
String sql = "insert into student values(?,?)"; //占位符(1,2)此处不是从0开始计算,而是从1开始计算
//jdbc中还需要搭配一个特定的对象,来描述这里的sql的情况
PreparedStatement statement = connection.prepareStatement(sql); //会对sql语句做一些处理解析,减轻mysql服务器的压力
//填充占位符
statement.setInt(1,id);
statement.setString(2, name);
System.out.println("sql:" + statement);
3.2.4.查询或操作数据库
//4.执行sql语句,控制客户端给服务器发送网络请求,返回结果的含义是这个操作影响到几行
/**
* 针对增、删、改,使用executeUpdate来执行
* 针对查,使用executeQuery来执行
*/
int ret = statement.executeUpdate();
System.out.println("ret = " + ret);
3.2.5.关闭数据库连接
//5.断开数据库连接,并且释放必要的资源,资源释放的顺序和创建的顺序是相反的
statement.close();
connection.close();
执行代码——插入
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 JDBCInsertDemo {
public static void main(String[] args) throws SQLException {
//使用 jdbc 往数据库中,插入一个记录
//需要提前准备好数据库(java106)和数据表(student)
//1.创建数据源,描述了数据库服务器在哪
DataSource dataSource = new MysqlDataSource(); //向上转型
//设置数据库所在的地址和端口以及数据库名,当前是固定写法
((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/java106?characterEncoding=utf8&useSSL=false"); //向下转型
//这样写的好处是后续代码使用DataSource类型的实例,避免MysqlDataSource这个名字扩散到代码的各个地方(高内聚),未来要是换数据库,只改动这一个代码即可
// //也可以不做任何转型
// MysqlDataSource mysqlDataSource = new MysqlDataSource();
// mysqlDataSource.setURL();
//指定数据库登录的用户:root,这是mysql自带的用户,也可配置别的,但基本用不到
((MysqlDataSource)dataSource).setUser("root");
//指定数据库登录的密码,密码就是安装数据库的时候,手动设置的密码
((MysqlDataSource)dataSource).setPassword("12345678");
//2.和数据库建立网络连接,写的 jdbc 代码本质上是实现一个 mysql 客户端,要通过网络和服务器进行通信
Connection connection = dataSource.getConnection();
//通过控制台,来输入用户的信息
Scanner scanner = new Scanner(System.in);
System.out.println("请输入学号:");
int id = scanner.nextInt();
System.out.println("请输入姓名:");
String name = scanner.next();
//3.构造一个sql语句,来完成插入操作
String sql = "insert into student values(?,?)"; //占位符(1,2)此处不是从0开始计算,而是从1开始计算
//jdbc中还需要搭配一个特定的对象,来描述这里的sql的情况
PreparedStatement statement = connection.prepareStatement(sql); //会对sql语句做一些处理解析,减轻mysql服务器的压力
statement.setInt(1,id);
statement.setString(2, name);
System.out.println("sql:" + statement);
//4.执行sql语句,控制客户端给服务器发送网络请求,返回结果的含义是这个操作影响到几行
/**
* 针对增、删、改,使用executeUpdate来执行
* 针对查,使用executeQuery来执行
*/
int ret = statement.executeUpdate();
System.out.println("ret = " + ret);
//5.断开数据库连接,并且释放必要的资源,资源释放的顺序和创建的顺序是相反的
statement.close();
connection.close();
}
}
执行代码——修改、删除
和插入的代码非常像,只需改动sql语句即可~
执行代码——查询
查询数据库使⽤ PreparedStatement.executeQuery ⽅法,返回⼀个 ResultSet 对象。
ResultSet 对象它被称为结果集,它代表符合 SQL 语句条件的所有⾏,并且它通过⼀套 getXXX ⽅法提供了对这些⾏中数据的访问。
ResultSet ⾥的数据⼀⾏⼀⾏排列,每⾏有多个字段,并且有⼀个记录指针,指针所指的数据⾏叫做当前数据⾏,我们只能来操作当前的数据⾏。我们如果想要取得某⼀条记录,就要使⽤ ResultSet 的 next() ⽅法 ,如果我们想要得到 ResultSet ⾥的所有记录,就应该使⽤ while 循环。
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 JDBCSelectDemo {
public static void main(String[] args) throws SQLException {
DataSource dataSource = new MysqlDataSource();
((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/java106?characterEncoding=utf8&useSSL=false");
((MysqlDataSource)dataSource).setUser("root");
((MysqlDataSource)dataSource).setPassword("12345678");
Connection connection = dataSource.getConnection();
String sql = "select * from student where id>?";
PreparedStatement statement = connection.prepareStatement(sql);
statement.setInt(1,2);
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);
}
statement.close();
connection.close();
}
}
PS:使用DriverManager实现查询
jdbc支持2种风格的代码,一个是DriverManager,一个是DataSource。
- DriverManager使用时,需要借助反射,反射不属于常规的编程手段,是特殊情况下的特殊手段。
- DataSource相比于DriverManager,内置了数据库连接池,可以重复利用连接。 推荐使用DataSource。
使⽤ DriverManager 只是获取 Connection 之前的两步代码不⼀样:
import java.sql.*;
public class App2 {
public static void main(String[] args) throws SQLException, ClassNotFoundException {
// 1.加载JDBC驱动程序:反射,这样调⽤初始化com.mysql.jdbc.Driver类,即将该类加载到JVM⽅法区,并执⾏该类的静态⽅法块、静态属性。
Class.forName("com.mysql.jdbc.Driver");
// 2.创建数据库连接
Connection connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/java33?user=root&password=12345678&characterEncoding=UTF-8&useSSL=true");
// 3.获得执⾏器
PreparedStatement statement = connection.prepareStatement("select * from student where username=?");
// 3.1 占位符赋值
statement.setString(1, "王五");
// 4.获得结果集
ResultSet resultSet = statement.executeQuery();
// 4.1 获得结果并打印
while (resultSet.next()) {
String sn = resultSet.getString("sn");
String username = resultSet.getString("username");
String mail = resultSet.getString("mail");
System.out.println(String.format("SN:%s,UserName:%s,Mail:%s", sn, username, mail));
}
// 5. 关闭资源
resultSet.close();
connection.close();
}
}
实际开发中,用框架Mybatis,JPA这些框架来代替JDBC。