Presentation is loading. Please wait.

Presentation is loading. Please wait.

Safe Query Objects: Statically Typed Objects as Remotely Executable Queries By: William Cook & Siddhartha Rai ICSE 2005.

Similar presentations


Presentation on theme: "Safe Query Objects: Statically Typed Objects as Remotely Executable Queries By: William Cook & Siddhartha Rai ICSE 2005."— Presentation transcript:

1 Safe Query Objects: Statically Typed Objects as Remotely Executable Queries By: William Cook & Siddhartha Rai ICSE 2005

2 Introduction Fact: Large Applications require persistence. Existing solutions: –EJB –Hibernate –JDO Problem: individual objects granularity.

3 Problems String encoding Runtime checking only Complex queries must be weaved by hand… Programmers must learn two languages.

4 New Idea Safe Query Objects –Represent a query as a statically typed object. –Combine object-relational mapping with object-oriented languages. We will see: –Statically typed interface to the dynamically typed functionality in the JDO 1.0 specification.

5 JDO Background: The Persistence Manager Interface Access to persistent objects via instance of the PersistenceManager interface. Loading individual objects: – getObjectById Creating a new Query: – newQuery interface javax.jdo.PeristenceManager{ Object getObjectById(Object id); Javax.jdo.Query newQuery(Class class); // methods for transactions not listed } interface javax.jdo.PeristenceManager{ Object getObjectById(Object id); Javax.jdo.Query newQuery(Class class); // methods for transactions not listed }

6 JDO Background: The Query Interface Query execution is provided by the Query Interface. interface javax.jdo.Query{ void setFilter(String filter); void setOrdering(String ordering); void declareImports(String imports); void declareParameters(String params); void declareVariable(String vars); Object execute(); Object execute(Object arg1); Object executeWithMap(Map parameters); // bookkeeping methods not listed } interface javax.jdo.Query{ void setFilter(String filter); void setOrdering(String ordering); void declareImports(String imports); void declareParameters(String params); void declareVariable(String vars); Object execute(); Object execute(Object arg1); Object executeWithMap(Map parameters); // bookkeeping methods not listed }

7 JDO Background: Candidate Classes Candidate classes: –Have structural correspondence to tables in database. We will use: class Employee{ String name; float salary; Department department; Employee manager; } class Employee{ String name; float salary; Department department; Employee manager; } class Department{ String name; Collection employees; } class Department{ String name; Collection employees; }

8 JDO Background: Usage Collection execute(PersistenceManager pm){ javax.jdo.Query payCheck = pm.newQuery(Employee.class); payCheck.setFilter(“salary > maneger.salary”); Object result = payCheck.execute(); return (Collection )result; } Collection execute(PersistenceManager pm){ javax.jdo.Query payCheck = pm.newQuery(Employee.class); payCheck.setFilter(“salary > maneger.salary”); Object result = payCheck.execute(); return (Collection )result; } The misspelled “maneger” will not be detected until runtime!

9 Safe Query Safe query object contains: – Filtering method – Ordering method Safe Query Class –Subclass of SafeQuery –Instantiates RemoteQueryJDO class PayCheck extends SafeQuery instantiates RemoteQueryJDO{ boolean filter(Employee emp){ return emp.salary > emp.maneger.salary; } Candidate Class Compilation Error

10 Filtering Method Defines the “WHERE” condition in the query. Must be called filter Must return a boolean value. Free of side effects: –Must not modify states –No iterative constructs

11 Sorted Results : JDO Queries often specify sort order for the set of query results. Relational query languages: – ascending/descending order. Sorting in JDO: –setOrdering method. Collection sortEmployees(){ javax.jdo.Query q = pm.newQuery(Employee.class); q.setOrdering(“department.name ascending,” + “ salary descending”); return (Collection) q.execute(); } Collection sortEmployees(){ javax.jdo.Query q = pm.newQuery(Employee.class); q.setOrdering(“department.name ascending,” + “ salary descending”); return (Collection) q.execute(); }

12 Sorted Results: Safe Query Safe query defines order method –Takes a candidate object –Returns a linked list of the of sortable values. class SortQuery instantiates RemoteQueryJDO extends SafeQuery { Sort order(Employee emp){ return new Sort(emp.department.name, Sort.Direction.ASCENDING, new Sort(emp.salary, Sort.Direction.DESCENDING)); } class SortQuery instantiates RemoteQueryJDO extends SafeQuery { Sort order(Employee emp){ return new Sort(emp.department.name, Sort.Direction.ASCENDING, new Sort(emp.salary, Sort.Direction.DESCENDING)); }

13 Parameterized Queries: JDO Needed when a query behavior depends upon one or more input value. JDO approach: –declareParameters method Collection salaryLimitEmployees(double limit){ javax.jdo.Query q = pm.newQuery(Employee.class); q.setFilter(“salary > limit”); q.declareParameters(“Double limit”); Collection r = (Collection)q.execute(new Double(limit)); return r; } Collection salaryLimitEmployees(double limit){ javax.jdo.Query q = pm.newQuery(Employee.class); q.setFilter(“salary > limit”); q.declareParameters(“Double limit”); Collection r = (Collection)q.execute(new Double(limit)); return r; } What happens if we omit the call to declareParameters?

14 Parameterized Queries: Safe Query Query parameters are defined as standard Java function parameters. Declared as arguments to the query constructor Stored as member variables of the query object. class SalaryLimit instantiates RemoteQueryJDO extends SafeQuery { double limit; /*parameter*/ SalaryLimit(double limit){ this.limit = limit; } boolean filter(Employee employee){ return employee.salary > limit; } class SalaryLimit instantiates RemoteQueryJDO extends SafeQuery { double limit; /*parameter*/ SalaryLimit(double limit){ this.limit = limit; } boolean filter(Employee employee){ return employee.salary > limit; }

15 Dynamic Queries: JDO Involve filters, parameters or sort orders Constructed at runtime. Collection search(String namePrefix, Double minSalary){ String filter = null; String paramDecl = “”; HashMap paramMap = new HashMap(); javax.jdo.Query q =makeQuery(Employee.class); if (namePrefix!= null){ q.declareParameters(“String namePrefix”); paramMap.put(“namePrefix”,namePrefix); filter = and(filter,”(name.startsWith(namePrefix))”); } if (minSalary != null){ q.declareParameters(“double minSalary”); paramMap.put(“minSalary”, minSalary); filter= and(filter, “(salary >= minSalary)”); } q.setFilter(filter); return q.executeWithMap(pramMap); } String and(String a, String b){…} Collection search(String namePrefix, Double minSalary){ String filter = null; String paramDecl = “”; HashMap paramMap = new HashMap(); javax.jdo.Query q =makeQuery(Employee.class); if (namePrefix!= null){ q.declareParameters(“String namePrefix”); paramMap.put(“namePrefix”,namePrefix); filter = and(filter,”(name.startsWith(namePrefix))”); } if (minSalary != null){ q.declareParameters(“double minSalary”); paramMap.put(“minSalary”, minSalary); filter= and(filter, “(salary >= minSalary)”); } q.setFilter(filter); return q.executeWithMap(pramMap); } String and(String a, String b){…}

16 Dynamic Queries: Safe Query class DynQuery instantiates RemoteQueryJDO extends SafeQuery { private String namePrefix; // may be null private Double minSalary; // may be null DynQuery (String namePrefix, Double minSalary){ this.namePrefix = namePrefix; this.minSalary = minSalary; } boolean filter(Employee item){ return (namePrefix == null || item.name.startsWith(namePrefix)) && (minSalary == null || item.salary >= minSalary); } class DynQuery instantiates RemoteQueryJDO extends SafeQuery { private String namePrefix; // may be null private Double minSalary; // may be null DynQuery (String namePrefix, Double minSalary){ this.namePrefix = namePrefix; this.minSalary = minSalary; } boolean filter(Employee item){ return (namePrefix == null || item.name.startsWith(namePrefix)) && (minSalary == null || item.salary >= minSalary); }

17 Null Values Relational databases allow nullable values –Operations involving null return null OOP languages –Allow null object references –Problem 1: Primitive types cannot be null Solution: Boxing –Problem 2: Navigation NullPointerException treated as false returned from “filtering” Example: or(emp.department == dept, emp.salary > min) Solution: …

18 Implementation The query translation is encapsulated in the RemoteQueryJDO metaclass which is applied to the safe query by the JavaOpen instantiates keyword. OpenJava runs the metaclass at compile time, supplying the definition of the of the query class (e.g. PayCheck) as input. The RemoteQueryJDO metaclass examines the user-defined filter method and generates the corresponding execute method.

19 OpenJava RemoteQueryJDO Metaclass Query Class Definition Execute Method Compile Time

20 Advantages Queries defined using OO language –Static type checking –Syntax errors (at compilation time) –JDO seems more comfortable Observation: Most queries are either static or dynamic with static tables. –Safe query can help.

21 Disadvantages Dynamic queries and data-driven with query definition loaded from DB –Open problem… What about creating new tables? Updating tables..

22 The End


Download ppt "Safe Query Objects: Statically Typed Objects as Remotely Executable Queries By: William Cook & Siddhartha Rai ICSE 2005."

Similar presentations


Ads by Google