260 likes | 351 Views
omsCube. Objektverwaltung, basierend auf einem relationale n Datenbankmanagementsystem. Wichtigkeit von Persistenz. Persistenz ist eine der wichtigsten Funktionalitäten in Businessanwendungen In vielen Anwendungen bilden die Datenbankoperationen einen große n Teil des Sourcecodes
E N D
omsCube Objektverwaltung, basierend auf einem relationalen Datenbankmanagementsystem
Wichtigkeit von Persistenz • Persistenz ist eine der wichtigsten Funktionalitäten in Businessanwendungen • In vielen Anwendungen bilden die Datenbankoperationen einen großen Teil des Sourcecodes • Die Daten werden länger genutzt als die Anwendungen, die die Daten erzeugt haben • Performance von Datenbankoperationen hat entscheidende Rolle in der Anwendungsperformance
Persistenz-Lösungen • RDBMS – relational database management systems • Problem: object-relational impedance mismatch • ODBMS – object database management systems • ORDBMS – object/relational database management systems • Andere Lösungen • flat files, XML, „in memory“
stored procedures - Beispiel ... FUNCTION createElement(p_displayName IN VARCHAR2,p_bookmark IN VARCHAR2,p_scm_Id IN NUMBER,p_creating_elm_Id IN NUMBER )RETURN NUMBER; FUNCTION updateElement(p_elm_Id IN NUMBER,p_displayName IN VARCHAR2,p_bookmark IN VARCHAR2,p_modifying_elm_Id IN NUMBER )RETURN NUMBER; FUNCTION cloneElementAppend(p_elm_Id IN NUMBER,p_target_elm_id IN NUMBER,p_target_cat_id IN NUMBER,p_target_key IN VARCHAR,p_recursive IN NUMBER,p_cloneAssociations IN NUMBER,p_creating_elm_Id IN NUMBER ) RETURN NUMBER; FUNCTION removeElementRecursive(p_elm_Id IN NUMBER,includeSelf IN NUMBER,removeAssociations IN NUMBER ) RETURN NUMBER; PROCEDURE moveCompositionBefore(p_cmp_Id in number,p_before_cmp_Id INNUMBER,p_modifying_elm_Id in number ); ...
stored procedures - packages • PCK_AUTHORISATION • PCK_COMPOSITIONPATH • PCK_ELEMENT • PCK_EXCEPTION • PCK_LOCKING • PCK_META • PCK_NAMESPACEPATH • PCK_RELATION • PCK_VALIDATOR
Anfragebeispiel DECLARE v_bookmark element.elm_bookmark%TYPE; v_id element.elm_id%TYPE; v_ids t_array; BEGIN v_bookmark := :in_string_bookmark; BEGIN select elm_id into v_id from element where elm_bookmark = v_bookmark; EXCEPTION when NO_DATA_FOUND then v_id := 0; END; SELECT ass_target_elm_id BULK COLLECT INTO v_ids FROM association WHERE ass_cat_id = :in_int_members_att_id AND ass_source_elm_id = v_id; OPEN :out_cursor_tree FOR SELECT * FROM composition, association, element, simplevalue, uniquevalue, clobvalue, TABLE( CAST( v_ids AS t_array ) ) ids WHERE cmp_target_elm_id = ids.COLUMN_VALUE AND elm_id = cmp_target_elm_id AND ass_source_elm_id (+)= elm_id AND svl_elm_id (+)= elm_id AND cvl_elm_id (+)= elm_id AND uvl_elm_id (+)= elm_id; END;
Beispiel – generierte Klassen 2/2 Finders Entities
Beispiel – Loginprozedur 1/3 Profile getProfile( String username, String password ) { DataStore store = Context.getDataStore(); ProfileFinder finder = new ProfileFinder( store ); Profile profile = finder.findProfileWithRolesByLogin( username ); store.commit(); password = MD5.getHashString( password ); if( profile == null || !profile.getPassword().equalsIgnoreCase( password ) ) { return null; } return profile; }
Beispiel – Loginprozedur 2/3 public Profile findProfileWithRolesByLogin( String loginName ) throws Exception { Scheme profileScm = getMetaData().getScheme( Profile.NAMESPACE_PATH, Profile.SCHEME_NAME ); BoundVariable[] bindVariables = new BoundVariable[] { new BoundVariable( "out_cursor_tree", null ), new BoundVariable( "in_string_username", loginName ), new BoundVariable( "in_int_username_att_id", profileScm.getSimpleAttributeByName( Profile.SAT_USERNAME ).getId() ), new BoundVariable( "in_int_roles_att_id", profileScm.getComplexAttributeByName(Profile.CAT_ROLES).getId() ), }; OMSStructure tree = getStructureByResource( ProfileFinder.class, "findProfileWithRolesByLogin.sql", null, bindVariables ); OMSElement[] elements = tree.getElements(); for (int i = 0; elements != null && i < elements.length; i++) if( elements[ i ].getNamespacePath().equals( Profile.NAMESPACE_PATH ) && elements[ i ].getSchemeName().equals( Profile.SCHEME_NAME ) ) { return new Profile( elements[ i ] ); } return null; }
Beispiel – Loginprozedur 3/3 SELECT * FROM association JOIN element ON ( elm_id = ass_target_elm_id OR elm_id = v_profile_id ) LEFT OUTER JOIN simplevalue ON svl_elm_id = elm_id LEFT OUTER JOIN clobvalue ON cvl_elm_id = elm_id LEFT OUTER JOIN blobvalue ON bvl_elm_id = elm_id LEFT OUTER JOIN uniquevalue ON uvl_elm_id = elm_id WHERE ( ass_cat_id = v_roles_cat_id AND ass_source_elm_id = v_profile_id ) ; DECLARE v_count INTEGER; v_roles_count INTEGER; v_profile_id element.elm_id%TYPE; v_roles_cat_id complexattribute.cat_id%TYPE; v_cur SYS_REFCURSOR; BEGIN v_roles_cat_id := :in_int_roles_att_id; SELECT MAX( uvl_elm_id ) into v_profile_id FROM uniquevalue WHERE uvl_sat_id = :in_int_username_att_id AND uvl_value = :in_string_username; IF v_profile_id IS NOT NULL THEN SELECT count(*) INTO v_roles_count FROM association WHERE ass_cat_id = v_roles_cat_id AND ass_source_elm_id = v_profile_id; IF v_roles_count > 0 THEN OPEN v_cur FOR -- ELSE OPEN v_cur FOR -- END IF; ELSE OPEN v_cur FOR SELECT * FROM DUAL WHERE ROWNUM = 0; END IF; :out_cursor_tree := v_cur; END; SELECT * FROM ELEMENT LEFT OUTER JOIN simplevalue ON svl_elm_id = elm_id LEFT OUTER JOIN clobvalue ON cvl_elm_id = elm_id LEFT OUTER JOIN blobvalue ON bvl_elm_id = elm_id LEFT OUTER JOIN uniquevalue ON uvl_elm_id = elm_id WHERE elm_id = v_profile_id;
Vorteile • Direkte Abbildung von Businessklassen in der Datenbank • Leichte Erweiterbarkeit des logischen Datenbankschemas • Gute Ablage von Baumstrukturen • Gut für Speicherung von vielen unterschiedlichen Objekten geeignet • Gute Performance von Suchoperationen • Alle Objekte sind auf die selbe Weise in der Datenbank gespeichert • Nutzt oft bereits vorhandene und gut bekannte relationale Datenbanken als Basis • Kann mit relationalen Modellen kombiniert werden
Nachteile • Komplizierte Abfragen • Anwendungslogik-Klassen sind von der Datenbankschicht abhängig • Schlechte Unterstützung für verschiedene Datenbanken • Numerische- und Datums-Werte sind als VARCHAR gespeichert • Schlechtere Performance von Schreiboperationen • Die Technologie ist nicht weit verbreitet
Fazit Wähle immer die Technologie, die am besten Deinen Anforderungen und Bedürfnissen entspricht There is no silver bullet
Kontakt • FINGO: www.fingo.pl • Robert Marek: robert@fingo.pl • Präsentationsfolien: www.fingo.info/omscube/ • omsCube offizielle Seite: www.opencube.org • openCube Verein: info@opencube.org