-
Notifications
You must be signed in to change notification settings - Fork 212
/
Copy pathspringBatch.html
180 lines (169 loc) · 11.2 KB
/
springBatch.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
<!DOCTYPE html>
<!--
| Generated by Apache Maven Doxia Site Renderer 2.0.0-M18 from src/site/markdown/docs/springBatch.md at 03 Jun 2024
| Rendered using Apache Maven Fluido Skin 2.0.0-M9
-->
<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="generator" content="Apache Maven Doxia Site Renderer 2.0.0-M18" />
<title>MyBatis Dynamic SQL</title>
<link rel="stylesheet" href="../css/apache-maven-fluido-2.0.0-M9.min.css" />
<link rel="stylesheet" href="../css/site.css" />
<link rel="stylesheet" href="../css/print.css" media="print" />
<script src="../js/apache-maven-fluido-2.0.0-M9.min.js"></script>
</head>
<body>
<div class="container-fluid container-fluid-top">
<header>
<div id="banner">
<div class="pull-left"><div id="bannerLeft"><h1><a href="../docs/introduction.html">MyBatis Dynamic SQL</a></h1></div></div>
<div class="pull-right"><div id="bannerRight"><h1><a href="http://www.mybatis.org/" class="externalLink"><img class="imageLink" src="https://mybatis.org/images/mybatis-logo.png" alt="MyBatis logo" /> MyBatis</a></h1></div></div>
<div class="clear"><hr/></div>
</div>
<div id="breadcrumbs">
<ul class="breadcrumb">
<li id="publishDate">Last Published: 03 Jun 2024<span class="divider">|</span>
</li>
<li id="projectVersion">Version: 1.5.2</li>
</ul>
</div>
</header>
<div class="row-fluid">
<header id="leftColumn" class="span2">
<nav class="well sidebar-nav">
<ul class="nav nav-list">
<li class="nav-header">User's Guide</li>
<li><a href="../docs/introduction.html">Introduction</a></li>
<li><a href="../docs/CHANGELOG.html">Change Log</a></li>
<li><a href="../docs/quickStart.html">Quick Start</a></li>
<li><a href="../docs/exceptions.html">Exceptions thrown by the Library</a></li>
<li><a href="../docs/configuration.html">Configuration of the Library</a></li>
<li><a href="../docs/databaseObjects.html">Modeling Database Objects</a></li>
<li><a href="../docs/whereClauses.html"><span class="icon-chevron-down"></span>WHERE Clause Support</a>
<ul class="nav nav-list">
<li><a href="../docs/conditions.html">WHERE Conditions</a></li>
</ul></li>
<li><a href="../docs/select.html"><span class="icon-chevron-down"></span>SELECT Statements</a>
<ul class="nav nav-list">
<li><a href="../docs/caseExpressions.html">Case Expressions</a></li>
<li><a href="../docs/complexQueries.html">Complex Queries</a></li>
</ul></li>
<li><a href="../docs/delete.html">DELETE Statements</a></li>
<li><a href="../docs/insert.html">INSERT Statements</a></li>
<li><a href="../docs/update.html">UPDATE Statements</a></li>
<li><a href="../docs/subQueries.html">SubQuery Support</a></li>
<li><a href="../docs/functions.html">Database Functions</a></li>
<li><a href="../docs/mybatis3.html">MyBatis3 Support</a></li>
<li><a href="../docs/spring.html">Spring Support</a></li>
<li class="active"><a>Spring Batch Support</a></li>
<li><a href="../docs/kotlinOverview.html"><span class="icon-chevron-right"></span>Kotlin Support</a></li>
<li><a href="../docs/howItWorks.html">How it Works</a></li>
<li><a href="../docs/extending.html">Extending the Library</a></li>
<li><a href="../docs/codingStandards.html">Coding Standards</a></li>
<li><a href="../docs/motivation.html">Motivation</a></li>
<li class="nav-header">Project Documentation</li>
<li><a href="../project-info.html"><span class="icon-chevron-right"></span>Project Information</a></li>
<li><a href="../project-reports.html"><span class="icon-chevron-right"></span>Project Reports</a></li>
</ul>
</nav>
<div class="well sidebar-nav">
<div id="poweredBy">
<div class="clear"></div>
<div class="clear"></div>
<a href="https://maven.apache.org/" class="builtBy" target="_blank"><img class="builtBy" alt="Built by Maven" src="../images/logos/maven-feather.png" /></a>
</div>
</div>
</header>
<main id="bodyColumn" class="span10">
<section><a id="Spring_Batch_Support"></a>
<h1>Spring Batch Support</h1>
<p>This library provides some utilities to make it easier to interact with the MyBatis Spring Batch support.</p><section><a id="The_Problem"></a>
<h2>The Problem</h2>
<p>MyBatis Spring support provides utility classes for interacting with Spring Batch (see <a href="http://www.mybatis.org/spring/batch.html" class="externalLink">http://www.mybatis.org/spring/batch.html</a>). These classes are specialized implementations of Spring Batch's <code>ItemReader</code> and <code>ItemWriter</code> interfaces that have support for MyBatis mappers.</p>
<p>The <code>ItemWriter</code> implementations work with SQL generated by MyBatis Dynamic SQL with no modification needed.</p>
<p>The <code>ItemReader</code> implementations need special care. Those classes assume that all query parameters will be placed in a Map (as per usual when using multiple parameters in a query). MyBatis Dynamic SQL, by default, builds a parameter object that should be the only parameter in a query and will not work when placed in a Map of parameters.</p></section><section><a id="The_Solution"></a>
<h2>The Solution</h2>
<p>The solution involves these steps:</p>
<ol style="list-style-type: decimal;">
<li>The SQL must be rendered such that the parameter markers are aware of the enclosing parameter Map in the <code>ItemReader</code></li>
<li>The <code>SelectStatementProvider</code> must be placed in the <code>ItemReader</code> parameter Map with a known key.</li>
<li>The <code>@SelectProvider</code> must be configured to be aware of the enclosing parameter Map</li>
</ol>
<p>MyBatis Dynamic SQL provides utilities for each of these requirements. Each utility uses a shared Map key for consistency.</p></section><section><a id="Spring_Batch_Item_Readers"></a>
<h2>Spring Batch Item Readers</h2>
<p>MyBatis Spring support supplies two implementations of the <code>ItemReader</code> interface:</p>
<ol style="list-style-type: decimal;">
<li><code>org.mybatis.spring.batch.MyBatisCursorItemReader</code> - for queries that can be efficiently processed through a single select statement and a cursor</li>
<li><code>org.mybatis.spring.batch.MyBatisPagingItemReader</code> - for queries that should be processed as a series of paged selects. Note that MyBatis does not provide any native support for paged queries - it is up to the user to write SQL for paging. The <code>MyBatisPagingItemWriter</code> simply makes properties available that specify which page should be read currently.</li>
</ol>
<p>MyBatis Dynamic SQL supplies specialized select statements that will render properly for the different implementations of <code>ItemReader</code>:</p>
<ol style="list-style-type: decimal;">
<li><code>SpringBatchUtility.selectForCursor(...)</code> will create a select statement that is appropriate for the <code>MyBatisCursorItemReader</code> - a single select statement that will be read with a cursor</li>
<li><code>SpringBatchUtility.selectForPaging(...)</code> will create a select statement that is appropriate for the <code>MyBatisPagingItemReader</code> - a select statement that will be called multiple times - one for each page as configured on the batch job.</li>
</ol>
<p><strong>Very Important:</strong> The paging implementation will only work for databases that support limit and offset in select statements. Fortunately, most databases do support this - with the notable exception of Oracle.</p><section><a id="Rendering_for_Cursor"></a>
<h3>Rendering for Cursor</h3>
<p>Queries intended for the <code>MyBatisCursorItemReader</code> should be rendered as follows:</p>
<pre><code class="language-java"> SelectStatementProvider selectStatement = SpringBatchUtility.selectForCursor(person.allColumns())
.from(person)
.where(lastName, isEqualTo("flintstone"))
.build()
.render(); // renders for MyBatisCursorItemReader
</code></pre></section><section><a id="Rendering_for_Paging"></a>
<h3>Rendering for Paging</h3>
<p>Queries intended for the <code>MyBatisPagingItemReader</code> should be rendered as follows:</p>
<pre><code class="language-java"> SelectStatementProvider selectStatement = SpringBatchUtility.selectForPaging(person.allColumns())
.from(person)
.where(lastName, isEqualTo("flintstone"))
.build()
.render(); // renders for MyBatisPagingItemReader
</code></pre></section></section><section><a id="Creating_the_Parameter_Map"></a>
<h2>Creating the Parameter Map</h2>
<p>The <code>SpringBatchUtility</code> provides a method to create the parameter values Map needed by the MyBatis Spring <code>ItemReader</code> implementations. It can be used as follows:</p>
<p>For cursor based queries…</p>
<pre><code class="language-java"> MyBatisCursorItemReader<Person> reader = new MyBatisCursorItemReader<>();
reader.setQueryId(PersonMapper.class.getName() + ".selectMany");
reader.setSqlSessionFactory(sqlSessionFactory);
reader.setParameterValues(SpringBatchUtility.toParameterValues(selectStatement)); // create parameter map
</code></pre>
<p>For paging based queries…</p>
<pre><code class="language-java"> MyBatisPagingItemReader<Person> reader = new MyBatisPagingItemReader<>();
reader.setQueryId(PersonMapper.class.getName() + ".selectMany");
reader.setSqlSessionFactory(sqlSessionFactory);
reader.setPageSize(7);
reader.setParameterValues(SpringBatchUtility.toParameterValues(selectStatement)); // create parameter map
</code></pre></section><section><a id="Specialized_.40SelectProvider_Adapter"></a>
<h2>Specialized @SelectProvider Adapter</h2>
<p>MyBatis mapper methods should be configured to use the specialized <code>@SelectProvider</code> adapter as follows:</p>
<pre><code class="language-java"> @SelectProvider(type=SpringBatchProviderAdapter.class, method="select") // use the Spring batch adapter
@Results({
@Result(column="id", property="id", id=true),
@Result(column="first_name", property="firstName"),
@Result(column="last_name", property="lastName")
})
List<Person> selectMany(Map<String, Object> parameterValues);
</code></pre></section><section><a id="Complete_Example"></a>
<h2>Complete Example</h2>
<p>The unit tests for MyBatis Dynamic SQL include a complete example of using MyBatis Spring Batch support using the MyBatis supplied reader as well as both types of MyBatis supplied writers. You can see the full example here: <a href="https://github.com/mybatis/mybatis-dynamic-sql/tree/master/src/test/java/examples/springbatch" class="externalLink">https://github.com/mybatis/mybatis-dynamic-sql/tree/master/src/test/java/examples/springbatch</a></p></section></section>
</main>
</div>
</div>
<hr/>
<footer>
<div class="container-fluid">
<div class="row-fluid">
<p>© 2016–2024
<a href="https://www.mybatis.org/">MyBatis.org</a>
</p>
</div>
</div>
</footer>
<script>
if(anchors) {
anchors.add();
}
</script>
</body>
</html>