Data Source Patterns.  Table Data Gateway  Row Data Gateway  Active Record  Data Mapper  Unit of Work  Identity Map.

Slides:



Advertisements
Similar presentations
Bruce Scharlau, University of Aberdeen, 2012 Data storage options for mobiles Mobile Computing.
Advertisements

Connecting to Databases. relational databases tables and relations accessed using SQL database -specific functionality –transaction processing commit.
And so to Code. Forward, Reverse, and Round-Trip Engineering Forward Engineering Reverse Engineering Round-Trip Engineering.
SQL Lecture 10 Inst: Haya Sammaneh. Example Instance of Students Relation  Cardinality = 3, degree = 5, all rows distinct.
.NET Database Technologies: Open-Source Frameworks.
SOEN 343 Software Design Section H Fall 2006 Dr Greg Butler
15-Jun-15 JDBC. JDBC is a Sun trademark It is often taken to stand for Java Database Connectivity Java is very standardized, but there are many versions.
From Class Diagrams to Databases. So far we have considered “objects” Objects have attributes Objects have operations Attributes are the things you record.
1 JDBC Java Database Connectivity. 2 c.pdf
Spring 2009Computer Science Department, TUC-N Object Oriented Methods Architectural Patterns 2.
Session-02.
UFCE4Y UFCE4Y-20-3 Components and Services Julia Dawson.
Data Persistence and Object-Relational Mapping Slides by James Brucker, used with his permission 1.
Data Access Patterns. Motivation Most software systems require persistent data (i.e. data that persists between program executions). In general, distributing.
Design I: Web Application Architecture and Patterns Peter Dolog dolog [at] cs [dot] aau [dot] dk Intelligent Web and Information Systems September.
Domain Logic Patterns  Transaction Script  Domain Model  Table Module  Service Layer.
Java Database Connectivity (JDBC). Introduction Database –Collection of data DBMS –Database management system –Storing and organizing data SQL –Relational.
Entity Framework Code First End to End
JDBC. What is JDBC JDBC is an acronym for –Java Data Base Connectivity. It allows java/jsp program to connect to any database.
What is Architecture  Architecture is a subjective thing, a shared understanding of a system’s design by the expert developers on a project  In the.
Lecture Set 14 B new Introduction to Databases - Database Processing: The Connected Model (Using DataReaders)
Anti Orgla, Nortal AS Spring Framework
SOEN 6011 Software Engineering Processes Section SS Fall 2007 Dr Greg Butler
.NET Database Technologies: Data Models and Patterns.
Chapter 26 GoF Design Patterns. The Adapter Design Pattern.
NMED 3850 A Advanced Online Design January 12, 2010 V. Mahadevan.
Stored procedures1 Stored procedures and functions Procedures and functions stored in the database.
JDBC Java and Databases. RHS – SOC 2 JDBC JDBC – Java DataBase Connectivity An API (i.e. a set of classes and methods), for working with databases in.
Object-to-Relational Mapping: The Crossing Chasms Pattern and Implementation Considerations Use of Meta Data in the Java Persistence Layer Presented by.
Hibernate Persistence. What is Persistence Persist data to database or other storage.  In OO world, persistence means persist object to external storage.
JDBC Enterprise Systems Programming. JDBC  Java Database Connectivity  Database Access Interface provides access to a relational database (by allowing.
Chapter 8 Databases.
JDBC – Java Database Concentricity
Spring 2009Computer Science Department, TUC-N Object Oriented Methods Architectural Patterns 3.
Architectural Patterns Support Lecture. Software Architecture l Architecture is OVERLOADED System architecture Application architecture l Architecture.
1 Mapping to Relational Databases Presented by Ramona Su.
Lecture Set 14 B new Introduction to Databases - Database Processing: The Connected Model (Using DataReaders)
Java Database Connectivity. Java and the database Database is used to store data. It is also known as persistent storage as the data is stored and can.
Copyright © 2002 ProsoftTraining. All rights reserved. Building Database Client Applications Using JDBC 2.0.
Creating competitive advantage Copyright © 2003 Enterprise Java Beans Presenter: Wickramanayake HMKSK Version:0.1 Last Updated:
JDBC. Java.sql.package The java.sql package contains various interfaces and classes used by the JDBC API. This collection of interfaces and classes enable.
JDBC CS 124. JDBC Java Database Connectivity Database Access Interface provides access to a relational database (by allowing SQL statements to be sent.
COMP 321 Week 4. Overview Normalization Entity-Relationship Diagrams SQL JDBC/JDBC Drivers hsqldb Lab 4-1 Introduction.
EXAMPLE I An application showing JDBC access to Cloudscape.
How I spend my money Software architecture course Mohan, Maxim.
March R McFadyen1 Object Relational Mapping example TopLink Part of Oracle environment Provides an Object/Relational Mapping Layer References:
Elaboration Iteration 3 – Part 3 - Persistence Framework -
Copyright 2007 SpringSource. Copying, publishing or distributing without express written permission is prohibited. Introduction to Data Access with Spring.
DESIGNING A PERSISTENCE FRAMEWORK WITH PATTERNS. The Problem: Persistent Objects persistent object An object that can survive the process or thread that.
Data The fact and figures that can be recorded in system and that have some special meaning assigned to it. Eg- Data of a customer like name, telephone.
Copyright 2007 SpringSource. Copying, publishing or distributing without express written permission is prohibited. Introduction to Spring JDBC Simplifying.
JDBC Java and Databases. SWC – JDBC JDBC – Java DataBase Connectivity An API (i.e. a set of classes and methods), for working with databases in.
Hibernate Thuy, Le Huu. Pentalog VN. Agenda Hibernate Annotations Improving performance – Lazy loading – Fetching Strategies – Dynamic insert, dynamic.
Java Object-Relational Layer Sharon Diskin GUS 3.0 Workshop June 18-21, 2002.
CS 440 Database Management Systems Stored procedures & OR mapping 1.
Database Management Systems 3ed, R. Ramakrishnan and J. Gehrke1 The Relational Model Chapter 3.
JDBC. What is JDBC JDBC is an acronym for –Java Data Base Connectivity. It allows java program to connect to any database.
JDBC III IS Outline  Scrollable ResultSets  Updatable ResultSets  Prepared statements  Stored procedures.
Java Access to RDB Relational databases (RDBs) dominate today, due to:
JDBC 15-Apr-18.
Architecture Patterns Design Patterns
Object Relational Mapping example
Enterprise application architecture
JDBC 15-Nov-18.
Lecture Set 14 B new Introduction to Databases - Database Processing: The Connected Model (Using DataReaders)
SOEN 343 Software Design Computer Science and Software Engineering Department Concordia University Fall 2004 Instructor: Patrice Chalin.
SOEN 343 Software Design Computer Science and Software Engineering Department Concordia University Fall 2004 Instructor: Patrice Chalin.
SOEN 343 Software Design Computer Science and Software Engineering Department Concordia University Fall 2004 Instructor: Patrice Chalin.
Software design Lecture 7.
Presentation transcript:

Data Source Patterns

 Table Data Gateway  Row Data Gateway  Active Record  Data Mapper  Unit of Work  Identity Map

Table Data Gateway  An object that acts as a Gateway to a database table. One instance handles all the rows in the table.  Separate SQL from business logic  Hide SQL in Gateway from business logic  A Table Data Gateway holds all the SQL for accessing a table.  All CRUD operations on the table  Usually a table data gateway is stateless

TDG: Architecture Table Module businessTransaction1() businessTransaction2() businessTransaction3() Table Data Gateway findDataForBusinessTransaction1(sql_query) insertRecordsForBusinessTransaction1(sql_insert, items) updateRecordsForBusinessTransaction2(sql_update, items) … sql_query= “ SELECT * FROM table 1…” sql_insert = “INSERT into tablei…” sql_update = “ UPDATE tablei …” sql_delete = “DELETE FROM …” DB

TDG: When to use it  Works best with Table Module  Works lest with Domain Model

TDG: Example  Database Schema Product Name type Contract date _signed revenue RevenueRecognition Amount date 1 1 * *

TDG: Example RecognitionTableModule calcRecognitions(contract#) recognizedRevenue(contract#, date) … RecognitationGateway findRecognitionsFor(contract#, date) insertRecognition(contract#, revenue, date) … Sql_findContract = “ SELECT * FROM Contract WHERE id = ?” Sql_findRecogns = “select* from recog Where cid=? and date<?” …… DB

createContract() Sequence Diagram: test cases :RecognitionTableModule:RecognitionGateway :Tester insertContract() INSERT into contract … :Database calcRecognitions() insertRecognition() INSERT iinto Recog… recognizedRevenue() findRecognitionsFor() SELECT * FROM … insertRecognition() INSERT iinto Recog… insertRecognition() :ContractTableModule :ContractGateway

TDG: Example class RecognitionGateway { static String findRecogns = “SELECT * FROM revenueRecognition WHERE contract = ? And date <= ?”; static String findContract = “SELECT * FROM contract c, product p WHERE c.id = ? And c.pid = p.id”; public ResultSet findRecognitionsFor(int contrno, Date d) { PreparedStatement s = db.prepareStatement(findRecongs); s.setInt(1, contrno); s.setDate(2, d); ResultSet result = s.executeQuery(); return result; } Class ContractGateway { public ResultSet findContract(int contrno) { PreparedStatement s = db.prepareStatement(findContract); s.setInt(1, contrno); ResultSet result = s.executeQuery(); return result; }

TDG: Example class RecognitionTableModule { private RecognitionGateway gw = new RecognitionGateway(); public Money recognizedRevenue(int contrno, Date d) { Money Result = Money.dollar(0); ResultSet rs = gw.findRecognitionsFor(contrno, d); while (rs.next()) { result = result.add(rs.getBigDecimal(“amount”)); } return result; } public void calculateRevenueRecognitions(int contrno) { ResultSet contrs = contractGateway.findContract(contrno); totalRevenue = contrs.getBigDecimal(“revenue”); dates = contrs.getDate(“date_signed”); type = contrs.getChar(“type”); if (type == ‘S’) { gw.insertRecognition(contrno, totalRevenue/3, date); gw.insertRecognition(contrno, totalRevenue/3, date+60); gw.insertRecognition(contrno, totalRevenue/3, date+90); } else if (type = ‘W’) { gw.insertRecognition(contrno, totalRevenue, date); } else if (type == ‘D’ {... }...

Row Data Gateway  An object that acts as a gateway to a single record in a table.

RDG: Example - PersonGateway Person ID int primary key, last varchar(30), First varchar(30), Dependents int PersonGateway last, first, numOfDeps insert() update() delete() DB PersonFinder last, first, numOfDeps find(int ID) findParents() Registry getPerson(ID) addPerson(person)

RDG: Example – Person Record class PersonGateway { int id; String last; String first; int numOfDeps; // getters and setters Static String updateSQL = “UPDATE person SET last = ?, first =?, dependents = ? WHERE id =?”; static String insertSQL = “...”; static String delete = “... “; void update() { PreparedStatement st= null; try { st = db.prepareStatment(updateSQL); st.setString(1, last); st.setString(2, first); st.setInt(3, numOfDeps); st.setInt(4, id); st.execute(); } catch (SQLException) {... } } void insert() {... } void delete() {... } }

RDG: Example – PersonFinder class PersonFinder { Static String personSQL = “SELECT * FROM person WHERE id =?”; static String parentsSQL = “SELECT * FROM person WHERE dependents >0”; PersonGateway find(int ID) { PersonGateway result = Registry.getPerson(ID); if (result != null) return result; PreparedStatement st= null; try { st = db.prepareStatment(personSQL); st.setString(1, ID); ResultSet rs = st.executeQuery(); rs.next(); result = PersonGateway.load(rs); return result; } catch (SQLException) {... } finally { db.cleanup(st, rs); } }

RDG: Example – PersonFinder class PersonFinder { Static String personSQL = “SELECT * FROM person WHERE id =?”; static String parentsSQL = “SELECT * FROM person WHERE dependents >0”; List findParents() { List result = new ArrayList(); PreparedStatement st= null; try { st = db.prepareStatment(parentSQL); ResultSet rs = st.executeQuery(); while (rs.next()) { result.add(PersonGateway.load(rs)); } return result; } catch (SQLException) {... } finally { db.cleanup(st, rs); } }

RDG: PersonGateway.load() class PersonGateway {... Static PersonGateway load(ResultSet rs) { int id = rs.getInt(1); PersonGateway result = Registry.getPerson(id); if (result != null) { return result; } result = new Person(id, rs.getString(2), rs.getString(3), rs.getInt(4)); Registry.add(result); return result; }

PersonGateway :PersonFinder Find(id=123) RDG: Sequence Diagram: find(id=123) :TableModule Registry getPerson(123) new Return ResultSet return aPerson DB SELECT aPerson:PersonGateway Return null load(ResultSet) new Add(aPerson) return aPerson

RDG: As a Data Holder class Person { private PersonGateway data; public Person(PersonGateway data) { this.data = data; } public int getNumberOfDependents() { return data.getNumberOfDependents(); } public Money getExemption() { Money baseExemption = 1500; Money dependentExemption = 750; return baseExemption + dependentExemption * data.getNumberOfDependents(); } When RowDataGateway is used with Domain Model. RowDataGateway may be employed as a data holder of the domain object.

Active Record  An object that wraps a row in a database table or view, encapsulates the database access, and adds domain logic on that data  Putting DB access login in the domain object.  Each active record is responsible for DB access as well as domain logic  Find methods may be static of ActiveRecord  Find methods may be put into a Finder class.

AR: Architecture Person(Table_1) Person (ActiveRecord1) LastName firstName numberOfDependents Id lastName firstName NumberOfDependents Table_2 CRUD operations getExemption isFlaggedforAudit getTaxableEarnings Attributes Table_n ActiveRecordn CRUD operations on Table_n Business Logic related to Table_n Attributes Database

AR: Example – Person Record class Person{ int id; String last; String first; int numOfDeps; // getters and setters Static String updateSQL = “UPDATE person SET last = ?, first =?, dependents = ? WHERE id =?”; static String insertSQL = “...”; static String delete = “... “; void update() { PreparedStatement st= null; try { st = db.prepareStatment(updateSQL); st.setString(1, last); st.setString(2, first); st.setInt(3, numOfDeps); st.setInt(4, id); st.execute(); } catch (SQLException) {... } } void insert() {... } void delete() {... } }

AR: Person.load() class Person {... Static Person load(ResultSet rs) { int id = rs.getInt(1); Person result = Registry.getPerson(id); if (result != null) { return result; } result = new Person(id, rs.getString(2), rs.getString(3), rs.getInt(4)); Registry.add(result); return result; }

AR: Domain Logic class Person {... public Money getExemption() { Money baseExemption = Money.dollars(1500); Money dependentExemption = Money.dollar(7500); Money totalDepExemptions = dependentExemption.multiply( this.getNumberOfDependent()); Money totalExemption.add(totalDepExemptions); return totalExemptions; }

Data Mapper  A layer of Mappers that moves data between objects and a database while keeping them independent of each and the mapper itself.  The data mapper layer is to separate the in-memory objects from the database  It allows the object model and database to evolve (or be designed) independently  A mapper is an object that sets up a communication between two independent objects  Works best with Domain Model  Use existing framework for data mappers (Hibernate)

DMP: How It Works  A simple mapper maps a database table to an memory class on a field-to-field basis  A find method of a mapper loads the object from DB.  Identify Map may be used to keep one copy in memory  For insert and update, the mapping knows what new objects have been created and what have been destroyed.  A request from client could load a graph of object from DB  A purchase order contains multiple line items  Unit of Work determines what to write back to DB  Lazy Load may be used to postpone the load of some objects.

DMP: When to Use It  When the object model and database schema need to evolve independently  When Domain Model is used for domain logic.  The object model does not know the structure of the database  Don’t use Data Mapper without Domain Model

DMP: A Simple Data Mapper class Person{ String last; String first; int numOfDeps;... } Class PersonMapper extends AbstractMapper { static Person find(int id) { return (Person) abstractFind(id); } String findStatement() { return “SELECT * FROM person WHERE id =?”; } DomainObject doLoad(int id, ResultSet rs) { String lName = rs.getString(2); String fName = rs.getString(3); int numOfDependents = rs.getInt(4); return new Person(id, lName, fName, numOfDependents); }... } findStatement() – part of TemplateMethod, to be called by AbstractMapper.abstractFind(); to be called by AbstractMapper.load();

DMP: A Simple Data Mapper Class AbstractMapper { protected Map identityMap = new HashMap(); abstract String findStatement(); DomainObject abstractFind(int id) { DomainObject result = (DomainObject)identityMap(id); if (result != null) return result; PreparedStatement findStmt; try { findStmtn = DB.prepareStatement(findStatement()); findStmt.setInt(1, id); ResultSet rs = findStmt.executQuery(); rs.next(); result = load(rs); return result; } catch (SQLException) {... } finally { DB.cleanup(); } Template Method Pattern here: findStatement() to be implemented by PersonMapper

DMP: A Simple Data Mapper Class AbstractMapper { DomainObject load(ResultSet rs) { int id = rs.getInt(1); if (identityMap.containsKey(id) return (DomainObject) identityMap.get(id); DomainObject result = doLoad(id, rs); identityMap.put(id, result); return result; } Defined in PersonMapper.doLoad()

DMP: A Simple Data Mapper Class PersonMapper extends AbstractMapper { static String updateSQL = “UPDATE person SET lastName = ?...”; public void update(Person subject) { PreparedStatement update = null; try { update = DB.prepareStatement(updateSQL); update.setInt(1, subject.getId()); update.setString(2, subject.getLastName()); update.setString(3, subject.getFirstName()); update.setInt(4, subject.getNumberOfDependents()); update.execute(); } catch (SQLException) {... } finally { DB.cleanup(update); } public void insert(Person subject) { // similar to update() }

DMP: Separate Finders ArtistFinder find(id) DomainObject Artist Id: long Album AbstractMapper ArtistMapper Mapper Package Domain Package Insert() Update() Load() findStatement() doLoad() find(id) findStatement() doLoad() Dependency Injection Principle

DMP: Separate Finders Interface ArtistFinder { Artist find(int id); } Class ArtistMapper extends AbstractMapper implements ArtistFinder { public Artist find(int id) { return (Artist) abstractFind(id); } String findStatement() { return “SELECT * FROM Artist WHERE id = ?”; } Class AbstractMapper { // similar to the AbstractMapper of previous example }

Unit of Work  Maintains a list of objects affected by a business transaction and coordinates the writing out of changes and the resolution of concurrency problems..  To keep track of what objects have changed so they can be written back to the DB  Batch multiple DB statements for performance  Implement transactions  To control concurrency related problems

UoW: Architecture Unit of Work registerNew(object) registerDirty(object) registerClean(object) registerDelete(object) commit() DB

UoW: How It Works  Each time you touch the database, create a Unit of Work.  Every time you create, change, or delete an object, you tell the Unit of Work.  When you are done, ask the Unit of Work to commit  The Unit of Work opens a transaction, does needed concurrency control, and writes changes to the DB.

UoW: How to Tell Unit of Work  Caller Registration: the client of an object has to register the object with the Unit of Work.  Object Registration: Each object will register itself when it is changed. For example:  Load an object: UnitOfWork.registerClean(obj);  Setters: UnitOfWork.registerDirty(obj)  Unit of Work Controller: UnitOfWork keeps a copy of each object when loaded from DB, then compares with the actual object when committing.

UoW: Example Class UnitOfWork{ private List newObjects = new ArrayList(); private List dirtyObjects = new ArrayList(); private List removedObjects = new ArrayList(); public void registerNew(DomainObject obj) { newObjects.add(obj); } public void registerDirty(DomainObject obj) { dirtyObjects.add(obj); } public void registerRemoved(DomainObject obj) { removedObjects.add(obj); } public void registerClean(DomainObject obj) { if (!identityMap.contains(obj.getId())) { identityMap.add(obj.getId(), obj); }

UoW: Example Class UnitOfWork{ // commit() public void commit() { insertNew(); updateDirty(); deleteRemoved(); } public void insetNew() { for (Iterator objs = newObjects.iterator(); objs.hasNext()) { DomainObject obj = (DomainObject)objs.next(); MapperRegistry.getMapper(obj.getClass()).insert(obj); } public void updateDirty() { // similar to insertNew() } public void deleteRemoved() { // similar to insertNew() }

UoW: Example // one UnitOfWork per Thread Class UnitOfWork{ Private static ThreadLocal current = ThreadLocal(); public static void newCurrent() { setCurrent(new UnitOfWord()); } public static void setCurrent(UnitOfWork, uow) { current.set(uow); } public static UnitOfWork getCurrent() { return (UnitOfWork) current.get(); }  Each business transaction is carried out in a Thread  Create a UnitOfWork local of the Thread

UoW: Example // Abstract Class that handles registration Class DomainObject { protected void markNew() { UnitOfWOrk.getCurrent.registerNew(this); } protected void markClean() { UnitOfWOrk.getCurrent.registerClean(this); } protected void markDirty() { UnitOfWOrk.getCurrent.registerDirty(this); } protected void markRemoved() { UnitOfWOrk.getCurrent.registerRemoved(this); }

UoW: Example // how a domain object register with Unit of Work Class Album extends DomainObject { // attributes public static Album create(String name) { Album obj = new Album(IdGenerator.nextId(), name); obj.markNew(); return obj; } pubic void setTitle(String title) { this.title = title; markDirty(); } // how domain logic employs Unit Of Work Class EditAlbumTransactionScript { public static void updateTitle(int albumId, String title) { UnitOfWOrk.newCurrent(); Mapper mapper = MapperRegistry.getMapper(Album.class); Album album = (Album)Mapper.find(albumId); album.setTitle(title); UnitOfWork.getCurrent().commit(); }

Identity Map  Ensure that each object gets loaded only once by keeping every loaded object in a map.  We don’t want to have two separate objects from the same DB record.  Looks up objects using the map when referring to them  If a record in memory as an object, don’t load it from the DB again

IM: How It Works  Each DB table corresponds to an Identity Map  Choice of Keys: the key of the map may be the primary key or a surrogate key  Explicit or Generic:  An explicit map is accessed with distinct methods for each kind of objects, e.g., findPerson(123)  A generic map uses a single method for all kinds of objects, e.g., find(“Person”, 123)

IM: How It Works  How Many:  A single map for the session  One map per class/table  A single map for each inheritance tree  Where to Put Them:  Inside the Unit Of Work if exists, or  Inside a Registry of the session

IM: When to Use It  To avoid multiple objects to the same DB record  To act as a cache for DB reads  Don’t use it for immutable objects  Don’t use it for dependent objects which are to be handled by their parent.

IM: Example Class PersonIdentityMap { private Map persons = new HashMap(); public static void addPerson(Person p) { soleInstance.persons.put(p.getId(), p); } pubic static Person getPerson(int id) { return (Person) soleInstance.persons.get(id); }

Data Source: Summary  Table Data Gateway  Row Data Gateway  Active Record  Data Mapper  Unit of Work  Identity Map