Oracleのエラーコードごとに例外を作って、エラー発生時、コードに対応する例外を投げさせる。
データベースを更新するとき、事前に整合性をチェックするのはめんどいので、とりあえず更新してみて、整合性に問題があればそのとき対応しようというアプローチ。
デメリットは…スピード?Oracleにエラー判定をさせるので、この設計を嫌がる人はいるかも。
OracleException
Oracle用の例外。一意制約、参照整合性制約以外のエラーはこの例外が投げられる。
package oraerr.exception;import java.sql.SQLException;
public class OracleException extends RuntimeException {
private String sql = null;
public static OracleException newInstance(String sql, SQLException cause) {
OracleException e = null;
switch (cause.getErrorCode()) {
case 1:
e = new OracleUniqueException(sql, cause);
break;
case 2291:
e = new OracleForeignKeyException(sql, cause);
break;
default:
e = new OracleException(sql, cause);
break;
}
return e;
}
protected OracleException(String sql, SQLException e) {
super("SQL: " + sql, e);
}
public String getSql() {
return sql;
}
public void setSql(String sql) {
this.sql = sql;
}
}
OracleUniqueException
一意制約用の例外。
package oraerr.exception;import java.sql.SQLException;
public class OracleUniqueException extends OracleException {
OracleUniqueException(String sql, SQLException e) {
super(sql, e);
}
}
OracleForeignKeyException
参照整合性制約用の例外。
package oraerr.exception;import java.sql.SQLException;
public class OracleForeignKeyException extends OracleException {
public OracleForeignKeyException(String sql, SQLException e) {
super(sql, e);
}
}
実行クラス
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;import oraerr.exception.OracleException;
import oraerr.exception.OracleForeignKeyException;
import oraerr.exception.OracleUniqueException;
public class Runner {
public static void main(String[] args) throws ClassNotFoundException {
Class.forName("oracle.jdbc.driver.OracleDriver");
// 一意制約
try {
update("insert into DEPT values ('10', 'ACCOUNTING', 'NEW YORK')");
} catch (OracleUniqueException e) {
System.out.println("エラー: 一意制約");
}
// 参照整合性制約
try {
update("insert into emp values (8000, 'MILLER', 'CLERK', 7782, '1982-01-23', 1300, null, 99)");
} catch (OracleForeignKeyException e) {
System.out.println("エラー: 参照整合性制約");
}
}
private static int update(String sql) throws OracleException {
Connection conn = null;
PreparedStatement stmt = null;
int count = 0;
try {
conn = DriverManager.getConnection(
"jdbc:oracle:thin:@//localhost:1521/myoracle", "sugawara",
"sugawara");
stmt = conn.prepareStatement(sql);
count = stmt.executeUpdate();
} catch (SQLException e) {
throw OracleException.newInstance(sql, e);
} finally {
close(null, stmt, conn, sql);
}
return count;
}
private static void close(ResultSet rs, Statement stmt, Connection conn,
String sql) throws OracleException {
try {
if (rs != null) {
rs.close();
}
if (stmt != null) {
stmt.close();
}
if (conn != null) {
conn.close();
}
} catch (SQLException e) {
throw OracleException.newInstance(sql, e);
}
}
}
実行結果は次の通り。
エラー: 一意制約
エラー: 参照整合性制約