jdbc.html 140.0 KB
Newer Older
茶陵後's avatar
茶陵後 已提交
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 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586
<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>JDBC Support | Spring Docs</title>
    <meta name="generator" content="VuePress 1.9.7">
    <link rel="icon" type="image/png" sizes="16x16" href="/images/icons/favicon.ico">
    <link rel="icon" type="image/png" sizes="48x48" href="/images/icons/icon-48x48.png">
    <link rel="icon" type="image/png" sizes="72x72" href="/images/icons/icon-72x72.png">
    <link rel="manifest" href="/manifest.webmanifest">
    <link rel="apple-touch-icon" href="/images/icons/icon_48x48.png">
    <link rel="mask-icon" href="/images/icons/favicon.ico" color="#5dac38">
    <script>
    var _hmt = _hmt || [];
    (function () {
      var hm = document.createElement("script");
      hm.src = "https://hm.baidu.com/hm.js?8eefd6b163dcb3f5762af6b0825e2dd1";
      var s = document.getElementsByTagName("script")[0];
      s.parentNode.insertBefore(hm, s);
    })();
    </script>
    <meta name="description" content="Spring Integration provides channel adapters for receiving and sending messages by using database queries.
Through those adapters, Spring Integration supports not only plain JDBC SQL queries but also stored procedure and stored function calls.">
    <meta name="twitter:title" content="JDBC Support">
    <meta name="twitter:description" content="Spring Integration provides channel adapters for receiving and sending messages by using database queries.
Through those adapters, Spring Integration supports not only plain JDBC SQL queries but also stored procedure and stored function calls.">
    <meta name="twitter:card" content="summary">
    <meta name="twitter:url" content="https://spring.gitcode.net/en/spring-integration/jdbc.html">
    <meta property="og:type" content="article">
    <meta property="og:title" content="JDBC Support">
    <meta property="og:description" content="Spring Integration provides channel adapters for receiving and sending messages by using database queries.
Through those adapters, Spring Integration supports not only plain JDBC SQL queries but also stored procedure and stored function calls.">
    <meta property="og:url" content="https://spring.gitcode.net/en/spring-integration/jdbc.html">
    <meta property="og:site_name" content="Spring 中文文档社区">
    <meta itemprop="name" content="JDBC Support">
    <meta itemprop="description" content="Spring Integration provides channel adapters for receiving and sending messages by using database queries.
Through those adapters, Spring Integration supports not only plain JDBC SQL queries but also stored procedure and stored function calls.">
    <meta name="application-name" content="Spring 中文文档社区">
    <meta name="apple-mobile-web-app-title" content="Spring 中文社区">
    <meta name="apple-mobile-web-app-status-bar-style" content="black">
    <meta name="msapplication-TileColor" content="#5dac38">
    <meta name="theme-color" content="#5dac38">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="baidu-site-verification" content="code-tApgxyb9G8">
    
    <link rel="preload" href="/assets/css/0.styles.af3770e9.css" as="style"><link rel="preload" href="/assets/js/app.cf11b18e.js" as="script"><link rel="preload" href="/assets/js/3.50918073.js" as="script"><link rel="preload" href="/assets/js/4.cd4c3ff4.js" as="script"><link rel="preload" href="/assets/js/119.5a4712e9.js" as="script"><link rel="prefetch" href="/assets/js/10.675f4d7e.js"><link rel="prefetch" href="/assets/js/100.89ddf0f9.js"><link rel="prefetch" href="/assets/js/101.a2584c55.js"><link rel="prefetch" href="/assets/js/102.53225958.js"><link rel="prefetch" href="/assets/js/103.be06048d.js"><link rel="prefetch" href="/assets/js/104.a2328e06.js"><link rel="prefetch" href="/assets/js/105.78529341.js"><link rel="prefetch" href="/assets/js/106.fc779386.js"><link rel="prefetch" href="/assets/js/107.375c8dec.js"><link rel="prefetch" href="/assets/js/108.cf4ca7e2.js"><link rel="prefetch" href="/assets/js/109.f4d3964d.js"><link rel="prefetch" href="/assets/js/11.b58e279a.js"><link rel="prefetch" href="/assets/js/110.4ae56c4d.js"><link rel="prefetch" href="/assets/js/111.baf7121d.js"><link rel="prefetch" href="/assets/js/112.a963ade8.js"><link rel="prefetch" href="/assets/js/113.edbb458c.js"><link rel="prefetch" href="/assets/js/114.7e2b354f.js"><link rel="prefetch" href="/assets/js/115.4e41285c.js"><link rel="prefetch" href="/assets/js/116.1ee84ed6.js"><link rel="prefetch" href="/assets/js/117.4952cce2.js"><link rel="prefetch" href="/assets/js/118.306eabfa.js"><link rel="prefetch" href="/assets/js/12.c41ab7bc.js"><link rel="prefetch" href="/assets/js/120.496c9660.js"><link rel="prefetch" href="/assets/js/121.e4a22135.js"><link rel="prefetch" href="/assets/js/122.02f82a94.js"><link rel="prefetch" href="/assets/js/123.53c5a24e.js"><link rel="prefetch" href="/assets/js/124.11d8be3e.js"><link rel="prefetch" href="/assets/js/125.c0740874.js"><link rel="prefetch" href="/assets/js/126.9cb2911c.js"><link rel="prefetch" href="/assets/js/127.6f87a638.js"><link rel="prefetch" href="/assets/js/128.456206df.js"><link rel="prefetch" href="/assets/js/129.ce51dc7d.js"><link rel="prefetch" href="/assets/js/13.1147a447.js"><link rel="prefetch" href="/assets/js/130.66718f4c.js"><link rel="prefetch" href="/assets/js/131.713226b7.js"><link rel="prefetch" href="/assets/js/132.6e2b68e3.js"><link rel="prefetch" href="/assets/js/133.11148e38.js"><link rel="prefetch" href="/assets/js/134.8de25763.js"><link rel="prefetch" href="/assets/js/135.961f6693.js"><link rel="prefetch" href="/assets/js/136.8abc4532.js"><link rel="prefetch" href="/assets/js/137.331bfb6b.js"><link rel="prefetch" href="/assets/js/138.f76ee7b9.js"><link rel="prefetch" href="/assets/js/139.578aa70e.js"><link rel="prefetch" href="/assets/js/14.1c437f54.js"><link rel="prefetch" href="/assets/js/140.9f1f28a0.js"><link rel="prefetch" href="/assets/js/141.b08ac1ec.js"><link rel="prefetch" href="/assets/js/142.e5c934cf.js"><link rel="prefetch" href="/assets/js/143.2a9d47c6.js"><link rel="prefetch" href="/assets/js/144.76090f65.js"><link rel="prefetch" href="/assets/js/145.41a54d41.js"><link rel="prefetch" href="/assets/js/146.979b34c1.js"><link rel="prefetch" href="/assets/js/147.46e366af.js"><link rel="prefetch" href="/assets/js/148.efcd2b17.js"><link rel="prefetch" href="/assets/js/149.04135c0b.js"><link rel="prefetch" href="/assets/js/15.cbd21f6a.js"><link rel="prefetch" href="/assets/js/150.679d76bf.js"><link rel="prefetch" href="/assets/js/151.2b0748da.js"><link rel="prefetch" href="/assets/js/152.cee5bbcd.js"><link rel="prefetch" href="/assets/js/153.680b4156.js"><link rel="prefetch" href="/assets/js/154.0c6972fe.js"><link rel="prefetch" href="/assets/js/155.35a3e5ab.js"><link rel="prefetch" href="/assets/js/156.6782d874.js"><link rel="prefetch" href="/assets/js/157.b9fe2583.js"><link rel="prefetch" href="/assets/js/158.96656194.js"><link rel="prefetch" href="/assets/js/159.2a0f7744.js"><link rel="prefetch" href="/assets/js/16.0cc4679e.js"><link rel="prefetch" href="/assets/js/160.c26bf909.js"><link rel="prefetch" href="/assets/js/161.45a3950a.js"><link rel="prefetch" href="/assets/js/162.4a08c069.js"><link rel="prefetch" href="/assets/js/163.a540d00c.js"><link rel="prefetch" href="/assets/js/164.117eb7b8.js"><link rel="prefetch" href="/assets/js/165.4fabe2ea.js"><link rel="prefetch" href="/assets/js/166.27d3bfe9.js"><link rel="prefetch" href="/assets/js/167.c8a74627.js"><link rel="prefetch" href="/assets/js/168.e16111b9.js"><link rel="prefetch" href="/assets/js/169.458ea1d8.js"><link rel="prefetch" href="/assets/js/17.d3f5977b.js"><link rel="prefetch" href="/assets/js/170.4b38adcf.js"><link rel="prefetch" href="/assets/js/171.98cb45b7.js"><link rel="prefetch" href="/assets/js/172.9ca2eb1a.js"><link rel="prefetch" href="/assets/js/173.14074c7f.js"><link rel="prefetch" href="/assets/js/174.8e1f9887.js"><link rel="prefetch" href="/assets/js/175.5989a4ca.js"><link rel="prefetch" href="/assets/js/176.89b35f24.js"><link rel="prefetch" href="/assets/js/177.8ca04666.js"><link rel="prefetch" href="/assets/js/178.f1f78ad5.js"><link rel="prefetch" href="/assets/js/179.a1faadfe.js"><link rel="prefetch" href="/assets/js/18.1a2bbade.js"><link rel="prefetch" href="/assets/js/180.33be0a0d.js"><link rel="prefetch" href="/assets/js/181.074198fc.js"><link rel="prefetch" href="/assets/js/182.2ea92f58.js"><link rel="prefetch" href="/assets/js/183.316f0529.js"><link rel="prefetch" href="/assets/js/184.f6dd5f36.js"><link rel="prefetch" href="/assets/js/185.134f1457.js"><link rel="prefetch" href="/assets/js/186.2aa74077.js"><link rel="prefetch" href="/assets/js/187.3a956aba.js"><link rel="prefetch" href="/assets/js/188.01a6573f.js"><link rel="prefetch" href="/assets/js/189.a8d65b4d.js"><link rel="prefetch" href="/assets/js/19.e062ea88.js"><link rel="prefetch" href="/assets/js/190.c753d8e3.js"><link rel="prefetch" href="/assets/js/191.280fe1e2.js"><link rel="prefetch" href="/assets/js/192.bbc94e32.js"><link rel="prefetch" href="/assets/js/193.41421d14.js"><link rel="prefetch" href="/assets/js/194.15f508e4.js"><link rel="prefetch" href="/assets/js/195.a17f3877.js"><link rel="prefetch" href="/assets/js/196.d17bfcdf.js"><link rel="prefetch" href="/assets/js/197.65791a5a.js"><link rel="prefetch" href="/assets/js/198.0441041e.js"><link rel="prefetch" href="/assets/js/199.538f2285.js"><link rel="prefetch" href="/assets/js/20.6c49f026.js"><link rel="prefetch" href="/assets/js/200.4ff8dbc4.js"><link rel="prefetch" href="/assets/js/201.088ccf86.js"><link rel="prefetch" href="/assets/js/202.8bdad311.js"><link rel="prefetch" href="/assets/js/203.45d3ecc5.js"><link rel="prefetch" href="/assets/js/204.c403aa39.js"><link rel="prefetch" href="/assets/js/205.e992b689.js"><link rel="prefetch" href="/assets/js/206.eed8bd42.js"><link rel="prefetch" href="/assets/js/207.3db1fc87.js"><link rel="prefetch" href="/assets/js/208.27399a7b.js"><link rel="prefetch" href="/assets/js/209.829f007c.js"><link rel="prefetch" href="/assets/js/21.0ed0e55b.js"><link rel="prefetch" href="/assets/js/210.35079683.js"><link rel="prefetch" href="/assets/js/211.94056191.js"><link rel="prefetch" href="/assets/js/212.431059ab.js"><link rel="prefetch" href="/assets/js/213.4d25e21f.js"><link rel="prefetch" href="/assets/js/214.e62f8fc5.js"><link rel="prefetch" href="/assets/js/215.433d7113.js"><link rel="prefetch" href="/assets/js/216.6de56c4d.js"><link rel="prefetch" href="/assets/js/217.ad3e1cd0.js"><link rel="prefetch" href="/assets/js/218.c225521d.js"><link rel="prefetch" href="/assets/js/219.f4241738.js"><link rel="prefetch" href="/assets/js/22.3563c6e0.js"><link rel="prefetch" href="/assets/js/220.ac9c6899.js"><link rel="prefetch" href="/assets/js/221.ff4ee0d2.js"><link rel="prefetch" href="/assets/js/222.20629300.js"><link rel="prefetch" href="/assets/js/223.a5fa0166.js"><link rel="prefetch" href="/assets/js/224.65290c4f.js"><link rel="prefetch" href="/assets/js/225.e698f717.js"><link rel="prefetch" href="/assets/js/226.4b28f10d.js"><link rel="prefetch" href="/assets/js/227.f44065ae.js"><link rel="prefetch" href="/assets/js/228.0b254d68.js"><link rel="prefetch" href="/assets/js/229.560ccb5c.js"><link rel="prefetch" href="/assets/js/23.2bc6a9e3.js"><link rel="prefetch" href="/assets/js/230.2e09449c.js"><link rel="prefetch" href="/assets/js/231.b09e3f00.js"><link rel="prefetch" href="/assets/js/232.eaa54385.js"><link rel="prefetch" href="/assets/js/233.36843a48.js"><link rel="prefetch" href="/assets/js/234.1e3e41c7.js"><link rel="prefetch" href="/assets/js/235.2dff4846.js"><link rel="prefetch" href="/assets/js/236.bb6fd980.js"><link rel="prefetch" href="/assets/js/237.e97364da.js"><link rel="prefetch" href="/assets/js/238.d8ce22f3.js"><link rel="prefetch" href="/assets/js/239.be791e5e.js"><link rel="prefetch" href="/assets/js/24.4b60795e.js"><link rel="prefetch" href="/assets/js/240.3927116f.js"><link rel="prefetch" href="/assets/js/241.6539a7f9.js"><link rel="prefetch" href="/assets/js/242.1241e424.js"><link rel="prefetch" href="/assets/js/243.a07d3be3.js"><link rel="prefetch" href="/assets/js/244.f98f98a1.js"><link rel="prefetch" href="/assets/js/245.ecb7c922.js"><link rel="prefetch" href="/assets/js/246.95ed23ce.js"><link rel="prefetch" href="/assets/js/247.fb5d42c6.js"><link rel="prefetch" href="/assets/js/248.f7b4f364.js"><link rel="prefetch" href="/assets/js/249.ac22d922.js"><link rel="prefetch" href="/assets/js/25.ef18cc01.js"><link rel="prefetch" href="/assets/js/250.01fbf76b.js"><link rel="prefetch" href="/assets/js/251.08f19bbd.js"><link rel="prefetch" href="/assets/js/252.9f11061d.js"><link rel="prefetch" href="/assets/js/253.cd7f85b9.js"><link rel="prefetch" href="/assets/js/254.2493e550.js"><link rel="prefetch" href="/assets/js/255.ac6d41ee.js"><link rel="prefetch" href="/assets/js/256.068eb5a6.js"><link rel="prefetch" href="/assets/js/257.b108c715.js"><link rel="prefetch" href="/assets/js/258.d614b5d4.js"><link rel="prefetch" href="/assets/js/259.87ba5ef3.js"><link rel="prefetch" href="/assets/js/26.5baa4d2c.js"><link rel="prefetch" href="/assets/js/260.c771e39d.js"><link rel="prefetch" href="/assets/js/261.0dbaf460.js"><link rel="prefetch" href="/assets/js/262.35e64a26.js"><link rel="prefetch" href="/assets/js/263.c16fca32.js"><link rel="prefetch" href="/assets/js/264.ea414912.js"><link rel="prefetch" href="/assets/js/265.f2e0d5bb.js"><link rel="prefetch" href="/assets/js/266.629a2d15.js"><link rel="prefetch" href="/assets/js/267.c7332e80.js"><link rel="prefetch" href="/assets/js/268.8be99f76.js"><link rel="prefetch" href="/assets/js/269.452ff2d4.js"><link rel="prefetch" href="/assets/js/27.2a2950d8.js"><link rel="prefetch" href="/assets/js/270.a5c429cb.js"><link rel="prefetch" href="/assets/js/271.1ad3cd83.js"><link rel="prefetch" href="/assets/js/272.354cef59.js"><link rel="prefetch" href="/assets/js/273.681156b7.js"><link rel="prefetch" href="/assets/js/274.6c51e7ae.js"><link rel="prefetch" href="/assets/js/275.24ef01b4.js"><link rel="prefetch" href="/assets/js/276.afeb2acd.js"><link rel="prefetch" href="/assets/js/277.6472c22d.js"><link rel="prefetch" href="/assets/js/278.416d9788.js"><link rel="prefetch" href="/assets/js/279.c190fbc9.js"><link rel="prefetch" href="/assets/js/28.6320d8c1.js"><link rel="prefetch" href="/assets/js/280.28b1b955.js"><link rel="prefetch" href="/assets/js/281.77afd7c5.js"><link rel="prefetch" href="/assets/js/282.eee0e9c0.js"><link rel="prefetch" href="/assets/js/283.e59fb0e5.js"><link rel="prefetch" href="/assets/js/284.9c6ff275.js"><link rel="prefetch" href="/assets/js/285.3e2d030a.js"><link rel="prefetch" href="/assets/js/286.d7562f9b.js"><link rel="prefetch" href="/assets/js/287.9e228e80.js"><link rel="prefetch" href="/assets/js/288.f9448d7d.js"><link rel="prefetch" href="/assets/js/289.30726f95.js"><link rel="prefetch" href="/assets/js/29.a420635f.js"><link rel="prefetch" href="/assets/js/290.f79765e2.js"><link rel="prefetch" href="/assets/js/291.0943618c.js"><link rel="prefetch" href="/assets/js/292.bd04f6db.js"><link rel="prefetch" href="/assets/js/293.776f4c0d.js"><link rel="prefetch" href="/assets/js/294.54e52863.js"><link rel="prefetch" href="/assets/js/295.bd033d69.js"><link rel="prefetch" href="/assets/js/296.1090c539.js"><link rel="prefetch" href="/assets/js/297.ec37f6e8.js"><link rel="prefetch" href="/assets/js/298.fa434214.js"><link rel="prefetch" href="/assets/js/299.50bd7c87.js"><link rel="prefetch" href="/assets/js/30.6c81ca7b.js"><link rel="prefetch" href="/assets/js/300.7a2c6632.js"><link rel="prefetch" href="/assets/js/301.4ae4e645.js"><link rel="prefetch" href="/assets/js/302.e1ef7459.js"><link rel="prefetch" href="/assets/js/303.3894068b.js"><link rel="prefetch" href="/assets/js/304.840b09e3.js"><link rel="prefetch" href="/assets/js/305.40ec0bf6.js"><link rel="prefetch" href="/assets/js/306.9fa4d8aa.js"><link rel="prefetch" href="/assets/js/307.33656e76.js"><link rel="prefetch" href="/assets/js/308.19398f71.js"><link rel="prefetch" href="/assets/js/309.bde6f12f.js"><link rel="prefetch" href="/assets/js/31.2b4f2752.js"><link rel="prefetch" href="/assets/js/310.69ced632.js"><link rel="prefetch" href="/assets/js/311.c8e57d0e.js"><link rel="prefetch" href="/assets/js/312.80c4d6a7.js"><link rel="prefetch" href="/assets/js/313.14060a06.js"><link rel="prefetch" href="/assets/js/314.29165d83.js"><link rel="prefetch" href="/assets/js/315.901aabf1.js"><link rel="prefetch" href="/assets/js/316.7f0d18e3.js"><link rel="prefetch" href="/assets/js/317.112de6ec.js"><link rel="prefetch" href="/assets/js/318.091ea533.js"><link rel="prefetch" href="/assets/js/319.25ca175e.js"><link rel="prefetch" href="/assets/js/32.ab03e16f.js"><link rel="prefetch" href="/assets/js/320.b89e85c9.js"><link rel="prefetch" href="/assets/js/321.69316136.js"><link rel="prefetch" href="/assets/js/322.567512f0.js"><link rel="prefetch" href="/assets/js/323.2d67bb75.js"><link rel="prefetch" href="/assets/js/324.c41411db.js"><link rel="prefetch" href="/assets/js/325.a412ca77.js"><link rel="prefetch" href="/assets/js/326.22408ce6.js"><link rel="prefetch" href="/assets/js/327.33524443.js"><link rel="prefetch" href="/assets/js/328.561ebeb1.js"><link rel="prefetch" href="/assets/js/329.d7a280e4.js"><link rel="prefetch" href="/assets/js/33.199f45ed.js"><link rel="prefetch" href="/assets/js/330.d01a7e1b.js"><link rel="prefetch" href="/assets/js/331.a3ad2556.js"><link rel="prefetch" href="/assets/js/332.36ad912a.js"><link rel="prefetch" href="/assets/js/333.2fb229c4.js"><link rel="prefetch" href="/assets/js/334.d170f507.js"><link rel="prefetch" href="/assets/js/335.90ca0539.js"><link rel="prefetch" href="/assets/js/336.454d4374.js"><link rel="prefetch" href="/assets/js/337.dba45eb4.js"><link rel="prefetch" href="/assets/js/338.c8e4ba66.js"><link rel="prefetch" href="/assets/js/339.ae85118e.js"><link rel="prefetch" href="/assets/js/34.d0c7a02e.js"><link rel="prefetch" href="/assets/js/340.7033b85b.js"><link rel="prefetch" href="/assets/js/341.13cfe1aa.js"><link rel="prefetch" href="/assets/js/342.b33302b5.js"><link rel="prefetch" href="/assets/js/343.946f30dc.js"><link rel="prefetch" href="/assets/js/344.b2add405.js"><link rel="prefetch" href="/assets/js/345.12433fa3.js"><link rel="prefetch" href="/assets/js/346.b1bdfeba.js"><link rel="prefetch" href="/assets/js/347.53530bff.js"><link rel="prefetch" href="/assets/js/348.48aa580e.js"><link rel="prefetch" href="/assets/js/349.53c4baca.js"><link rel="prefetch" href="/assets/js/35.5512348f.js"><link rel="prefetch" href="/assets/js/350.e4b2d6e6.js"><link rel="prefetch" href="/assets/js/351.d41b01c1.js"><link rel="prefetch" href="/assets/js/352.1c4d1250.js"><link rel="prefetch" href="/assets/js/353.7fd27c0f.js"><link rel="prefetch" href="/assets/js/354.47199c90.js"><link rel="prefetch" href="/assets/js/355.68bccab4.js"><link rel="prefetch" href="/assets/js/356.e3602eb5.js"><link rel="prefetch" href="/assets/js/357.cd5ce764.js"><link rel="prefetch" href="/assets/js/358.bee621d4.js"><link rel="prefetch" href="/assets/js/359.648aa4f0.js"><link rel="prefetch" href="/assets/js/36.bdebdf29.js"><link rel="prefetch" href="/assets/js/360.439f5fae.js"><link rel="prefetch" href="/assets/js/361.39f782b4.js"><link rel="prefetch" href="/assets/js/362.106acf4c.js"><link rel="prefetch" href="/assets/js/363.562a4e1e.js"><link rel="prefetch" href="/assets/js/364.5940b069.js"><link rel="prefetch" href="/assets/js/365.e429c365.js"><link rel="prefetch" href="/assets/js/366.cc650df8.js"><link rel="prefetch" href="/assets/js/367.347592c9.js"><link rel="prefetch" href="/assets/js/368.d68ce88d.js"><link rel="prefetch" href="/assets/js/369.034e7f1e.js"><link rel="prefetch" href="/assets/js/37.9d026956.js"><link rel="prefetch" href="/assets/js/370.ac6fc7a5.js"><link rel="prefetch" href="/assets/js/371.e70219a6.js"><link rel="prefetch" href="/assets/js/372.c449fc49.js"><link rel="prefetch" href="/assets/js/373.f07bea72.js"><link rel="prefetch" href="/assets/js/374.8152408f.js"><link rel="prefetch" href="/assets/js/375.63c70dab.js"><link rel="prefetch" href="/assets/js/376.06de19db.js"><link rel="prefetch" href="/assets/js/377.2319ddb1.js"><link rel="prefetch" href="/assets/js/378.4821e23c.js"><link rel="prefetch" href="/assets/js/379.54a13769.js"><link rel="prefetch" href="/assets/js/38.23e83578.js"><link rel="prefetch" href="/assets/js/380.dac4cd46.js"><link rel="prefetch" href="/assets/js/381.8f83d1d7.js"><link rel="prefetch" href="/assets/js/382.e76e7d88.js"><link rel="prefetch" href="/assets/js/383.df731ee4.js"><link rel="prefetch" href="/assets/js/384.5093369e.js"><link rel="prefetch" href="/assets/js/385.ee576341.js"><link rel="prefetch" href="/assets/js/386.087a29a9.js"><link rel="prefetch" href="/assets/js/387.9f44d03b.js"><link rel="prefetch" href="/assets/js/388.a3f70992.js"><link rel="prefetch" href="/assets/js/389.df6e2ced.js"><link rel="prefetch" href="/assets/js/39.e9699d7f.js"><link rel="prefetch" href="/assets/js/390.c377efca.js"><link rel="prefetch" href="/assets/js/391.d7747385.js"><link rel="prefetch" href="/assets/js/392.bf8e8c1a.js"><link rel="prefetch" href="/assets/js/393.b4ed3be0.js"><link rel="prefetch" href="/assets/js/394.48eb505a.js"><link rel="prefetch" href="/assets/js/395.d9cd4812.js"><link rel="prefetch" href="/assets/js/396.b386a6b5.js"><link rel="prefetch" href="/assets/js/397.d19960fa.js"><link rel="prefetch" href="/assets/js/398.15f66e2a.js"><link rel="prefetch" href="/assets/js/399.cc4af83b.js"><link rel="prefetch" href="/assets/js/40.3a541653.js"><link rel="prefetch" href="/assets/js/400.d99e4b93.js"><link rel="prefetch" href="/assets/js/401.13fa06dd.js"><link rel="prefetch" href="/assets/js/402.3629b866.js"><link rel="prefetch" href="/assets/js/403.5826b040.js"><link rel="prefetch" href="/assets/js/404.d4b35549.js"><link rel="prefetch" href="/assets/js/405.9142a002.js"><link rel="prefetch" href="/assets/js/406.ba50e04d.js"><link rel="prefetch" href="/assets/js/407.b5271c6f.js"><link rel="prefetch" href="/assets/js/408.18baa241.js"><link rel="prefetch" href="/assets/js/409.6151d46b.js"><link rel="prefetch" href="/assets/js/41.b10ef41f.js"><link rel="prefetch" href="/assets/js/410.bb1fd058.js"><link rel="prefetch" href="/assets/js/411.9273fd47.js"><link rel="prefetch" href="/assets/js/412.d6b790c1.js"><link rel="prefetch" href="/assets/js/413.4c5a30bb.js"><link rel="prefetch" href="/assets/js/414.01aa0e0a.js"><link rel="prefetch" href="/assets/js/415.2633ad61.js"><link rel="prefetch" href="/assets/js/416.7a2263a9.js"><link rel="prefetch" href="/assets/js/417.98368241.js"><link rel="prefetch" href="/assets/js/418.ffeb9c9c.js"><link rel="prefetch" href="/assets/js/419.633f9efe.js"><link rel="prefetch" href="/assets/js/42.aa8b7c99.js"><link rel="prefetch" href="/assets/js/420.69868f4a.js"><link rel="prefetch" href="/assets/js/421.937d87cc.js"><link rel="prefetch" href="/assets/js/422.375fe09b.js"><link rel="prefetch" href="/assets/js/423.8d335fd6.js"><link rel="prefetch" href="/assets/js/424.d5b181d7.js"><link rel="prefetch" href="/assets/js/425.e06749ea.js"><link rel="prefetch" href="/assets/js/426.d7a23361.js"><link rel="prefetch" href="/assets/js/427.c26079c3.js"><link rel="prefetch" href="/assets/js/428.788e60b3.js"><link rel="prefetch" href="/assets/js/429.212c3091.js"><link rel="prefetch" href="/assets/js/43.bbf1f09a.js"><link rel="prefetch" href="/assets/js/430.e156b1fa.js"><link rel="prefetch" href="/assets/js/431.b41e44c6.js"><link rel="prefetch" href="/assets/js/432.7534e280.js"><link rel="prefetch" href="/assets/js/433.3d203e2b.js"><link rel="prefetch" href="/assets/js/434.41bb5350.js"><link rel="prefetch" href="/assets/js/435.a5c93fd3.js"><link rel="prefetch" href="/assets/js/436.60910866.js"><link rel="prefetch" href="/assets/js/437.7ae74f40.js"><link rel="prefetch" href="/assets/js/438.dc802af3.js"><link rel="prefetch" href="/assets/js/439.0de7c2a4.js"><link rel="prefetch" href="/assets/js/44.c0079627.js"><link rel="prefetch" href="/assets/js/440.43bc725f.js"><link rel="prefetch" href="/assets/js/441.1402dd2a.js"><link rel="prefetch" href="/assets/js/442.6106e1be.js"><link rel="prefetch" href="/assets/js/443.40909ac7.js"><link rel="prefetch" href="/assets/js/444.e506898d.js"><link rel="prefetch" href="/assets/js/445.8636f7a3.js"><link rel="prefetch" href="/assets/js/446.de915ed4.js"><link rel="prefetch" href="/assets/js/447.c7ac8e6e.js"><link rel="prefetch" href="/assets/js/448.9797a750.js"><link rel="prefetch" href="/assets/js/449.5d1f4748.js"><link rel="prefetch" href="/assets/js/45.2a09d581.js"><link rel="prefetch" href="/assets/js/450.42babefe.js"><link rel="prefetch" href="/assets/js/451.ee1b8ff8.js"><link rel="prefetch" href="/assets/js/452.7536e7c2.js"><link rel="prefetch" href="/assets/js/453.39a21d52.js"><link rel="prefetch" href="/assets/js/454.6511d1e1.js"><link rel="prefetch" href="/assets/js/455.2abb8ea0.js"><link rel="prefetch" href="/assets/js/456.5724d799.js"><link rel="prefetch" href="/assets/js/457.c32c0755.js"><link rel="prefetch" href="/assets/js/458.f67c539b.js"><link rel="prefetch" href="/assets/js/459.1634e8da.js"><link rel="prefetch" href="/assets/js/46.58b302e4.js"><link rel="prefetch" href="/assets/js/460.a22ac002.js"><link rel="prefetch" href="/assets/js/461.2c152148.js"><link rel="prefetch" href="/assets/js/462.14b038cf.js"><link rel="prefetch" href="/assets/js/463.dd0a3a00.js"><link rel="prefetch" href="/assets/js/464.f22ba288.js"><link rel="prefetch" href="/assets/js/465.9c187041.js"><link rel="prefetch" href="/assets/js/466.9957dd67.js"><link rel="prefetch" href="/assets/js/467.047041e8.js"><link rel="prefetch" href="/assets/js/468.425b6f20.js"><link rel="prefetch" href="/assets/js/469.2f70ecf7.js"><link rel="prefetch" href="/assets/js/47.987d79be.js"><link rel="prefetch" href="/assets/js/470.602b7d98.js"><link rel="prefetch" href="/assets/js/471.ddabe1b6.js"><link rel="prefetch" href="/assets/js/472.3a1ad521.js"><link rel="prefetch" href="/assets/js/473.2be352ab.js"><link rel="prefetch" href="/assets/js/474.e9c805de.js"><link rel="prefetch" href="/assets/js/475.93cab6cb.js"><link rel="prefetch" href="/assets/js/476.89384fa4.js"><link rel="prefetch" href="/assets/js/477.2b282ee8.js"><link rel="prefetch" href="/assets/js/478.27790491.js"><link rel="prefetch" href="/assets/js/479.2b728ba6.js"><link rel="prefetch" href="/assets/js/48.0e76d761.js"><link rel="prefetch" href="/assets/js/480.bd0beea9.js"><link rel="prefetch" href="/assets/js/481.004a0005.js"><link rel="prefetch" href="/assets/js/482.d9c6dc45.js"><link rel="prefetch" href="/assets/js/483.e7842361.js"><link rel="prefetch" href="/assets/js/484.702ac9a3.js"><link rel="prefetch" href="/assets/js/485.d38ba4c2.js"><link rel="prefetch" href="/assets/js/486.8a0cd211.js"><link rel="prefetch" href="/assets/js/487.18e243bb.js"><link rel="prefetch" href="/assets/js/488.cb0ad1bf.js"><link rel="prefetch" href="/assets/js/489.7c7adc5c.js"><link rel="prefetch" href="/assets/js/49.83e0619b.js"><link rel="prefetch" href="/assets/js/490.3f86a6a4.js"><link rel="prefetch" href="/assets/js/491.c1c90b4f.js"><link rel="prefetch" href="/assets/js/492.5658313d.js"><link rel="prefetch" href="/assets/js/493.9b953b18.js"><link rel="prefetch" href="/assets/js/494.80e3d4f4.js"><link rel="prefetch" href="/assets/js/495.66650a67.js"><link rel="prefetch" href="/assets/js/496.4e0d753b.js"><link rel="prefetch" href="/assets/js/497.1837b7c2.js"><link rel="prefetch" href="/assets/js/498.e2dcd450.js"><link rel="prefetch" href="/assets/js/499.4d5022f2.js"><link rel="prefetch" href="/assets/js/5.f343fd5d.js"><link rel="prefetch" href="/assets/js/50.6716fe91.js"><link rel="prefetch" href="/assets/js/500.10c0ee69.js"><link rel="prefetch" href="/assets/js/501.be3f9599.js"><link rel="prefetch" href="/assets/js/502.27844894.js"><link rel="prefetch" href="/assets/js/503.15f84a9b.js"><link rel="prefetch" href="/assets/js/504.60780a8e.js"><link rel="prefetch" href="/assets/js/505.6f9bed41.js"><link rel="prefetch" href="/assets/js/506.3e19b413.js"><link rel="prefetch" href="/assets/js/507.a12a02cb.js"><link rel="prefetch" href="/assets/js/508.b1384524.js"><link rel="prefetch" href="/assets/js/509.c74ef6c0.js"><link rel="prefetch" href="/assets/js/51.bc8d5aaf.js"><link rel="prefetch" href="/assets/js/510.266a6048.js"><link rel="prefetch" href="/assets/js/511.be98a2ef.js"><link rel="prefetch" href="/assets/js/512.e033e89e.js"><link rel="prefetch" href="/assets/js/513.837b9052.js"><link rel="prefetch" href="/assets/js/514.38271d19.js"><link rel="prefetch" href="/assets/js/515.c08327b5.js"><link rel="prefetch" href="/assets/js/516.3d573fdf.js"><link rel="prefetch" href="/assets/js/517.5406a8bd.js"><link rel="prefetch" href="/assets/js/518.543bea6f.js"><link rel="prefetch" href="/assets/js/519.e4967ce6.js"><link rel="prefetch" href="/assets/js/52.20603f07.js"><link rel="prefetch" href="/assets/js/520.0a863135.js"><link rel="prefetch" href="/assets/js/521.80c26149.js"><link rel="prefetch" href="/assets/js/522.5d0549ee.js"><link rel="prefetch" href="/assets/js/523.4b5d705c.js"><link rel="prefetch" href="/assets/js/524.24354cd8.js"><link rel="prefetch" href="/assets/js/525.d201b688.js"><link rel="prefetch" href="/assets/js/526.f405c35a.js"><link rel="prefetch" href="/assets/js/527.921d252f.js"><link rel="prefetch" href="/assets/js/528.cb45a5dd.js"><link rel="prefetch" href="/assets/js/529.aeec69e2.js"><link rel="prefetch" href="/assets/js/53.9604c447.js"><link rel="prefetch" href="/assets/js/530.7d5514c0.js"><link rel="prefetch" href="/assets/js/531.de381ab2.js"><link rel="prefetch" href="/assets/js/532.31b6e993.js"><link rel="prefetch" href="/assets/js/533.23335bff.js"><link rel="prefetch" href="/assets/js/534.131d260d.js"><link rel="prefetch" href="/assets/js/535.3057e7f2.js"><link rel="prefetch" href="/assets/js/536.1df4cc6e.js"><link rel="prefetch" href="/assets/js/537.c23a3391.js"><link rel="prefetch" href="/assets/js/538.ac3546d3.js"><link rel="prefetch" href="/assets/js/539.36137525.js"><link rel="prefetch" href="/assets/js/54.841e8e8f.js"><link rel="prefetch" href="/assets/js/540.f9171241.js"><link rel="prefetch" href="/assets/js/541.00a9732f.js"><link rel="prefetch" href="/assets/js/542.d981dcf7.js"><link rel="prefetch" href="/assets/js/543.0016cdef.js"><link rel="prefetch" href="/assets/js/544.b24fa17d.js"><link rel="prefetch" href="/assets/js/545.8adcd15c.js"><link rel="prefetch" href="/assets/js/546.189f10ef.js"><link rel="prefetch" href="/assets/js/547.d47175ac.js"><link rel="prefetch" href="/assets/js/548.67ed7a21.js"><link rel="prefetch" href="/assets/js/549.a72c957e.js"><link rel="prefetch" href="/assets/js/55.eccc64f8.js"><link rel="prefetch" href="/assets/js/550.c127415f.js"><link rel="prefetch" href="/assets/js/551.288648b2.js"><link rel="prefetch" href="/assets/js/552.5191109c.js"><link rel="prefetch" href="/assets/js/553.a0417c79.js"><link rel="prefetch" href="/assets/js/554.05224c83.js"><link rel="prefetch" href="/assets/js/555.d95f24bd.js"><link rel="prefetch" href="/assets/js/556.42a17364.js"><link rel="prefetch" href="/assets/js/557.a066d457.js"><link rel="prefetch" href="/assets/js/558.1f4641c3.js"><link rel="prefetch" href="/assets/js/559.f85fd85a.js"><link rel="prefetch" href="/assets/js/56.9ede6cf7.js"><link rel="prefetch" href="/assets/js/560.c486ead6.js"><link rel="prefetch" href="/assets/js/561.5654ef71.js"><link rel="prefetch" href="/assets/js/562.8ac06965.js"><link rel="prefetch" href="/assets/js/563.209407dd.js"><link rel="prefetch" href="/assets/js/564.4da5848b.js"><link rel="prefetch" href="/assets/js/565.0ea0c2cb.js"><link rel="prefetch" href="/assets/js/566.fbb62b05.js"><link rel="prefetch" href="/assets/js/567.0454bee2.js"><link rel="prefetch" href="/assets/js/568.5aad57f8.js"><link rel="prefetch" href="/assets/js/569.b4b199ad.js"><link rel="prefetch" href="/assets/js/57.2e9b38e9.js"><link rel="prefetch" href="/assets/js/570.890f1d05.js"><link rel="prefetch" href="/assets/js/571.56e5f721.js"><link rel="prefetch" href="/assets/js/572.fa3418f1.js"><link rel="prefetch" href="/assets/js/573.224ada77.js"><link rel="prefetch" href="/assets/js/574.4cc85330.js"><link rel="prefetch" href="/assets/js/575.61a17f5e.js"><link rel="prefetch" href="/assets/js/576.0ec5efb8.js"><link rel="prefetch" href="/assets/js/577.6bc915dd.js"><link rel="prefetch" href="/assets/js/578.fd4e39e7.js"><link rel="prefetch" href="/assets/js/579.0238c950.js"><link rel="prefetch" href="/assets/js/58.f28ad3cc.js"><link rel="prefetch" href="/assets/js/580.a08c6c02.js"><link rel="prefetch" href="/assets/js/581.392f9c6f.js"><link rel="prefetch" href="/assets/js/582.2f59e9f2.js"><link rel="prefetch" href="/assets/js/583.2097fe85.js"><link rel="prefetch" href="/assets/js/584.f0d8c622.js"><link rel="prefetch" href="/assets/js/585.85fab1f2.js"><link rel="prefetch" href="/assets/js/586.c359098c.js"><link rel="prefetch" href="/assets/js/587.1dff90c3.js"><link rel="prefetch" href="/assets/js/588.6afc16eb.js"><link rel="prefetch" href="/assets/js/589.4337cfee.js"><link rel="prefetch" href="/assets/js/59.9079a4f5.js"><link rel="prefetch" href="/assets/js/590.f969cc18.js"><link rel="prefetch" href="/assets/js/591.dfceaca2.js"><link rel="prefetch" href="/assets/js/592.b670f7b8.js"><link rel="prefetch" href="/assets/js/593.85ff3e7e.js"><link rel="prefetch" href="/assets/js/594.87d3c73b.js"><link rel="prefetch" href="/assets/js/595.18f2a1df.js"><link rel="prefetch" href="/assets/js/596.adb07b39.js"><link rel="prefetch" href="/assets/js/597.4bfdae44.js"><link rel="prefetch" href="/assets/js/598.a4f73bf5.js"><link rel="prefetch" href="/assets/js/599.5b85b7f2.js"><link rel="prefetch" href="/assets/js/6.6f5ae702.js"><link rel="prefetch" href="/assets/js/60.3095e21a.js"><link rel="prefetch" href="/assets/js/600.98cef029.js"><link rel="prefetch" href="/assets/js/601.34cfecd2.js"><link rel="prefetch" href="/assets/js/602.afaf2e1f.js"><link rel="prefetch" href="/assets/js/603.5f081041.js"><link rel="prefetch" href="/assets/js/604.a55dc3e4.js"><link rel="prefetch" href="/assets/js/605.cc600bca.js"><link rel="prefetch" href="/assets/js/606.9e0874e1.js"><link rel="prefetch" href="/assets/js/607.bd0a2835.js"><link rel="prefetch" href="/assets/js/608.e3c0bb6d.js"><link rel="prefetch" href="/assets/js/609.968adfbe.js"><link rel="prefetch" href="/assets/js/61.cd58c0e2.js"><link rel="prefetch" href="/assets/js/610.6ddb82e2.js"><link rel="prefetch" href="/assets/js/611.f6573e33.js"><link rel="prefetch" href="/assets/js/612.cd703232.js"><link rel="prefetch" href="/assets/js/613.5ae48097.js"><link rel="prefetch" href="/assets/js/614.c9fc5628.js"><link rel="prefetch" href="/assets/js/615.5f3c1162.js"><link rel="prefetch" href="/assets/js/616.3efeed17.js"><link rel="prefetch" href="/assets/js/617.25dec672.js"><link rel="prefetch" href="/assets/js/618.b53f21b6.js"><link rel="prefetch" href="/assets/js/619.e0c2de74.js"><link rel="prefetch" href="/assets/js/62.aa4d202d.js"><link rel="prefetch" href="/assets/js/620.88136c6a.js"><link rel="prefetch" href="/assets/js/621.494122df.js"><link rel="prefetch" href="/assets/js/622.e2a6e4bd.js"><link rel="prefetch" href="/assets/js/623.20a56d61.js"><link rel="prefetch" href="/assets/js/624.602dd933.js"><link rel="prefetch" href="/assets/js/625.70f44f60.js"><link rel="prefetch" href="/assets/js/626.11524978.js"><link rel="prefetch" href="/assets/js/627.b3badb72.js"><link rel="prefetch" href="/assets/js/628.e613665e.js"><link rel="prefetch" href="/assets/js/629.20e73b43.js"><link rel="prefetch" href="/assets/js/63.f7cd40f4.js"><link rel="prefetch" href="/assets/js/630.6099312f.js"><link rel="prefetch" href="/assets/js/631.669bcda0.js"><link rel="prefetch" href="/assets/js/632.d33f5ec9.js"><link rel="prefetch" href="/assets/js/633.211456ee.js"><link rel="prefetch" href="/assets/js/634.ea9d07ae.js"><link rel="prefetch" href="/assets/js/635.f22368f1.js"><link rel="prefetch" href="/assets/js/636.ebe249f7.js"><link rel="prefetch" href="/assets/js/637.7b645ab3.js"><link rel="prefetch" href="/assets/js/638.4565c395.js"><link rel="prefetch" href="/assets/js/639.c5144f9c.js"><link rel="prefetch" href="/assets/js/64.8cd3aa43.js"><link rel="prefetch" href="/assets/js/640.2dc2eba9.js"><link rel="prefetch" href="/assets/js/641.70155ce7.js"><link rel="prefetch" href="/assets/js/642.c55f5ca8.js"><link rel="prefetch" href="/assets/js/643.69a5b8e5.js"><link rel="prefetch" href="/assets/js/644.84431935.js"><link rel="prefetch" href="/assets/js/645.5119ebc2.js"><link rel="prefetch" href="/assets/js/646.506fc745.js"><link rel="prefetch" href="/assets/js/647.e5f03652.js"><link rel="prefetch" href="/assets/js/648.47ae0cc5.js"><link rel="prefetch" href="/assets/js/649.b3a67529.js"><link rel="prefetch" href="/assets/js/65.14b3da5d.js"><link rel="prefetch" href="/assets/js/650.89765bb0.js"><link rel="prefetch" href="/assets/js/651.19b73cf8.js"><link rel="prefetch" href="/assets/js/652.4436725f.js"><link rel="prefetch" href="/assets/js/653.391168ff.js"><link rel="prefetch" href="/assets/js/654.8b449d07.js"><link rel="prefetch" href="/assets/js/655.27051c8c.js"><link rel="prefetch" href="/assets/js/656.7adaae31.js"><link rel="prefetch" href="/assets/js/657.4fee46d2.js"><link rel="prefetch" href="/assets/js/658.0243a6e8.js"><link rel="prefetch" href="/assets/js/659.f69398bc.js"><link rel="prefetch" href="/assets/js/66.899fc260.js"><link rel="prefetch" href="/assets/js/660.5e51ab7c.js"><link rel="prefetch" href="/assets/js/661.980d3d5a.js"><link rel="prefetch" href="/assets/js/662.79643730.js"><link rel="prefetch" href="/assets/js/663.d030bd1d.js"><link rel="prefetch" href="/assets/js/664.32b3c0e8.js"><link rel="prefetch" href="/assets/js/665.384c456b.js"><link rel="prefetch" href="/assets/js/666.2672eb36.js"><link rel="prefetch" href="/assets/js/667.2ca85ff9.js"><link rel="prefetch" href="/assets/js/668.b80ef3b4.js"><link rel="prefetch" href="/assets/js/669.41f08cb1.js"><link rel="prefetch" href="/assets/js/67.c0e799e4.js"><link rel="prefetch" href="/assets/js/670.48512f45.js"><link rel="prefetch" href="/assets/js/671.93e1cdd9.js"><link rel="prefetch" href="/assets/js/672.aa2a7e31.js"><link rel="prefetch" href="/assets/js/673.b19ed80d.js"><link rel="prefetch" href="/assets/js/674.0337bf32.js"><link rel="prefetch" href="/assets/js/675.88a9d569.js"><link rel="prefetch" href="/assets/js/676.7fd2de1c.js"><link rel="prefetch" href="/assets/js/677.1356b477.js"><link rel="prefetch" href="/assets/js/678.d99fd658.js"><link rel="prefetch" href="/assets/js/679.a2e40bc7.js"><link rel="prefetch" href="/assets/js/68.2e72dacb.js"><link rel="prefetch" href="/assets/js/680.58e5d76e.js"><link rel="prefetch" href="/assets/js/681.2e66d773.js"><link rel="prefetch" href="/assets/js/682.42526013.js"><link rel="prefetch" href="/assets/js/683.447d4972.js"><link rel="prefetch" href="/assets/js/684.19beb22a.js"><link rel="prefetch" href="/assets/js/685.cd3fd615.js"><link rel="prefetch" href="/assets/js/686.c6200f3f.js"><link rel="prefetch" href="/assets/js/687.3d6cf8bb.js"><link rel="prefetch" href="/assets/js/688.e9ddd041.js"><link rel="prefetch" href="/assets/js/689.74bb6414.js"><link rel="prefetch" href="/assets/js/69.d29a7787.js"><link rel="prefetch" href="/assets/js/690.82b51acd.js"><link rel="prefetch" href="/assets/js/691.a6edc5c3.js"><link rel="prefetch" href="/assets/js/692.c5fd2fa7.js"><link rel="prefetch" href="/assets/js/693.0c0b8126.js"><link rel="prefetch" href="/assets/js/694.551ae4d1.js"><link rel="prefetch" href="/assets/js/695.2801a2f2.js"><link rel="prefetch" href="/assets/js/696.8723006b.js"><link rel="prefetch" href="/assets/js/697.275e71c7.js"><link rel="prefetch" href="/assets/js/698.431e2bfb.js"><link rel="prefetch" href="/assets/js/699.c82907d3.js"><link rel="prefetch" href="/assets/js/7.c8b0ee6b.js"><link rel="prefetch" href="/assets/js/70.53b18677.js"><link rel="prefetch" href="/assets/js/700.9faf8917.js"><link rel="prefetch" href="/assets/js/701.5ce77f04.js"><link rel="prefetch" href="/assets/js/702.488262eb.js"><link rel="prefetch" href="/assets/js/703.8f79363d.js"><link rel="prefetch" href="/assets/js/704.a4cfe8cb.js"><link rel="prefetch" href="/assets/js/705.4f1759eb.js"><link rel="prefetch" href="/assets/js/706.baf03b10.js"><link rel="prefetch" href="/assets/js/707.48c01840.js"><link rel="prefetch" href="/assets/js/708.b3cda177.js"><link rel="prefetch" href="/assets/js/709.260cc3a8.js"><link rel="prefetch" href="/assets/js/71.b44506bc.js"><link rel="prefetch" href="/assets/js/710.e4fa6646.js"><link rel="prefetch" href="/assets/js/711.7816aba5.js"><link rel="prefetch" href="/assets/js/712.14939ffd.js"><link rel="prefetch" href="/assets/js/72.9793c1ce.js"><link rel="prefetch" href="/assets/js/73.b4d37c7e.js"><link rel="prefetch" href="/assets/js/74.b816cbc7.js"><link rel="prefetch" href="/assets/js/75.9f45a274.js"><link rel="prefetch" href="/assets/js/76.4921e235.js"><link rel="prefetch" href="/assets/js/77.f9258c97.js"><link rel="prefetch" href="/assets/js/78.55656c0f.js"><link rel="prefetch" href="/assets/js/79.b5784c72.js"><link rel="prefetch" href="/assets/js/8.44118d7c.js"><link rel="prefetch" href="/assets/js/80.98240933.js"><link rel="prefetch" href="/assets/js/81.5421fa90.js"><link rel="prefetch" href="/assets/js/82.72a10ccf.js"><link rel="prefetch" href="/assets/js/83.abdca93e.js"><link rel="prefetch" href="/assets/js/84.5d0190e3.js"><link rel="prefetch" href="/assets/js/85.5d2a1647.js"><link rel="prefetch" href="/assets/js/86.5aea5730.js"><link rel="prefetch" href="/assets/js/87.bfe2bb57.js"><link rel="prefetch" href="/assets/js/88.4097611c.js"><link rel="prefetch" href="/assets/js/89.e5a98da0.js"><link rel="prefetch" href="/assets/js/9.612b54fd.js"><link rel="prefetch" href="/assets/js/90.5564a69b.js"><link rel="prefetch" href="/assets/js/91.ff219511.js"><link rel="prefetch" href="/assets/js/92.8191f073.js"><link rel="prefetch" href="/assets/js/93.4b6ecb16.js"><link rel="prefetch" href="/assets/js/94.fd999a73.js"><link rel="prefetch" href="/assets/js/95.c96c310d.js"><link rel="prefetch" href="/assets/js/96.2eb0ab2f.js"><link rel="prefetch" href="/assets/js/97.4c8c6fba.js"><link rel="prefetch" href="/assets/js/98.f9ef7bdb.js"><link rel="prefetch" href="/assets/js/99.513483d0.js"><link rel="prefetch" href="/assets/js/vendors~docsearch.49ad9c45.js">
    <link rel="stylesheet" href="/assets/css/0.styles.af3770e9.css">
  </head>
  <body>
    <div id="app" data-server-rendered="true"><div class="theme-container"><header class="navbar"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/en/" class="home-link router-link-active"><img src="/images/icons/spring-logo.svg" alt="Spring Docs" class="logo"> <span class="site-name can-hide">Spring Docs</span></a> <div class="links"><div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div> <nav class="nav-links can-hide"><div class="nav-item"><a href="/en/spring/why-spring.html" class="nav-link">
  Spring
</a></div><div class="nav-item"><a href="/en/spring-boot/getting-help.html" class="nav-link">
  Spring Boot
</a></div><div class="nav-item"><a href="/en/spring-cloud/documentation-overview.html" class="nav-link">
  Spring Cloud
</a></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="Others" class="dropdown-title"><span class="title">more</span> <span class="arrow down"></span></button> <button type="button" aria-label="Others" class="mobile-dropdown-title"><span class="title">more</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/en/spring-framework/overview.html" class="nav-link">
  Spring Framework
</a></li><li class="dropdown-item"><!----> <a href="/en/spring-data/spring-data.html" class="nav-link">
  Spring Data
</a></li><li class="dropdown-item"><!----> <a href="/en/spring-cloud-data-flow/spring-cloud-dataflow.html" class="nav-link">
  Spring Cloud Data Flow
</a></li><li class="dropdown-item"><!----> <a href="/en/spring-security/overview.html" class="nav-link">
  Spring Security
</a></li><li class="dropdown-item"><!----> <a href="/en/spring-for-graphql/spring-graphql.html" class="nav-link">
  Spring for GraphQL
</a></li><li class="dropdown-item"><!----> <a href="/en/spring-session/_index.html" class="nav-link">
  Spring Session
</a></li><li class="dropdown-item"><!----> <a href="/en/spring-integration/preface.html" class="nav-link">
  Spring Integration
</a></li><li class="dropdown-item"><!----> <a href="/en/spring-hateoas/spring-hateoas.html" class="nav-link">
  Spring HATEOAS
</a></li><li class="dropdown-item"><!----> <a href="/en/spring-rest-docs/spring-restdocs.html" class="nav-link">
  Spring REST Docs
</a></li><li class="dropdown-item"><!----> <a href="/en/spring-batch/spring-batch-intro.html" class="nav-link">
  Spring Batch
</a></li><li class="dropdown-item"><!----> <a href="/en/spring-amqp/spring-amqp.html" class="nav-link">
  Spring AMQP
</a></li><li class="dropdown-item"><!----> <a href="/en/spring-credhub/spring-credhub.html" class="nav-link">
  Spring CredHub
</a></li><li class="dropdown-item"><!----> <a href="/en/spring-flo/spring-flo.html" class="nav-link">
  Spring Flo
</a></li><li class="dropdown-item"><!----> <a href="/en/spring-for-apache-kafka/spring-kafka.html" class="nav-link">
  Spring for Apache Kafka
</a></li><li class="dropdown-item"><!----> <a href="/en/spring-ldap/spring-ldap.html" class="nav-link">
  Spring LDAP
</a></li><li class="dropdown-item"><!----> <a href="/en/spring-shell/spring-shell.html" class="nav-link">
  Spring Shell
</a></li><li class="dropdown-item"><!----> <a href="/en/spring-statemachine/spring-statemachine.html" class="nav-link">
  Spring Statemachine
</a></li><li class="dropdown-item"><!----> <a href="/en/spring-vault/spring-vault.html" class="nav-link">
  Spring Vault
</a></li><li class="dropdown-item"><!----> <a href="/en/spring-web-flow/preface.html" class="nav-link">
  Spring Web Flow
</a></li><li class="dropdown-item"><!----> <a href="/en/spring-web-services/spring-web-service.html" class="nav-link">
  Spring Web Services
</a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="Select language" class="dropdown-title"><span class="title">Language</span> <span class="arrow down"></span></button> <button type="button" aria-label="Select language" class="mobile-dropdown-title"><span class="title">Language</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/en/spring-integration/jdbc.html" aria-current="page" class="nav-link router-link-exact-active router-link-active">
  English
</a></li><li class="dropdown-item"><!----> <a href="/spring-integration/jdbc.html" class="nav-link">
  简体中文
</a></li></ul></div></div> <a href="https://gitcode.net/dev-cloud/spring-docs" target="_blank" rel="noopener noreferrer" class="repo-link">
    GitCode
    <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></nav></div></header> <div class="sidebar-mask"></div> <aside class="sidebar"><nav class="nav-links"><div class="nav-item"><a href="/en/spring/why-spring.html" class="nav-link">
  Spring
</a></div><div class="nav-item"><a href="/en/spring-boot/getting-help.html" class="nav-link">
  Spring Boot
</a></div><div class="nav-item"><a href="/en/spring-cloud/documentation-overview.html" class="nav-link">
  Spring Cloud
</a></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="Others" class="dropdown-title"><span class="title">more</span> <span class="arrow down"></span></button> <button type="button" aria-label="Others" class="mobile-dropdown-title"><span class="title">more</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/en/spring-framework/overview.html" class="nav-link">
  Spring Framework
</a></li><li class="dropdown-item"><!----> <a href="/en/spring-data/spring-data.html" class="nav-link">
  Spring Data
</a></li><li class="dropdown-item"><!----> <a href="/en/spring-cloud-data-flow/spring-cloud-dataflow.html" class="nav-link">
  Spring Cloud Data Flow
</a></li><li class="dropdown-item"><!----> <a href="/en/spring-security/overview.html" class="nav-link">
  Spring Security
</a></li><li class="dropdown-item"><!----> <a href="/en/spring-for-graphql/spring-graphql.html" class="nav-link">
  Spring for GraphQL
</a></li><li class="dropdown-item"><!----> <a href="/en/spring-session/_index.html" class="nav-link">
  Spring Session
</a></li><li class="dropdown-item"><!----> <a href="/en/spring-integration/preface.html" class="nav-link">
  Spring Integration
</a></li><li class="dropdown-item"><!----> <a href="/en/spring-hateoas/spring-hateoas.html" class="nav-link">
  Spring HATEOAS
</a></li><li class="dropdown-item"><!----> <a href="/en/spring-rest-docs/spring-restdocs.html" class="nav-link">
  Spring REST Docs
</a></li><li class="dropdown-item"><!----> <a href="/en/spring-batch/spring-batch-intro.html" class="nav-link">
  Spring Batch
</a></li><li class="dropdown-item"><!----> <a href="/en/spring-amqp/spring-amqp.html" class="nav-link">
  Spring AMQP
</a></li><li class="dropdown-item"><!----> <a href="/en/spring-credhub/spring-credhub.html" class="nav-link">
  Spring CredHub
</a></li><li class="dropdown-item"><!----> <a href="/en/spring-flo/spring-flo.html" class="nav-link">
  Spring Flo
</a></li><li class="dropdown-item"><!----> <a href="/en/spring-for-apache-kafka/spring-kafka.html" class="nav-link">
  Spring for Apache Kafka
</a></li><li class="dropdown-item"><!----> <a href="/en/spring-ldap/spring-ldap.html" class="nav-link">
  Spring LDAP
</a></li><li class="dropdown-item"><!----> <a href="/en/spring-shell/spring-shell.html" class="nav-link">
  Spring Shell
</a></li><li class="dropdown-item"><!----> <a href="/en/spring-statemachine/spring-statemachine.html" class="nav-link">
  Spring Statemachine
</a></li><li class="dropdown-item"><!----> <a href="/en/spring-vault/spring-vault.html" class="nav-link">
  Spring Vault
</a></li><li class="dropdown-item"><!----> <a href="/en/spring-web-flow/preface.html" class="nav-link">
  Spring Web Flow
</a></li><li class="dropdown-item"><!----> <a href="/en/spring-web-services/spring-web-service.html" class="nav-link">
  Spring Web Services
</a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="Select language" class="dropdown-title"><span class="title">Language</span> <span class="arrow down"></span></button> <button type="button" aria-label="Select language" class="mobile-dropdown-title"><span class="title">Language</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/en/spring-integration/jdbc.html" aria-current="page" class="nav-link router-link-exact-active router-link-active">
  English
</a></li><li class="dropdown-item"><!----> <a href="/spring-integration/jdbc.html" class="nav-link">
  简体中文
</a></li></ul></div></div> <a href="https://gitcode.net/dev-cloud/spring-docs" target="_blank" rel="noopener noreferrer" class="repo-link">
    GitCode
    <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></nav>  <ul class="sidebar-links"><li><section class="sidebar-group depth-0"><p class="sidebar-heading open"><span>Spring Integration</span> <!----></p> <ul class="sidebar-links sidebar-group-items"><li><a href="/en/spring-integration/preface.html" class="sidebar-link">Preface</a></li><li><a href="/en/spring-integration/whats-new.html" class="sidebar-link">What’s New?</a></li><li><a href="/en/spring-integration/overview.html" class="sidebar-link">Overview of Spring Integration Framework</a></li><li><a href="/en/spring-integration/core.html" class="sidebar-link">Core Messaging</a></li><li><a href="/en/spring-integration/message.html" class="sidebar-link">Message</a></li><li><a href="/en/spring-integration/message-routing.html" class="sidebar-link">Message Routing</a></li><li><a href="/en/spring-integration/message-transformation.html" class="sidebar-link">Message Transformation</a></li><li><a href="/en/spring-integration/messaging-endpoints.html" class="sidebar-link">Messaging Endpoints</a></li><li><a href="/en/spring-integration/dsl.html" class="sidebar-link">Java DSL</a></li><li><a href="/en/spring-integration/kotlin-dsl.html" class="sidebar-link">Kotlin DSL</a></li><li><a href="/en/spring-integration/system-management.html" class="sidebar-link">System Management</a></li><li><a href="/en/spring-integration/reactive-streams.html" class="sidebar-link">Reactive Streams Support</a></li><li><a href="/en/spring-integration/endpoint-summary.html" class="sidebar-link">Integration Endpoints</a></li><li><a href="/en/spring-integration/amqp.html" class="sidebar-link">AMQP Support</a></li><li><a href="/en/spring-integration/event.html" class="sidebar-link">Spring ApplicationEvent Support</a></li><li><a href="/en/spring-integration/feed.html" class="sidebar-link">Feed Adapter</a></li><li><a href="/en/spring-integration/file.html" class="sidebar-link">File Support</a></li><li><a href="/en/spring-integration/ftp.html" class="sidebar-link">FTP/FTPS</a></li><li><a href="/en/spring-integration/gemfire.html" class="sidebar-link">Pivotal GemFire and Apache Geode Support</a></li><li><a href="/en/spring-integration/http.html" class="sidebar-link">HTTP Support</a></li><li><a href="/en/spring-integration/jdbc.html" aria-current="page" class="active sidebar-link">JDBC Support</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/en/spring-integration/jdbc.html#jdbc-support-2" class="sidebar-link">JDBC Support</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/en/spring-integration/jdbc.html#inbound-channel-adapter" class="sidebar-link">Inbound Channel Adapter</a></li><li class="sidebar-sub-header"><a href="/en/spring-integration/jdbc.html#outbound-channel-adapter" class="sidebar-link">Outbound Channel Adapter</a></li><li class="sidebar-sub-header"><a href="/en/spring-integration/jdbc.html#outbound-gateway" class="sidebar-link">Outbound Gateway</a></li><li class="sidebar-sub-header"><a href="/en/spring-integration/jdbc.html#jdbc-message-store" class="sidebar-link">JDBC Message Store</a></li><li class="sidebar-sub-header"><a href="/en/spring-integration/jdbc.html#stored-procedures" class="sidebar-link">Stored Procedures</a></li><li class="sidebar-sub-header"><a href="/en/spring-integration/jdbc.html#jdbc-lock-registry" class="sidebar-link">JDBC Lock Registry</a></li><li class="sidebar-sub-header"><a href="/en/spring-integration/jdbc.html#jdbc-metadata-store" class="sidebar-link">JDBC Metadata Store</a></li></ul></li></ul></li><li><a href="/en/spring-integration/jpa.html" class="sidebar-link">JPA Support</a></li><li><a href="/en/spring-integration/jms.html" class="sidebar-link">JMS Support</a></li><li><a href="/en/spring-integration/jmx.html" class="sidebar-link">JMX Support</a></li><li><a href="/en/spring-integration/kafka.html" class="sidebar-link">Apache Kafka Support</a></li><li><a href="/en/spring-integration/mail.html" class="sidebar-link">Mail Support</a></li><li><a href="/en/spring-integration/mongodb.html" class="sidebar-link">MongoDb Support</a></li><li><a href="/en/spring-integration/mqtt.html" class="sidebar-link">MQTT Support</a></li><li><a href="/en/spring-integration/r2dbc.html" class="sidebar-link">R2DBC Support</a></li><li><a href="/en/spring-integration/redis.html" class="sidebar-link">Redis Support</a></li><li><a href="/en/spring-integration/resource.html" class="sidebar-link">Resource Support</a></li><li><a href="/en/spring-integration/rmi.html" class="sidebar-link">RMI Support</a></li><li><a href="/en/spring-integration/rsocket.html" class="sidebar-link">RSocket Support</a></li><li><a href="/en/spring-integration/sftp.html" class="sidebar-link">SFTP Adapters</a></li><li><a href="/en/spring-integration/stomp.html" class="sidebar-link">STOMP Support</a></li><li><a href="/en/spring-integration/stream.html" class="sidebar-link">Stream Support</a></li><li><a href="/en/spring-integration/syslog.html" class="sidebar-link">Syslog Support</a></li><li><a href="/en/spring-integration/ip.html" class="sidebar-link">TCP and UDP Support</a></li><li><a href="/en/spring-integration/webflux.html" class="sidebar-link">WebFlux Support</a></li><li><a href="/en/spring-integration/web-sockets.html" class="sidebar-link">WebSockets Support</a></li><li><a href="/en/spring-integration/ws.html" class="sidebar-link">Web Services Support</a></li><li><a href="/en/spring-integration/xml.html" class="sidebar-link">XML Support - Dealing with XML Payloads</a></li><li><a href="/en/spring-integration/xmpp.html" class="sidebar-link">XMPP Support</a></li><li><a href="/en/spring-integration/zeromq.html" class="sidebar-link">ZeroMQ Support</a></li><li><a href="/en/spring-integration/zookeeper.html" class="sidebar-link">Zookeeper Support</a></li><li><a href="/en/spring-integration/error-handling.html" class="sidebar-link">Error Handling</a></li><li><a href="/en/spring-integration/spel.html" class="sidebar-link">Spring Expression Language (SpEL)</a></li><li><a href="/en/spring-integration/message-publishing.html" class="sidebar-link">Message Publishing</a></li><li><a href="/en/spring-integration/transactions.html" class="sidebar-link">Transaction Support</a></li><li><a href="/en/spring-integration/security.html" class="sidebar-link">Security in Spring Integration</a></li><li><a href="/en/spring-integration/configuration.html" class="sidebar-link">Configuration</a></li><li><a href="/en/spring-integration/testing.html" class="sidebar-link">Testing support</a></li><li><a href="/en/spring-integration/samples.html" class="sidebar-link">Spring Integration Samples</a></li><li><a href="/en/spring-integration/resources.html" class="sidebar-link">Additional Resources</a></li><li><a href="/en/spring-integration/history.html" class="sidebar-link">Change History</a></li></ul></section></li></ul> </aside> <main class="page"> <div class="theme-default-content content__default"><h1 id="jdbc-support"><a href="#jdbc-support" class="header-anchor">#</a> JDBC Support</h1> <h2 id="jdbc-support-2"><a href="#jdbc-support-2" class="header-anchor">#</a> JDBC Support</h2> <p>Spring Integration provides channel adapters for receiving and sending messages by using database queries.
Through those adapters, Spring Integration supports not only plain JDBC SQL queries but also stored procedure and stored function calls.</p> <p>You need to include this dependency into your project:</p> <p>Maven</p> <div class="language- extra-class"><pre class="language-text"><code>&lt;dependency&gt;
    &lt;groupId&gt;org.springframework.integration&lt;/groupId&gt;
    &lt;artifactId&gt;spring-integration-jdbc&lt;/artifactId&gt;
    &lt;version&gt;5.5.9&lt;/version&gt;
&lt;/dependency&gt;
</code></pre></div><p>Gradle</p> <div class="language- extra-class"><pre class="language-text"><code>compile &quot;org.springframework.integration:spring-integration-jdbc:5.5.9&quot;
</code></pre></div><p>By default, the following JDBC components are available:</p> <ul><li><p><a href="#jdbc-inbound-channel-adapter">Inbound Channel Adapter</a></p></li> <li><p><a href="#jdbc-outbound-channel-adapter">Outbound Channel Adapter</a></p></li> <li><p><a href="#jdbc-outbound-gateway">Outbound Gateway</a></p></li> <li><p><a href="#stored-procedure-inbound-channel-adapter">Stored Procedure Inbound Channel Adapter</a></p></li> <li><p><a href="#stored-procedure-outbound-channel-adapter">Stored Procedure Outbound Channel Adapter</a></p></li> <li><p><a href="#stored-procedure-outbound-gateway">Stored Procedure Outbound Gateway</a></p></li></ul> <p>The Spring Integration JDBC Module also provides a <a href="#jdbc-message-store">JDBC Message Store</a>.</p> <h3 id="inbound-channel-adapter"><a href="#inbound-channel-adapter" class="header-anchor">#</a> Inbound Channel Adapter</h3> <p>The main function of an inbound channel adapter is to execute a SQL <code>SELECT</code> query and turn the result set into a message.
The message payload is the whole result set (expressed as a <code>List</code>), and the types of the items in the list depend on the row-mapping strategy.
The default strategy is a generic mapper that returns a <code>Map</code> for each row in the query result.
Optionally, you can change this by adding a reference to a <code>RowMapper</code> instance (see the <a href="https://docs.spring.io/spring/docs/current/spring-framework-reference/html/jdbc.html" target="_blank" rel="noopener noreferrer">Spring JDBC<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a> documentation for more detailed information about row mapping).</p> <table><thead><tr><th></th> <th>If you want to convert rows in the <code>SELECT</code> query result to individual messages, you can use a downstream splitter.</th></tr></thead> <tbody></tbody></table> <p>The inbound adapter also requires a reference to either a <code>JdbcTemplate</code> instance or a <code>DataSource</code>.</p> <p>As well as the <code>SELECT</code> statement to generate the messages, the adapter also has an <code>UPDATE</code> statement that marks the records as processed so that they do not show up in the next poll.
The update can be parameterized by the list of IDs from the original select.
By default, this is done through a naming convention (a column in the input result set called <code>id</code> is translated into a list in the parameter map for the update called <code>id</code>).
The following example defines an inbound channel adapter with an update query and a <code>DataSource</code> reference.</p> <div class="language- extra-class"><pre class="language-text"><code>&lt;int-jdbc:inbound-channel-adapter query=&quot;select * from item where status=2&quot;
    channel=&quot;target&quot; data-source=&quot;dataSource&quot;
    update=&quot;update item set status=10 where id in (:id)&quot; /&gt;
</code></pre></div><table><thead><tr><th></th> <th>The parameters in the update query are specified with a colon (<code>:</code>) prefix to the name of a parameter (which, in the preceding example, is an expression to be applied to each of the rows in the polled result set).<br>This is a standard feature of the named parameter JDBC support in Spring JDBC, combined with a convention (projection onto the polled result list) adopted in Spring Integration.<br>The underlying Spring JDBC features limit the available expressions (for example, most special characters other than a period are disallowed), but since the target is usually a list of objects (possibly a list of one) that are addressable by bean paths this is not unduly restrictive.</th></tr></thead> <tbody></tbody></table> <p>To change the parameter generation strategy, you can inject a <code>SqlParameterSourceFactory</code> into the adapter to override the default behavior (the adapter has a <code>sql-parameter-source-factory</code> attribute).
Spring Integration provides <code>ExpressionEvaluatingSqlParameterSourceFactory</code>, which creates a SpEL-based parameter source, with the results of the query as the <code>#root</code> object.
(If <code>update-per-row</code> is true, the root object is the row).
If the same parameter name appears multiple times in the update query, it is evaluated only once, and its result is cached.</p> <p>You can also use a parameter source for the select query.
In this case, since there is no “result” object to evaluate against, a single parameter source is used each time (rather than using a parameter source factory).
Starting with version 4.0, you can use Spring to create a SpEL based parameter source, as the following example shows:</p> <div class="language- extra-class"><pre class="language-text"><code>&lt;int-jdbc:inbound-channel-adapter query=&quot;select * from item where status=:status&quot;
	channel=&quot;target&quot; data-source=&quot;dataSource&quot;
	select-sql-parameter-source=&quot;parameterSource&quot; /&gt;

&lt;bean id=&quot;parameterSource&quot; factory-bean=&quot;parameterSourceFactory&quot;
			factory-method=&quot;createParameterSourceNoCache&quot;&gt;
	&lt;constructor-arg value=&quot;&quot; /&gt;
&lt;/bean&gt;

&lt;bean id=&quot;parameterSourceFactory&quot;
		class=&quot;o.s.integration.jdbc.ExpressionEvaluatingSqlParameterSourceFactory&quot;&gt;
	&lt;property name=&quot;parameterExpressions&quot;&gt;
		&lt;map&gt;
			&lt;entry key=&quot;status&quot; value=&quot;@statusBean.which()&quot; /&gt;
		&lt;/map&gt;
	&lt;/property&gt;
&lt;/bean&gt;

&lt;bean id=&quot;statusBean&quot; class=&quot;foo.StatusDetermination&quot; /&gt;
</code></pre></div><p>The <code>value</code> in each parameter expression can be any valid SpEL expression.
The <code>#root</code> object for the expression evaluation is the constructor argument defined on the <code>parameterSource</code> bean.
It is static for all evaluations (in the preceding example, an empty <code>String</code>).</p> <p>Starting with version 5.0, you ca supply <code>ExpressionEvaluatingSqlParameterSourceFactory</code> with <code>sqlParameterTypes</code> to specify the target SQL type for the particular parameter.</p> <p>The following example provides SQL types for the parameters being used in the query:</p> <div class="language- extra-class"><pre class="language-text"><code>&lt;int-jdbc:inbound-channel-adapter query=&quot;select * from item where status=:status&quot;
    channel=&quot;target&quot; data-source=&quot;dataSource&quot;
    select-sql-parameter-source=&quot;parameterSource&quot; /&gt;

&lt;bean id=&quot;parameterSource&quot; factory-bean=&quot;parameterSourceFactory&quot;
            factory-method=&quot;createParameterSourceNoCache&quot;&gt;
    &lt;constructor-arg value=&quot;&quot; /&gt;
&lt;/bean&gt;

&lt;bean id=&quot;parameterSourceFactory&quot;
        class=&quot;o.s.integration.jdbc.ExpressionEvaluatingSqlParameterSourceFactory&quot;&gt;
    &lt;property name=&quot;sqlParameterTypes&quot;&gt;
        &lt;map&gt;
            &lt;entry key=&quot;status&quot; value=&quot;#{ T(java.sql.Types).BINARY}&quot; /&gt;
        &lt;/map&gt;
    &lt;/property&gt;
&lt;/bean&gt;
</code></pre></div><table><thead><tr><th></th> <th>Use the <code>createParameterSourceNoCache</code> factory method.<br>Otherwise, the parameter source caches the result of the evaluation.<br>Also note that, because caching is disabled, if the same parameter name appears in the select query multiple times, it is re-evaluated for each occurrence.</th></tr></thead> <tbody></tbody></table> <h4 id="polling-and-transactions"><a href="#polling-and-transactions" class="header-anchor">#</a> Polling and Transactions</h4> <p>The inbound adapter accepts a regular Spring Integration poller as a child element.
Consequently, the frequency of the polling can be controlled (among other uses).
An important feature of the poller for JDBC usage is the option to wrap the poll operation in a transaction, as the following example shows:</p> <div class="language- extra-class"><pre class="language-text"><code>&lt;int-jdbc:inbound-channel-adapter query=&quot;...&quot;
        channel=&quot;target&quot; data-source=&quot;dataSource&quot; update=&quot;...&quot;&gt;
    &lt;int:poller fixed-rate=&quot;1000&quot;&gt;
        &lt;int:transactional/&gt;
    &lt;/int:poller&gt;
&lt;/int-jdbc:inbound-channel-adapter&gt;
</code></pre></div><table><thead><tr><th></th> <th>If you do not explicitly specify a poller, a default value is used.<br>As is normal with Spring Integration, it can be defined as a top-level bean).</th></tr></thead> <tbody></tbody></table> <p>In the preceding example, the database is polled every 1000 milliseconds (or once a second), and the update and select queries are both executed in the same transaction.
The transaction manager configuration is not shown.
However, as long as it is aware of the data source, the poll is transactional.
A common use case is for the downstream channels to be direct channels (the default), so that the endpoints are invoked in the same thread and, hence, the same transaction.
That way, if any of them fail, the transaction rolls back and the input data is reverted to its original state.</p> <h4 id="max-rows-versus-max-messages-per-poll"><a href="#max-rows-versus-max-messages-per-poll" class="header-anchor">#</a> <code>max-rows</code> Versus <code>max-messages-per-poll</code></h4> <p>The JDBC inbound channel adapter defines an attribute called <code>max-rows</code>.
When you specify the adapter’s poller, you can also define a property called <code>max-messages-per-poll</code>.
While these two attributes look similar, their meaning is quite different.</p> <p><code>max-messages-per-poll</code> specifies the number of times the query is executed per polling interval, whereas <code>max-rows</code> specifies the number of rows returned for each execution.</p> <p>Under normal circumstances, you would likely not want to set the poller’s <code>max-messages-per-poll</code> property when you use the JDBC inbound channel adapter.
Its default value is <code>1</code>, which means that the JDBC inbound channel adapter’s <a href="https://docs.spring.io/spring-integration/api/org/springframework/integration/jdbc/JdbcPollingChannelAdapter.html#receive()" target="_blank" rel="noopener noreferrer"><code>receive()</code><span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a> method is executed exactly once for each poll interval.</p> <p>Setting the <code>max-messages-per-poll</code> attribute to a larger value means that the query is executed that many times back to back.
For more information regarding the <code>max-messages-per-poll</code> attribute, see <a href="/en/spring-integration/channel-adapter.html#channel-adapter-namespace-inbound">Configuring An Inbound Channel Adapter</a>.</p> <p>In contrast, the <code>max-rows</code> attribute, if greater than <code>0</code>, specifies the maximum number of rows to be used from the query result set created by the <code>receive()</code> method.
If the attribute is set to <code>0</code>, all rows are included in the resulting message.
The attribute defaults to <code>0</code>.</p> <table><thead><tr><th></th> <th>It is recommended to use result set limiting via vendor-specific query options, for example MySQL <code>LIMIT</code> or SQL Server <code>TOP</code> or Oracle’s <code>ROWNUM</code>.<br>See the particular vendor documentation for more information.</th></tr></thead> <tbody></tbody></table> <h3 id="outbound-channel-adapter"><a href="#outbound-channel-adapter" class="header-anchor">#</a> Outbound Channel Adapter</h3> <p>The outbound channel adapter is the inverse of the inbound: its role is to handle a message and use it to execute a SQL query.
By default, the message payload and headers are available as input parameters to the query, as the following example shows:</p> <div class="language- extra-class"><pre class="language-text"><code>&lt;int-jdbc:outbound-channel-adapter
    query=&quot;insert into foos (id, status, name) values (:headers[id], 0, :payload[something])&quot;
    data-source=&quot;dataSource&quot;
    channel=&quot;input&quot;/&gt;
</code></pre></div><p>In the preceding example, messages arriving on the channel labelled <code>input</code> have a payload of a map with a key of <code>something</code>, so the <code>[]</code> operator dereferences that value from the map.
The headers are also accessed as a map.</p> <table><thead><tr><th></th> <th>The parameters in the preceding query are bean property expressions on the incoming message (not SpEL expressions).<br>This behavior is part of the <code>SqlParameterSource</code>, which is the default source created by the outbound adapter.<br>You can inject a different <code>SqlParameterSourceFactory</code> to get different behavior.</th></tr></thead> <tbody></tbody></table> <p>The outbound adapter requires a reference to either a <code>DataSource</code> or a <code>JdbcTemplate</code>.
You can also inject a <code>SqlParameterSourceFactory</code> to control the binding of each incoming message to a query.</p> <p>If the input channel is a direct channel, the outbound adapter runs its query in the same thread and, therefore, the same transaction (if there is one) as the sender of the message.</p> <h4 id="passing-parameters-by-using-spel-expressions"><a href="#passing-parameters-by-using-spel-expressions" class="header-anchor">#</a> Passing Parameters by Using SpEL Expressions</h4> <p>A common requirement for most JDBC channel adapters is to pass parameters as part of SQL queries or stored procedures or functions.
As mentioned earlier, these parameters are by default bean property expressions, not SpEL expressions.
However, if you need to pass SpEL expression as parameters, you must explicitly inject a <code>SqlParameterSourceFactory</code>.</p> <p>The following example uses a <code>ExpressionEvaluatingSqlParameterSourceFactory</code> to achieve that requirement:</p> <div class="language- extra-class"><pre class="language-text"><code>&lt;jdbc:outbound-channel-adapter data-source=&quot;dataSource&quot; channel=&quot;input&quot;
    query=&quot;insert into MESSAGES (MESSAGE_ID,PAYLOAD,CREATED_DATE)     \
    values (:id, :payload, :createdDate)&quot;
    sql-parameter-source-factory=&quot;spelSource&quot;/&gt;

&lt;bean id=&quot;spelSource&quot;
      class=&quot;o.s.integration.jdbc.ExpressionEvaluatingSqlParameterSourceFactory&quot;&gt;
    &lt;property name=&quot;parameterExpressions&quot;&gt;
        &lt;map&gt;
            &lt;entry key=&quot;id&quot;          value=&quot;headers['id'].toString()&quot;/&gt;
            &lt;entry key=&quot;createdDate&quot; value=&quot;new java.util.Date()&quot;/&gt;
            &lt;entry key=&quot;payload&quot;     value=&quot;payload&quot;/&gt;
        &lt;/map&gt;
    &lt;/property&gt;
&lt;/bean&gt;
</code></pre></div><p>For further information, see <a href="#sp-defining-parameter-sources">Defining Parameter Sources</a>.</p> <h4 id="using-the-preparedstatement-callback"><a href="#using-the-preparedstatement-callback" class="header-anchor">#</a> Using the <code>PreparedStatement</code> Callback</h4> <p>Sometimes, the flexibility and loose-coupling of <code>SqlParameterSourceFactory</code> does not do what we need for the target <code>PreparedStatement</code> or we need to do some low-level JDBC work.
The Spring JDBC module provides APIs to configure the execution environment (such as <code>ConnectionCallback</code> or <code>PreparedStatementCreator</code>) and manipulate parameter values (such as <code>SqlParameterSource</code>).
It can even access APIs for low-level operations, such as <code>StatementCallback</code>.</p> <p>Starting with Spring Integration 4.2, <code>MessagePreparedStatementSetter</code> allows the specification of parameters on the <code>PreparedStatement</code> manually, in the <code>requestMessage</code> context.
This class plays exactly the same role as <code>PreparedStatementSetter</code> in the standard Spring JDBC API.
Actually, it is invoked directly from an inline <code>PreparedStatementSetter</code> implementation when the <code>JdbcMessageHandler</code> invokes <code>execute</code> on the <code>JdbcTemplate</code>.</p> <p>This functional interface option is mutually exclusive with <code>sqlParameterSourceFactory</code> and can be used as a more powerful alternative to populate parameters of the <code>PreparedStatement</code> from the <code>requestMessage</code>.
For example, it is useful when we need to store <code>File</code> data to the DataBase <code>BLOB</code> column in a streaming manner.
The following example shows how to do so:</p> <div class="language- extra-class"><pre class="language-text"><code>@Bean
@ServiceActivator(inputChannel = &quot;storeFileChannel&quot;)
public MessageHandler jdbcMessageHandler(DataSource dataSource) {
    JdbcMessageHandler jdbcMessageHandler = new JdbcMessageHandler(dataSource,
            &quot;INSERT INTO imagedb (image_name, content, description) VALUES (?, ?, ?)&quot;);
    jdbcMessageHandler.setPreparedStatementSetter((ps, m) -&gt; {
        ps.setString(1, m.getHeaders().get(FileHeaders.FILENAME));
        try (FileInputStream inputStream = new FileInputStream((File) m.getPayload()); ) {
            ps.setBlob(2, inputStream);
        }
        catch (Exception e) {
            throw new MessageHandlingException(m, e);
        }
        ps.setClob(3, new StringReader(m.getHeaders().get(&quot;description&quot;, String.class)));
    });
    return jdbcMessageHandler;
}
</code></pre></div><p>From the XML configuration perspective, the <code>prepared-statement-setter</code> attribute is available on the <code>&lt;int-jdbc:outbound-channel-adapter&gt;</code> component.
It lets you specify a <code>MessagePreparedStatementSetter</code> bean reference.</p> <h4 id="batch-update"><a href="#batch-update" class="header-anchor">#</a> Batch Update</h4> <p>Starting with version 5.1, the <code>JdbcMessageHandler</code> performs a <code>JdbcOperations.batchUpdate()</code> if the payload of the request message is an <code>Iterable</code> instance.
Each element of the <code>Iterable</code> is wrapped to a <code>Message</code> with the headers from the request message.
In the case of regular <code>SqlParameterSourceFactory</code>-based configuration these messages are used to build an <code>SqlParameterSource[]</code> for an argument used in the mentioned <code>JdbcOperations.batchUpdate()</code> function.
When a <code>MessagePreparedStatementSetter</code> configuration is applied, a <code>BatchPreparedStatementSetter</code> variant is used to iterate over those messages for each item and the provided <code>MessagePreparedStatementSetter</code> is called against them.
The batch update is not supported when <code>keysGenerated</code> mode is selected.</p> <h3 id="outbound-gateway"><a href="#outbound-gateway" class="header-anchor">#</a> Outbound Gateway</h3> <p>The outbound gateway is like a combination of the outbound and inbound adapters: Its role is to handle a message and use it to execute a SQL query and then respond with the result by sending it to a reply channel.
By default, the message payload and headers are available as input parameters to the query, as the following example shows:</p> <div class="language- extra-class"><pre class="language-text"><code>&lt;int-jdbc:outbound-gateway
    update=&quot;insert into mythings (id, status, name) values (:headers[id], 0, :payload[thing])&quot;
    request-channel=&quot;input&quot; reply-channel=&quot;output&quot; data-source=&quot;dataSource&quot; /&gt;
</code></pre></div><p>The result of the preceding example is to insert a record into the <code>mythings</code> table and return a message that indicates the number of rows affected (the payload is a map: <code>{UPDATED=1}</code>) to the output channel .</p> <p>If the update query is an insert with auto-generated keys, you can populate the reply message with the generated keys by adding <code>keys-generated=&quot;true&quot;</code> to the preceding example (this is not the default because it is not supported by some database platforms).
The following example shows the changed configuration:</p> <div class="language- extra-class"><pre class="language-text"><code>&lt;int-jdbc:outbound-gateway
    update=&quot;insert into mythings (status, name) values (0, :payload[thing])&quot;
    request-channel=&quot;input&quot; reply-channel=&quot;output&quot; data-source=&quot;dataSource&quot;
    keys-generated=&quot;true&quot;/&gt;
</code></pre></div><p>Instead of the update count or the generated keys, you can also provide a select query to execute and generate a reply message from the result (such as the inbound adapter), as the following example shows:</p> <div class="language- extra-class"><pre class="language-text"><code>&lt;int-jdbc:outbound-gateway
    update=&quot;insert into foos (id, status, name) values (:headers[id], 0, :payload[foo])&quot;
    query=&quot;select * from foos where id=:headers[$id]&quot;
    request-channel=&quot;input&quot; reply-channel=&quot;output&quot; data-source=&quot;dataSource&quot;/&gt;
</code></pre></div><p>Since Spring Integration 2.2, the update SQL query is no longer mandatory.
You can now provide only a select query, by using either the <code>query</code> attribute or the <code>query</code> element.
This is extremely useful if you need to actively retrieve data by using, for example, a generic gateway or a payload enricher.
The reply message is then generated from the result (similar to how the inbound adapter works) and passed to the reply channel.
The following example show to use the <code>query</code> attribute:</p> <div class="language- extra-class"><pre class="language-text"><code>&lt;int-jdbc:outbound-gateway
    query=&quot;select * from foos where id=:headers[id]&quot;
    request-channel=&quot;input&quot;
    reply-channel=&quot;output&quot;
    data-source=&quot;dataSource&quot;/&gt;
</code></pre></div><table><thead><tr><th></th> <th>By default, the component for the <code>SELECT</code> query returns only one (the first) row from the cursor.<br>You can adjust this behavior with the <code>max-rows</code> option.<br>If you need to return all the rows from the SELECT, consider specifying <code>max-rows=&quot;0&quot;</code>.</th></tr></thead> <tbody></tbody></table> <p>As with the channel adapters, you can also provide <code>SqlParameterSourceFactory</code> instances for request and reply.
The default is the same as for the outbound adapter, so the request message is available as the root of an expression.
If <code>keys-generated=&quot;true&quot;</code>, the root of the expression is the generated keys (a map if there is only one or a list of maps if multi-valued).</p> <p>The outbound gateway requires a reference to either a <code>DataSource</code> or a <code>JdbcTemplate</code>.
It can also have a <code>SqlParameterSourceFactory</code> injected to control the binding of the incoming message to the query.</p> <p>Starting with the version 4.2, the <code>request-prepared-statement-setter</code> attribute is available on the <code>&lt;int-jdbc:outbound-gateway&gt;</code> as an alternative to <code>request-sql-parameter-source-factory</code>.
It lets you specify a <code>MessagePreparedStatementSetter</code> bean reference, which implements more sophisticated <code>PreparedStatement</code> preparation before its execution.</p> <p>See <a href="#jdbc-outbound-channel-adapter">Outbound Channel Adapter</a> for more information about <code>MessagePreparedStatementSetter</code>.</p> <h3 id="jdbc-message-store"><a href="#jdbc-message-store" class="header-anchor">#</a> JDBC Message Store</h3> <p>Spring Integration provides two JDBC specific message store implementations.
The <code>JdbcMessageStore</code> is suitable for use with aggregators and the claim check pattern.
The <code>JdbcChannelMessageStore</code> implementation provides a more targeted and scalable implementation specifically for message channel.</p> <p>Note that you can use a <code>JdbcMessageStore</code> to back a message channel, <code>JdbcChannelMessageStore</code> is optimized for that purpose.</p> <table><thead><tr><th></th> <th>Starting with versions 5.0.11, 5.1.2, the indexes for the <code>JdbcChannelMessageStore</code> have been optimized.<br>If you have large message groups in such a store, you may wish to alter the indexes.<br>Furthermore, the index for <code>PriorityChannel</code> is commented out because it is not needed unless you are using such channels backed by JDBC.</th></tr></thead> <tbody></tbody></table> <table><thead><tr><th></th> <th>When using the <code>OracleChannelMessageStoreQueryProvider</code>, the priority channel index <strong>must</strong> be added because it is included in a hint in the query.</th></tr></thead> <tbody></tbody></table> <h4 id="initializing-the-database"><a href="#initializing-the-database" class="header-anchor">#</a> Initializing the Database</h4> <p>Before starting to use JDBC message store components, you should provision a target database with the appropriate objects.</p> <p>Spring Integration ships with some sample scripts that can be used to initialize a database.
In the <code>spring-integration-jdbc</code> JAR file, you can find scripts in the <code>org.springframework.integration.jdbc</code> package.
It provides an example create and an example drop script for a range of common database platforms.
A common way to use these scripts is to reference them in a <a href="https://docs.spring.io/spring/docs/current/spring-framework-reference/html/jdbc.html#jdbc-intializing-datasource" target="_blank" rel="noopener noreferrer">Spring JDBC data source initializer<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>.
Note that the scripts are provided as samples and as specifications of the required table and column names.
You may find that you need to enhance them for production use (for, example, by adding index declarations).</p> <h4 id="the-generic-jdbc-message-store"><a href="#the-generic-jdbc-message-store" class="header-anchor">#</a> The Generic JDBC Message Store</h4> <p>The JDBC module provides an implementation of the Spring Integration <code>MessageStore</code> (important in the claim check pattern) and <code>MessageGroupStore</code> (important in stateful patterns such as an aggregator) backed by a database.
Both interfaces are implemented by the <code>JdbcMessageStore</code>, and there is support for configuring store instances in XML, as the following example shows:</p> <div class="language- extra-class"><pre class="language-text"><code>&lt;int-jdbc:message-store id=&quot;messageStore&quot; data-source=&quot;dataSource&quot;/&gt;
</code></pre></div><p>You can specify a <code>JdbcTemplate</code> instead of a <code>DataSource</code>.</p> <p>The following example shows some other optional attributes:</p> <div class="language- extra-class"><pre class="language-text"><code>&lt;int-jdbc:message-store id=&quot;messageStore&quot; data-source=&quot;dataSource&quot;
    lob-handler=&quot;lobHandler&quot; table-prefix=&quot;MY_INT_&quot;/&gt;
</code></pre></div><p>In the preceding example, we have specified a <code>LobHandler</code> for dealing with messages as large objects (which is often necessary for Oracle) and a prefix for the table names in the queries generated by the store.
The table name prefix defaults to <code>INT_</code>.</p> <h4 id="backing-message-channels"><a href="#backing-message-channels" class="header-anchor">#</a> Backing Message Channels</h4> <p>If you intend to backing message channels with JDBC, we recommend using the <code>JdbcChannelMessageStore</code> implementation.
It works only in conjunction with Message Channels.</p> <h5 id="supported-databases"><a href="#supported-databases" class="header-anchor">#</a> Supported Databases</h5> <p>The <code>JdbcChannelMessageStore</code> uses database-specific SQL queries to retrieve messages from the database.
Therefore, you must set the <code>ChannelMessageStoreQueryProvider</code> property on the <code>JdbcChannelMessageStore</code>.
This <code>channelMessageStoreQueryProvider</code> provides the SQL queries for the particular database you specify.
Spring Integration provides support for the following relational databases:</p> <ul><li><p>PostgreSQL</p></li> <li><p>HSQLDB</p></li> <li><p>MySQL</p></li> <li><p>Oracle</p></li> <li><p>Derby</p></li> <li><p>H2</p></li> <li><p>SqlServer</p></li> <li><p>Sybase</p></li> <li><p>DB2</p></li></ul> <p>If your database is not listed, you can extend the <code>AbstractChannelMessageStoreQueryProvider</code> class and provide your own custom queries.</p> <p>Version 4.0 added the <code>MESSAGE_SEQUENCE</code> column to the table to ensure first-in-first-out (FIFO) queueing even when messages are stored in the same millisecond.</p> <h5 id="custom-message-insertion"><a href="#custom-message-insertion" class="header-anchor">#</a> Custom Message Insertion</h5> <p>Since version 5.0, by overloading the <code>ChannelMessageStorePreparedStatementSetter</code> class, you can provide a custom implementation for message insertion in the <code>JdbcChannelMessageStore</code>.
You can use it to set different columns or change the table structure or serialization strategy.
For example, instead of default serialization to <code>byte[]</code>, you can store its structure as a JSON string.</p> <p>The following example uses the default implementation of <code>setValues</code> to store common columns and overrides the behavior to store the message payload as a <code>varchar</code>:</p> <div class="language- extra-class"><pre class="language-text"><code>public class JsonPreparedStatementSetter extends ChannelMessageStorePreparedStatementSetter {

    @Override
    public void setValues(PreparedStatement preparedStatement, Message&lt;?&gt; requestMessage,
        Object groupId, String region, 	boolean priorityEnabled) throws SQLException {
        // Populate common columns
        super.setValues(preparedStatement, requestMessage, groupId, region, priorityEnabled);
        // Store message payload as varchar
        preparedStatement.setString(6, requestMessage.getPayload().toString());
    }
}
</code></pre></div><table><thead><tr><th></th> <th>Generally, we do not recommend using a relational database for queuing.<br>Instead, if possible, consider using either JMS- or AMQP-backed channels instead.<br>For further reference, see the following resources:<br><br>* <a href="https://www.engineyard.com/blog/2011/5-subtle-ways-youre-using-mysql-as-a-queue-and-why-itll-bite-you/" target="_blank" rel="noopener noreferrer">5 subtle ways you’re using MySQL as a queue, and why it’ll bite you<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>.<br><br>* <a href="https://mikehadlow.blogspot.com/2012/04/database-as-queue-anti-pattern.html" target="_blank" rel="noopener noreferrer">The Database As Queue Anti-Pattern<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>.</th></tr></thead> <tbody></tbody></table> <h5 id="concurrent-polling"><a href="#concurrent-polling" class="header-anchor">#</a> Concurrent Polling</h5> <p>When polling a message channel, you have the option to configure the associated <code>Poller</code> with a <code>TaskExecutor</code> reference.</p> <table><thead><tr><th></th> <th>Keep in mind, though, that if you use a JDBC backed message channel and you plan to poll the channel and consequently the message store transactionally with multiple threads, you should ensure that you use a relational database that supports <a href="https://en.wikipedia.org/wiki/Multiversion_concurrency_control" target="_blank" rel="noopener noreferrer">Multiversion Concurrency Control<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a> (MVCC).<br>Otherwise, locking may be an issue and the performance, when using multiple threads, may not materialize as expected.<br>For example, Apache Derby is problematic in that regard.<br><br>To achieve better JDBC queue throughput and avoid issues when different threads may poll the same <code>Message</code> from the queue, it is <strong>important</strong> to set the <code>usingIdCache</code> property of <code>JdbcChannelMessageStore</code> to <code>true</code> when using databases that do not support MVCC.<br>The following example shows how to do so:<br><br><code>&lt;br/&gt;&lt;bean id=&quot;queryProvider&quot;&lt;br/&gt; class=&quot;o.s.i.jdbc.store.channel.PostgresChannelMessageStoreQueryProvider&quot;/&gt;&lt;br/&gt;&lt;br/&gt;&lt;int:transaction-synchronization-factory id=&quot;syncFactory&quot;&gt;&lt;br/&gt; &lt;int:after-commit expression=&quot;@store.removeFromIdCache(headers.id.toString())&quot; /&gt;&lt;br/&gt; &lt;int:after-rollback expression=&quot;@store.removeFromIdCache(headers.id.toString())&quot;/&gt;&lt;br/&gt;&lt;/int:transaction-synchronization-factory&gt;&lt;br/&gt;&lt;br/&gt;&lt;task:executor id=&quot;pool&quot; pool-size=&quot;10&quot;&lt;br/&gt; queue-capacity=&quot;10&quot; rejection-policy=&quot;CALLER_RUNS&quot; /&gt;&lt;br/&gt;&lt;br/&gt;&lt;bean id=&quot;store&quot; class=&quot;o.s.i.jdbc.store.JdbcChannelMessageStore&quot;&gt;&lt;br/&gt; &lt;property name=&quot;dataSource&quot; ref=&quot;dataSource&quot;/&gt;&lt;br/&gt; &lt;property name=&quot;channelMessageStoreQueryProvider&quot; ref=&quot;queryProvider&quot;/&gt;&lt;br/&gt; &lt;property name=&quot;region&quot; value=&quot;TX_TIMEOUT&quot;/&gt;&lt;br/&gt; &lt;property name=&quot;usingIdCache&quot; value=&quot;true&quot;/&gt;&lt;br/&gt;&lt;/bean&gt;&lt;br/&gt;&lt;br/&gt;&lt;int:channel id=&quot;inputChannel&quot;&gt;&lt;br/&gt; &lt;int:queue message-store=&quot;store&quot;/&gt;&lt;br/&gt;&lt;/int:channel&gt;&lt;br/&gt;&lt;br/&gt;&lt;int:bridge input-channel=&quot;inputChannel&quot; output-channel=&quot;outputChannel&quot;&gt;&lt;br/&gt; &lt;int:poller fixed-delay=&quot;500&quot; receive-timeout=&quot;500&quot;&lt;br/&gt; max-messages-per-poll=&quot;1&quot; task-executor=&quot;pool&quot;&gt;&lt;br/&gt; &lt;int:transactional propagation=&quot;REQUIRED&quot; synchronization-factory=&quot;syncFactory&quot;&lt;br/&gt; isolation=&quot;READ_COMMITTED&quot; transaction-manager=&quot;transactionManager&quot; /&gt;&lt;br/&gt; &lt;/int:poller&gt;&lt;br/&gt;&lt;/int:bridge&gt;&lt;br/&gt;&lt;br/&gt;&lt;int:channel id=&quot;outputChannel&quot; /&gt;&lt;br/&gt;</code></th></tr></thead> <tbody></tbody></table> <h5 id="priority-channel"><a href="#priority-channel" class="header-anchor">#</a> Priority Channel</h5> <p>Starting with version 4.0, <code>JdbcChannelMessageStore</code> implements <code>PriorityCapableChannelMessageStore</code> and provides the <code>priorityEnabled</code> option, letting it be used as a <code>message-store</code> reference for <code>priority-queue</code> instances.
For this purpose, the <code>INT_CHANNEL_MESSAGE</code> table has a <code>MESSAGE_PRIORITY</code> column to store the value of <code>PRIORITY</code> message headers.
In addition, a new <code>MESSAGE_SEQUENCE</code> column lets us achieve a robust first-in-first-out (FIFO) polling mechanism, even when multiple messages are stored with the same priority in the same millisecond.
Messages are polled (selected) from the database with <code>order by MESSAGE_PRIORITY DESC NULLS LAST, CREATED_DATE, MESSAGE_SEQUENCE</code>.</p> <table><thead><tr><th></th> <th>We do not recommend using the same <code>JdbcChannelMessageStore</code> bean for priority and non-priority queue channels, because the <code>priorityEnabled</code> option applies to the entire store and proper FIFO queue semantics are not retained for the queue channel.<br>However, the same <code>INT_CHANNEL_MESSAGE</code> table (and even <code>region</code>) can be used for both <code>JdbcChannelMessageStore</code> types.<br>To configure that scenario, you can extend one message store bean from the other, as the following example shows:</th></tr></thead> <tbody></tbody></table> <div class="language- extra-class"><pre class="language-text"><code>&lt;bean id=&quot;channelStore&quot; class=&quot;o.s.i.jdbc.store.JdbcChannelMessageStore&quot;&gt;
    &lt;property name=&quot;dataSource&quot; ref=&quot;dataSource&quot;/&gt;
    &lt;property name=&quot;channelMessageStoreQueryProvider&quot; ref=&quot;queryProvider&quot;/&gt;
&lt;/bean&gt;

&lt;int:channel id=&quot;queueChannel&quot;&gt;
    &lt;int:queue message-store=&quot;channelStore&quot;/&gt;
&lt;/int:channel&gt;

&lt;bean id=&quot;priorityStore&quot; parent=&quot;channelStore&quot;&gt;
    &lt;property name=&quot;priorityEnabled&quot; value=&quot;true&quot;/&gt;
&lt;/bean&gt;

&lt;int:channel id=&quot;priorityChannel&quot;&gt;
    &lt;int:priority-queue message-store=&quot;priorityStore&quot;/&gt;
&lt;/int:channel&gt;
</code></pre></div><h4 id="partitioning-a-message-store"><a href="#partitioning-a-message-store" class="header-anchor">#</a> Partitioning a Message Store</h4> <p>It is common to use a <code>JdbcMessageStore</code> as a global store for a group of applications or nodes in the same application.
To provide some protection against name clashes and to give control over the database meta-data configuration, the message store lets the tables be partitioned in two ways.
One way is to use separate table names, by changing the prefix (as <a href="#jdbc-message-store-generic">described earlier</a>).
The other way is to specify a <code>region</code> name for partitioning data within a single table.
An important use case for the second approach is when the <code>MessageStore</code> is managing persistent queues that back a Spring Integration Message Channel.
The message data for a persistent channel is keyed in the store on the channel name.
Consequently, if the channel names are not globally unique, the channels can pick up data that is not intended for them.
To avoid this danger, you can use the message store <code>region</code> to keep data separate for different physical channels that have the same logical name.</p> <h3 id="stored-procedures"><a href="#stored-procedures" class="header-anchor">#</a> Stored Procedures</h3> <p>In certain situations, plain JDBC support is not sufficient.
Maybe you deal with legacy relational database schemas or you have complex data processing needs, but, ultimately, you have to use <a href="https://en.wikipedia.org/wiki/Stored_procedure" target="_blank" rel="noopener noreferrer">stored procedures<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a> or stored functions.
Since Spring Integration 2.1, we provide three components to execute stored procedures or stored functions:</p> <ul><li><p>Stored Procedures Inbound Channel Adapter</p></li> <li><p>Stored Procedures Outbound Channel Adapter</p></li> <li><p>Stored Procedures Outbound Gateway</p></li></ul> <h4 id="supported-databases-2"><a href="#supported-databases-2" class="header-anchor">#</a> Supported Databases</h4> <p>In order to enable calls to stored procedures and stored functions, the stored procedure components use the <a href="https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/jdbc/core/simple/SimpleJdbcCall.html" target="_blank" rel="noopener noreferrer"><code>org.springframework.jdbc.core.simple.SimpleJdbcCall</code><span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a> class.
Consequently, the following databases are fully supported for executing stored procedures:</p> <ul><li><p>Apache Derby</p></li> <li><p>DB2</p></li> <li><p>MySQL</p></li> <li><p>Microsoft SQL Server</p></li> <li><p>Oracle</p></li> <li><p>PostgreSQL</p></li> <li><p>Sybase</p></li></ul> <p>If you want to execute stored functions instead, the following databases are fully supported:</p> <ul><li><p>MySQL</p></li> <li><p>Microsoft SQL Server</p></li> <li><p>Oracle</p></li> <li><p>PostgreSQL</p></li></ul> <table><thead><tr><th></th> <th>Even though your particular database may not be fully supported, chances are that you can use the stored procedure Spring Integration components quite successfully anyway, provided your RDBMS supports stored procedures or stored functions.<br><br>As a matter of fact, some of the provided integration tests use the <a href="https://www.h2database.com/" target="_blank" rel="noopener noreferrer">H2 database<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>.<br>Nevertheless, it is very important to thoroughly test those usage scenarios.</th></tr></thead> <tbody></tbody></table> <h4 id="configuration"><a href="#configuration" class="header-anchor">#</a> Configuration</h4> <p>The stored procedure components provide full XML Namespace support, and configuring the components is similar as for the general purpose JDBC components discussed earlier.</p> <h4 id="common-configuration-attributes"><a href="#common-configuration-attributes" class="header-anchor">#</a> Common Configuration Attributes</h4> <p>All stored procedure components share certain configuration parameters:</p> <ul><li><p><code>auto-startup</code>: Lifecycle attribute signaling whether this component should be started during application context startup.
It defaults to <code>true</code>.
Optional.</p></li> <li><p><code>data-source</code>: Reference to a <code>javax.sql.DataSource</code>, which is used to access the database.
Required.</p></li> <li><p><code>id</code>: Identifies the underlying Spring bean definition, which is an instance of either <code>EventDrivenConsumer</code> or <code>PollingConsumer</code>, depending on whether the outbound channel adapter’s <code>channel</code> attribute references a <code>SubscribableChannel</code> or a <code>PollableChannel</code>.
Optional.</p></li> <li><p><code>ignore-column-meta-data</code>: For fully supported databases, the underlying <a href="https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/jdbc/core/simple/SimpleJdbcCall.html" target="_blank" rel="noopener noreferrer"><code>SimpleJdbcCall</code><span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a> class can automatically retrieve the parameter information for the stored procedure or stored function from the JDBC metadata.</p> <p>However, if the database does not support metadata lookups or if you need to provide customized parameter definitions, this flag can be set to <code>true</code>.
It defaults to <code>false</code>.
Optional.</p></li> <li><p><code>is-function</code>: If <code>true</code>, a SQL Function is called.
In that case, the <code>stored-procedure-name</code> or <code>stored-procedure-name-expression</code> attributes define the name of the called function.
It defaults to <code>false</code>.
Optional.</p></li> <li><p><code>stored-procedure-name</code>: This attribute specifies the name of the stored procedure.
If the <code>is-function</code> attribute is set to <code>true</code>, this attribute specifies the function name instead.
Either this property or <code>stored-procedure-name-expression</code> must be specified.</p></li> <li><p><code>stored-procedure-name-expression</code>: This attribute specifies the name of the stored procedure by using a SpEL expression.
By using SpEL, you have access to the full message (if available), including its headers and payload.
You can use this attribute to invoke different stored procedures at runtime.
For example, you can provide stored procedure names that you would like to execute as a message header.
The expression must resolve to a <code>String</code>.</p> <p>If the <code>is-function</code> attribute is set to <code>true</code>, this attribute specifies a stored function.
Either this property or <code>stored-procedure-name</code> must be specified.</p></li> <li><p><code>jdbc-call-operations-cache-size</code>: Defines the maximum number of cached <code>SimpleJdbcCallOperations</code> instances.
Basically, for each stored procedure name, a new <a href="https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/jdbc/core/simple/SimpleJdbcCallOperations.html" target="_blank" rel="noopener noreferrer"><code>SimpleJdbcCallOperations</code><span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a> instance is created that, in return, is cached.</p> <table><thead><tr><th></th> <th>Spring Integration 2.2 added the <code>stored-procedure-name-expression</code> attribute and the <code>jdbc-call-operations-cache-size</code> attribute.</th></tr></thead> <tbody></tbody></table> <p>The default cache size is <code>10</code>.
A value of <code>0</code> disables caching.
Negative values are not permitted.</p> <p>If you enable JMX, statistical information about the <code>jdbc-call-operations-cache</code> is exposed as an MBean.
See <a href="/en/spring-integration/jmx.html#jmx-mbean-exporter">MBean Exporter</a> for more information.</p></li> <li><p><code>sql-parameter-source-factory</code>: (Not available for the stored procedure inbound channel adapter.)
Reference to a <code>SqlParameterSourceFactory</code>.
By default, bean properties of the passed in <code>Message</code> payload are used as a source for the stored procedure’s input parameters by using a <code>BeanPropertySqlParameterSourceFactory</code>.</p> <p>This may suffice for basic use cases.
For more sophisticated options, consider passing in one or more <code>ProcedureParameter</code> values.
See <a href="#sp-defining-parameter-sources">Defining Parameter Sources</a>.
Optional.</p></li> <li><p><code>use-payload-as-parameter-source</code>: (Not available for the stored procedure inbound channel adapter.)
If set to <code>true</code>, the payload of the <code>Message</code> is used as a source for providing parameters.
If set to <code>false</code>, however, the entire <code>Message</code> is available as a source for parameters.</p> <p>If no procedure parameters are passed in, this property defaults to <code>true</code>.
This means that, by using a default <code>BeanPropertySqlParameterSourceFactory</code>, the bean properties of the payload are used as a source for parameter values for the stored procedure or stored function.</p> <p>However, if procedure parameters are passed in, this property (by default) evaluates to <code>false</code>.<code>ProcedureParameter</code> lets SpEL Expressions be provided.
Therefore, it is highly beneficial to have access to the entire <code>Message</code>.
The property is set on the underlying <code>StoredProcExecutor</code>.
Optional.</p></li></ul> <h4 id="common-configuration-sub-elements"><a href="#common-configuration-sub-elements" class="header-anchor">#</a> Common Configuration Sub-Elements</h4> <p>The stored procedure components share a common set of child elements that you can use to define and pass parameters to stored procedures or stored functions.
The following elements are available:</p> <ul><li><p><code>parameter</code></p></li> <li><p><code>returning-resultset</code></p></li> <li><p><code>sql-parameter-definition</code></p></li> <li><p><code>poller</code></p></li> <li><p><code>parameter</code>: Provides a mechanism to provide stored procedure parameters.
Parameters can be either static or provided by using a SpEL Expressions.</p> <div class="language- extra-class"><pre class="language-text"><code>&lt;int-jdbc:parameter name=&quot;&quot;         (1)
                    type=&quot;&quot;         (2)
                    value=&quot;&quot;/&gt;      (3)

&lt;int-jdbc:parameter name=&quot;&quot;
                    expression=&quot;&quot;/&gt; (4)
</code></pre></div><p>+
&lt;1&gt; The name of the parameter to be passed into the Stored Procedure or Stored Function.
Required.
&lt;2&gt; This attribute specifies the type of the value.
If nothing is provided, this attribute defaults to <code>java.lang.String</code>.
This attribute is used only when the <code>value</code> attribute is used.
Optional.
&lt;3&gt; The value of the parameter.
You must provide either this attribute or the <code>expression</code> attribute.
Optional.
&lt;4&gt; Instead of the <code>value</code> attribute, you can specify a SpEL expression for passing the value of the parameter.
If you specify the <code>expression</code>, the <code>value</code> attribute is not allowed.
Optional.</p> <p>Optional.</p></li> <li><p><code>returning-resultset</code>: Stored procedures may return multiple result sets.
By setting one or more <code>returning-resultset</code> elements, you can specify <code>RowMappers</code> to convert each returned <code>ResultSet</code> to meaningful objects.
Optional.</p> <div class="language- extra-class"><pre class="language-text"><code>&lt;int-jdbc:returning-resultset name=&quot;&quot; row-mapper=&quot;&quot; /&gt;
</code></pre></div></li> <li><p><code>sql-parameter-definition</code>: If you use a database that is fully supported, you typically do not have to specify the stored procedure parameter definitions.
Instead, those parameters can be automatically derived from the JDBC metadata.
However, if you use databases that are not fully supported, you must set those parameters explicitly by using the <code>sql-parameter-definition</code> element.</p> <p>You can also choose to turn off any processing of parameter metadata information obtained through JDBC by using the <code>ignore-column-meta-data</code> attribute.</p> <div class="language- extra-class"><pre class="language-text"><code>&lt;int-jdbc:sql-parameter-definition
                                   name=&quot;&quot;                           (1)
                                   direction=&quot;IN&quot;                    (2)
                                   type=&quot;STRING&quot;                     (3)
                                   scale=&quot;5&quot;                         (4)
                                   type-name=&quot;FOO_STRUCT&quot;            (5)
                                   return-type=&quot;fooSqlReturnType&quot;/&gt;  (6)
</code></pre></div><table><thead><tr><th><strong>1</strong></th> <th>Specifies the name of the SQL parameter.<br>Required.</th></tr></thead> <tbody><tr><td><strong>2</strong></td> <td>Specifies the direction of the SQL parameter definition.<br>Defaults to <code>IN</code>.<br>Valid values are: <code>IN</code>, <code>OUT</code>, and <code>INOUT</code>.<br>If your procedure is returning result sets, use the <code>returning-resultset</code> element.<br>Optional.</td></tr> <tr><td><strong>3</strong></td> <td>The SQL type used for this SQL parameter definition.<br>Translates into an integer value, as defined by <code>java.sql.Types</code>.<br>Alternatively, you can provide the integer value as well.<br>If this attribute is not explicitly set, it defaults to 'VARCHAR'.<br>Optional.</td></tr> <tr><td><strong>4</strong></td> <td>The scale of the SQL parameter.<br>Only used for numeric and decimal parameters.<br>Optional.</td></tr> <tr><td><strong>5</strong></td> <td>The <code>typeName</code> for types that are user-named, such as: <code>STRUCT</code>, <code>DISTINCT</code>, <code>JAVA_OBJECT</code>, and named array types.<br>This attribute is mutually exclusive with the <code>scale</code> attribute.<br>Optional.</td></tr> <tr><td><strong>6</strong></td> <td>The reference to a custom value handler for complex types.<br>An implementation of <a href="https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/jdbc/core/SqlReturnType.html" target="_blank" rel="noopener noreferrer"><code>SqlReturnType</code><span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>.<br>This attribute is mutually exclusive with the <code>scale</code> attribute and is only applicable for OUT and INOUT parameters.<br>Optional.</td></tr></tbody></table></li> <li><p><code>poller</code>: Lets you configure a message poller if this endpoint is a <code>PollingConsumer</code>.
Optional.</p></li></ul> <h4 id="defining-parameter-sources"><a href="#defining-parameter-sources" class="header-anchor">#</a> Defining Parameter Sources</h4> <p>Parameter sources govern the techniques of retrieving and mapping the Spring Integration message properties to the relevant stored procedure input parameters.</p> <p>The stored procedure components follow certain rules.
By default, the bean properties of the <code>Message</code> payload are used as a source for the stored procedure’s input parameters.
In that case, a <code>BeanPropertySqlParameterSourceFactory</code> is used.
This may suffice for basic use cases.
The next example illustrates that default behavior.</p> <table><thead><tr><th></th> <th>For the “automatic” lookup of bean properties by using the <code>BeanPropertySqlParameterSourceFactory</code> to work, your bean properties must be defined in lower case.<br>This is due to the fact that in <code>org.springframework.jdbc.core.metadata.CallMetaDataContext</code> (the Java method is <code>matchInParameterValuesWithCallParameters()</code>), the retrieved stored procedure parameter declarations are converted to lower case.<br>As a result, if you have camel-case bean properties (such as <code>lastName</code>), the lookup fails.<br>In that case, provide an explicit <code>ProcedureParameter</code>.</th></tr></thead> <tbody></tbody></table> <p>Suppose we have a payload that consists of a simple bean with the following three properties: <code>id</code>, <code>name</code>, and <code>description</code>.
Furthermore, we have a simplistic Stored Procedure called <code>INSERT_COFFEE</code> that accepts three input parameters: <code>id</code>, <code>name</code>, and <code>description</code>.
We also use a fully supported database.
In that case, the following configuration for a stored procedure outbound adapter suffices:</p> <div class="language- extra-class"><pre class="language-text"><code>&lt;int-jdbc:stored-proc-outbound-channel-adapter data-source=&quot;dataSource&quot;
    channel=&quot;insertCoffeeProcedureRequestChannel&quot;
    stored-procedure-name=&quot;INSERT_COFFEE&quot;/&gt;
</code></pre></div><p>For more sophisticated options, consider passing in one or more <code>ProcedureParameter</code> values.</p> <p>If you do provide <code>ProcedureParameter</code> values explicitly, by default, an <code>ExpressionEvaluatingSqlParameterSourceFactory</code> is used for parameter processing, to enable the full power of SpEL expressions.</p> <p>If you need even more control over how parameters are retrieved, consider passing in a custom implementation of <code>SqlParameterSourceFactory</code> by using the <code>sql-parameter-source-factory</code> attribute.</p> <h4 id="stored-procedure-inbound-channel-adapter"><a href="#stored-procedure-inbound-channel-adapter" class="header-anchor">#</a> Stored Procedure Inbound Channel Adapter</h4> <p>The following listing calls out the attributes that matter for a stored procedure inbound channel adapter:</p> <div class="language- extra-class"><pre class="language-text"><code>&lt;int-jdbc:stored-proc-inbound-channel-adapter
                                   channel=&quot;&quot;                                    (1)
                                   stored-procedure-name=&quot;&quot;
                                   data-source=&quot;&quot;
                                   auto-startup=&quot;true&quot;
                                   id=&quot;&quot;
                                   ignore-column-meta-data=&quot;false&quot;
                                   is-function=&quot;false&quot;
                                   skip-undeclared-results=&quot;&quot;                    (2)
                                   return-value-required=&quot;false&quot;                 (3)
    &lt;int:poller/&gt;
    &lt;int-jdbc:sql-parameter-definition name=&quot;&quot; direction=&quot;IN&quot;
                                               type=&quot;STRING&quot;
                                               scale=&quot;&quot;/&gt;
    &lt;int-jdbc:parameter name=&quot;&quot; type=&quot;&quot; value=&quot;&quot;/&gt;
    &lt;int-jdbc:parameter name=&quot;&quot; expression=&quot;&quot;/&gt;
    &lt;int-jdbc:returning-resultset name=&quot;&quot; row-mapper=&quot;&quot; /&gt;
&lt;/int-jdbc:stored-proc-inbound-channel-adapter&gt;
</code></pre></div><table><thead><tr><th><strong>1</strong></th> <th>Channel to which polled messages are sent.<br>If the stored procedure or function does not return any data, the payload of the <code>Message</code> is null.<br>Required.</th></tr></thead> <tbody><tr><td><strong>2</strong></td> <td>If this attribute is set to <code>true</code>, all results from a stored procedure call that do not have a corresponding <code>SqlOutParameter</code> declaration are bypassed.<br>For example, stored procedures can return an update count value, even though your stored procedure declared only a single result parameter.<br>The exact behavior depends on the database implementation.<br>The value is set on the underlying <code>JdbcTemplate</code>.<br>The value defaults to <code>true</code>.<br>Optional.</td></tr> <tr><td><strong>3</strong></td> <td>Indicates whether this procedure’s return value should be included.<br>Since Spring Integration 3.0.<br>Optional.</td></tr></tbody></table> <h4 id="stored-procedure-outbound-channel-adapter"><a href="#stored-procedure-outbound-channel-adapter" class="header-anchor">#</a> Stored Procedure Outbound Channel Adapter</h4> <p>The following listing calls out the attributes that matter for a stored procedure outbound channel adapter:</p> <div class="language- extra-class"><pre class="language-text"><code>&lt;int-jdbc:stored-proc-outbound-channel-adapter channel=&quot;&quot;                        (1)
                                               stored-procedure-name=&quot;&quot;
                                               data-source=&quot;&quot;
                                               auto-startup=&quot;true&quot;
                                               id=&quot;&quot;
                                               ignore-column-meta-data=&quot;false&quot;
                                               order=&quot;&quot;                          (2)
                                               sql-parameter-source-factory=&quot;&quot;
                                               use-payload-as-parameter-source=&quot;&quot;&gt;
    &lt;int:poller fixed-rate=&quot;&quot;/&gt;
    &lt;int-jdbc:sql-parameter-definition name=&quot;&quot;/&gt;
    &lt;int-jdbc:parameter name=&quot;&quot;/&gt;

&lt;/int-jdbc:stored-proc-outbound-channel-adapter&gt;
</code></pre></div><table><thead><tr><th><strong>1</strong></th> <th>The receiving message channel of this endpoint.<br>Required.</th></tr></thead> <tbody><tr><td><strong>2</strong></td> <td>Specifies the order for invocation when this endpoint is connected as a subscriber to a channel.<br>This is particularly relevant when that channel is using a <code>failover</code> dispatching strategy.<br>It has no effect when this endpoint is itself a polling consumer for a channel with a queue.<br>Optional.</td></tr></tbody></table> <h4 id="stored-procedure-outbound-gateway"><a href="#stored-procedure-outbound-gateway" class="header-anchor">#</a> Stored Procedure Outbound Gateway</h4> <p>The following listing calls out the attributes that matter for a stored procedure outbound channel adapter:</p> <div class="language- extra-class"><pre class="language-text"><code>&lt;int-jdbc:stored-proc-outbound-gateway request-channel=&quot;&quot;                        (1)
                                       stored-procedure-name=&quot;&quot;
                                       data-source=&quot;&quot;
                                   auto-startup=&quot;true&quot;
                                   id=&quot;&quot;
                                   ignore-column-meta-data=&quot;false&quot;
                                   is-function=&quot;false&quot;
                                   order=&quot;&quot;
                                   reply-channel=&quot;&quot;                              (2)
                                   reply-timeout=&quot;&quot;                              (3)
                                   return-value-required=&quot;false&quot;                 (4)
                                   skip-undeclared-results=&quot;&quot;                    (5)
                                   sql-parameter-source-factory=&quot;&quot;
                                   use-payload-as-parameter-source=&quot;&quot;&gt;
&lt;int-jdbc:sql-parameter-definition name=&quot;&quot; direction=&quot;IN&quot;
                                   type=&quot;&quot;
                                   scale=&quot;10&quot;/&gt;
&lt;int-jdbc:sql-parameter-definition name=&quot;&quot;/&gt;
&lt;int-jdbc:parameter name=&quot;&quot; type=&quot;&quot; value=&quot;&quot;/&gt;
&lt;int-jdbc:parameter name=&quot;&quot; expression=&quot;&quot;/&gt;
&lt;int-jdbc:returning-resultset name=&quot;&quot; row-mapper=&quot;&quot; /&gt;
</code></pre></div><table><thead><tr><th><strong>1</strong></th> <th>The receiving message channel of this endpoint.<br>Required.</th></tr></thead> <tbody><tr><td><strong>2</strong></td> <td>Message channel to which replies should be sent after receiving the database response.<br>Optional.</td></tr> <tr><td><strong>3</strong></td> <td>Lets you specify how long this gateway waits for the reply message to be sent successfully before throwing an exception.<br>Keep in mind that, when sending to a <code>DirectChannel</code>, the invocation occurs in the sender’s thread.<br>Consequently, the failing of the send operation may be caused by other components further downstream.<br>By default, the gateway waits indefinitely.<br>The value is specified in milliseconds.<br>Optional.</td></tr> <tr><td><strong>4</strong></td> <td>Indicates whether this procedure’s return value should be included.<br>Optional.</td></tr> <tr><td><strong>5</strong></td> <td>If the <code>skip-undeclared-results</code> attribute is set to <code>true</code>, all results from a stored procedure call that do not have a corresponding <code>SqlOutParameter</code> declaration are bypassed.<br>For example, stored procedures may return an update count value, even though your stored procedure only declared a single result parameter.<br>The exact behavior depends on the database.<br>The value is set on the underlying <code>JdbcTemplate</code>.<br>The value defaults to <code>true</code>.<br>Optional.</td></tr></tbody></table> <h4 id="examples"><a href="#examples" class="header-anchor">#</a> Examples</h4> <p>This section contains two examples that call <a href="https://db.apache.org/derby/" target="_blank" rel="noopener noreferrer">Apache Derby<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a> stored procedures.
The first procedure calls a stored procedure that returns a <code>ResultSet</code>.
By using a <code>RowMapper</code>, the data is converted into a domain object, which then becomes the Spring Integration message payload.</p> <p>In the second sample, we call a stored procedure that uses output parameters to return data instead.</p> <table><thead><tr><th></th> <th>Have a look at the <a href="https://github.com/spring-projects/spring-integration-samples" target="_blank" rel="noopener noreferrer">Spring Integration Samples project<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>.<br><br>The project contains the Apache Derby example referenced here, as well as instructions on how to run it.<br>The Spring Integration Samples project also provides an <a href="https://github.com/spring-projects/spring-integration-samples/tree/main/intermediate/stored-procedures-oracle" target="_blank" rel="noopener noreferrer">example<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a> of using Oracle stored procedures.</th></tr></thead> <tbody></tbody></table> <p>In the first example, we call a stored procedure named <code>FIND_ALL_COFFEE_BEVERAGES</code> that does not define any input parameters but that returns a <code>ResultSet</code>.</p> <p>In Apache Derby, stored procedures are implemented in Java.
The following listing shows the method signature:</p> <div class="language- extra-class"><pre class="language-text"><code>public static void findAllCoffeeBeverages(ResultSet[] coffeeBeverages)
            throws SQLException {
    ...
}
</code></pre></div><p>The following listing shows the corresponding SQL:</p> <div class="language- extra-class"><pre class="language-text"><code>CREATE PROCEDURE FIND_ALL_COFFEE_BEVERAGES() \
PARAMETER STYLE JAVA LANGUAGE JAVA MODIFIES SQL DATA DYNAMIC RESULT SETS 1 \
EXTERNAL NAME 'o.s.i.jdbc.storedproc.derby.DerbyStoredProcedures.findAllCoffeeBeverages';
</code></pre></div><p>In Spring Integration, you can now call this stored procedure by using, for example, a <code>stored-proc-outbound-gateway</code>, as the following example shows:</p> <div class="language- extra-class"><pre class="language-text"><code>&lt;int-jdbc:stored-proc-outbound-gateway id=&quot;outbound-gateway-storedproc-find-all&quot;
                                       data-source=&quot;dataSource&quot;
                                       request-channel=&quot;findAllProcedureRequestChannel&quot;
                                       expect-single-result=&quot;true&quot;
                                       stored-procedure-name=&quot;FIND_ALL_COFFEE_BEVERAGES&quot;&gt;
&lt;int-jdbc:returning-resultset name=&quot;coffeeBeverages&quot;
    row-mapper=&quot;org.springframework.integration.support.CoffeBeverageMapper&quot;/&gt;
&lt;/int-jdbc:stored-proc-outbound-gateway&gt;
</code></pre></div><p>In the second example, we call a stored procedure named <code>FIND_COFFEE</code> that has one input parameter.
Instead of returning a <code>ResultSet</code>, it uses an output parameter.
The following example shows the method signature:</p> <div class="language- extra-class"><pre class="language-text"><code>public static void findCoffee(int coffeeId, String[] coffeeDescription)
            throws SQLException {
    ...
}
</code></pre></div><p>The following listing shows the corresponding SQL:</p> <div class="language- extra-class"><pre class="language-text"><code>CREATE PROCEDURE FIND_COFFEE(IN ID INTEGER, OUT COFFEE_DESCRIPTION VARCHAR(200)) \
PARAMETER STYLE JAVA LANGUAGE JAVA EXTERNAL NAME \
'org.springframework.integration.jdbc.storedproc.derby.DerbyStoredProcedures.findCoffee';
</code></pre></div><p>In Spring Integration, you can now call this Stored Procedure by using, for example, a <code>stored-proc-outbound-gateway</code>, as the following example shows:</p> <div class="language- extra-class"><pre class="language-text"><code>&lt;int-jdbc:stored-proc-outbound-gateway id=&quot;outbound-gateway-storedproc-find-coffee&quot;
                                       data-source=&quot;dataSource&quot;
                                       request-channel=&quot;findCoffeeProcedureRequestChannel&quot;
                                       skip-undeclared-results=&quot;true&quot;
                                       stored-procedure-name=&quot;FIND_COFFEE&quot;
                                       expect-single-result=&quot;true&quot;&gt;
    &lt;int-jdbc:parameter name=&quot;ID&quot; expression=&quot;payload&quot; /&gt;
&lt;/int-jdbc:stored-proc-outbound-gateway&gt;
</code></pre></div><h3 id="jdbc-lock-registry"><a href="#jdbc-lock-registry" class="header-anchor">#</a> JDBC Lock Registry</h3> <p>Version 4.3 introduced the <code>JdbcLockRegistry</code>.
Certain components (for example, aggregator and resequencer) use a lock obtained from a <code>LockRegistry</code> instance to ensure that only one thread manipulates a group at a time.
The <code>DefaultLockRegistry</code> performs this function within a single component.
You can now configure an external lock registry on these components.
When used with a shared <code>MessageGroupStore</code>, you can use the <code>JdbcLockRegistry</code> to provide this functionality across multiple application instances, such that only one instance can manipulate the group at a time.</p> <p>When a lock is released by a local thread, another local thread can generally acquire the lock immediately.
If a lock is released by a thread that uses a different registry instance, it can take up to 100ms to acquire the lock.</p> <p>The <code>JdbcLockRegistry</code> is based on the <code>LockRepository</code> abstraction, which has a <code>DefaultLockRepository</code> implementation.
The database schema scripts are located in the <code>org.springframework.integration.jdbc</code> package, which is divided for the particular RDBMS vendors.
For example, the following listing shows the H2 DDL for the lock table:</p> <div class="language- extra-class"><pre class="language-text"><code>CREATE TABLE INT_LOCK  (
    LOCK_KEY CHAR(36),
    REGION VARCHAR(100),
    CLIENT_ID CHAR(36),
    CREATED_DATE TIMESTAMP NOT NULL,
    constraint INT_LOCK_PK primary key (LOCK_KEY, REGION)
);
</code></pre></div><p>The <code>INT_</code> can be changed according to the target database design requirements.
Therefore, you must use <code>prefix</code> property on the <code>DefaultLockRepository</code> bean definition.</p> <p>Sometimes, one application has moved to such a state that it cannot release the distributed lock and remove the particular record in the database.
For this purpose, such dead locks can be expired by the other application on the next locking invocation.
The <code>timeToLive</code> (TTL) option on the <code>DefaultLockRepository</code> is provided for this purpose.
You may also want to specify <code>CLIENT_ID</code> for the locks stored for a given <code>DefaultLockRepository</code> instance.
If so, you can specify the <code>id</code> to be associated with the <code>DefaultLockRepository</code> as a constructor parameter.</p> <p>Starting with version 5.1.8, the <code>JdbcLockRegistry</code> can be configured with the <code>idleBetweenTries</code> - a <code>Duration</code> to sleep between lock record insert/update executions.
By default it is <code>100</code> milliseconds and in some environments non-leaders pollute connections with data source too often.</p> <p>Starting with version 5.4, the <code>RenewableLockRegistry</code> interface has been introduced and added to <code>JdbcLockRegistry</code>.
The <code>renewLock()</code> method must be called during locked process in case of the locked process would be longer than time to live of the lock.
So the time to live can be highly reduce and deployments can retake a lost lock quickly.</p> <table><thead><tr><th></th> <th>The lock renewal can be done only if the lock is held by the current thread.</th></tr></thead> <tbody></tbody></table> <p>String with version 5.5.6, the <code>JdbcLockRegistry</code> is support automatically clean up cache for JdbcLock in <code>JdbcLockRegistry.locks</code> via <code>JdbcLockRegistry.setCacheCapacity()</code>.
See its JavaDocs for more information.</p> <h3 id="jdbc-metadata-store"><a href="#jdbc-metadata-store" class="header-anchor">#</a> JDBC Metadata Store</h3> <p>Version 5.0 introduced the JDBC <code>MetadataStore</code> (see <a href="/en/spring-integration/meta-data-store.html#metadata-store">Metadata Store</a>) implementation.
You can use the <code>JdbcMetadataStore</code> to maintain the metadata state across application restarts.
This <code>MetadataStore</code> implementation can be used with adapters such as the following:</p> <ul><li><p><a href="/en/spring-integration/feed.html#feed-inbound-channel-adapter">Feed inbound channel adapters</a></p></li> <li><p><a href="/en/spring-integration/file.html#file-reading">File inbound channel adapters</a></p></li> <li><p><a href="/en/spring-integration/ftp.html#ftp-inbound">FTP inbound channel adapters</a></p></li> <li><p><a href="/en/spring-integration/sftp.html#sftp-inbound">SFTP inbound channel adapters</a></p></li></ul> <p>To configure these adapters to use the <code>JdbcMetadataStore</code>, declare a Spring bean by using a bean name of <code>metadataStore</code>.
The Feed inbound channel adapter and the feed inbound channel adapter both automatically pick up and use the declared <code>JdbcMetadataStore</code>, as the following example shows:</p> <div class="language- extra-class"><pre class="language-text"><code>@Bean
public MetadataStore metadataStore(DataSource dataSource) {
    return new JdbcMetadataStore(dataSource);
}
</code></pre></div><p>The <code>org.springframework.integration.jdbc</code> package has Database schema scripts for several RDMBS vendors.
For example, the following listing shows the H2 DDL for the metadata table:</p> <div class="language- extra-class"><pre class="language-text"><code>CREATE TABLE INT_METADATA_STORE  (
	METADATA_KEY VARCHAR(255) NOT NULL,
	METADATA_VALUE VARCHAR(4000),
	REGION VARCHAR(100) NOT NULL,
	constraint INT_METADATA_STORE_PK primary key (METADATA_KEY, REGION)
);
</code></pre></div><p>You can change the <code>INT_</code> prefix to match the target database design requirements.
You can also configure <code>JdbcMetadataStore</code> to use the custom prefix.</p> <p>The <code>JdbcMetadataStore</code> implements <code>ConcurrentMetadataStore</code>, letting it be reliably shared across multiple application instances, where only one instance can store or modify a key’s value.
All of these operations are atomic, thanks to transaction guarantees.</p> <p>Transaction management must use <code>JdbcMetadataStore</code>.
Inbound channel adapters can be supplied with a reference to the <code>TransactionManager</code> in the poller configuration.
Unlike non-transactional <code>MetadataStore</code> implementations, with <code>JdbcMetadataStore</code>, the entry appears in the target table only after the transaction commits.
When a rollback occurs, no entries are added to the <code>INT_METADATA_STORE</code> table.</p> <p>Since version 5.0.7, you can configure the <code>JdbcMetadataStore</code> with the RDBMS vendor-specific <code>lockHint</code> option for lock-based queries on metadata store entries.
By default, it is <code>FOR UPDATE</code> and can be configured with an empty string if the target database does not support row locking functionality.
Consult with your vendor for particular and possible hints in the <code>SELECT</code> expression for locking rows before updates.</p></div> <footer class="page-edit"><div class="edit-link"><a href="https://gitcode.net/dev-cloud/spring-docs/-/blob/master/docs/en/spring-integration/jdbc.md" target="_blank" rel="noopener noreferrer">Edit this page on GitCode</a> <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></div> <div class="last-updated"><span class="prefix">Last Updated:</span> <span class="time">Thu Mar 17 2022 18:19:53 GMT+0800</span></div></footer> <div class="page-nav"><p class="inner"><span class="prev">

      <a href="/en/spring-integration/http.html" class="prev">
        HTTP Support
      </a></span> <span class="next"><a href="/en/spring-integration/jpa.html">
        JPA Support
      </a>

    </span></p></div> </main></div><div class="global-ui"></div></div>
    <script src="/assets/js/app.cf11b18e.js" defer></script><script src="/assets/js/3.50918073.js" defer></script><script src="/assets/js/4.cd4c3ff4.js" defer></script><script src="/assets/js/119.5a4712e9.js" defer></script>
  </body>
</html>