JDBC详解 骑猪看日落 2022-12-23 07:09 204阅读 0赞 #### 一、介绍 #### 为了能让 **程序** 操作 **数据库**,对数据库中的 **表** 进行操作,每一种数据库都会提供一套连接和操作该数据库的驱动。而且每种数据库的驱动都各不相同,例如:mysql数据库使用mysql驱动,oracle数据库使用oracle驱动。假如我们编写的程序哪一天想要换数据库,那样就会很不方便,因为所有连接数据库的代码都要从新编写。 SUN公司为简化开发工作,统一对数据库的操作,定义了一套Java操作数据库的**标准或者规范,这个规范就是JDBC** JDBC全称为:Java Data Base Connectivity(Java数据库连接),它主要由**接口**组成。我们在开发过程中,只要实现它相应的接口就可以非常简便快速地连接数据库。在开发JDBC应用时,还需要导入相应的**数据库的驱动jar包**,这些驱动jar包是由数据库公司自己编写的。 #### 二、使用 #### ##### 1、在项目中导入相应数据库的驱动jar包 ##### ##### 2、在JDBC中注册数据驱动 ##### 虽然我们第一步在新建的Java项目中将mysql数据库的驱动jar包导入进来了,但是JBDC不知道这里有一个驱动包,此时我们就需要将这个驱动包交给JBDC去管理。我们可以使用**java.sql**包下的 **DriverManager** 工具类提供的**registerDriver(Driver driver)** 方法来在JDBC中注册这个数据驱动。这个registerDriver(Driver driver)方法需要一个Driver对象,而这个Driver类本身是JDBC提供的一个接口,我们的驱动里面已经实现了这个接口,所以我们只需要写如下代码就可以实现注册数据库驱动的功能 import java.sql.DriverManager; //需要导入的是接口类包 DriverManager.registerDriver(new Driver()); ##### 3、获取(创建)数据库的连接 ##### 注册好数据库驱动后,并没有**连接上数据库**。只有先连接上数据库,才能对数据库进行操作 import java.sql.Connection; //导入的是接口类包 Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "root"); //这里使用的是一个名为test的mysql数据库,用户名和密码都是root ##### 4、创建传输器对象 ##### 上一步我们已经创建了数据库的连接,并已经连上了数据库。但是如果我们想要**操作该数据库**,我们需要用到sql语句。而我们怎样在Java程序中使用sql语句来操作数据库呢??这里我们就需要一个**传输器对象**来传输**sql语句到数据库**中去**执行**。上一步使用到的**Connection类**中就有一个createStatement()的方法可以创建一个传输器对象 import java.sql.Statement; //导入的是接口类包 Statement stat = conn.createStatement(); ##### 5、利用传输器对象传输sql语句到数据库中执行操作,将结果用结果集返回 ##### **java.sql.Statement** 身上有许多传输sql语句的方法,其中用的最多的是: * executeQuery(String sql) :用于向数据发送**查询**语句 * executeUpdate(String sql):用于向数据库发送**insert、update或delete**语句 * execute(String sql):用于向数据库发送**任意sql**语句 import java.sql.ResultSet; //需要导入的接口类包 //传输一条查询语句,查询book表中所有的数据 ResultSet rs = stat.executeQuery("select * from book"); ##### 6、遍历结果集,并获取查询对象 ##### JDBC程序中的ResultSet用于代表Sql语句的执行结果。Resultset封装执行结果时,采用了类似于**表格**的方式。ResultSet对象维护了一个指向表格数据行的**游标**。初始的时候,游标在**第一行之前**,调用**ResultSet.next()** 方法,可以使游标指向具体的数据行,进而调用方法获取该行的数据。 **ResultSet对象提供的方法:** 获取指定类型的数据 * getString(int index) * getString(String columnName) ResultSet还提供了对结果集进行滚动的方法 * next():移动到下一行 * Previous():移动到前一行 * absolute(int row):移动到指定行 * beforeFirst():移动到resultSet的最前面 * afterLast() :移动到resultSet的最后面 while(rs.next()) { String name = rs.getString("name"); System.out.println(name); } ##### 7、关闭连接(先创建的后关闭) ##### JDBC程序运行完后,切记要**释放**程序在运行过程中创建的那些与数据库进行**交互的对象**,这些对象通常是**ResultSet, Statement和Connection对象**。 特别是Connection对象,它是非常稀有的资源,用完后必须马上释放。如果Connection不能及时、正确的关闭,极易导致系统宕机。Connection的**使用原则**是**尽量晚创建,尽量早的释放**。 rs.close(); // rs表示结果集 stat.close(); conn.close(); #### 三、完整代码 #### import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; //不能导入 java.sql 中的 Driver 接口,要导入驱动jar包中实现该接口的类,只有这要才能注册相对应的数据库驱动 import com.mysql.jdbc.Driver; public class JDBCTest { public static void main(String[] args) throws SQLException { //1.注册数据库驱动 DriverManager.registerDriver(new Driver()); //2.获取数据库的连接 Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test?useSSL=false", "root", "root"); //3.创建传输器对象 Statement stat = conn.createStatement(); //4.利用传输器对象传输sql语句到数据库中执行操作,将结果用结果集返回 ResultSet rs = stat.executeQuery("select * from book"); //5.遍历结果集,并获取查询结果 while(rs.next()) { String name = rs.getString("name"); System.out.println(name); } //6.关闭连接(后开先关) rs.close(); stat.close(); conn.close(); } } #### 四、上述代码会遇到的问题 #### ##### 1、注册数据库驱动方法不当,导致出现了两次注册 ##### Driver类源码: public class Driver extends NonRegisteringDriver implements java.sql.Driver { // // Register ourselves with the DriverManager // static { try { java.sql.DriverManager.registerDriver(new Driver()); } catch (SQLException E) { throw new RuntimeException("Can't register driver!"); } } } 查看Driver类源码,可以看到第7行代码中mysql驱动在Driver类的实现中自己注册了一次,而我们在自己的代码中也注册了一次,因此导致了注册两次。 **解决办法:** 使用Class.forName() 方法将mysql中已经实现的Driver类加载到程序中来,由于Driver类在实现接口时使用的是**静态代码块**,而静态代码块只会在**类加载的时候执行一次**,即保证了数据库驱动只会被注册一次,同时不用导入mysql驱动里的类包,程序通用性提高 Class.forName("com.mysql.jdbc.Driver"); ##### 2、忽略了程序中可能会抛出的异常(最大的问题) ##### 在执行程序时,它的许多方法的调用都会抛出异常。如果它抛出异常后,没有做相应的处理(**catch 这个异常**),**那么程序就会中断执行**。Statement对象和Connection对象就没有被关闭,而我们知道Connection对象,它是非常稀有的资源,用完后必须马上释放,如果Connection不能及时、正确的关闭,极易导致系统宕机。所以,我们需要保证无论程序中哪一步出现了异常导致程序中断,连接关闭的代码都会被执行,此时我们就会想到异常处理中的**finally代码块**,先 try 住然后 catch 异常,最后执行 finally 代码块。 修改之后,发现每个close() 都提示有异常要处理,此时我们也直接 try/catch 每个异常 修改后的代码: import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; public class JDBCTest { public static void main(String[] args) { Connection conn = null; Statement stat = null; ResultSet rs = null; try { //1.注册数据库驱动 Class.forName("com.mysql.jdbc.Driver"); // ??? //2.获取数据库的连接 conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test?useSSL=false", "root", "root"); //3.创建传输器对象 stat = conn.createStatement(); //4.利用传输器对象传输sql语句到数据库中执行操作,将结果用结果集返回 rs = stat.executeQuery("select * from book"); //5.遍历结果集,并获取查询结果 while(rs.next()) { String name = rs.getString("name"); System.out.println(name); } }catch(Exception e) { e.printStackTrace(); }finally { //6.关闭连接(后开先关) try { rs.close(); } catch (SQLException e) { e.printStackTrace(); } try { stat.close(); } catch (SQLException e) { e.printStackTrace(); } try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } } ##### 3、程序中易被忽略的异常 ##### 由于在程序开头先声明了三个对象的引用,并且都赋值为null,假如程序在执行到注册数据库这一步时就抛出了异常,此时catch到这个异常后执行finally代码块,结果发现ResultSet对象的引用,Connection对象的引用以及Statement对象的引用都是空值,**调用这个对象上的方法就会抛出空指针异常** close()这个方法身上也有异常,如果我们不做相应的异常处理,那些对象还是不能被正常关闭 **解决办法:** 为了防止出现**空指针异常**,我们可以先判断对象的引用是否为null,如果不为null,则执行异常处理代码 在每个close()异常处理后加上一个finally静态代码块,将每个相应对象的引用值置为null。原理是:如果程序执行到close() 方法并抛出了异常,那么最后finally代码块执行,**给该对象的值置为null,由于这个对象没有任何引用指向它,它就成为了垃圾对象,JVM垃圾回收器就会回收这个对象资源,这个对象也就关闭了** 最终代码: import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; public class JDBCTest { public static void main(String[] args) { Connection conn = null; Statement stat = null; ResultSet rs = null; try { //1.注册数据库驱动 Class.forName("com.mysql.jdbc.Driver"); //2.获取数据库的连接 conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test?useSSL=false", "root", "root"); //3.创建传输器对象 stat = conn.createStatement(); //4.利用传输器对象传输sql语句到数据库中执行操作,将结果用结果集返回 rs = stat.executeQuery("select * from book"); //5.遍历结果集,并获取查询结果 while(rs.next()) { String name = rs.getString("name"); System.out.println(name); } }catch(Exception e) { e.printStackTrace(); }finally { //6.关闭连接(后开先关) if(rs != null) { try { rs.close(); } catch (SQLException e) { e.printStackTrace(); } finally { rs = null; } } if(stat != null) { try { stat.close(); } catch (SQLException e) { e.printStackTrace(); }finally { stat = null; } } if(conn != null) { try { conn.close(); } catch (SQLException e) { e.printStackTrace(); }finally { conn = null; } } } //--finally } //--main }//--class
相关 JDBC详解 目录 一、JDBC简介 二、JDBC的快速入门 三、DriverManager详解 1. 注册驱动 2.获取数据库连接 四、Connection详解 1.获 不念不忘少年蓝@/ 2024年03月30日 17:28/ 0 赞/ 72 阅读
相关 JDBC 详解 一、JDBC快速入门 1.jdbc的概念 JDBC(Java DataBase Connectivity,java数据库连接)是一种用于执行SQL语句的Jav 落日映苍穹つ/ 2024年03月23日 18:06/ 0 赞/ 70 阅读
相关 JDBC详解 目录 一、JDBC基本概念 1、概念 2、JDBC本质 二、JDBC快速入门 1、步骤 2、代码示例 三、JDBC各个对象详解 1、DriverManager驱 红太狼/ 2023年10月19日 08:05/ 0 赞/ 102 阅读
相关 JDBC详解 JDBC 1、什么是JDBC? JDBC 全称是 java DataBase Connectivity,是java连接数据库的规范和 API。该规范中定义了一系列的 逃离我推掉我的手/ 2023年09月28日 11:16/ 0 赞/ 113 阅读
相关 JDBC详解 一、介绍 为了能让 程序 操作 数据库,对数据库中的 表 进行操作,每一种数据库都会提供一套连接和操作该数据库的驱动。而且每种数据库的驱动都各不相同,例如:mysql数据 骑猪看日落/ 2022年12月23日 07:09/ 0 赞/ 205 阅读
相关 JDBC 详解 首先是官方文档: [https://docs.oracle.com/javase/tutorial/jdbc/basics/index.html][https_docs.or 蔚落/ 2022年10月22日 04:10/ 0 赞/ 191 阅读
相关 JDBC详解 JDBC(Java Data Base Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用 你的名字/ 2021年12月15日 14:29/ 0 赞/ 263 阅读
相关 JDBC详解 【一】JDBC介绍 1.JDBC(Java Data Base Connectivity,java数据库连接)是一种执行SQL语句的JavaAPI,可以为多种关系型数据库 水深无声/ 2021年10月01日 06:16/ 0 赞/ 421 阅读
还没有评论,来说两句吧...