Java中JDBC连接数据库详解

发布时间 - 2026-01-11 00:12:36    点击率:

一、概念

  1. 为了能让程序操作数据库,对数据库中的表进行操作,每一种数据库都会提供一套连接和操作该数据库的驱动,而且每种数据库的驱动都各不相同,例如mysql数据库使用mysql驱动,oracle数据库使用oracle驱动,这样假如我们编写的程序哪一天想要换数据库,那样就会很不方便,因为所有连接数据库的代码都要从新编写。SUN公司为了简化。统一对数据库的操作,定义了一套java操作数据库的标准或者规范,这个规范就是JDBC。

  2.JDBC全称为:Java Data Base Connectivity(java数据库连接),它主要由接口组成。我们在开发过程中,只要实现它相应的接口就可以非常进行连接。    

  3.我们在开发JDBC应用时,还需要导入相应的数据库的驱动jar包,这些驱动jar包是由数据库公司自己编写的。

二、编写JDBC应用程序(需要连接数据库的程序)的前提准备

1.首先要确定连接的是哪个数据库实例,例如在mysql中,我们可以先创建一个库,然后在库中新建一张表,在表中插入一些数据,我在这里提供一段在mysql数据库中创建一个库,以及表和数据的sql语句,这也是下面连接数据库后操作的库和表。

create database test ; /*创建一个名为Test的数据库*/
use test;        /*使用该数据库或者说切换到该数据库*/
create table book (
  id int primary key auto_increment, /*列:id ,类型:int,从0开始,自动增加, 备注:主键*/
  name varchar(40) NOT NULL,    /*列:name ,类型:varchar, 备注:非空*/
  author varchar(40)NOT NULL, /*列:author ,类型:varchar, 备注:非空*/
  prices double NOT NULL  /*列:prices ,类型:double, 备注:非空*/
); /*新建一张名为book的表*/
/*插入四大名著的数据*/
insert into book(id,name,author,prices) values (null,'西游记','吴承恩',25.00);
insert into book(id,name,author,prices) values (null,'水浒传','施耐庵',30.00);
insert into book(id,name,author,prices) values (null,'红楼梦','曹雪芹',35.00);
insert into book(id,name,author,prices) values (null,'三国演义','罗贯中',40.00);

2.新建一个java项目,然后把mysql的驱动jar包导入进来,即添加到程序运行的库中,具体的驱动jar包,我们可以在数据库的安装目录下找到,或者都网上自己下载相对应的数据库驱动jar包

三、连接数据库操作的步骤解析

(1)注册数据库驱动

虽然我们刚才在新建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());

(2)获取(创建)数据库的连接

我们注册好数据库驱动后,并没有连接上数据库,以往,我们不管在CMD窗口下,通过可视化数据库管理工具操作数据库时,我们都需要先连接数据库服务器,java程序连接数据库也不例外,这里的java程序就相当于客户端,只有先连接上数据库服务,才能对数据库进行操作

客户端与数据库所有交互都是通过connection对象完成的,这个对象的常用方法:

createStatement():创建向数据库发送sql的statement对象。

prepareStatement(sql) :创建向数据库发送预编译sql的

这里我们可以通过DriverManager 工具类里的getConnection(url,user,password)方法来创建数据库连接对象,此方法需要传入三个参数:

User: 数据库的用户名

Password:用户密码

URL:数据库服务器地址,不同的数据库的URL写法不同,我在这里提供三种主流数据库的URL地址写法:

Oracle写法:jdbc:oracle:thin:@localhost:1521:sid

SqlServe写法:jdbc:microsoft:sqlserver://localhost:1433; DatabaseName=sid

MySql写法:jdbc:mysql://localhost:3306/sid

Mysql的url地址的简写形式: jdbc:mysql:///sid

注:后面的sid就是数据库的实例名称(使用的数据库名)

import java.sql.Connection; //导入的是接口类包
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "root"); //这里使用的是一个名为test的mysql数据库,用户名和密码都是root 

(3)创建传输器对象

上面我们已经创建了数据库的连接,已经连上数据库了,但是如果我们想要操作该数据库,我们需要用到sql语句,而我们怎样使用在java程序中使用sql语句来操作数据库呢,这里我们就需要一个传输器对象来传输sql语句到数据库中去执行。上文提到在Connection 类中就有一个createStatement()的方法可以创建一个传输器对象

import java.sql.Statement; //导入的是接口类包
Statement stat = conn.createStatement();

(4)利用传输器对象传输sql语句到数据库中执行操作,将结果用结果集返回

java.sql.Statement身上有许多传输sql语句的方法:其中用的最多的是

executeQuery(String sql) :用于向数据发送查询语句。

executeUpdate(String sql):用于向数据库发送insert、update或delete语句

execute(String sql):用于向数据库发送任意sql语句

import java.sql.ResultSet; //需要导入的接口类包
ResultSet rs = stat.executeQuery("select * from book"); //传输一条查询语句,查询book表中所有的元组数据

(5) 遍历结果集,并获取查询对象

Jdbc程序中的ResultSet用于代表Sql语句的执行结果。Resultset封装执行结果时,采用的类似于表格的方式。ResultSet 对象维护了一个指向表格数据行的游标,初始的时候,游标在第一行之前,调用ResultSet.next() 方法,可以使游标指向具体的数据行,进行调用方法获取该行的数据。

ResultSet既然用于封装执行结果的,所以该对象提供的都是用于获取数据的get方法:

获取指定类型的数据,例如:

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);
}

(6)关闭连接(先创建的后关闭)

Jdbc程序运行完后,切记要释放程序在运行过程中,创建的那些与数据库进行交互的对象,这些对象通常是ResultSet, Statement和Connection对象。

特别是Connection对象,它是非常稀有的资源,用完后必须马上释放,如果Connection不能及时、正确的关闭,极易导致系统宕机。Connection的使用原则是尽量晚创建,尽量早的释放。

rs.close(); 
stat.close();
conn.close(); 

初期完整的源代码

package jdbcDemo;
/****************************
 * 初版连接数据库程序
 **************************/
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类的源码中可以看到如下代码,从第7行代码中我们可以看到,mysql在Driver类的实现中自己注册了一次,而我们在程序中又注册了一次,导致注册两次

我们在注册驱动时,需要导入mysql驱动jar包中已经实现的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!");
 }
 }

修复方法:

使用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 每个异常

修改后的源代码:

package jdbcDemo;
/****************************
 * 修改版连接数据库程序
 **************************/
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();
  }
 }
 } 
}

五、修改后程序中被忽略的异常

异常问题

1.由于我们在程序开头先声明了三个对象的引用,并且都赋值为null,假如程序在执行到注册数据库这一步时就抛出了异常,此时catch 到这个异常 后执行finally 代码块,结果发现ResultSet 对象的引用,Connection对象的引用以及Statement对象的引用都是空值,调用这个对象上的方法就会抛出空指针异常

2.close()这个方法身上也有异常,如果我们不做相应的异常处理,那些对象还是不能被正常关闭

解决办法

1---为了防止出现空指针异常,我们可以先判断哪些对象的引用是否为null,如果不为null,则执行异常处理代码

2---在每个close()异常处理后在加上一个finally静态代码块,将每个相应对象的引用值置为null,原理是:如果程序执行到close() 方法并抛出了异常,那么最后finally代码块执行,给该对象的应用值置为null,由于这个对象没有任何引用指向它,它就成为了垃圾对象,JVM垃圾回收器就会回收这个对象资源,这个对象也就关闭了

异常处理完后最终的源代码:

package jdbcDemo;
/****************************
 * 无异常版连接数据库程序
 **************************/
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

总结:

这里我只是把所有的异常处理完,但是程序的通用性还不是特别高,因为连接数据库用到的Driver类名、URL、user以及password 都写在程序中,我们其实可以写在一个文本文件中,通过对文件的读取来获得每种数据库特有的连接参数

还有就是在实际开发过程中,连接数据库的程序代码一般会写在一个工具类中,我们想要对数据库中的数据进行操作时,只需要调用这个工具类就可以了,不用每次都写那么多代码

接下来我还会更新一篇如何将数据库的连接信息保存在文本文件中,然后读取这个文件来实现连接数据库的操作,同时我也会将这个程序修改为连接数据库的一个工具类

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持!


# java中jdbc连接数据库  # jdbc连接数据库  # java配置dbcp连接池(数据库连接池)示例分享  # java 获取数据库连接的实现代码  # Java数据库连接池的几种配置方法(以MySQL数据库为例)  # java连接数据库增、删、改、查工具类  # java配置数据库连接池的方法步骤  # Java程序连接数据库的常用的类和接口介绍  # Java中连接数据库方式详细步骤记录  # 连接数据库  # 的是  # 就会  # 数据库中  # 抛出  # 都是  # 我们可以  # 遍历  # 开先  # 创建一个  # 写在  # 查询结果  # 源代码  # 就可以  # 过程中  # 两次  # 它是  # 可以看到  # 方法来  # 完后 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 详解Android中Activity的四大启动模式实验简述  韩国服务器如何优化跨境访问实现高效连接?  Laravel如何使用Laravel Vite编译前端_Laravel10以上版本前端静态资源管理【教程】  Mybatis 中的insertOrUpdate操作  轻松掌握MySQL函数中的last_insert_id()  如何基于云服务器快速搭建个人网站?  如何在建站之星绑定自定义域名?  深圳网站制作的公司有哪些,dido官方网站?  Gemini手机端怎么发图片_Gemini手机端发图方法【步骤】  谷歌浏览器如何更改浏览器主题 Google Chrome主题设置教程  Laravel如何与Docker(Sail)协同开发?(环境搭建教程)  Laravel怎么自定义错误页面_Laravel修改404和500页面模板  谷歌浏览器下载文件时中断怎么办 Google Chrome下载管理修复  惠州网站建设制作推广,惠州市华视达文化传媒有限公司怎么样?  如何在阿里云虚拟机上搭建网站?步骤解析与避坑指南  如何在云服务器上快速搭建个人网站?  Laravel如何理解并使用服务容器(Service Container)_Laravel依赖注入与容器绑定说明  如何在云主机快速搭建网站站点?  宙斯浏览器文件分类查看教程 快速筛选视频文档与图片方法  php嵌入式断网后怎么恢复_php检测网络重连并恢复硬件控制【操作】  高配服务器限时抢购:企业级配置与回收服务一站式优惠方案  Laravel怎么实现验证码功能_Laravel集成验证码库防止机器人注册  Laravel如何使用Livewire构建动态组件?(入门代码)  Laravel如何实现用户注册和登录?(Auth脚手架指南)  在线制作视频的网站有哪些,电脑如何制作视频短片?  Claude怎样写结构化提示词_Claude结构化提示词写法【教程】  Laravel事件监听器怎么写_Laravel Event和Listener使用教程  Android okhttputils现在进度显示实例代码  Laravel如何集成Inertia.js与Vue/React?(安装配置)  Laravel怎么实现软删除SoftDeletes_Laravel模型回收站功能与数据恢复【步骤】  最好的网站制作公司,网购哪个网站口碑最好,推荐几个?谢谢?  如何在Ubuntu系统下快速搭建WordPress个人网站?  高防网站服务器:DDoS防御与BGP线路的AI智能防护方案  Laravel如何使用集合(Collections)进行数据处理_Laravel Collection常用方法与技巧  浏览器如何快速切换搜索引擎_在地址栏使用不同搜索引擎【搜索】  如何在景安服务器上快速搭建个人网站?  大连网站制作公司哪家好一点,大连买房网站哪个好?  Laravel如何处理跨站请求伪造(CSRF)保护_Laravel表单安全机制与令牌校验  Laravel如何使用withoutEvents方法临时禁用模型事件  ,南京靠谱的征婚网站?  Laravel如何实现登录错误次数限制_Laravel自带LoginThrottles限流配置【方法】  如何在阿里云购买域名并搭建网站?  宙斯浏览器视频悬浮窗怎么开启 边看视频边操作其他应用教程  高端网站建设与定制开发一站式解决方案 中企动力  如何快速建站并高效导出源代码?  高性价比服务器租赁——企业级配置与24小时运维服务  laravel服务容器和依赖注入怎么理解_laravel服务容器与依赖注入解析  如何在阿里云虚拟服务器快速搭建网站?  Laravel如何实现多对多模型关联?(Eloquent教程)  制作旅游网站html,怎样注册旅游网站?