3

我目前面临以下问题:

我编写了一个解析 XML 数据并将数据放入数据库的 Java 程序。因为我使用 MyBatis,所以数据库几乎可以是所有已经存在的数据库。我只是给你看一段代码,然后我会解释这个问题。

public void insert(SourceContent content){    
    SqlSession session = sqlSessionFactory.openSession();           
        try {
            session.insert("SourceDocument.insert", content);
            session.commit();
        }   catch (Exception e){
            e.printStackTrace();
        } finally {
            session.close();
        }           
    }

这是我的 DAO 类,用于调用 MyBatis 映射器文件的 sql 语句。如果 MyBatis 的映射配置正确完成,插入我的内容(这是一个 java bean 的实例)就没有问题了。但是想象一下,如果我在我的数据库中重命名一个表,那么连接失败是因为配置错误。现在我想捕捉即将到来的错误。当我使用上面的语句时:

catch (Exception e){
            e.printStackTrace();
        } 

程序打印正确的异常:### Cause: java.sql.SQLSyntaxErrorException: ORA-00942: Tabelle oder View nicht vorhanden 但我不想捕获所有异常,我只想捕获 SQLSyntaxErrorException,因为我想告诉用户,表示数据库中的他的表不可用。但是除了上面看到的正常异常之外,我无法捕获任何其他异常。我希望我已经说清楚了。任何人都可以帮助我吗?

4

2 回答 2

6

您的异常已被包装到另一个异常中。捕获其他异常,然后分析其原因。例如:

try {
   ....
} catch (PersistenceException e) {
  try { throw e.getCause(); }
  catch (SQLSyntaxException e) {
    // handle the exception
  }
}

如果这不令人满意,您可以instanceof改为调查原因:

try {
   ....
} catch (PersistenceException e) {
  final Throwable cause = e.getCause();
  if (cause instanceof SQLSyntaxException) {
    // handle the exception
  }
}
于 2012-07-26T12:58:24.993 回答
0

我正在做Marko所说的,但是我找到了一种在mybatis上捕获sql异常的更优雅的方法。

例如,如果您在 Java 类上定义映射器,则可以让每个方法都抛出 MySQLIntegrityConstraintViolationException。然后当你调用一个映射器函数时,只插入一个 MySQLIntegrityConstraintViolationException 异常类型的 catch 块。

在映射器上:

@Select({
    "SELECT * FROM device WHERE id = #{id} AND deleted=0"
})
public Device getDeviceById(@Param("id") int id)  throws MySQLIntegrityConstraintViolationException;

无论您在哪里使用映射器:

try{
        mapper.registerAndroidDevice(newDevice);
        return newDevice.getId();
    }catch(MySQLIntegrityConstraintViolationException sql){
        logger.error("Constraint violation",sql);
        return -1;
    }catch(Exception e){
        logger.error("Error inserting Android device into Database", e);
        return -1;
    }

当然你可以用其他 SQL jdbc4 异常来做这件事,因为是 mybatis 内部使用的库。

于 2013-09-19T06:32:08.450 回答