编程语言,如Java,C、C++、Python等
数据库,如Oracle,MySQL,SQL Server等
数据库驱动包:不同的数据库,对应不同的编程语言提供了不同的数据库驱动包,如:MySQL提供了Java的驱动包mysql-connector-java,需要基于Java操作MySQL即需要该驱动包。同样的,要基于Java操作Oracle数据库则需要Oracle的数据库驱动包ojdbc。
使⽤程序之所以能操作数据库,主要是因为数据库⼚商提供了操作的 API,也就是数据库驱动,驱使数据库⾏动起来,就是数据库驱动。不光是程序,像我们之所以能通过命令⾏操作MySQL,也是因为MySQL 的数据库驱动,对于操作界⾯来说,数据库驱动就是:
输⼊的命令就是 MySQL 数据驱动的⼀部分。
数据库驱动包含了数据库操作 API,它们的关系如下:
在了解 JDBC 概念之前,我们先来想⼏个问题:
不同数据库⼚商的数据库驱动⼀样吗?
不同数据库⼚商的 API 调⽤⼀样吗?
使⽤ Java 程序只操作 MySQL 吗?还是有可能操作 Oracle、Sql Server、DB2 等数据库?
以上的答案都是否定的,也就是说不同⼚商提供了不同的数据库驱动,提供了不同的 API 接⼝,那我们的 Java 程序要怎么实现?难道是针对⼀个数据库写⼀套调⽤的⽅法吗?因为驱动和 API 完全不同,所以不同的数据操作也是不同的,要针对每种数据库写⼀套调⽤代码就太麻烦了,那要怎么办?
解决以上问题的办法就是使⽤ JDBC。
JDBC,即 Java Database Connectivity,Java 数据库连接。是⼀种⽤于执⾏ SQL 语句的 Java API,它是 Java 中的数据库连接规范。
这个 API java.sql.*,javax.sql.*
包中的⼀些类和接⼝组成,它为Java 开发⼈员操作数据库提供了⼀个标准的 API,可以为多种关系数据库提供统⼀访问。
简单来说,使⽤了 JDBC 之后,不管是什么数据库与什么数据库驱动,我们只需要使⽤⼀套标准代码就可以实现对不同数据库进⾏统⼀操作(添加、修改、删除、查询),也就解决了我们上⾯说的那些问题了。
JDBC 为多种关系数据库提供了统⼀访问⽅式,作为特定⼚商数据库访问 API 的⼀种⾼级抽象,它主要包含⼀些通⽤的接⼝类。
JDBC 访问数据库层次结构:
JDBC 优势:
1、Java 语⾔访问数据库操作完全⾯向抽象接⼝编程。
2、开发数据库应⽤不⽤限定在特定数据库⼚商的 API。
3、程序的可移植性⼤⼤增强。
创建⼀个 Java 项⽬,并添加 MySQL 驱动(mysql-connector-java-5.1.47.jar),需要注意不同数据库版本要对应相应的驱动包。
操作步骤:点击项⽬属性 -> Modules -> Dependencies -> 点击“+”号 -> 1.Jars or directories -> 选择驱动包 -> 点击 OK 确认。
操作数据库 MySQL 提供了两种操作 API:
DriverManager
DataSource(推荐使⽤)
接下来咱们使⽤ DataSource 来实现操作数据库。
使⽤代码操作数据库分为以下 5 个步骤:
1.获取数据源(准备⼯作,点击 MySQL 连接⼯具,并输⼊⽤户名、密码)
2. 获取连接(敲击回⻋试图建⽴客户端和服务器端的连接)
3. 获取执⾏器(连接到服务器并切换到数据库,并组装SQL)
4. 查询或操作数据库(输⼊命令,并得到结果)
5. 关闭连接(关闭客户端)
6.2.1获得数据源
数据源是 MysqlDataSource,获取⽅式如下,需要输⼊数据库连接的 MySQL 服务器地址、⽤户名和密码:
// 1.创建数据源
MysqlDataSource dataSource = new MysqlDataSource();
// 1.1 设置连接的 MySQL 服务器
dataSource.setURL("jdbc:mysql://127.0.0.1:3306/java33?characterEncoding=utf8&useSSL=true");
// 1.2 设置⽤户名
dataSource.setUser("root");
// 1.3 设置密码
dataSource.setPassword("12345678");
//(Datasource获取的数据库连接不用关闭物理连接,只重置,重新初始化后又放回连接池)
6.2.2获得连接
连接对象是 Connection,注意此步骤操作容易出错,⼀定是 com.mysql.jdbc 包下的 Connection 对象:
6.2.3获得执行器
执⾏器是⽤来执⾏ SQL 命令的,执⾏器有三种:
Statement
PreparedStatement(常用)
CallableStatement(基本不使用,因为存储过程无法调试、修改和维护)
实际开发中最常⽤的是 PreparedStatement 对象,PreparedStatement 优点如下:
具体实现如下:
// 1.创建数据源
MysqlDataSource dataSource = new MysqlDataSource();
// 1.1 设置连接的 MySQL 服务器
dataSource.setURL("jdbc:mysql://127.0.0.1:3306/java33?
characterEncoding=utf8&useSSL=true");
// 1.2 设置⽤户名
dataSource.setUser("root");
// 1.3 设置密码
dataSource.setPassword("12345678");
// 2.创建连接
Connection connection = (Connection) dataSource.getConnection();
// 3.获得执⾏器
PreparedStatement statement = connection.prepareStatement("select * from student where username=?");
// 3.1 占位符赋值
statement.setString(1, "王五");
6.2.4执行SQL,获得结果集
PreparedStatement 有主要两种重要的⽅法:
executeQuery():⽅法执⾏后返回单个结果集的,通常⽤于 select 语句。
executeUpdate():⽅法返回值是⼀个整数,指示受影响的⾏数,通常⽤于 update、insert、delete 语句。
6.2.5关闭数据库连接
关闭数据库连接是为了不浪费 MySQL 服务器端的资源,最终实现代码:
import com.mysql.jdbc.Connection;
import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class AddCity {
public static void main(String[] args) throws SQLException {
//1、获得数据源 SataSource(设置mysql的服务器地址)
MysqlDataSource dataSource=new MysqlDataSource();
//1.1设置mysql的服务器地址
// dataSource.setURL("jdbc:mysql://127.0.0.1:3306/java33?user=root&password=12345678&characterEncoding=utf8&useSSL=true");
dataSource.setURL("jdbc:mysql://127.0.0.1:3306/java33?characterEncoding=utf8&useSSL=true");
dataSource.setUser("root");//1.2设置连接mysql的用户名
dataSource.setPassword("12345678");//1.3设置连接MySQL的登录密码
//2、得到连接 Connection
Connection connection= (Connection) dataSource.getConnection();
//3.得到执行器(组装SQL)
String insertSQL="insert into city(id,name) values(?,?)";//组装SQL,使用占位符“?”
PreparedStatement statement=connection.prepareStatement(insertSQL);
//填充占位符
statement.setInt(1,4);
statement.setString(2,"深圳");
//4、执行SQL
int result= statement.executeUpdate();//返回一个受影响的行数
System.out.println("受影响的行数"+result);
//5、关闭资源(从小到大)
statement.close();//关闭执行器
connection.close();//关闭连接
}
}
import com.mysql.jdbc.Connection;
import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class UpdateCity {
public static void main(String[] args) throws SQLException {
//1、得到数据源 DataSource (URL,user,password)
MysqlDataSource dataSource=new MysqlDataSource();
dataSource.setURL("jdbc:mysql://127.0.0.1:3306/java33?characterEncoding=utf8&useSSL=true");
dataSource.setUser("root");
dataSource.setPassword("12345678");
//2.得到连接 Connection
Connection connection= (Connection) dataSource.getConnection();
//3.组装SQL 得到执行器
String updateSQL="update city set name=? where id=?";
PreparedStatement statement=connection.prepareStatement(updateSQL);
statement.setString(1,"广东");
statement.setInt(2,4);
//4、执行SQL,得到结果
int result=statement.executeUpdate();
System.out.println("执行结果"+result);
//5.关闭资源
statement.close();
connection.close();
}
import com.mysql.jdbc.Connection;
import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class DeleteCity {
public static void main(String[] args) throws SQLException {
MysqlDataSource dataSource=new MysqlDataSource();
dataSource.setURL("jdbc:mysql://127.0.0.1:3306/java33?characterEncoding=utf8&useSSL=true");
dataSource.setUser("root");
dataSource.setPassword("12345678");
Connection connection= (Connection) dataSource.getConnection();
String deleteSQL="delete from city where id=? ";
PreparedStatement statement=connection.prepareStatement(deleteSQL);
statement.setInt(1,5);
int result=statement.executeUpdate();
System.out.println("受影响的行数"+result);
statement.close();
connection.close();
}
}
ResultSet 对象它被称为结果集,它代表符合 SQL 语句条件的所有⾏,并且它通过⼀套 getXXX⽅法提供了对这些⾏中数据的访问。
ResultSet ⾥的数据⼀⾏⼀⾏排列,每⾏有多个字段,并且有⼀个记录指针,指针所指的数据⾏叫做当前数据⾏,我们只能来操作当前的数据⾏。我们如果想要取得某⼀条记录,就要使⽤ResultSet 的 next() ⽅法 ,如果我们想要得到 ResultSet ⾥的所有记录,就应该使⽤ while 循环。
/**
* 辅助类
* 创建了一个城市的实体类
*/
public class City {
private int id;
private String name;
public City() {
}
public int getId() {
return id;
}
@Override
public String toString() {
return "City{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
public void setId(int id) {
this.id = id;
}
public City(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public City(String name) {
this.name = name;
}
}
import com.mysql.jdbc.Connection;
import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class SelectCity {
public static void main(String[] args) throws SQLException {
//1、得到数据源 DataSource (URL,user,password)
MysqlDataSource dataSource=new MysqlDataSource();
dataSource.setURL("jdbc:mysql://127.0.0.1:3306/java33?characterEncoding=utf8&useSSL=true");
dataSource.setUser("root");
dataSource.setPassword("12345678");
//2.得到连接 Connection
Connection connection= (Connection) dataSource.getConnection();
//3.组装SQL 得到执行器
String selectSQL="select * from city where id";
PreparedStatement statement=connection.prepareStatement(selectSQL);
statement.setInt(1,10);
//4、执行SQL,得到结果[特殊]
ResultSet resultSet=statement.executeQuery();
while (resultSet.next()){//如果结果集的下一行有数据的话
//每次循环可以得到一行数据
City city=new City();
city.setId(resultSet.getInt("id"));
city.setName(resultSet.getString("name"));
//打印city对象
System.out.println(city);
}
//5.关闭资源
resultSet.close();
statement.close();
connection.close();
}
}
使⽤ DriverManager 只是获取 Connection 之前的两步代码不⼀样:
// 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");
完整代码:
import com.mysql.jdbc.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* 使用DriverManager进行JDBC的查询
*/
public class SelectCity2 {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
//1.选择mysql的驱动
Class.forName("com.mysql.jdbc.Driver");
//2、得到连接
Connection connection = (Connection) DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/java33?user=root&password=12345678&characterEncoding=UTF-8&useSSL=true");
//3、拼接sql,得到执行器
PreparedStatement statement=connection.prepareStatement("select * from city");
//4、执行sql,得到结果
ResultSet resultSet=statement.executeQuery();
while (resultSet.next()){
City city=new City();
city.setId(resultSet.getInt("id"));
city.setName(resultSet.getString("name"));
//打印city对象
System.out.println(city);
}
//5.关闭资源
resultSet.close();
statement.close();
connection.close();
}
}