SQL 异常简介

对于数据库的操作访问,必然也很可能抛出异常。
JDBC中定义了SQLException,用于描述数据库相关操作中可能出现的异常情况。
java.sql.SQLException 
 
异常本质没有什么特别的逻辑,通常借助于异常的名称传达异常的类型,通过携带的信息进行进一步分析
SQLException是SQL相关的异常的始祖,主要有以下扩展:
  • BatchUpdateException
  • RowSetWarning
  • SerialException
  • SQLClientInfoException
  • SQLNonTransientException
  • SQLRecoverableException
  • SQLTransientException
  • SQLWarning
  • SyncFactoryException
  • SyncProviderException
每个 SQLException 都可提供以下多种消息:
特定于每个供应商的整数错误代码。通常,这将是底层数据库返回的实际错误代码。
描述错误的字符串。此字符串用作 Java Exception 消息,可以通过方法 getMessage 获得(继承来的方法)。
"SQLstate" 字符串,该字符串遵守 XOPEN SQLstate 约定或 SQL:2003 约定。SQLState 字符串的值在适当的规范中描述。DatabaseMetaData 的方法 getSQLStateType 可用于确定驱动程序返回 XOPEN 类型还是 SQL:2003 类型。
到下一个 Exception 的链接。可以使用此链接提供其他错误信息。
因果关系,如果存在任何导致此 SQLException 的原因。 

方法列表如下:

int getErrorCode()
          获取此 SQLException 对象的特定于供应商的异常代码。
String getSQLState()
          获取此 SQLException 对象的 SQLState。
Iterator<Throwable> iterator()
          返回在链接的 SQLExceptions 上进行迭代的迭代器。
void setNextException(SQLException ex)
          将 SQLException 对象添加到链接的末尾。
SQLException getNextException()
          通过 setNextException(SQLException ex) 获取链接到此 SQLException 对象的异常。

异常处理

下面是第一个JDBC示例中的代码,没有很好地处理异常,直接throws Exception了
package jdbc.jdbc;

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.ResultSet;

import java.sql.Statement;

/**

* 第一个JDBC

* @author noteless

*/

public class FirstJDBC {

public static void main(String[] args) throws Exception {

//1、注册驱动

Class.forName("com.mysql.jdbc.Driver");

//数据库连接所需参数

String user = "root";

String password = "123456";

String url = "jdbc:mysql://localhost:3306/sampledb?useUnicode=true&characterEncoding=utf-8";

//2、获取连接对象

Connection conn = DriverManager.getConnection(url, user, password);

//设置sql语句

String sql = "select * from student";

//3、获得sql语句执行对象

Statement stmt = conn.createStatement();

//4、执行sql并保存结果集

ResultSet rs = stmt.executeQuery(sql);

//5、处理结果集

while (rs.next()) {

System.out.print("id:" + rs.getInt(1));

System.out.print(",姓名:" + rs.getString(2));

System.out.print(",年龄:" + rs.getInt(3));

System.out.println(",性别:" + rs.getString(4));

}

//6、资源关闭

rs.close();

stmt.close();

conn.close();

}

}
对于可能抛出异常的代码,应该使用try包裹
不管如何,资源最终都应该被关闭,但是如果资源在打开前就出现异常,直接关闭可能会出现问题
而且在资源关闭过程中也可能出现异常
一个稍微规范一点的形式可能如下所示
package jdbc;

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.ResultSet;

import java.sql.SQLException;

import java.sql.Statement;

public class FirstJDBCFormal {

public static void main(String[] args) throws Exception {

//1、注册驱动

Class.forName("com.mysql.jdbc.Driver");

//数据库连接所需参数

String user = "root";

String password = "123456";

String url = "jdbc:mysql://localhost:3306/sampledb?useUnicode=true&characterEncoding=utf-8";

Connection conn = null;

Statement stmt = null;

ResultSet rs = null;

try {

//2、获取连接对象

conn = DriverManager.getConnection(url, user, password);

//3、设置sql语句

String sql = "select * from student";

//4、获得sql语句执行对象

stmt = conn.createStatement();

//5、执行并保存结果集

rs = stmt.executeQuery(sql);

//6、处理结果集

while (rs.next()) {

System.out.print("id:" + rs.getInt(1));

System.out.print(",姓名:" + rs.getString(2));

System.out.print(",年龄:" + rs.getInt(3));

System.out.println(",性别:" + rs.getString(4));

}

} catch (Exception e) {

throw new RuntimeException(e);

} finally {

//7、资源关闭

try {

if (conn != null) {

conn.close();

}

if (rs != null) {

rs.close();

}

if (stmt != null) {

stmt.close();

}
} catch (SQLException e) { }
}
}
}
最后一块的finally也可以处理成下面这种形式
if (conn != null) {

try{

conn.close();

}catch (SQLException e){

}

}

if (rs != null) {

try{

rs.close();

}catch (SQLException e){

}

}

if (stmt != null) {

try{

stmt.close();

}catch (SQLException e){

}

}
注意:
catch()后面都应该做些处理的,上面的示例中也省略了

总结

对于JDBC中的异常,我们重点在于要认识常见的异常,以及出现异常的原因,能够通过异常信息得到对问题有一个基本的定位
现在借助于各种框架工具,根本就不需要手动编写JDBC程序,更别说自己处理JDBC中的异常了
但是,借助于框架底层的一些异常仍旧是根源于JDBC,所以需要对JDBC中的异常有一个简单了解,以及如何使用
 
在执行SQL的时候,可能会出现多个Exception,每个Exception都有它们自己的Cause。
可以递归使用getNextException获取所有的Exception,每次获取Exception时候再递归调用getCause获取所有Cause Throwable。
try{
//...
}catch(SQLException ex) {
while(ex != null) {
System.out.println("SQLState:" + ex.getSQLState());
System.out.println("Error Code:" + ex.getErrorCode());
System.out.println("Message:" + ex.getMessage());
Throwable t = ex.getCause();
while(t != null) {
System.out.println("Cause:" + t);
t = t.getCause();
}
ex = ex.getNextException();
}
}
也可以使用ForEach直接获取所有Cause Throwable
try{

//...

}catch(SQLException ex) {

for(Throwable e : ex ) {

System.out.println("Error encountered: " + e);

}

}
 
 
 

JDBC 异常简介 jDBC简介(六)的更多相关文章

  1. JDBC设计理念浅析 JDBC简介(一)

    概念 JDBC是J2EE的标准规范之一,J2EE就是为了规范JAVA解决企业级应用开发制定的一系列规范,JDBC也不例外. JDBC是用于Java编程语言和数据库之间的数据库无关连接的标准Java A ...

  2. JDBC驱动程序注册 JDBC简介(二)

    使用JDBC进行数据库操作的第一步就是驱动注册(当然你得先导入JAR). 驱动注册有多种方式,第一步必然是获得正确的驱动名称与URL格式 驱动名称与URL格式 RDBMS 驱动程序名称        ...

  3. DriverManager 驱动管理器类简介 JDBC简介(三)

    驱动程序管理器是负责管理驱动程序的,驱动注册以后,会保存在DriverManager中的已注册列表中 后续的处理就可以对这个列表进行操作 简言之,驱动管理器,就是字面含义,主要负责就是管理 驱动 概述 ...

  4. Data Source与数据库连接池简介 JDBC简介(八)

    DataSource是作为DriverManager的替代品而推出的,DataSource 对象是获取连接的首选方法. 起源 为何放弃DriverManager DriverManager负责管理驱动 ...

  5. JDBC 异常特殊原因 (数据库只读解决办法)

    JDBC 异常特殊原因   有时候并不是因为程序写的有问题  ,是因为  数据库只读 在sqlserver2005中附加数据库时,附加的数据库会变成只读的,只能进行查询操作. 解决方法: 1 打开Sq ...

  6. JDBC异常之数据库表不存在

    JDBC异常之数据库表不存在 1.具体错误如下: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException:Table 'YHD.t_yhd_ ...

  7. maven(多个模块)项目 部署 开发环境 问题处理历程【异常Name jdbc is not bound in this Context 异常java.lang.NoSuchMethodE】

    maven(多个模块)项目 部署 开发环境 问题处理历程[异常Name jdbc is not bound in this Context 异常java.lang.NoSuchMethodE] 201 ...

  8. Spring之 JDBC 异常

    JDBC异常抽象 Spring会将数据操作的异常转换为DataAccessException 解析错误码 SQLErrorCodeSQLExceptionTranslator ErrorCode定义 ...

  9. JDBC基础:JDBC快速入门,JDBC工具类,SQL注入攻击,JDBC管理事务

    JDBC基础 重难点梳理 一.JDBC快速入门 1.jdbc的概念 JDBC(Java DataBase Connectivity:java数据库连接)是一种用于执行SQL语句的Java API,可以 ...

随机推荐

  1. android BLE Peripheral 模拟 ibeacon 发出ble 广播

    Android对外模模式(peripheral)的支持: 从Android 5.0+开始才支持. api level >= 21 所以5.0 之前设备,是不能向外发送广播的. Android中心 ...

  2. 将Redhat,CentOS,Ubuntu虚拟机的IP设为静态IP的方法

    一般在主机上创建的虚拟机默认是通过DHCP(Dynamic Host Configuration Protocol,动态主机配置协议)网络协议来动态生成的,这样会导致你安装的虚拟机的IP地址是动态变化 ...

  3. Win 10 Revit 2019 安装过程,亲自踩的一遍坑,有你想要的细节

    首先就是安装吖,不管是管理员权限还是普通权限,都是以下这个问题,跟权限没关系 failed to load .....revitcontentpackui.dll (126) 尝试了网上能查到的各种方 ...

  4. Mac上常用工具总结

    iOS开发辅助工具 Reveal :Xcode辅助界面调试工具 官网地址:https://revealapp.com/download/ 图标: SimPholders : 快速打开模拟器中的应用程序 ...

  5. PHP 反射的简单使用

    反射机制简介 之前已经介绍过Java反射机制的简单使用,所有的反射机制的思想作用等都是类似的,下面就一起来了解一下PHP反射机制. 个人理解:反射机制就是可以利用类名或者一个类的对象来获取关于这个类的 ...

  6. js 阻止事件执行

    三种阻止事件执行的方式 event.preventDefault() event.stopPropagation() return false event.preventDefault() 阻止特定事 ...

  7. 教你 Debug 的正确姿势——记一次 CoreMotion 的 Crash

    作者:林蓝东 最近的一个手机 QQ 版本发出去后收到比较多关于 CoreMotion 的 crash 上报,案发现场如下: 但是看看这个堆栈发现它完全不按照套路出牌啊! 乍一看是挂在 CoreMoti ...

  8. 为wordpress博客网站替换鼠标样式

    第一种方法是使用插件来实现这个功能,Unique Cursor  插件.可以在后台直接安装启用,然后就可以设置喜欢鼠标样式,点击保存就可以了.切记在选择的同时有二个选项一个是disable意思是关闭还 ...

  9. TCP的三次握手与四次挥手(个人总结)

    序列号seq:占4个字节,用来标记数据段的顺序,TCP把连接中发送的所有数据字节都编上一个序号,第一个字节的编号由本地随机产生:给字节编上序号后,就给每一个报文段指派一个序号:序列号seq就是这个报文 ...

  10. Hive篇--相关概念和使用二

    一.基本概念 Hive分桶: 1.概念 分桶表是对列值取哈希值的方式,将不同数据放到不同文件中存储.对于hive中每一个表.分区都可以进一步进行分桶.(可以对列,也可以对表进行分桶)由列的哈希值除以桶 ...