一: 本节⽬标
掌握JDBC常⽤接⼝和类
熟练使⽤JDBC进⾏数据库交互
如何通过java程序操作数据库
二:什么是JDBC
JDBC(Java Data Base Connectivity, Java数据库连接)是Java程序和数据库之间的桥梁,包含了⼀套Java定义的⽤于执⾏SQL语句的接⼝,使开发者能够编写数据库的程序。JDBC 的主要作⽤是:与数据库建⽴连接、发送SQL语句和处理数据库执⾏结果。
- JDBC的应⽤场景
java可以搭配不同的数据库进行开发
- JDBC⼯作原理
a. JDBC⼯作原理简洁地概括为:加载驱动、建⽴连接、创建Statement、执⾏SQL、处理结果和关闭资源。
为了解决不同数据库的使用场景,java中只定义了由于连接和操作数据库的接口------jabc
具体的实现由数据库厂商完成。
三:为什么要使⽤JDBC
⾸先回顾⼀下使⽤客⼾端操作数据库的过程,主要分为以下⼏步:
a. 连接到数据库服务 getconnection
b. 发送SQL语句 query
c. 得到返回结果并显⽰ resultSet
d. 关闭连接 close
JDBC使⽤过程可以概括为:加载数据库⼚商的驱动包、建⽴连接、创建Statement、执⾏SQL、处理结果释放资源和关闭连接jadb 只定义了这些方法(getconnection、query、resultSet、close), 对于程序员来说,只需要调用JDBc定义的方法,就可以完成对数据库的操作。
四:使⽤JDBC
4.1 创建Maven⼯程
在idea创建项目 build system 选择 maven
项目中关于maven的配置文件就是pom
这个main就是开发时项目的源代码
test就是测试的
resources存放静态资源的
maven仓库中有java项目中所有的依赖
比如有连接MySql的jar包
4.2 获取MySQL驱动包
maven仓库有很多依赖。
在Maven仓库 mvnrepository.com 搜索MySQL,找到最新版的驱动包
举个例子啊:
点开maven仓库:
查找mysql依赖
后面带J就是最新版,java就是老版
选择一个java打开:
出先很多版本,以后根据所需选择就可以
点开一个8.0.33:
4.3 修改pom.xml⽂件
出现这些代码:
1手动创建一个标签<>
2把上个图片的代码复制一下
3报红我们点一下这个就可以,重新loag过程
在目录页就可以看到我们的依赖8.0.33
maven仓库一般都在国外,有时候下载依赖时候就很慢
可以把仓库配置成国内的
1:打开settings
2:找到这里
3找配置文件
4然后我们下载阿里云的国内镜像:
需要的话联系博主
4.4 建⽴数据库连接
使⽤驱动管理类 DriverManager 的静态⽅法获取数据库连接
sqlpublic class Demo01_DriverManger { public static void main(String[] args) { //1:加载数据库厂商提供的驱动 try { Class.forName("com.mysql.jdbc.Driver"); //2:创建数据库连接 Connection connection = DriverManager.getConnection( "jdbc:mysql://localhost:3306/test", "root", "123456"); }catch (ClassNotFoundException e){ throw new RuntimeException(e); }catch (SQLException e){ throw new RuntimeException(e); } } }
4.5 创建Statement
sqlStatement是⽤于执⾏静态SQL语句并返回执⾏结果的对象 statement = connection.createStatement();
4.6 执⾏SQL语句
sql执⾏select查询时返回的是⼀个结果集,⽤ResultSet接收 执⾏nsert, update, delete操作时,返回的是受影响的⾏数,⽤int类型接收 String sql ="select id,name,sno,age,gender,enroll_date,class_id from student"; //5执行sql语句(增删改都用executeUpdate方法) //查询是executeQuery方法 resultSet= statement.executeQuery(sql);//获取结果
4.7 处理结果集
sql如果返回的是⼀个结果集,则需要遍历这个集合获取对应列的值,具体代码如下: //6遍历结果集,获取数据行 while (resultSet.next()){//resultSet.next()返回true则有下一行数据,false则没有 //7获取数据列 int id = resultSet.getInt(1); String name = resultSet.getString(2); String sno = resultSet.getString(3); int age = resultSet.getInt(4); Boolean gender = resultSet.getBoolean(5); Date enroll_date = resultSet.getDate(6); int class_id = resultSet.getInt(7); //8输出数据 System.out.println("id:"+id+",name:"+name+",sno:"+sno+",age:"+age+",gender:"+gender+",enroll_date:"+enroll_date+",class_id:"+class_id); }
4.8 释放资源
sql在整个数据库访问过程中创建的对象都需要释放,包括:ResultSet,Statement和Connection, 后创建的先释放 finally { //9关闭资源 if (resultSet != null) { try { resultSet.close(); } catch (SQLException e) { throw new RuntimeException(e); } } if (statement != null) { try { statement.close(); } catch (SQLException e) { throw new RuntimeException(e); } } if (connection != null) { try { connection.close(); } catch (SQLException e) { throw new RuntimeException(e); } } }
五: JDBC常⽤接⼝和类
5.1 DriverManager 和DataSource
DriverManager驱动管理类,⽤于管理JDBC驱动程序,可以从驱动程序中获取数据库连接,始于JDK1.1。
DataSource数据源是DriverManager的替代⽅案,始于JDK1.4,是获取数据库连接的⾸选⽅法,推荐使⽤。
5.2 DriverManager 与 DataSource 的区别
DriverManager和DataSource都可以获取到数据库连接,但它们之间存着着⼀些区别,主要在于连接的管理⽅式和资源利⽤效率
连接管理⽅式不同:
DriverManager每次调⽤getConnection⽅法都会初始化⼀个新的连接,使⽤完成后会关闭真实连接,导致资源浪费
DataSource使⽤了连接池的技术,会在初始化时创建⼀定数量的数据库连接,这些连接可以重复使⽤,关闭时并不是真正关闭连接,⽽是将连接归还给连接池,以供后续使⽤,有效地提⾼资源利⽤率和和性能
六:实例
使用DriverManager去打印数据库的数据
sql我们如果想打印一列:就如下代码 打印一列,遍历结果集使用if package com.bitjiuyeke; import java.sql. * ; import java.util.Scanner; public class Demo02_Statement { public static void main(String[] args) { Connection connection = null; Statement statement =null; ResultSet resultSet = null; //1:加载数据库厂商提供的驱动 try { Class.forName("com.mysql.cj.jdbc.Driver"); //2:创建数据库连接 connection = DriverManager.getConnection( "jdbc:mysql://localhost:3306/java116", "root", "123456"); //3创建statement对象,执行sql语句 statement = connection.createStatement(); Scanner scanner= new Scanner(System.in); String inputname = scanner.next(); //4定义sql语句 String sql ="select id,name,sno,age,gender,enroll_date,class_id from student where name = '"+inputname+"'"; //5执行sql语句(增删改都用executeUpdate方法) //查询是executeQuery方法 resultSet= statement.executeQuery(sql);//获取结果 //6遍历结果集,获取数据行 //遍历多条数据,使用while循环 // while (resultSet.next()){//resultSet.next()返回true则有下一行数据,false则没有 // //7获取数据列 // int id = resultSet.getInt(1); // String name = resultSet.getString(2); // String sno = resultSet.getString(3); // int age = resultSet.getInt(4); // Boolean gender = resultSet.getBoolean(5); // Date enroll_date = resultSet.getDate(6); // int class_id = resultSet.getInt(7); // //8输出数据 // System.out.println("id:"+id+",name:"+name+",sno:"+sno+",age:"+age+",gender:"+gender+",enroll_date:"+enroll_date+",class_id:"+class_id); // } //遍历一条结果集,使用if语句 if (resultSet.next()){//resultSet.next()返回true则有下一行数据,false则没有 //7获取数据列 int id = resultSet.getInt(1); String name = resultSet.getString(2); String sno = resultSet.getString(3); int age = resultSet.getInt(4); Boolean gender = resultSet.getBoolean(5); Date enroll_date = resultSet.getDate(6); int class_id = resultSet.getInt(7); //8输出数据 System.out.println("id:"+id+",name:"+name+",sno:"+sno+",age:"+age+",gender:"+gender+",enroll_date:"+enroll_date+",class_id:"+class_id); } }catch (ClassNotFoundException es throw new RuntimeException(e); } } } } }
运行结果:
使用DataSource:去打印数据库中的数据
sqlpackage com.bitjiuyeke; import com.mysql.cj.jdbc.MysqlDataSource; import javax.sql.DataSource; import java.sql.*; import java.util.ResourceBundle; import java.util.Scanner; public class Demo03_DataSource { public static void main(String[] args) { //定义mysql数据源 MysqlDataSource mysqlDataSource = new MysqlDataSource(); //设置数据库的连接串 mysqlDataSource.setURL("jdbc:mysql://localhost:3306/java116"); //设置用户名和密码 mysqlDataSource.setUser("root"); mysqlDataSource.setPassword("123456"); //定义jdbc数据源对象 DataSource dataSource = mysqlDataSource; //声明数据库连接对象 Connection connection = null; //声明sql语句预处理对象 PreparedStatement statement = null; //声明查询结果集对象 ResultSet resultSet = null; //获取数据库连接 try { connection = dataSource.getConnection(); String sql = "select id ,name,sno,age,gender,enroll_date , class_id from student where name=? "; // 占位符替换 // 接收用户输入的姓名 Scanner scanner = new Scanner(System.in); System.out.println("请输入要查询的学生姓名:"); String inputname = scanner.next(); scanner.close(); // 关闭 Scanner // 初始化 PreparedStatement statement = connection.prepareStatement(sql); // 用真实的姓名替换占位符 statement.setString(1, inputname); // 占位符的index从1开始 // 执行sql语句 resultSet = statement.executeQuery(); // 获取查询结果集 // 遍历一条结果集,使用if语句 if (resultSet.next()) { // resultSet.next()返回true则有下一行数据,false则没有 // 获取数据列 int id = resultSet.getInt("id"); String name = resultSet.getString("name"); String sno = resultSet.getString("sno"); int age = resultSet.getInt("age"); Boolean gender = "M".equals(resultSet.getString("gender")); // 假设 'M' 代表男性,'F' 代表女性 Date enroll_date = resultSet.getDate("enroll_date"); int class_id = resultSet.getInt("class_id"); // 输出数据 System.out.println("id:" + id + ",name:" + name + ",sno:" + sno + ",age:" + age + ",gender:" + gender + ",enroll_date:" + enroll_date + ",class_id:" + class_id); } } catch (SQLException e) { throw new RuntimeException(e); } finally { // 关闭资源 if (resultSet != null) { try { resultSet.close(); } catch (SQLException e) { throw new RuntimeException(e); } } if (statement != null) { try { statement.close(); } catch (SQLException e) { throw new RuntimeException(e); } } if (connection != null) { try { connection.close(); } catch (SQLException e) { throw new RuntimeException(e); } } } } }
使用DataSource插入数据:
sqlpackage com.bitjiuyeke; import com.mysql.cj.jdbc.MysqlDataSource; import javax.sql.DataSource; import java.sql.*; import java.util.Scanner; public class Demo04_Insert { public static void main(String[] args) { //定义mysql数据源 MysqlDataSource mysqlDataSource = new MysqlDataSource(); //设置数据库的连接串 mysqlDataSource.setURL("jdbc:mysql://localhost:3306/java116"); //设置用户名和密码 mysqlDataSource.setUser("root"); mysqlDataSource.setPassword("123456"); //定义jdbc数据源对象 DataSource dataSource = mysqlDataSource; //声明数据库连接对象 Connection connection = null; //声明sql语句预处理对象 PreparedStatement statement = null; //声明查询结果集对象 ResultSet resultSet = null; try {//1获取数据库连接 connection = dataSource.getConnection(); //2定义sql语句 String sql = "insert into student (name,sno,age,gender,enroll_date,class_id) values(?,?,?,?,?,?) "; // 占位符替换 // 3获取sql预处理对象 statement = connection.prepareStatement(sql); // 接收用户输入的姓名 Scanner scanner = new Scanner(System.in); String inputname = scanner.next(); String inputsno=scanner.next(); int inputage=scanner.nextInt(); String inputgender=scanner.next(); String inputenroll_date=scanner.next(); int inputclass_id=scanner.nextInt(); // 4设置参数 statement.setString(1, inputname); statement.setString(2, inputsno); statement.setInt(3, inputage); statement.setString(4, inputgender); statement.setString(5, inputenroll_date); statement.setInt(6, inputclass_id); // 5执行sql语句 int row = statement.executeUpdate(); // 获取查询结果集 // 6遍历一条结果集,使用if语句 if (row==1 ) { // resultSet.next()返回true则有下一行数据,false则没有 // 获取数据列 System.out.println("数据插入成功!"); }else { System.out.println("数据插入失败!"); } } catch (SQLException e) { throw new RuntimeException(e); } finally { // 7关闭资源 if (resultSet != null) { try { resultSet.close(); } catch (SQLException e) { throw new RuntimeException(e); } } if (statement != null) { try { statement.close(); } catch (SQLException e) { throw new RuntimeException(e); } } if (connection != null) { try { connection.close(); } catch (SQLException e) { throw new RuntimeException(e); } } } } }
占位符要和设置参数相匹配
sql每次写连接太麻烦创建一个类,去调用就可以: `package utils; import com.mysql.cj.jdbc.MysqlDataSource; import javax.sql.DataSource; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; public class DBUtil { //定义一个数据源对象 private static DataSource dataSource; //定义URL private static String url="jdbc:mysql://localhost:3306/java116"; //定义用户名 private static String username="root"; //定义密码 private static String password="123456"; //在类加载的时候初始化dataSource对象 static { //定义mysql数据源 MysqlDataSource mysqlDataSource = new MysqlDataSource(); //设置数据库的连接串 mysqlDataSource.setURL(url); //设置用户名和密码 mysqlDataSource.setUser(username); mysqlDataSource.setPassword(password); //定义jdbc数据源对象 dataSource = mysqlDataSource; } private DBUtil() {} public static Connection getConnection() throws SQLException{ return dataSource.getConnection(); } public static void close(ResultSet resultSet, Statement statement, Connection connection){ // 7关闭资源 if (resultSet != null) { try { resultSet.close(); } catch (SQLException e) { throw new RuntimeException(e); } } if (statement != null) { try { statement.close(); } catch (SQLException e) { throw new RuntimeException(e); } } if (connection != null) { try { connection.close(); } catch (SQLException e) { throw new RuntimeException(e); } } } }`
upda实例使用Datasource:
sqlpackage com.bitjiuyeke; import utils.DBUtil; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.Scanner; public class Demo05_Update { public static void main(String[] args) throws SQLException { Connection connection = null; PreparedStatement statement = null; Scanner scanner = new Scanner(System.in); try { // 1. 获取数据库连接 connection = DBUtil.getConnection(); // 2. 定义SQL语句, 根据Id修改学号 String sql = "update student set sno = ? where id = ?"; // 3. 定义SQL的预处理对象 statement = connection.prepareStatement(sql); // 4. 用真实的数据替换占位符 System.out.println("请输入要修改的记录Id-->"); long inId = scanner.nextLong(); System.out.println("请输入要修改的学号-->"); String inSno = scanner.next(); statement.setString(1, inSno); statement.setLong(2, inId); // 5. 执行SQL int row = statement.executeUpdate(); // 6. 获取执行结果 if (row >0) { System.out.println("修改成功"); } else { System.out.println("修改失败"); } } catch (SQLException e) { throw new RuntimeException(e); } finally { // 释放资源 DBUtil.close(null, statement, connection); scanner.close(); } } }
使用DataSource删除数据库中数据:
sqlpackage com.bitjiuyeke; import utils.DBUtil; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.Scanner; public class Demo06_Delete { public static void main(String[] args) { Connection connection = null; PreparedStatement statement = null; Scanner scanner = new Scanner(System.in); try{ // 1. 连接数据库 connection = DBUtil.getConnection(); //2.定义sql语句 String sql="delete from student where name=?"; //3.创建PreparedStatement对象 statement = connection.prepareStatement(sql); //4输入要删除的学生姓名 System.out.println("请输入要删除的学生姓名:"); String name = scanner.next(); //5.设置参数 statement.setString(1, name); //6.执行sql语句 int row = statement.executeUpdate(); if(row>0){ System.out.println("删除成功!"); }else{ System.out.println("删除失败!"); } } catch (SQLException e) { throw new RuntimeException(e); }finally{ //7.关闭资源 DBUtil.close(null, statement, connection); scanner.close(); } } }