引言
1. JDBC 编程是什么
JDBC,即 Java Database Connectivity,即 Java 数据库连接。是一种用于执行 SQL 语句的 Java API,它是 Java中的数据库连接规范。这个 API 为 Java 开发人员操作数据库提供了一个标准,可以为多种关系数据库提供统一访问。
API:Application Programming Interface(应用程序接口)
2. JDBC 的存在优势
① Java 语言访问数据库操作完全面向抽象接口编程
② 开发数据库应用不用限定在特定数据库厂商的 API
③ 程序的可移植性大大增强,这和 Java 的特性是一样的,所以这正是 Java 语言拥有 JDBC 编程的原因。
一、引入 JDBC 相关依赖
1. 去 maven 仓库直接搜索 mysql,选择如下分组。
2. 找到一个与我们数据库的大版本号匹配的一个依赖版本。
3. 复制到 maven 项目中的 " pom.xml " 文件中。
4. 点击右侧的 " Maven ",并刷新。
5. 根据引入的依赖名字,在 IDEA 中搜索,如果找到的目录下如下,即可正常使用 JDBC 编程了。
二、JDBC 编程的基本流程
1. 创建数据源
DataSource 是一个接口。不能直接实例化,必须通过 它的实现类 MysqlDataSource 来实例化对象,而这个对象就相当于描述了数据库服务器在哪。
第一条语句:向上转型
后三条语句:向下转型
DataSource dataSource = new MysqlDataSource(); //向上转型 //设置数据库所在的地址 ((MysqlDataSource) dataSource).setURL("jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf8&useSSL=false"); //设置登录数据库的用户名 ((MysqlDataSource) dataSource).setUser("root"); //设置登录数据库的密码 ((MysqlDataSource) dataSource).setPassword("12345678"); //向下转型
解析上面的代码。
(1) setURL 方法中的 URL 是什么?
URL:Uniform Resource Locator 【统一资源定位符】
URL 是网络服务程序上用于指定信息位置的表示方法,简单地说,就是网址。
(2) setUser 方法中的 root 是什么?
root 是 MySQL 管理员默认自带的管理员用户。
(3) setPassword 方法中,填的就是我们安装 MySQL 时设置的密码。
2. 让代码和数据库之间建立连接
Connection connection = dataSource.getConnection();
选择 Connection 接口时,注意选择的是 java,.sql 下的包。
同时记得在方法中抛出异常。
为什么会需要我们抛出异常呢?抛出异常就证明,在后面写的代码中,程序非常有可能会发生异常,也许是受查异常,也许是非受查异常。举个例子,当你想与服务器建立连接的时候,你给的 URL 地址出错了,这就会发生异常,再举个列子,如果你的 URL 给对了,但密码又给错了,这是不是也无法让代码与服务器建立连接呢?
3. 操作数据库
我们举一个插入数据表的一个例子,注意写法。
// 此处光是一个 String 类型的 SQL 还不行,需要把这个 String 包装成一个 "语句对象" String sql = " insert into student values( 1, 'Jack' ) " ; PreparedStatement statement = connection.prepareStatement(sql);
上面的操作旨在与将一个字符串风格的 SQL 语句转换成一个 JDBC 中的对象,后面我们需要通过 statement 执行其他操作。
4. 执行 SQL
//如果是 insert,update,delete 都是用 executeUpdate 方法 //如果是 select,使用 executeQuery 方法 int ret = statement.executeUpdate(); System.out.println(ret);
上面接收的返回值就表示当前这个操作,影响到了几行 ( 即哪一行被操作成功了,哪一行被操作失败了 ),对应 cmd 窗口的下列输出。本质上就是当一个 SQL 语句执行完之后,服务器给你的提示。
5. SQL 执行完毕,释放资源
// 先创建的,后释放;后创建的,先释放 // 先打开冰箱,后打开抽屉;而先关闭抽屉,后关闭冰箱 statement.close(); connection.close();
这和 C语言中的 free 方法很像,只不过 C语言中 free方法需要搭配 malloc 方法使用。本质上就是说,把之前在内存中执行的资源释放掉,那么新空出来的内存供给其他使用。
而 Java 中自带垃圾回收机制,JVM 可以自动释放内存。但在这里连接的时候,情况又有不同,JVM 会从系统中申请到一些硬件资源,所以当 SQL 执行完后,还是得记得释放。
三、总结 JDBC 中的一些接口、类
JDBC 编程中常用的一些接口、 类:
1. DataSource 接口 / MysqlDataSource 类
用来描述数据源和描述数据库的地址,( 端口,数据库名,用户名,密码)
我们常用 getConnection 方法
2. Connection 接口
表示数据库连接
我们常用 prepareStatement 方法
3. PreparedStatement 接口
通过这个对象来描述要执行的SQL,还可以对 SQL 进行动态拼接。
我们常用 executeUpdate/executeQuery 方法
注意:
不管 JDBC 编程使用了什么类、什么接口,也不管代码是怎么编程的,但有一点我们需要明确:核心永远在 SQL 语句上。 因为 JDBC 代码始终是固定写法,不管底层是怎么实现的,或许我们不理解它的原理,多写几次代码,依然能记住。但 SQL 语句就不一样了,本质上,就是 SQL 对数据库起直接作用。
四、测试代码
1. 插入数据
import com.mysql.jdbc.jdbc2.optional.MysqlDataSource; import javax.sql.DataSource; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; public class Test1 { public static void main(String[] args) throws SQLException { //1. 创建好数据源 DataSource dataSource = new MysqlDataSource(); //设置数据库所在的地址 ((MysqlDataSource) dataSource).setURL("jdbc:mysql://127.0.0.1:3306/test6?characterEncoding=utf8&useSSL=false"); //设置登录数据库的用户名 ((MysqlDataSource) dataSource).setUser("root"); //设置登录数据库的密码 ((MysqlDataSource) dataSource).setPassword("12345678"); //2. 让代码和数据库服务器建立连接 Connection connection = dataSource.getConnection(); //3. 操作数据库 String sql = " insert into student values( 1, 'Jack' ) " ; PreparedStatement statement = connection.prepareStatement(sql); //4. 执行 SQL int ret = statement.executeUpdate(); System.out.println(ret); //5. sql 执行完毕,需要释放资源 statement.close(); connection.close(); } }
输出结果为:1 (表示插入一行成功)
2. 以占位符的形式添加数据
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 Test2 { public static void main(String[] args) throws SQLException { //1. 创建好数据源 DataSource dataSource = new MysqlDataSource(); ((MysqlDataSource) dataSource).setURL("jdbc:mysql://127.0.0.1:3306/test6?characterEncoding=utf8&useSSL=false"); ((MysqlDataSource) dataSource).setUser("root"); ((MysqlDataSource) dataSource).setPassword("1234567"); //2. 让代码和数据库服务器建立连接 Connection connection = dataSource.getConnection(); //2.1 让用户通过控制台输入一下待插入的数据 Scanner scanner = new Scanner(System.in); System.out.println("输入学号: "); int id = scanner.nextInt(); System.out.println("输入姓名: "); String name = scanner.next(); //3. 操作数据库 String sql = " insert into student values(?,?) " ; PreparedStatement statement = connection.prepareStatement(sql); //3.1 进行替换操作 statement.setInt(1,id); statement.setString(2,name); System.out.println("statement: " + statement); //4. 执行 SQL int ret = statement.executeUpdate(); System.out.println(ret); //5. sql 执行完毕,需要释放资源 statement.close(); connection.close(); } }
我们可以通过控制台输入来执行输入对应的字段值。
输出结果:下面的红色框框,我们可以验证是否正确插入。
看看下列四行代码,是否有些疑惑?
String sql = " insert into student values(?,?) " ; statement.setInt(1,id); statement.setString(2,name); System.out.println("statement: " + statement);
针对这四行代码,解释如下图:
" ? " 表示占位符,相当于告诉 Java,这两个待插入的值还未确定,而第一个问号索引是从 1 开始的,第二个索引为2,依次往后… 其中,set 方法表示替换
而我们打印出来 statement 就是为了检查替换是否正确 !
3. 删除数据
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; /** * 根据学生 id 进行删除操作 */ public class Test3 { public static void main(String[] args) throws SQLException { //1. 创建好数据源 DataSource dataSource = new MysqlDataSource(); ((MysqlDataSource) dataSource).setURL("jdbc:mysql://127.0.0.1:3306/test6?characterEncoding=utf8&useSSL=false"); ((MysqlDataSource) dataSource).setUser("root"); ((MysqlDataSource) dataSource).setPassword("1234567"); //2. 让代码和数据库建立连接 Connection connection = dataSource.getConnection(); //3. 输入需要删除的学号 Scanner scanner = new Scanner(System.in); System.out.println("输入学号:"); int id = scanner.nextInt(); //4. 操作数据库 String sql = "delete from student where id = ?" ; PreparedStatement statement = connection.prepareStatement(sql); statement.setInt(1,id); System.out.println("statement: " + statement); //5. 执行 SQL int ret = statement.executeUpdate(); System.out.println("ret: " + ret); //6. SQL 执行完毕,需要释放资源 statement.close(); connection.close(); } }
输出结果:
现在再看 测试3 的代码时,就很简单了,因为套路是一样的,JDBC 编程实现 增、删、改 的基本流程都是固定的。针对 SQL语句的 update 操作,我就不演示了,思想和上面都是相同的。
4. 查询数据
在测试4 中,我们演示了查询操作,查询操作比较于增删改,多了一个步骤:遍历结果集,即把结果中的数据获取到。
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 Test4 { public static void main(String[] args) throws SQLException { //1. 创建数据源 DataSource dataSource = new MysqlDataSource(); ((MysqlDataSource) dataSource).setURL("jdbc:mysql://127.0.0.1:3306/test6?characterEncoding=utf8&useSSL=false"); ((MysqlDataSource) dataSource).setUser("root"); ((MysqlDataSource) dataSource).setPassword("1234567"); //2. 建立连接 Connection connection = dataSource.getConnection(); //3. 操作数据库 String sql = " select * from student"; PreparedStatement statement = connection.prepareStatement(sql); //4. 执行 SQL // 查询操作与 增删改 不同,它始终是一个临时表,我们将临时表用 resultSet 接收 ResultSet resultSet = statement.executeQuery(); //5. 遍历 resultSet,固定写法 //先获取到某一行,再获取到这一行的所有列 //next 方法表示获取到一行数据,同时把光标往后移动一行 //如果遍历到表的末尾,此处的 next 直接返回 false while (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(); } }
输出结果:
对应 cmd 控制台:
分析结果集
分析 while 循环,这是一种固定写法。
针对结果集,我们依次获取到表中的每一行,再通过这一行来获取此行对应的列。
第一次执行 resultSet.next(),表示获取到了第一行( id = 1 )
第二次执行 resultSet.next(),表示获取到了第二行( id = 2 )
第三次执行 resultSet.next(),由于表到达了末尾,next 方法返回了 false,循环结束。
while (resultSet.next()){ int id = resultSet.getInt("id"); String name = resultSet.getString("name"); System.out.println( "id= " +id + ", name= " +name); }