* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Download Day 3 - Kuali Wiki
Concurrency control wikipedia , lookup
Entity–attribute–value model wikipedia , lookup
Microsoft SQL Server wikipedia , lookup
Open Database Connectivity wikipedia , lookup
Microsoft Jet Database Engine wikipedia , lookup
Clusterpoint wikipedia , lookup
Relational model wikipedia , lookup
Training - Day 3 OJB What is OR Mapping? • OR Mapping is the mapping of relational database tables to objects (Java Objects in our case) • Many OR Mapping tools available – Hibernate – iBatis – OJB • UIS supports Apache OJB – Current version: 1.0.4 Apache OJB • Open source project sponsored by the Apache Project • Makes working with a database feel like working with an Java object model • SQL is seldom used – OJB generates the SQL – Criteria objects Some of the features… • • • • • • • • • • • • • Store and retrieve Java objects to/from any JDBC compliant RDMS No special interfaces needed for your OJB objects – transparent persistence Object graphs can be persisted by persisting the root object Mapping support for 1:1, 1:n, and m:n associations OR Mappings defined in an XML repository Can use multiple databases Lazy loading via proxies (JDK or CGLIB) Support for polymorphism and extents Multiple sequence manager implementations Connection pooling and reuse of prepared statements JTA and JCA integration Optimistic (via number or timestamp) and pessimistic locking supported Support for object caching Supported APIs • Persistence Broker (PB) – Low level kernel API – Foundation of the others below • ODMG – Object Data Management Group Persistence 3.0 – Full support • JDO – Java Data Objects – Partial support • OTM – Object Transaction Manager – API or tool to build other tools on – Specific to OJB Persistence Broker • Kuali supported API • Low level API compared to OTM, ODMG or JDO, but still very easy to use • Store, update, delete, and retrieve objects or collections of objects • More on the PB after we learn how to configure OJB and map relationships OJB.properties • Usually found on the root of the project classpath • When upgrading OJB from any version, this file should be replaced and updated • Key points – Location of the repository.xml file – How to obtain database connections – How to obtain proxies – How to manage transactions Example • Let’s take a look at a real OJB.properties file The Repository Mapping • repository.xml usually on the root of the project classpath • A DTD is also needed • Good idea to break up the contents of repository.xml for easy reuse (testing) – repository_user.xml : OR Mappings – repository_database.xml : Database config repository.xml <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE descriptor-repository PUBLIC "-//Apache Software Foundation//DTD OJB Repository//EN" "repository.dtd" [ <!ENTITY database SYSTEM "repository_database.xml"> <!ENTITY user SYSTEM "repository_user.xml"> ]> <descriptor-repository version="1.0" isolation-level="read-uncommitted" proxy-prefetching-limit="50"> <!-- include all used database connections --> &database; <!-- include user defined mappings here --> &user; </descriptor-repository> repository_database.xml <!-- Datasource example --> <jdbc-connection-descriptor jcd-alias="MYDB" default-connection="true" platform="Oracle9i" jdbc-level="3.0" batch-mode="false" useAutoCommit="1" ignoreAutoCommitExceptions="false" testOnBorrow="true" testWhileIdle="true" testOnReturn="true" validationQuery="select 1 from dual"> <object-cache class="org.apache.ojb.broker.cache.ObjectCachePerBrokerImpl"> </object-cache> <sequence-manager className="org.apache.ojb.broker.util.sequence.SequenceManagerNextValImpl"> </sequence-manager> </jdbc-connection-descriptor> <class-descriptor> • Where you define your table to object mapping <class-descriptor class="edu.iu.uis.train.domain.User" table="TRN_USR_T"> <field-descriptor> • A database column, or object property <field-descriptor name=”username" column=”usr_nm" jdbc-type="VARCHAR" /> A few special fields • Primary keys – primarykey=“true” • Auto-incrementing PK – autoincrement=“true” – Will use the Sequence Manager that you have configured – If using Oracle sequences, you can set the sequence name: sequence-name=“some seq” • Locking field (we use optimistic locking – fast, data integrity only checked on an update) – locking=“true” – Need to store a hidden locking field on JSP pages – Long – incremented each time the column is updated • Long is recommended because of Oracle • Other possibilities are Integer and Timestamp JDBC Types JDBC Type Java Type CHAR VARCHAR LONGVARCHAR NUMERIC DECIMAL BIT BOOLEAN TINYINT SMALLINT INTEGER BIGINT REAL FLOAT DOUBLE BINARY VARBINARY LONGVARBINARY DATE TIME TIMESTAMP CLOB BLOB ARRAY DISTINCT STRUCT REF DATALINK JAVA_OBJECT String String String java.math.BigDecimal java.math.BigDecimal boolean / Boolean boolean / Boolean Byte / byte Short / short Integer / int Long / long Float / float Double / double Double / double byte[] byte[] byte[] java.sql.Date java.sql.Time java.sql.Timestamp Clob Blob Array mapping of underlying type Struct Ref java.net.URL underlying Java class <reference-descriptor> • 1:1 Relationship <reference-descriptor name=”movie" class-ref="edu.iu.uis.train.domain.Movie" auto-retrieve="true" auto-update="false" auto-delete="false" > <foreignkey field-ref=”movieId" target-field-ref="movieId"/> </reference-descriptor> <collection-descriptor> • 1:n Relationship or m:n Relationship <collection-descriptor name=”userCollection" element-class-ref="edu.iu.uis.train.domain.User" auto-retrieve="true" auto-update="true" auto-delete="true" proxy="false"> <inverse-foreignkey field-ref=”userId" target-field-ref=”userId"/> </collection-descriptor> repository_user.xml • Let’s take a looks at this file in the exercises project Exercise: Time to map your business objects • Open repository_user.xml and complete the TODO items – Need DDL for columns and types – Need domain objects for attribute names (which are mapped to the columns) Getting back to the PB API • You can use the PB to: – Query – Insert and update – Delete • It can also tap into database transactions, which you should probably do just about all, if not all, the time Saving an object public static void storeProduct(Product product) { PersistenceBroker broker = null; try { broker = PersistenceBrokerFactory.defaultPersistenceBroker(); broker.beginTransaction(); broker.store(product); broker.commitTransaction(); }catch(PersistenceBrokerException e) { if(broker != null) broker.abortTransaction(); // do more exception handling }finally { if (broker != null) broker.close(); } } Saving multiple objects public static void storeProducts(List products) { PersistenceBroker broker = null; try { broker = PersistenceBrokerFactory.defaultPersistenceBroker(); broker.beginTransaction(); for (Object productObj : products) { Project product = (Product) productObj; broker.store(product); } broker.commitTransaction(); } catch(PersistenceBrokerException e) { if(broker != null) broker.abortTransaction(); // do more exception handling } finally { if (broker != null) broker.close(); } } Deleting an object public static void storeProduct(Product product) { PersistenceBroker broker = null; try { broker = PersistenceBrokerFactory.defaultPersistenceBroker(); broker.beginTransaction(); broker.delete(product); broker.commitTransaction(); }catch(PersistenceBrokerException e){ if(broker != null) broker.abortTransaction(); // do more exception handling }finally { if (broker != null) broker.close(); } } Querying in OJB • You can build up a template object and query • You can use raw sql if you need to bypass OJB • You can use a Criteria object – Recommended way – This is the only way I will demonstrate for now, but there’s great docs on the OJB website if you want to try something else A simple query public static Collection getExpensiveLowStockProducts() { PersistenceBroker broker = null; Collection results = null; try { broker = PersistenceBrokerFactory.defaultPersistenceBroker(); Criteria criteria = new Criteria(); criteria.addLessOrEqualThan("stock", new Integer(20)); criteria.addGreaterOrEqualThan("price", new Double(100000.0)); QueryByCriteria query = new QueryByCriteria(Product.class, criteria); results = broker.getCollectionByQuery(query); } finally { if (broker != null) broker.close(); } return results; } More about the Criteria • You can add just about any kind of “criteria” to build up an SQL statement • Let’s take a look at the API http://db.apache.org/ojb/api/org/apache/ojb/broker/query/Criteria.html Updating an object public static boolean sellOneProduct(Integer stock) { PersistenceBroker broker = null; boolean isSold = false; try { broker = PersistenceBrokerFactory.defaultPersistenceBroker(); Criteria criteria = new Criteria(); criteria.addLessOrEqualThan("stock", stock); criteria.addGreaterOrEqualThan("price", new Double(100000.0)); QueryByCriteria query = new QueryByCriteria(Product.class, criteria); Product result = (Product) broker.getObjectByQuery(query); if (result != null) { broker.beginTransaction(); result.setStock(new Integer(result.getStock().intValue() - 1)); broker.store(result); broker.commitTransaction(); isSold = true; } } catch(PersistenceBrokerException e) { if(broker != null) broker.abortTransaction(); // do more exception handling } finally { if (broker != null) broker.close(); } return isSold; } Exercise: The MovieDAOImpl • It’s time to write your first DAO • You shouldn’t need to extend any files, just implement the MovieDAO interface – Use eclipse to do this when you create the class and it will create all of the methods for you – Let’s do this part together A better way to do all this • Now that you’ve seen how the PB API works, there’s a much better way to work with OJB • We will see more of this when we talk about Spring References • Object Relational Bridge – http://db.apache.org/ojb/ • OJB Tutorials – http://db.apache.org/ojb/docu/tutorials/sum mary.html