further re-working of the ORM chapter
This commit is contained in:
parent
62406474e0
commit
660cd3d00a
|
|
@ -15,8 +15,7 @@
|
||||||
|
|
||||||
<para>This section documents the classic usage patterns that you might
|
<para>This section documents the classic usage patterns that you might
|
||||||
encounter in a legacy Spring application. For the currently recommended
|
encounter in a legacy Spring application. For the currently recommended
|
||||||
usage patterns, please refer to the <xref linkend="orm" /> chapter.
|
usage patterns, please refer to the <xref linkend="orm" /> chapter.</para>
|
||||||
</para>
|
|
||||||
|
|
||||||
<section id="classic-spring-hibernate">
|
<section id="classic-spring-hibernate">
|
||||||
<title>Hibernate</title>
|
<title>Hibernate</title>
|
||||||
|
|
@ -170,6 +169,93 @@
|
||||||
</section>
|
</section>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<section id="classic-spring-jdo">
|
||||||
|
<title>JDO</title>
|
||||||
|
|
||||||
|
<para>For the currently recommended usage patterns for JDO see <xref
|
||||||
|
linkend="orm-jdo" /></para>
|
||||||
|
|
||||||
|
<section id="orm-jdo-template">
|
||||||
|
<title><classname>JdoTemplate</classname> and
|
||||||
|
<classname>JdoDaoSupport</classname></title>
|
||||||
|
|
||||||
|
<para>Each JDO-based DAO will then receive the
|
||||||
|
<interfacename>PersistenceManagerFactory</interfacename> through
|
||||||
|
dependency injection. Such a DAO could be coded against plain JDO API,
|
||||||
|
working with the given
|
||||||
|
<interfacename>PersistenceManagerFactory</interfacename>, but will
|
||||||
|
usually rather be used with the Spring Framework's
|
||||||
|
<classname>JdoTemplate</classname>:</para>
|
||||||
|
|
||||||
|
<programlisting language="xml"><beans>
|
||||||
|
|
||||||
|
<bean id="myProductDao" class="product.ProductDaoImpl">
|
||||||
|
<property name="persistenceManagerFactory" ref="myPmf"/>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
</beans></programlisting>
|
||||||
|
|
||||||
|
<programlisting language="java">public class ProductDaoImpl implements ProductDao {
|
||||||
|
|
||||||
|
private JdoTemplate jdoTemplate;
|
||||||
|
|
||||||
|
public void setPersistenceManagerFactory(PersistenceManagerFactory pmf) {
|
||||||
|
this.jdoTemplate = new JdoTemplate(pmf);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Collection loadProductsByCategory(final String category) throws DataAccessException {
|
||||||
|
return (Collection) this.jdoTemplate.execute(new JdoCallback() {
|
||||||
|
public Object doInJdo(PersistenceManager pm) throws JDOException {
|
||||||
|
Query query = pm.newQuery(Product.class, "category = pCategory");
|
||||||
|
query.declareParameters("String pCategory");
|
||||||
|
List result = query.execute(category);
|
||||||
|
<lineannotation>// do some further stuff with the result list</lineannotation>
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}</programlisting>
|
||||||
|
|
||||||
|
<para>A callback implementation can effectively be used for any JDO
|
||||||
|
data access. <classname>JdoTemplate</classname> will ensure that
|
||||||
|
<classname>PersistenceManager</classname>s are properly opened and
|
||||||
|
closed, and automatically participate in transactions. The template
|
||||||
|
instances are thread-safe and reusable, they can thus be kept as
|
||||||
|
instance variables of the surrounding class. For simple single-step
|
||||||
|
actions such as a single <literal>find</literal>,
|
||||||
|
<literal>load</literal>, <literal>makePersistent</literal>, or
|
||||||
|
<literal>delete</literal> call, <classname>JdoTemplate</classname>
|
||||||
|
offers alternative convenience methods that can replace such one line
|
||||||
|
callback implementations. Furthermore, Spring provides a convenient
|
||||||
|
<classname>JdoDaoSupport</classname> base class that provides a
|
||||||
|
<literal>setPersistenceManagerFactory(..)</literal> method for
|
||||||
|
receiving a <classname>PersistenceManagerFactory</classname>, and
|
||||||
|
<methodname>getPersistenceManagerFactory()</methodname> and
|
||||||
|
<methodname>getJdoTemplate()</methodname> for use by subclasses. In
|
||||||
|
combination, this allows for very simple DAO implementations for
|
||||||
|
typical requirements:</para>
|
||||||
|
|
||||||
|
<programlisting language="java">public class ProductDaoImpl extends JdoDaoSupport implements ProductDao {
|
||||||
|
|
||||||
|
public Collection loadProductsByCategory(String category) throws DataAccessException {
|
||||||
|
return getJdoTemplate().find(
|
||||||
|
Product.class, "category = pCategory", "String category", new Object[] {category});
|
||||||
|
}
|
||||||
|
}</programlisting>
|
||||||
|
|
||||||
|
<para>As alternative to working with Spring's
|
||||||
|
<classname>JdoTemplate</classname>, you can also code Spring-based
|
||||||
|
DAOs at the JDO API level, explicitly opening and closing a
|
||||||
|
<interfacename>PersistenceManager</interfacename>. As elaborated in
|
||||||
|
the corresponding Hibernate section, the main advantage of this
|
||||||
|
approach is that your data access code is able to throw checked
|
||||||
|
exceptions. <classname>JdoDaoSupport</classname> offers a variety of
|
||||||
|
support methods for this scenario, for fetching and releasing a
|
||||||
|
transactional <interfacename>PersistenceManager</interfacename> as
|
||||||
|
well as for converting exceptions.</para>
|
||||||
|
</section>
|
||||||
|
</section>
|
||||||
|
|
||||||
<section id="classic-spring-jpa">
|
<section id="classic-spring-jpa">
|
||||||
<title>JPA</title>
|
<title>JPA</title>
|
||||||
|
|
||||||
|
|
@ -259,167 +345,6 @@
|
||||||
it.</emphasis></para>
|
it.</emphasis></para>
|
||||||
</section>
|
</section>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section id="classic-spring-jdo">
|
|
||||||
<title>JDO</title>
|
|
||||||
|
|
||||||
<para>For the currently recommended usage patterns for JDO see <xref
|
|
||||||
linkend="orm-jdo" /></para>
|
|
||||||
|
|
||||||
<section id="orm-jdo-template">
|
|
||||||
<title><classname>JdoTemplate</classname> and
|
|
||||||
<classname>JdoDaoSupport</classname></title>
|
|
||||||
|
|
||||||
<para>Each JDO-based DAO will then receive the
|
|
||||||
<interfacename>PersistenceManagerFactory</interfacename> through
|
|
||||||
dependency injection. Such a DAO could be coded against plain JDO API,
|
|
||||||
working with the given
|
|
||||||
<interfacename>PersistenceManagerFactory</interfacename>, but will
|
|
||||||
usually rather be used with the Spring Framework's
|
|
||||||
<classname>JdoTemplate</classname>:</para>
|
|
||||||
|
|
||||||
<programlisting language="xml"><beans>
|
|
||||||
|
|
||||||
<bean id="myProductDao" class="product.ProductDaoImpl">
|
|
||||||
<property name="persistenceManagerFactory" ref="myPmf"/>
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
</beans></programlisting>
|
|
||||||
|
|
||||||
<programlisting language="java">public class ProductDaoImpl implements ProductDao {
|
|
||||||
|
|
||||||
private JdoTemplate jdoTemplate;
|
|
||||||
|
|
||||||
public void setPersistenceManagerFactory(PersistenceManagerFactory pmf) {
|
|
||||||
this.jdoTemplate = new JdoTemplate(pmf);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Collection loadProductsByCategory(final String category) throws DataAccessException {
|
|
||||||
return (Collection) this.jdoTemplate.execute(new JdoCallback() {
|
|
||||||
public Object doInJdo(PersistenceManager pm) throws JDOException {
|
|
||||||
Query query = pm.newQuery(Product.class, "category = pCategory");
|
|
||||||
query.declareParameters("String pCategory");
|
|
||||||
List result = query.execute(category);
|
|
||||||
<lineannotation>// do some further stuff with the result list</lineannotation>
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}</programlisting>
|
|
||||||
|
|
||||||
<para>A callback implementation can effectively be used for any JDO
|
|
||||||
data access. <classname>JdoTemplate</classname> will ensure that
|
|
||||||
<classname>PersistenceManager</classname>s are properly opened and
|
|
||||||
closed, and automatically participate in transactions. The template
|
|
||||||
instances are thread-safe and reusable, they can thus be kept as
|
|
||||||
instance variables of the surrounding class. For simple single-step
|
|
||||||
actions such as a single <literal>find</literal>,
|
|
||||||
<literal>load</literal>, <literal>makePersistent</literal>, or
|
|
||||||
<literal>delete</literal> call, <classname>JdoTemplate</classname>
|
|
||||||
offers alternative convenience methods that can replace such one line
|
|
||||||
callback implementations. Furthermore, Spring provides a convenient
|
|
||||||
<classname>JdoDaoSupport</classname> base class that provides a
|
|
||||||
<literal>setPersistenceManagerFactory(..)</literal> method for
|
|
||||||
receiving a <classname>PersistenceManagerFactory</classname>, and
|
|
||||||
<methodname>getPersistenceManagerFactory()</methodname> and
|
|
||||||
<methodname>getJdoTemplate()</methodname> for use by subclasses. In
|
|
||||||
combination, this allows for very simple DAO implementations for
|
|
||||||
typical requirements:</para>
|
|
||||||
|
|
||||||
<programlisting language="java">public class ProductDaoImpl extends JdoDaoSupport implements ProductDao {
|
|
||||||
|
|
||||||
public Collection loadProductsByCategory(String category) throws DataAccessException {
|
|
||||||
return getJdoTemplate().find(
|
|
||||||
Product.class, "category = pCategory", "String category", new Object[] {category});
|
|
||||||
}
|
|
||||||
}</programlisting>
|
|
||||||
|
|
||||||
<para>As alternative to working with Spring's
|
|
||||||
<classname>JdoTemplate</classname>, you can also code Spring-based
|
|
||||||
DAOs at the JDO API level, explicitly opening and closing a
|
|
||||||
<interfacename>PersistenceManager</interfacename>. As elaborated in
|
|
||||||
the corresponding Hibernate section, the main advantage of this
|
|
||||||
approach is that your data access code is able to throw checked
|
|
||||||
exceptions. <classname>JdoDaoSupport</classname> offers a variety of
|
|
||||||
support methods for this scenario, for fetching and releasing a
|
|
||||||
transactional <interfacename>PersistenceManager</interfacename> as
|
|
||||||
well as for converting exceptions.</para>
|
|
||||||
</section>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="classic-spring-ibatis">
|
|
||||||
<title>iBATIS</title>
|
|
||||||
|
|
||||||
<para>For the currently recommended usage patterns for iBATIS see <xref
|
|
||||||
linkend="orm-ibatis" /></para>
|
|
||||||
|
|
||||||
<section id="orm-ibatis-template">
|
|
||||||
<title>Using <classname>SqlMapClientTemplate</classname> and
|
|
||||||
<classname>SqlMapClientDaoSupport</classname></title>
|
|
||||||
|
|
||||||
<para>The <classname>SqlMapClientDaoSupport</classname> class offers a
|
|
||||||
supporting class similar to the
|
|
||||||
<classname>SqlMapDaoSupport</classname>. We extend it to implement our
|
|
||||||
DAO:</para>
|
|
||||||
|
|
||||||
<programlisting language="java">public class SqlMapAccountDao extends SqlMapClientDaoSupport implements AccountDao {
|
|
||||||
|
|
||||||
public Account getAccount(String email) throws DataAccessException {
|
|
||||||
return (Account) getSqlMapClientTemplate().queryForObject("getAccountByEmail", email);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void insertAccount(Account account) throws DataAccessException {
|
|
||||||
getSqlMapClientTemplate().update("insertAccount", account);
|
|
||||||
}
|
|
||||||
}</programlisting>
|
|
||||||
|
|
||||||
<para>In the DAO, we use the pre-configured
|
|
||||||
<classname>SqlMapClientTemplate</classname> to execute the queries,
|
|
||||||
after setting up the <literal>SqlMapAccountDao</literal> in the
|
|
||||||
application context and wiring it with our
|
|
||||||
<literal>SqlMapClient</literal> instance:</para>
|
|
||||||
|
|
||||||
<programlisting language="xml"><beans>
|
|
||||||
|
|
||||||
<bean id="accountDao" class="example.SqlMapAccountDao">
|
|
||||||
<property name="sqlMapClient" ref="sqlMapClient"/>
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
</beans></programlisting>
|
|
||||||
|
|
||||||
<para>Note that a <classname>SqlMapTemplate</classname> instance could
|
|
||||||
also be created manually, passing in the
|
|
||||||
<literal>SqlMapClient</literal> as constructor argument. The
|
|
||||||
<literal>SqlMapClientDaoSupport</literal> base class simply
|
|
||||||
pre-initializes a <classname>SqlMapClientTemplate</classname> instance
|
|
||||||
for us.</para>
|
|
||||||
|
|
||||||
<para>The <classname>SqlMapClientTemplate</classname> also offers a
|
|
||||||
generic <literal>execute</literal> method, taking a custom
|
|
||||||
<literal>SqlMapClientCallback</literal> implementation as argument.
|
|
||||||
This can, for example, be used for batching:</para>
|
|
||||||
|
|
||||||
<programlisting language="java">public class SqlMapAccountDao extends SqlMapClientDaoSupport implements AccountDao {
|
|
||||||
|
|
||||||
public void insertAccount(Account account) throws DataAccessException {
|
|
||||||
getSqlMapClientTemplate().execute(new SqlMapClientCallback() {
|
|
||||||
public Object doInSqlMapClient(SqlMapExecutor executor) throws SQLException {
|
|
||||||
executor.startBatch();
|
|
||||||
executor.update("insertAccount", account);
|
|
||||||
executor.update("insertAddress", account.getAddress());
|
|
||||||
executor.executeBatch();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}</programlisting>
|
|
||||||
|
|
||||||
<para>In general, any combination of operations offered by the native
|
|
||||||
<literal>SqlMapExecutor</literal> API can be used in such a callback.
|
|
||||||
Any <literal>SQLException</literal> thrown will automatically get
|
|
||||||
converted to Spring's generic
|
|
||||||
<classname>DataAccessException</classname> hierarchy.</para>
|
|
||||||
</section>
|
|
||||||
</section>
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section id="clasic-spring-mvc">
|
<section id="clasic-spring-mvc">
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue