db-ojb-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Thomas Mahler <t...@apache.org>
Subject Re: Patch for tutorial1.xml
Date Wed, 04 Dec 2002 20:02:21 GMT
Thanks!

O'brien, Tim wrote:
> Here is a patch for tutorial1, I'm only half done refactoring the
> grammar and refining some of the language, but I thought I'd submit
> something sooner rather than later.
> 
> Here are the changes I made
> 
> 1. Word choice and grammar fixes
> 2. Changed some of the subsections
> 3. Added a reference to tutorial 3 for Mapping.
> 4. Changed function references from "Class::function()" to
> "Class.function()".  This is trivial, but I think Java programmers will
> be more familiar with this referencing.
> 
> Meanwhile, I'll finish proofreading tutorial1, and move on to the next
> one....
> 
> --------
> Tim O'Brien 
> Transolutions, Inc.
> W 847-574-2143
> M 847-863-7045
> 
> 
> 
> ------------------------------------------------------------------------
> 
> Index: tutorial1.xml
> ===================================================================
> RCS file: /home/cvspublic/jakarta-ojb/xdocs/tutorial1.xml,v
> retrieving revision 1.11
> diff -u -r1.11 tutorial1.xml
> --- tutorial1.xml	31 Jul 2002 10:45:40 -0000	1.11
> +++ tutorial1.xml	4 Dec 2002 18:15:21 -0000
> @@ -3,6 +3,7 @@
>  
>    <properties>
>      <author email="thma@apache.org">Thomas Mahler</author>
> +    <author email="tobrien@transolutions.net">Tim O'Brien</author>
>      <title>ObJectRelationalBridge Tutorial - Part 1</title>
>    </properties>
>  
> @@ -20,64 +21,96 @@
>      <B><code>org.apache.ojb.tutorial1</code></B>.
>    </p>
>    <p>
> -    I begin with explaining the application and outlining its
> -    architecture. After that I will explain how the
> -    ObJectRelationalBridge API can be used in the implementations of the
> -    use cases to perform persistence operations like retrieval, storage
> -    and deletion of objects. Finally I will show how the O/R mapping is
> -    built for the applications persistent class <code>Product</code>.
> +    This document explains the architecture of a simple application which 
> +    uses the ObJectRelationalBridge API (PersistenceBroker) to 
> +    implement five use cases which include persistence operations (retrieval, 
> +    storage, deletion of objects). This document will also demonstrate how a 
> +    simple persistence object <code>Product</code> is mapped to a table
in 
> +    a relational database.
>    </p>
>  </subsection>
>  
> -<subsection name="The sample application">
> -  <p>
> -    The sample application is a console based data entry application.
> -    It's a product catalog database with simple use cases:
> -
> -    <ol>
> -      <li>
> -        List all Products in catalog (all Products entered in this or earlier
> -        sessions and did not get deleted must be displayed)
> -      </li>
> -      <li>
> -        Enter a new Product (the new Product must be made persistent)
> -      </li>
> -      <li>
> -        Edit an existing Product record
> -      </li>
> -      <li>
> -        Delete a Product record (the Product must be removed from the persistent
> -        store)
> -      </li>
> -      <li>
> -        To keep a homogenous design quitting the application is also modelled as
> -        a use case.
> -      </li>
> -    </ol>
> -
> -    These use case shall implement only a rudimentary functionality.
> -    Thus we don't have to care about special cases or variants.
> +<subsection name="The Tutorial Application">
> +  <p>
> +   The sample application is a console based data entry application -
> +   a program to manipulate a product catalog database with five simple
> +   use cases:
> +  </p>
> +
> +  <ol>
> +    <li>
> +      <b>List all Products</b> - 
> +      display all products from the persistent store.
> +    </li>
> +    <li>
> +      <b>Enter a new Product</b> -
> +      create a new product in the persistent store
> +    </li>
> +    <li>
> +      <b>Edit an existing Product record</b> -
> +      update a product in the persistent store
> +    </li>
> +    <li>
> +      <b>Delete a Product record</b> -
> +      remove a product from the persistent store
> +    </li>
> +    <li>
> +      <b>Quit the application</b> -
> +      for consistency we implement this as a use case
> +    </li>
> +  </ol>
> +
> +  <p>
> +  	Only these five basic use cases have been implemented in the
> +    interest of keeping this tutorial focused on conveying only the basic
> +    concepts of OJB.  This tutorial does not explain the necessary steps
> +    to model or implement 1:1, 1:n, or m:n mapping.  For information about
> +    this please refer to Tutorial 3 <a href="tutorial3.html">Advanced O/R</a>.
>    </p>
>  </subsection>
>  
> -<subsection name="see it running...">
> +<subsection name="Running the Tutorial Application">
>    
>    <p>
> -	To see the tutorial application at work you first have to compile the sources
> -	and to setup the test database
> -  	by executing <code>bin\build prepare-tutorials</code> under Win32 or
> -  	<code>bin/build.sh prepare-tutorials</code> under Unix/Linux
> -  	from the ojb toplevel directory.
> - </p>
> +   To execute the application described in this tutorial,
> +   you must prepare the tutorials from the source distribution of
> +   OJB. This is accomplished via Ant build scripts which are executed
> +   by a script in the "bin" directory of the OJB distribution. (Note:
> +   This tutorial assumes that you have already downloaded the OJB
> +   source distribution.)  Note: There is no need to configure a
> +   database in order to run these applications.  The tutorial applications
> +   ship with HSQLDB integration, all you need to do is run the
> +   prepare-tutorials Ant target.
> +  </p>
> +
> +  <p> 
> +   Unpack the OJB source distribution, make sure that your current
> +   working directory is the top level directory of the OJB
> +   distribution and run the following script:
> +  </p>
> +   
> +  <ul>
> +   <li>On Windows 9x/NT/2000/XP:
> +    <ul>
> +     <li><b>Prepare the Tutorials:</b> 
> +         <code>bin\build.bat prepare-tutorials</code></li>
> +     <li><b>Execute this Tutorial:</b>
> +         <code>bin\tutorial1.bat</code></li>
> +    </ul>
> +   </li>
> +   <li>On Unix/Linux:
> +    <ul>
> +     <li><b>Prepare the Tutorials:</b> 
> +         <code>bin/build.sh prepare-tutorials</code></li>
> +     <li><b>Execute this Tutorial:</b> 
> +         <code>bin/tutorial1.bat</code></li>
> +    </ul>
> +   </li>
> +  </ul>
>  
> -  <p>
> -    Now you can start the tutorial application by executing
> -    <code>bin\tutorial1</code> or <code>bin/tutorial1.sh</code>
> -    from the ojb toplevel directory.
> -  </p>
>  </subsection>
>  
> -<subsection name="Architectural scetch">
> +<subsection name="Tutorial Application Architecture">
>    <p>
>      The overall architecture of the application is outlined in the
>      class diagram below.
> @@ -89,8 +122,7 @@
>      provides some convenience code useful for all concrete
>      implementations. There are four concrete UseCase Implementations:
>      UCListAllProducts, UCEnterNewProduct, UCDeleteProduct and
> -    UCQuitApplication. These concrete classes implement the functionality
> -    of the above mentioned Use Cases. The class <code>Product</code>
> +    UCQuitApplication. The class <code>Product</code>
>      represents a product entry in the product database and is the only
>      persistent class in this application.<br/><br/><br/>
>    </p>
> @@ -99,14 +131,15 @@
>      <br/><br/>
>    </p>
>    <p>
> -    figure 1: Class Diagram with the application classes of the
> +    Figure 1: Class Diagram with the application classes of the
>      tutorial application
>    </p>
>    <p>
> -    The Application::run() method runs a non-terminating driver loop.
> -    It does the following: let the user select a use case and perform
> -    this use case and so forth:
> -  </p>
> +    The <code>Application.run()</code> method runs a main event loop. The
> +    program waits for user input in <code>Application.selectUserCase()</code>.
> +    Once a UseCase is selected, it is executed via the 
> +    <code>UseCase.apply()</code> method.  This UseCase class is a simple
> +    implementation of the well-known Command design pattern.</p>
>    <source><![CDATA[
>      while (true)
>      {
> @@ -123,16 +156,18 @@
>      }
>    ]]></source>
>    <p>
> -    A UseCase must implement two methods: <code>getDescription()</code>
and
> -    <code>apply()</code>. <code>UseCase::getDescription()</code>
is used to
> -    display a short information on the use case. This method is used in
> -    <code>Application::selectUseCase()</code> to display each use case.
> -    <code>UseCase::apply()</code> performs the business logic implemented
by the
> -    use case.
> +    The UseCase interface contains two methods: <code>getDescription()</code>

> +    and <code>apply()</code>. <code>UseCase.getDescription()</code>
is used 
> +    to display a short description of the use case to the user. 
> +    This method is used in <code>Application.selectUseCase()</code> to 
> +    display each use case in a menu. <code>UseCase.apply()</code> performs

> +    the business logic implemented by the specific implementation of 
> +    <code>UseCase</code>.
>    </p>
>    <p>
> -    Let's start with the most simple use case: <code>UCQuitApplication</code>.
> -    Here is its <code>apply()</code> method:
> +    Starting with the simplest use case in our application - 
> +    <code>UCQuitApplication</code>. Here is the <code>apply()</code>
method
> +    from the quit application use case:
>    </p>
>    <source><![CDATA[
>      public void apply()
> @@ -144,37 +179,48 @@
>  </subsection>
>  </section>
>  
> -<section name="Using the OJB PersistenceBroker API in the UseCase implementations">
> +<section name="Using the OJB PersistenceBroker API in the UseCase Implementations">
>    <p>
> -    Ok, that was rather trivial as no persistence operations were
> -    involved. Now to some real work: <code>UCListAllProducts</code>.
> -    This use case must lookup a Collection containing all products from
> -    the persistent storage. Then it must iterate over this collection and
> -    print each product. <br/>
> -    To lookup the collection from the persistent
> -    storage we need a method from the OJB API. OJB provides three major
> -    APIs. The PersistenceBroker, ODMG implementation, and JDO implementation. In this
> -    first tutorial I will only use the PersistenceBroker API as it is
> -    simpler to use. <a HREF="tutorial2.html">Using the ODMG API</a> and
> -    <a href="tutorial4.html">Using the JDO API</a> are
> -    covered in separate tutorials.
> +    The code example above was trivial - there are no persistence operations 
> +    involved in quitting the application.  Let's move on to a more relevant
> +    example - <code>UCListAllProducts</code>.
> +    This use case must retreive a <code>Collection</code> containing all

> +    products from the database. It must then iterate over this collection 
> +    and print each product.To retreive the collection from the database we need a method
from the 
> +    OJB API.
> +  </p> 
> +  
> +  <p><b>OJB provides three major APIs.</b>
> +  
> +  <ul>
> +   <li>The PersistenceBroker</li>
> +   <li>An ODMG implementation</li>
> +   <li>A JDO implementation</li>
> +  </ul>
> +   
> +  <p>
> +    In this first tutorial only the <b>PersistenceBroker API</b> is used
as it 
> +  	is the most straightforward of the three options. Tutorial 2: 
> +  	<a HREF="tutorial2.html">Using the ODMG API</a> and
> +    Tutorial 4: <a href="tutorial4.html">Using the JDO API</a> will 
> +    implement the same application using these different methods of
> +    database access.  
>    </p>
>    <p>
>      You will find the source for the PersistenceBroker API in the
>      package <code>org.apache.ojb.broker</code>. <A HREF="javadoc/ojb/broker/package-summary.html">The
> -    JavaDoc is here</A>. The Most important part of this API is the
> +    JavaDoc is here</A>. The key component in this package is the
>      interface <code>PersistenceBroker</code>. It
>      provides methods for retrieval, storage and deletion of objects. To
>      use it in your application you must know how to retrieve a Broker
>      instance, how to configure its O/R mapping repository and how to use
> -    its API.
> +    the available functionsI.
>    </p>
>  
> -  <subsection name="Obtaining a broker instance">
> +  <subsection name="Obtaining a Broker Instance">
>    <p>
> -    To learn how to obtain a Broker instance lets have a look at the
> -    Application class. The public constructor of this class looks like
> -    follows:
> +    How do we obtain a Broker instance? Take a look at the public constructor
> +    of the Application class to find the answer to this question.
>    </p>
>    <source><![CDATA[
>      public Application()
> @@ -197,29 +243,28 @@
>      }
>    ]]></source>
>    <p>
> -    We just ask the PersistenceBrokerFactory to create an instance that
> -    uses the file ./repository.xml as mapping repository (more details on
> -    this repository in the <A HREF="#def_or">section on the Object
> -    /Relational mapping</A>). This broker instance is reached to the
> -    constructors of the UseCases. The constructors just store it in a
> -    protected attribute <code>broker</code> for
> -    further usage.
> +    The PersistenceBrokerFactory creates an instance of PersistenceBroker
> +    using the resource ./repository.xml as a mapping repository (more
> +    details on this repository in the <A HREF="#def_or">section on the
> +    Object/Relational mapping</A>. The PersistenceBroker instance is
> +    passed to the constructor of the four UseCase objects which
> +    store this PersistenceBroker instance as a protected member variable.
>    </p>
>    </subsection>
> -<subsection name="Retrieving collections and iterators">
> + <subsection name="Retrieving Collections and Iterators">
>    <p>
> -    The next thing we need to know is how to use this broker instance to help us
> -    in our persistence operations. In this use case we have to retrieve a
> -    collection containing all product entries from the persistent store. To
> +    The next thing we need to know is how to use this broker instance to implement
> +    our persistence operations. In this use case, we have to retrieve a
> +    collection containing all product entries from the database. To
>      retrieve a collection containing objects matching some criteria we can use
> -    <code>PersistenceBroker::getCollectionByQuery(Query query)</code>.
> -    Where <code>Query</code> is a Class that allows to formulate criteria
like
> -    price &gt; 100. In our case we want to select <I>all</I> persistent
> -    instances, so we need no filtering criteria, they can thus be left
> -    <code>null</code>.
> +    <code>PersistenceBroker.getCollectionByQuery(Query query)</code>.
> +    Where <code>Query</code> is a class that allows to specify criteria
like
> +    price &gt; 100 or userId == 3. In our case we want to select <I>all</I>

> +	of the persistence objects stored in the Product table.  We need <b>no</b>

> +	(or <i>null</i>) filtering criteria.
>    </p>
>    <p>
> -    Here is the code of the <code>UCListAllProducts::apply()</code>method:
> +    Here is the code of the <code>UCListAllProducts.apply()</code>method:
>    </p>
>  
>    <source><![CDATA[
> @@ -249,17 +294,24 @@
>    ]]></source>
>  
>    <p>
> -    If you don't need the resulting collection for further reference as in this
> -    example where we just want to iterate over all products once, it may be a
> -    good idea not to use getCollectionByQuery() but getIteratorByQuery() which
> -    returns an Iterator.
> -  </p>
> -  <p>
> -    This method is extremely useful if you write applications that have to
> -    iterate over large resultsets. Instances are not created all at once but
> -    only on demand, and instances that are not longer referenced by the
> -    application my be reclaimed by the garbage collector. Using this method the
> -    code will look like follows:
> +   Imagine that there are 10,000 products in the product table:
> +   Retrieving a collection of all Products from the persistent store
> +   would be a very expensive operation - new objects are created and an
> +   entire table is loaded into memory.  In this tutorial application,
> +   performance is not a major issue, but in a real-world application OJB
> +   provides a more efficient mechanism for iterating through all the
> +   available products.  If your application does not need to maintain a
> +   collection of product objects in memory, you should call
> +   getIteratorByQuery() which returns an Iterator instead of a Collection.
> +  </p>
> +  <p>
> +    This method is extremely useful if you write applications that
> +    need to iterate over large resultsets. Instances are not created
> +    all at once, they are created on an "as needed" basis as you
> +    iterate through the result.  Instances of persistent objects which
> +    are no longer referenced by the application can be reclaimed by
> +    the garbage collector. Using this method the code will resemble
> +    the following:
>    </p>
>  
>    <source><![CDATA[
> @@ -273,7 +325,7 @@
>          try
>          {
>              // ask the broker to retrieve an Iterator
> -            java.util.Iterator iter = broker.getIteratorB
> +            java.util.Iterator iter = broker.getIteratorByQuery(query);
>              // now iterate over the result to print each product
>              while (iter.hasNext())
>              {
> @@ -301,7 +353,7 @@
>  product's data (productname, price and available stock). These data
>  is stored in the new objects attributes. Then we must store the newly
>  created object in the persistent store. We can use the method
> -<code>PersistenceBroker::store(Object obj)</code>
> +<code>PersistenceBroker.store(Object obj)</code>
>  for this task.
>  </p>
>    <source><![CDATA[
> @@ -349,14 +401,33 @@
>  
>  </subsection>
>  <subsection name="Updating Objects">
> +
>    <p>
> -    Editing and updating a product entry works quite similar. The user
> -    enters the products unique id and the broker tries to lookup the
> -    respective object. This lookup is necessary as our application does
> -    not hold a list of all products. The found product is then edited and
> -    then stored. The PersistenceBroker uses the <code>.store(...)</code>
> -    method for inserting new objects as well as for updating existing
> -    objects. Here is the code:
> +   When a user wants to edit a product ( by selecting item #2 from the
> +   menu ), a user must first enter the "id" of the product to be
> +   edited.  Since the application does not maintain a list of product
> +   objects, the system must first retrieve a product from persistent
> +   storage via the PersistenceBroker.
> +  </p>
> + 
> +  <p>
> +   Selecting an object from the PersistenceBroker is simple - we must
> +   first create a QueryByExample object.  A QueryByExample object is
> +   created with a new Product object that contains an "id" property
> +   which has been populated with the id the user supplied.  You will
> +   notice that all of the other properties of the Product object
> +   remain unpopulated. We have essentially defined a filter by
> +   specifying our desire for a Product object that matches this
> +   product id.
> +  </p>
> + 
> +  <p>
> +   The Product object is retrieved, with the call to
> +   <code>broker.getObjectByQuery(query)</code>.  This retreived object is
then
> +   edited by setting properties based on the user input, and this
> +   object is then stored in the persistence storage through a call to
> +   <code>broker.store(toBeEdited)</code>.  Here is the code from 
> +   <code>UCEditProduct</code>.
>    </p>
>  
>    <source><![CDATA[
> @@ -468,7 +539,13 @@
>    ]]></source>
>  
>  </subsection>
> -<subsection name="Finishing this application is left as an exercise to the interested
reader">
> +<subsection name="Completing the Tutorial Application">
> +
> +  <p>
> +   The completion of this tutorial program is left as an exercise for
> +   the tutorial reader.
> +  </p>
> +
>  
>    <p>
>      Now you are familiar with the basic functionalities of the OJB
> @@ -530,7 +607,7 @@
>      In the following sections I will show how the O/R mapping is
>      defined for the tutorial application.
>    </p>
> -<subsection name="the persistent class Product">
> +<subsection name="A Persistent Class: Product">
>    <p>
>      There is only one persistent class in our tutorial application,
>      the class <code>Product</code>. Here it's definition:
> @@ -560,7 +637,7 @@
>    </p>
>  </subsection>
>  
> -<subsection name="The corresponding database table">
> +<subsection name="The Product Database Table">
>    <p>
>      Now we take a look at a corresponding table definition, in SQL DDL
>      (I give the instantDB syntax here, the syntax may vary slightly for
> @@ -628,7 +705,7 @@
>  
>  </subsection>
>  
> -<subsection name="The Mapping">
> +<subsection name="The Product Mapping">
>  <p>
>  Now we have to describe the mapping from the class <code>Product</code>
>  to the database table <code>PRODUCT</code>. This
> @@ -812,7 +889,7 @@
>  	<a href="repository.html">found here</a>.
>  </p>
>  </subsection>
> -<subsection name="tool support">
> +<subsection name="Tool Support">
>  <p>
>  Generally speaking there are three approaches in building an O/R mapping:
>  </p>
> 
> 
> ------------------------------------------------------------------------
> 
> --
> To unsubscribe, e-mail:   <mailto:ojb-dev-unsubscribe@jakarta.apache.org>
> For additional commands, e-mail: <mailto:ojb-dev-help@jakarta.apache.org>




Mime
View raw message