【问题标题】:Can't catch SQLSyntaxErrorException in Java using MyBatis使用 MyBatis 无法在 Java 中捕获 SQLSyntaxErrorException
【发布时间】:2012-07-26 12:54:27
【问题描述】:

我目前面临以下问题:

我编写了一个解析 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,因为我想告诉用户,数据库中的他的表不可用。但是除了上面看到的正常异常之外,我无法捕获任何其他异常。 我希望我已经说清楚了。谁能帮帮我?

【问题讨论】:

    标签: java exception exception-handling try-catch mybatis


    【解决方案1】:

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

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

    【讨论】:

    • 感谢您的回复,我认为这应该可行,但 MybatisException 不存在并且 IbatisException 已被弃用。我还能用什么?
    • 看看你用catch Exception捕获的异常类型并使用它。
    • 我刚刚发现我可以使用 catch (PersistenceException) 但你的提示也很有效。非常感谢
    【解决方案2】:

    我是按照 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 内部使用的库。

    【讨论】:

      猜你喜欢
      • 2021-10-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-13
      • 2013-09-30
      • 1970-01-01
      相关资源
      最近更新 更多