特定のアプリケーション・データベース表に対する選択、挿入、更新、削除およびロックの動作をカプセル化した既存のPL/SQLパッケージがある場合は、次のコード・サンプルに示すように、ビルトインのエンティティ・オブジェクト・フレームワーク・メソッドdoDML()
およびdoSelect()
をオーバーライドして、エンティティ・オブジェクトのデータベース永続操作が、完全に既存パッケージに基づいて行われるようにできます。エンティティ・オブジェクト・エディタでdoDML()
メソッドのスケルトン・コードを生成できることに注意してください。
このトピックでは、最初にストアド・プロシージャとエンティティ・オブジェクトのコードを示し、その後で説明します。
CREATE OR REPLACE PACKAGE departments_pkg IS PROCEDURE do_lock(p_deptno number, p_dname out varchar2, p_loc out number); PROCEDURE do_select(p_deptno number, p_dname out varchar2, p_loc out number); PROCEDURE do_update(p_deptno number, p_dname varchar2, p_loc number); PROCEDURE do_insert(p_deptno number, p_dname varchar2, p_loc number); PROCEDURE do_delete(p_deptno number); END; . / SHOW ERRORS CREATE OR REPLACE PACKAGE BODY departments_pkg IS PROCEDURE do_select(p_deptno number, p_dname out varchar2, p_loc out number) IS BEGIN SELECT department_name, location_id INTO p_dname, p_loc FROM departments WHERE department_id = p_deptno FOR UPDATE NOWAIT; END; PROCEDURE do_lock(p_deptno number, p_dname out varchar2, p_loc out number) IS BEGIN SELECT department_name, location_id INTO p_dname, p_loc FROM departments WHERE department_id = p_deptno; END; PROCEDURE do_update(p_deptno number, p_dname varchar2, p_loc number) IS BEGIN UPDATE departments SET department_name = p_dname, location_id = p_loc WHERE department_id = p_deptno; END; PROCEDURE do_insert(p_deptno number, p_dname varchar2, p_loc number) IS BEGIN INSERT INTO departments(department_id, department_name,location_id) VALUES (p_deptno,p_dname,p_loc); END; PROCEDURE do_delete(p_deptno number) IS BEGIN DELETE FROM departments WHERE department_id = p_deptno; END; END; . / SHOW ERRORS
protected void doSelect(boolean lock) { if (lock) { this.handleStoredProcLock(); } else { this.handleStoredProcSelect(); } } public void doDML(int operation, TransactionEvent e) { switch (operation) { case DML_INSERT: { handleStoredProcInsert(); break; } case DML_UPDATE: { handleStoredProcUpdate(); break; } case DML_DELETE: { handleStoredProcDelete(); break; } } } void handleStoredProcSelect() { CallableStatement st = null; try { String stmt = "BEGIN departments_pkg.do_select(?,?,?); END;"; DBTransaction tr = getDBTransaction(); st = tr.createCallableStatement(stmt,1); st.setLong(1,getDepartmentId().longValue()); st.registerOutParameter(2,Types.VARCHAR); st.registerOutParameter(3,Types.NUMERIC); int rows = st.executeUpdate(); populateAttribute(DEPARTMENTNAME,st.getString(2),true,false); populateAttribute(LOCATIONID,st.getBigDecimal(3),true,false); } catch (SQLException s) { throw new JboException(s); } finally { try { if (st != null) st.close(); } catch (SQLException s) { /* ignore */} } } void handleStoredProcDelete() { CallableStatement st = null; try { String stmt = "BEGIN departments_pkg.do_delete(?); END;"; DBTransaction tr = getDBTransaction(); st = tr.createCallableStatement(stmt,1); st.setLong(1,getDepartmentId().longValue()); int rows = st.executeUpdate(); } catch (SQLException s) { throw new JboException(s); } finally { try { if (st != null) st.close(); } catch (SQLException s) { /* ignore */} } } void handleStoredProcInsert() { CallableStatement st = null; try { String stmt = "BEGIN departments_pkg.do_insert(?,?,?); END;"; DBTransaction tr = getDBTransaction(); st = tr.createCallableStatement(stmt,1); st.setLong(1,getDepartmentId().longValue()); if (getDepartmentName() != null) { st.setString(2,getDepartmentName()); } else { st.setNull(2,Types.VARCHAR); } if (getLocationId() != null) { st.setLong(3,getLocationId().longValue()); } else { st.setNull(3,Types.VARCHAR); } int rows = st.executeUpdate(); } catch (SQLException s) { throw new JboException(s); } finally { try { if (st != null) st.close(); } catch (SQLException s) { /* ignore */} } } void handleStoredProcUpdate() { CallableStatement st = null; try { String stmt = "BEGIN departments_pkg.do_update(?,?,?); END;"; DBTransaction tr = getDBTransaction(); st = tr.createCallableStatement(stmt,1); st.setLong(1,getDepartmentId().longValue()); if (getDepartmentName() != null) { st.setString(2,getDepartmentName()); } else { st.setNull(2,Types.VARCHAR); } if (getLocationId() != null) { st.setLong(3,getLocationId().longValue()); } else { st.setNull(3,Types.VARCHAR); } int rows = st.executeUpdate(); } catch (SQLException s) { throw new JboException(s); } finally { try { if (st != null) st.close(); } catch (SQLException s) { /* ignore */} } } void handleStoredProcLock() { CallableStatement st = null; try { String stmt = "BEGIN departments_pkg.do_lock(?,?,?); END;"; DBTransaction tr = getDBTransaction(); st = tr.createCallableStatement(stmt,1); st.setLong(1,getDepartmentId().longValue()); st.registerOutParameter(2,Types.VARCHAR); st.registerOutParameter(3,Types.NUMERIC); int rows = st.executeUpdate(); String newDname = st.getString(2); BigDecimal newLoc = st.getBigDecimal(3); // Compare the old values to the current values to // detect if row has changed. compareOldAttrTo(DEPARTMENTNAME,newDname); compareOldAttrTo(LOCATIONID,newLoc); } catch (SQLException s) { throw new JboException(s); } finally { try { if (st != null) st.close(); } catch (SQLException s) { /* ignore */} } } void compareOldAttrTo(int slot, Object newVal) { if ((getPostedAttribute(slot) == null && newVal != null) || (getPostedAttribute(slot) != null && newVal == null) || (getPostedAttribute(slot) != null && newVal != null && !getPostedAttribute(slot).equals(newVal))) { throw new RowInconsistentException(createPrimaryKey(getDepartmentId())); } }
doSelect()
のコードは、オーバーライドされたヘルパー・メソッドをコールします。ヘルパー・メソッドは、フレームワークで主キーに基づく行をフォルトインする(doSelect(false)
)か、既存の行をロックする(doSelect(true)
)かによって異なります。
doDML()
のコードは、実行を要求された操作の値に応じて、適切なヘルパー・メソッドをコールします。
各ヘルパー・メソッドはDBTransaction
インタフェースのcreateCallableStatement()
メソッドを使用して、JDBCコール可能な文を作成し、そのパラメータをバインドして実行します。
ロックのヘルパー・メソッドはロックを取得した後でDname
属性とLoc
属性を調べて、現在のユーザーが行を選択してから変更しようとするまでの間に、別のトランザクションによって行が変更されていないことを確認します。
現在、DBAはDepartment表の挿入、更新および削除権限を完全に取り消すことができます。また、すべてのDML操作は、作成、変更または削除されるDeptエンティティのストアド・プロシージャにルーティングされます。
Copyright © 1997, 2006, Oracle. All rights reserved.