camel-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From conflue...@apache.org
Subject [CONF] Apache Camel > MyBatis
Date Fri, 06 Apr 2012 08:12:00 GMT
<html>
<head>
    <base href="https://cwiki.apache.org/confluence">
            <link rel="stylesheet" href="/confluence/s/2042/9/1/_/styles/combined.css?spaceKey=CAMEL&amp;forWysiwyg=true"
type="text/css">
    </head>
<body style="background: white;" bgcolor="white" class="email-body">
<div id="pageContent">
<div id="notificationFormat">
<div class="wiki-content">
<div class="email">
    <h2><a href="https://cwiki.apache.org/confluence/display/CAMEL/MyBatis">MyBatis</a></h2>
    <h4>Page <b>edited</b> by             <a href="https://cwiki.apache.org/confluence/display/~davsclaus">Claus
Ibsen</a>
    </h4>
        <br/>
                         <h4>Changes (3)</h4>
                                 
    
<div id="page-diffs">
                    <table class="diff" cellpadding="0" cellspacing="0">
    
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >| {{consumer.useIterator}} | {{boolean}}
| {{true}} | If {{true}} each row returned when polling will be processed individually. If
{{false}} the entire {{List}} of data is set as the IN body. | <br>| {{consumer.routeEmptyResultSet}}
| {{boolean}} | {{false}} | Sets whether empty result set should be routed or not. By default,
empty result sets are not routed. | <br></td></tr>
            <tr><td class="diff-changed-lines" >| {{statementType}} | {{StatementType}}
| {{null}} | Mandatory to specify for producer to control which kind of operation to invoke.
The enum values are: {{SelectOne}}, {{SelectList}}, {{Insert}}, <span class="diff-added-words"style="background-color:
#dfd;">{{InsertList}},</span> {{Update}}, {{Delete}}. <span class="diff-added-words"style="background-color:
#dfd;">*Notice:* {{InsertList}} is available as of Camel 2.10.</span> | <br></td></tr>
            <tr><td class="diff-unchanged" >| {{maxMessagesPerPoll}} | {{int}}
| {{0}} | An integer to define a maximum messages to gather per poll. By default, no maximum
is set. Can be used to set a limit of e.g. 1000 to avoid when starting up the server that
there are thousands of files. Set a value of 0 or negative to disabled it. | <br>{div}
<br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >{snippet:id=e1|lang=java|url=camel/trunk/components/camel-mybatis/src/test/java/org/apache/camel/component/mybatis/MyBatisUpdateTest.java}
<br> <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">h4.
Using InsertList StatementType <br>*Available as of Camel 2.10* <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">MyBatis
allows you to insert multiple rows using its for-each batch driver. To use this, you need
to use the &lt;for-each&gt; in the mapper XML file. For example as shown below: <br>{snippet:id=insertList|lang=xml|url=camel/trunk/components/camel-mybatis/src/test/resources/org/apache/camel/component/mybatis/Account.xml}
<br> <br>Then you can insert multiple rows, by sending a Camel message to the
{{mybatis}} endpoint which uses the {{InsertList}} statement type, as shown below: <br>{snippet:id=e1|lang=java|url=camel/trunk/components/camel-mybatis/src/test/java/org/apache/camel/component/mybatis/MyBatisInsertListTest.java}
<br> <br> <br></td></tr>
            <tr><td class="diff-unchanged" >h4. Scheduled polling example <br>Since
this component does not support scheduled polling, you need to use another mechanism for triggering
the scheduled polls, such as the [Timer] or [Quartz] components. <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
    
            </table>
    </div>                            <h4>Full Content</h4>
                    <div class="notificationGreySide">
        <h2><a name="MyBatis-MyBatis"></a>MyBatis</h2>
<p><b>Available as of Camel 2.7</b></p>

<p>The <b>mybatis:</b> component allows you to query, poll, insert, update
and delete data in a relational database using <a href="http://mybatis.org/" class="external-link"
rel="nofollow">MyBatis</a>.</p>

<p>Maven users will need to add the following dependency to their <tt>pom.xml</tt>
for this component:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
<span class="code-tag">&lt;dependency&gt;</span>
    <span class="code-tag">&lt;groupId&gt;</span>org.apache.camel<span
class="code-tag">&lt;/groupId&gt;</span>
    <span class="code-tag">&lt;artifactId&gt;</span>camel-mybatis<span
class="code-tag">&lt;/artifactId&gt;</span>
    <span class="code-tag">&lt;version&gt;</span>x.x.x<span class="code-tag">&lt;/version&gt;</span>
    <span class="code-tag"><span class="code-comment">&lt;!-- use the same
version as your Camel core version --&gt;</span></span>
<span class="code-tag">&lt;/dependency&gt;</span>
</pre>
</div></div>

<h3><a name="MyBatis-URIformat"></a>URI format</h3>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
mybatis:statementName[?options]
</pre>
</div></div>

<p>Where <b>statementName</b> is the statement name in the MyBatis XML mapping
file which maps to the query, insert, update or delete operation you wish to evaluate.</p>

<p>You can append query options to the URI in the following format, <tt>?option=value&amp;option=value&amp;...</tt></p>

<p>This component will by default load the MyBatis SqlMapConfig file from the root of
the classpath and expected named as <tt>SqlMapConfig.xml</tt>.<br/>
If the file is located in another location, you would have to configure the <tt>configurationUri</tt>
option on the <tt>MyBatisComponent</tt> component.</p>

<h3><a name="MyBatis-Options"></a>Options</h3>
<div class="confluenceTableSmall"><div class='table-wrap'>
<table class='confluenceTable'><tbody>
<tr>
<th class='confluenceTh'> Option </th>
<th class='confluenceTh'> Type </th>
<th class='confluenceTh'> Default </th>
<th class='confluenceTh'> Description </th>
</tr>
<tr>
<td class='confluenceTd'> <tt>consumer.onConsume</tt> </td>
<td class='confluenceTd'> <tt>String</tt> </td>
<td class='confluenceTd'> <tt>null</tt> </td>
<td class='confluenceTd'> Statements to run after consuming. Can be used, for example,
to update rows after they have been consumed and processed in Camel. See sample later. Multiple
statements can be separated with comma. </td>
</tr>
<tr>
<td class='confluenceTd'> <tt>consumer.useIterator</tt> </td>
<td class='confluenceTd'> <tt>boolean</tt> </td>
<td class='confluenceTd'> <tt>true</tt> </td>
<td class='confluenceTd'> If <tt>true</tt> each row returned when polling
will be processed individually. If <tt>false</tt> the entire <tt>List</tt>
of data is set as the IN body. </td>
</tr>
<tr>
<td class='confluenceTd'> <tt>consumer.routeEmptyResultSet</tt> </td>
<td class='confluenceTd'> <tt>boolean</tt> </td>
<td class='confluenceTd'> <tt>false</tt> </td>
<td class='confluenceTd'> Sets whether empty result set should be routed or not. By
default, empty result sets are not routed. </td>
</tr>
<tr>
<td class='confluenceTd'> <tt>statementType</tt> </td>
<td class='confluenceTd'> <tt>StatementType</tt> </td>
<td class='confluenceTd'> <tt>null</tt> </td>
<td class='confluenceTd'> Mandatory to specify for producer to control which kind of
operation to invoke. The enum values are: <tt>SelectOne</tt>, <tt>SelectList</tt>,
<tt>Insert</tt>, <tt>InsertList</tt>, <tt>Update</tt>,
<tt>Delete</tt>. <b>Notice:</b> <tt>InsertList</tt> is
available as of Camel 2.10. </td>
</tr>
<tr>
<td class='confluenceTd'> <tt>maxMessagesPerPoll</tt> </td>
<td class='confluenceTd'> <tt>int</tt> </td>
<td class='confluenceTd'> <tt>0</tt> </td>
<td class='confluenceTd'> An integer to define a maximum messages to gather per poll.
By default, no maximum is set. Can be used to set a limit of e.g. 1000 to avoid when starting
up the server that there are thousands of files. Set a value of 0 or negative to disabled
it. </td>
</tr>
</tbody></table>
</div>
</div>

<h3><a name="MyBatis-MessageHeaders"></a>Message Headers</h3>
<p>Camel will populate the result message, either IN or OUT with a header with the statement
used:</p>
<div class="confluenceTableSmall"><div class='table-wrap'>
<table class='confluenceTable'><tbody>
<tr>
<th class='confluenceTh'> Header </th>
<th class='confluenceTh'> Type </th>
<th class='confluenceTh'> Description </th>
</tr>
<tr>
<td class='confluenceTd'> <tt>CamelMyBatisStatementName</tt> </td>
<td class='confluenceTd'> <tt>String</tt> </td>
<td class='confluenceTd'> The <b>statementName</b> used (for example: insertAccount).
</td>
</tr>
<tr>
<td class='confluenceTd'> <tt>CamelMyBatisResult</tt> </td>
<td class='confluenceTd'> <tt>Object</tt> </td>
<td class='confluenceTd'> The <b>response</b> returned from MtBatis in any
of the operations. For instance an <tt>INSERT</tt> could return the auto-generated
key, or number of rows etc. </td>
</tr>
</tbody></table>
</div>
</div>

<h3><a name="MyBatis-MessageBody"></a>Message Body</h3>
<p>The response from MyBatis will only be set as body if it's a <tt>SELECT</tt>
statement. That means, for example, for <tt>INSERT</tt> statements Camel will
not replace the body. This allows you to continue routing and keep the original body. The
response from MyBatis is always stored in the header with the key <tt>CamelMyBatisResult</tt>.</p>

<h3><a name="MyBatis-Samples"></a>Samples</h3>

<p>For example if you wish to consume beans from a JMS queue and insert them into a
database you could do the following:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
from(<span class="code-quote">"activemq:queue:newAccount"</span>).
  to(<span class="code-quote">"mybatis:insertAccount?statementType=Insert"</span>);
</pre>
</div></div>

<p>Notice we have to specify the <tt>statementType</tt>, as we need to instruct
Camel which kind of operation to invoke.</p>

<p>Where <b>insertAccount</b> is the MyBatis ID in the SQL mapping file:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
  <span class="code-tag"><span class="code-comment">&lt;!-- Insert example,
using the Account parameter class --&gt;</span></span>
  <span class="code-tag">&lt;insert id=<span class="code-quote">"insertAccount"</span>
parameterType=<span class="code-quote">"Account"</span>&gt;</span>
    insert into ACCOUNT (
      ACC_ID,
      ACC_FIRST_NAME,
      ACC_LAST_NAME,
      ACC_EMAIL
    )
    values (
      #{id}, #{firstName}, #{lastName}, #{emailAddress}
    )
  <span class="code-tag">&lt;/insert&gt;</span>
</pre>
</div></div>

<h3><a name="MyBatis-UsingStatementTypeforbettercontrolofMyBatis"></a>Using
StatementType for better control of MyBatis</h3>
<p>When routing to an MyBatis endpoint you want more fine grained control so you can
control whether the SQL statement to be executed is a <tt>SELEECT</tt>, <tt>UPDATE</tt>,
<tt>DELETE</tt> or <tt>INSERT</tt> etc. So for instance if we want
to route to an MyBatis endpoint in which the IN body contains parameters to a <tt>SELECT</tt>
statement we can do:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">from(<span class="code-quote">"direct:start"</span>)
    .to(<span class="code-quote">"mybatis:selectAccountById?statementType=SelectOne"</span>)
    .to(<span class="code-quote">"mock:result"</span>);
</pre>
</div></div>

<p>In the code above we can invoke the MyBatis statement <tt>selectAccountById</tt>
and the IN body should contain the account id we want to retrieve, such as an <tt>Integer</tt>
type.</p>

<p>We can do the same for some of the other operations, such as <tt>SelectList</tt>:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">from(<span class="code-quote">"direct:start"</span>)
    .to(<span class="code-quote">"mybatis:selectAllAccounts?statementType=SelectList"</span>)
    .to(<span class="code-quote">"mock:result"</span>);
</pre>
</div></div>

<p>And the same for <tt>UPDATE</tt>, where we can send an <tt>Account</tt>
object as IN body to MyBatis:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">from(<span class="code-quote">"direct:start"</span>)
    .to(<span class="code-quote">"mybatis:updateAccount?statementType=Update"</span>)
    .to(<span class="code-quote">"mock:result"</span>);
</pre>
</div></div>

<h4><a name="MyBatis-UsingInsertListStatementType"></a>Using InsertList
StatementType</h4>
<p><b>Available as of Camel 2.10</b></p>

<p>MyBatis allows you to insert multiple rows using its for-each batch driver. To use
this, you need to use the &lt;for-each&gt; in the mapper XML file. For example as
shown below:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml"><span class="code-tag"><span class="code-comment">&lt;!--
Batch Insert example, using the Account parameter class --&gt;</span></span>
<span class="code-tag">&lt;insert id=<span class="code-quote">"batchInsertAccount"</span>
parameterType=<span class="code-quote">"java.util.List"</span>&gt;</span>
    insert into ACCOUNT (
    ACC_ID,
    ACC_FIRST_NAME,
    ACC_LAST_NAME,
    ACC_EMAIL
    )
    values (
    <span class="code-tag">&lt;foreach item=<span class="code-quote">"Account"</span>
collection=<span class="code-quote">"list"</span> open=<span class="code-quote">""
close="</span><span class="code-quote">" separator="</span>),("&gt;</span>
        #{Account.id}, #{Account.firstName}, #{Account.lastName}, #{Account.emailAddress}
    <span class="code-tag">&lt;/foreach&gt;</span>
    )
<span class="code-tag">&lt;/insert&gt;</span>
</pre>
</div></div>

<p>Then you can insert multiple rows, by sending a Camel message to the <tt>mybatis</tt>
endpoint which uses the <tt>InsertList</tt> statement type, as shown below:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">from(<span class="code-quote">"direct:start"</span>)
    .to(<span class="code-quote">"mybatis:batchInsertAccount?statementType=InsertList"</span>)
    .to(<span class="code-quote">"mock:result"</span>);
</pre>
</div></div>


<h4><a name="MyBatis-Scheduledpollingexample"></a>Scheduled polling example</h4>
<p>Since this component does not support scheduled polling, you need to use another
mechanism for triggering the scheduled polls, such as the <a href="/confluence/display/CAMEL/Timer"
title="Timer">Timer</a> or <a href="/confluence/display/CAMEL/Quartz" title="Quartz">Quartz</a>
components.</p>

<p>In the sample below we poll the database, every 30 seconds using the <a href="/confluence/display/CAMEL/Timer"
title="Timer">Timer</a> component and send the data to the JMS queue:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
from(<span class="code-quote">"timer:<span class="code-comment">//pollTheDatabase?delay=30000"</span>).to(<span
class="code-quote">"mbatis:selectAllAccounts"</span>).to(<span class="code-quote">"activemq:queue:allAccounts"</span>);</span>
</pre>
</div></div>

<p>And the MyBatis SQL mapping file used:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
  <span class="code-tag"><span class="code-comment">&lt;!-- Select with no
parameters using the result map for Account class. --&gt;</span></span>
  <span class="code-tag">&lt;select id=<span class="code-quote">"selectAllAccounts"</span>
resultMap=<span class="code-quote">"AccountResult"</span>&gt;</span>
    select * from ACCOUNT
  <span class="code-tag">&lt;/select&gt;</span>
</pre>
</div></div>

<h4><a name="MyBatis-UsingonConsume"></a>Using onConsume</h4>
<p>This component supports executing statements <b>after</b> data have been
consumed and processed by Camel. This allows you to do post updates in the database. Notice
all statements must be <tt>UPDATE</tt> statements. Camel supports executing multiple
statements whose name should be separated by comma.</p>

<p>The route below illustrates we execute the <b>consumeAccount</b> statement
data is processed. This allows us to change the status of the row in the database to processed,
so we avoid consuming it twice or more.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">from(<span class="code-quote">"mybatis:selectUnprocessedAccounts?consumer.onConsume=consumeAccount"</span>).to(<span
class="code-quote">"mock:results"</span>);
</pre>
</div></div>

<p>And the statements in the sqlmap file:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml"><span class="code-tag">&lt;select id=<span class="code-quote">"selectUnprocessedAccounts"</span>
resultMap=<span class="code-quote">"AccountResult"</span>&gt;</span>
    select * from ACCOUNT where PROCESSED = false
<span class="code-tag">&lt;/select&gt;</span>
</pre>
</div></div>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml"><span class="code-tag">&lt;update id=<span class="code-quote">"consumeAccount"</span>
parameterType=<span class="code-quote">"Account"</span>&gt;</span>
    update ACCOUNT set PROCESSED = true where ACC_ID = #{id}
<span class="code-tag">&lt;/update&gt;</span>
</pre>
</div></div>

<h3><a name="MyBatis-SeeAlso"></a>See Also</h3>
<ul>
	<li><a href="/confluence/display/CAMEL/Configuring+Camel" title="Configuring Camel">Configuring
Camel</a></li>
	<li><a href="/confluence/display/CAMEL/Component" title="Component">Component</a></li>
	<li><a href="/confluence/display/CAMEL/Endpoint" title="Endpoint">Endpoint</a></li>
	<li><a href="/confluence/display/CAMEL/Getting+Started" title="Getting Started">Getting
Started</a></li>
</ul>

    </div>
        <div id="commentsSection" class="wiki-content pageSection">
        <div style="float: right;">
            <a href="https://cwiki.apache.org/confluence/users/viewnotifications.action"
class="grey">Change Notification Preferences</a>
        </div>
        <a href="https://cwiki.apache.org/confluence/display/CAMEL/MyBatis">View Online</a>
        |
        <a href="https://cwiki.apache.org/confluence/pages/diffpagesbyversion.action?pageId=25202095&revisedVersion=2&originalVersion=1">View
Changes</a>
                |
        <a href="https://cwiki.apache.org/confluence/display/CAMEL/MyBatis?showComments=true&amp;showCommentArea=true#addcomment">Add
Comment</a>
            </div>
</div>
</div>
</div>
</div>
</body>
</html>

Mime
View raw message