File: connector-j.html

package info (click to toggle)
mysql-connector-java 5.0.4%2Bdfsg-2
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 4,168 kB
  • ctags: 4,989
  • sloc: java: 53,054; xml: 812; makefile: 53
file content (2629 lines) | stat: -rw-r--r-- 173,862 bytes parent folder | download
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
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><title>1. MySQL Connector/J</title><meta name="generator" content="DocBook XSL Stylesheets V1.69.1"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="section" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="connector-j"></a>1. MySQL Connector/J</h2></div></div><hr></div><div class="toc"><dl><dt><span class="section"><a href="#connector-j-versions">1.1. Connector/J Versions</a></span></dt><dt><span class="section"><a href="#connector-j-installing">1.2. Installing Connector/J</a></span></dt><dt><span class="section"><a href="#connector-j-examples">1.3. Connector/J Examples</a></span></dt><dt><span class="section"><a href="#connector-j-reference">1.4. Connector/J (JDBC) Reference</a></span></dt><dt><span class="section"><a href="#connector-j-usagenotes">1.5. Connector/J Notes and Tips</a></span></dt><dt><span class="section"><a href="#connector-j-support">1.6. Connector/J Support</a></span></dt></dl></div><p>
    MySQL provides connectivity for client applications developed in the
    Java programming language via a JDBC driver, which is called MySQL
    Connector/J.
  </p><p>
    MySQL Connector/J is a JDBC-3.0 Type 4 driver, which means that is
    pure Java, implements version 3.0 of the JDBC specification, and
    communicates directly with the MySQL server using the MySQL
    protocol.
  </p><p>
    Although JDBC is useful by itself, we would hope that if you are not
    familiar with JDBC that after reading the first few sections of this
    manual, that you would avoid using naked JDBC for all but the most
    trivial problems and consider using one of the popular persistence
    frameworks such as
    <a href="http://www.hibernate.org/" target="_top">Hibernate</a>,
    <a href="http://www.springframework.org/" target="_top">Spring's JDBC
    templates</a> or <a href="http://ibatis.apache.org/" target="_top">Ibatis
    SQL Maps</a> to do the majority of repetitive work and heavier
    lifting that is sometimes required with JDBC.
  </p><p>
    This section is not designed to be a complete JDBC tutorial. If you
    need more information about using JDBC you might be interested in
    the following online tutorials that are more in-depth than the
    information presented here:
  </p><div class="itemizedlist"><ul type="disc"><li><p>
        <a href="http://java.sun.com/docs/books/tutorial/jdbc/basics/index.html" target="_top">JDBC
        Basics</a> — A tutorial from Sun covering beginner
        topics in JDBC
      </p></li><li><p>
        <a href="http://java.sun.com/developer/onlineTraining/Database/JDBCShortCourse/index.html" target="_top">JDBC
        Short Course</a> — A more in-depth tutorial from Sun
        and JGuru
      </p></li></ul></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="connector-j-versions"></a>1.1. Connector/J Versions</h3></div></div></div><div class="toc"><dl><dt><span class="section"><a href="#connector-j-versions-java">1.1.1. Java Versions Supported</a></span></dt></dl></div><p>
      There are currently three version of MySQL Connector/J available:
    </p><div class="itemizedlist"><ul type="disc"><li><p>
          Connector/J 3.0 provides core functionality and was designed
          with connectivity to MySQL 3.x or MySQL 4.1 servers, although
          it will provide basic compatibility with later versions of
          MySQL. Connector/J 3.0 does not support server-side prepared
          statements, and does not support any of the features in
          versions of MySQL later than 4.1.
        </p></li><li><p>
          Connector/J 3.1 was designed for connectivity to MySQL 4.1 and
          MySQL 5.0 servers and provides support for all the
          functionality in MySQL 5.0 except distributed transaction (XA)
          support.
        </p></li><li><p>
          Connector/J 5.0 provides support for all the functionality
          offered by Connector/J 3.1 and includes distributed
          transaction (XA) support.
        </p></li></ul></div><p>
      The current recommended version for Connector/J is 5.0. This guide
      covers all three connector versions, with specific notes given
      where a setting applies to a specific option.
    </p><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="connector-j-versions-java"></a>1.1.1. Java Versions Supported</h4></div></div></div><p>
        MySQL Connector/J supports Java-2 JVMs, including:
      </p><div class="itemizedlist"><ul type="disc"><li><p>JDK 1.2.x (only for Connector/J 3.1.x or earlier)</p></li><li><p>
            JDK 1.3.x
          </p></li><li><p>
            JDK 1.4.x
          </p></li><li><p>
            JDK 1.5.x
          </p></li></ul></div><p>
        If you are building Connector/J from source using the source
        distribution (see
        <a href="#connector-j-installing-source" title="1.2.4. Installing from the Development Source Tree">Section 1.2.4, “Installing from the Development Source Tree”</a>) then you must
        use JDK 1.4.x or newer to compiler the Connector package.
      </p><p>
        MySQL Connector/J does not support JDK-1.1.x or JDK-1.0.x
      </p><p>
        Because of the implementation of
        <code class="classname">java.sql.Savepoint</code>, Connector/J 3.1.0 and
        newer will not run on JDKs older than 1.4 unless the class
        verifier is turned off (by setting the
        <code class="option">-Xverify:none</code> option to the Java runtime). This
        is because the class verifier will try to load the class
        definition for <code class="classname">java.sql.Savepoint</code> even
        though it is not accessed by the driver unless you actually use
        savepoint functionality.
      </p><p>
        Caching functionality provided by Connector/J 3.1.0 or newer is
        also not available on JVMs older than 1.4.x, as it relies on
        <code class="classname">java.util.LinkedHashMap</code> which was first
        available in JDK-1.4.0.
      </p></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="connector-j-installing"></a>1.2. Installing Connector/J</h3></div></div></div><div class="toc"><dl><dt><span class="section"><a href="#connector-j-installing-binary">1.2.1. Installing Connector/J from a Binary Distribution</a></span></dt><dt><span class="section"><a href="#connector-j-installing-classpath">1.2.2. Installing the Driver and Configuring the <code class="literal">CLASSPATH</code></a></span></dt><dt><span class="section"><a href="#connector-j-installing-upgrading">1.2.3. Upgrading from an Older Version</a></span></dt><dt><span class="section"><a href="#connector-j-installing-source">1.2.4. Installing from the Development Source Tree</a></span></dt></dl></div><p>
      You can install the Connector/J package using two methods, using
      either the binary or source distribution. The binary distribution
      provides the easiest methods for installation; the source
      distribution enables you to customize your installation further.
      With with either solution, you must
    </p><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="connector-j-installing-binary"></a>1.2.1. Installing Connector/J from a Binary Distribution</h4></div></div></div><p>
        The easiest method of installation is to use the binary
        distribution of the Connector/J package. The binary distribution
        is available either as a Tar/Gzip or Zip file which you must
        extract to a suitable location and then optionally make the
        information about the package available by changing your
        <code class="literal">CLASSPATH</code> (see
        <a href="#connector-j-installing-classpath" title="1.2.2. Installing the Driver and Configuring the CLASSPATH">Section 1.2.2, “Installing the Driver and Configuring the <code class="literal">CLASSPATH</code>”</a>).
      </p><p>
        MySQL Connector/J is distributed as a .zip or .tar.gz archive
        containing the sources, the class files, and the JAR archive
        named
        <code class="filename">mysql-connector-java-<em class="replaceable"><code>[version]</code></em>-bin.jar</code>,
        and starting with Connector/J 3.1.8 a debug build of the driver
        in a file named
        <code class="filename">mysql-connector-java-<em class="replaceable"><code>[version]</code></em>-bin-g.jar</code>.
      </p><p>
        Starting with Connector/J 3.1.9, the <code class="filename">.class</code>
        files that constitute the JAR files are only included as part of
        the driver JAR file.
      </p><p>
        You should not use the debug build of the driver unless
        instructed to do so when reporting a problem ors bug to MySQL
        AB, as it is not designed to be run in production environments,
        and will have adverse performance impact when used. The debug
        binary also depends on the Aspect/J runtime library, which is
        located in the <code class="filename">src/lib/aspectjrt.jar</code> file
        that comes with the Connector/J distribution.
      </p><p>
        You will need to use the appropriate graphical or command-line
        utility to un-archive the distribution (for example, WinZip for
        the .zip archive, and <span><strong class="command">tar</strong></span> for the .tar.gz
        archive). Because there are potentially long filenames in the
        distribution, we use the GNU tar archive format. You will need
        to use GNU tar (or an application that understands the GNU tar
        archive format) to unpack the .tar.gz variant of the
        distribution.
      </p></div><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="connector-j-installing-classpath"></a>1.2.2. Installing the Driver and Configuring the <code class="literal">CLASSPATH</code></h4></div></div></div><p>
        Once you have extracted the distribution archive, you can
        install the driver by placing
        <code class="filename">mysql-connector-java-[version]-bin.jar </code>in
        your classpath, either by adding the full path to it to your
        <code class="literal">CLASSPATH</code> environment variable, or by
        directly specifying it with the command line switch -cp when
        starting your JVM.
      </p><p>
        If you are going to use the driver with the JDBC DriverManager,
        you would use <code class="literal">com.mysql.jdbc.Driver</code> as the
        class that implements java.sql.Driver.
      </p><p>
        You can set the <code class="literal">CLASSPATH</code> environment
        variableunder UNIX, Linux or Mac OS X either locally for a user
        within their <code class="literal">.profile</code>,
        <code class="literal">.login</code> or other login file. You can also set
        it globally by editing the global
        <code class="literal">/etc/profile</code> file.
      </p><p>
        For example, under a C shell (csh, tcsh) you would add the
        Connector/J driver to your <code class="literal">CLASSPATH</code> using
        the following:
      </p><pre class="programlisting">shell&gt; setenv CLASSPATH /path/to/mysql-connector-java-[version]-bin.jar:$CLASSPATH</pre><p>
        Or with a Bourne-compatible shell (sh, ksh, bash):
      </p><pre class="programlisting">export set CLASSPATH=/path/to/mysql-connector-java-[version]-bin.jar:$CLASSPATH</pre><p>
        Within Windows 2000, Windows XP and Windows Server 2003, you
        must set the environment variable through the System control
        panel.
      </p><p>
        If you want to use MySQL Connector/J with an application server
        such as Tomcat or JBoss, you will have to read your vendor's
        documentation for more information on how to configure
        third-party class libraries, as most application servers ignore
        the <code class="literal">CLASSPATH</code> environment variable. For
        configuration examples for some J2EE application servers, see
        <a href="#connector-j-usagenotes-j2ee" title="1.5.2. Using Connector/J with J2EE and Other Java Frameworks">Section 1.5.2, “Using Connector/J with J2EE and Other Java Frameworks”</a>. However, the
        authoritative source for JDBC connection pool configuration
        information for your particular application server is the
        documentation for that application server.
      </p><p>
        If you are developing servlets or JSPs, and your application
        server is J2EE-compliant, you can put the driver's .jar file in
        the WEB-INF/lib subdirectory of your webapp, as this is a
        standard location for third party class libraries in J2EE web
        applications.
      </p><p>
        You can also use the MysqlDataSource or
        MysqlConnectionPoolDataSource classes in the
        <code class="literal">com.mysql.jdbc.jdbc2.optional</code> package, if
        your J2EE application server supports or requires them. Starting
        with Connector/J 5.0.0, the
        <code class="literal">javax.sql.XADataSource</code> interface is
        implemented via the
        <code class="literal">com.mysql.jdbc.jdbc2.optional.MysqlXADataSource</code>
        class, which supports XA distributed transactions when used in
        combination with MySQL server version 5.0.
      </p><p>
        The various MysqlDataSource classes support the following
        parameters (through standard set mutators):
      </p><div class="itemizedlist"><ul type="disc"><li><p>
            user
          </p></li><li><p>
            password
          </p></li><li><p>
            serverName (see the previous section about fail-over hosts)
          </p></li><li><p>
            databaseName
          </p></li><li><p>
            port
          </p></li></ul></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="connector-j-installing-upgrading"></a>1.2.3. Upgrading from an Older Version</h4></div></div></div><p>
        MySQL AB tries to keep the upgrade process as easy as possible,
        however as is the case with any software, sometimes changes need
        to be made in new versions to support new features, improve
        existing functionality, or comply with new standards.
      </p><p>
        This section has information about what users who are upgrading
        from one version of Connector/J to another (or to a new version
        of the MySQL server, with respect to JDBC functionality) should
        be aware of.
      </p><div class="section" lang="en"><div class="titlepage"><div><div><h5 class="title"><a name="connector-j-installing-upgrading-3-0-to-3-1"></a>1.2.3.1. Upgrading from MySQL Connector/J 3.0 to 3.1</h5></div></div></div><p>
          Connector/J 3.1 is designed to be backward-compatible with
          Connector/J 3.0 as much as possible. Major changes are
          isolated to new functionality exposed in MySQL-4.1 and newer,
          which includes Unicode character sets, server-side prepared
          statements, SQLState codes returned in error messages by the
          server and various performance enhancements that can be
          enabled or disabled via configuration properties.
        </p><div class="itemizedlist"><ul type="disc"><li><p>
              <span class="bold"><strong>Unicode Character Sets</strong></span>
              — See the next section, as well as
              ???, for information on this new
              feature of MySQL. If you have something misconfigured, it
              will usually show up as an error with a message similar to
              <code class="literal">Illegal mix of collations</code>.
            </p></li><li><p>
              <span class="bold"><strong>Server-side Prepared
              Statements</strong></span> — Connector/J 3.1 will
              automatically detect and use server-side prepared
              statements when they are available (MySQL server version
              4.1.0 and newer).
            </p><p>
              Starting with version 3.1.7, the driver scans SQL you are
              preparing via all variants of
              <code class="literal">Connection.prepareStatement()</code> to
              determine if it is a supported type of statement to
              prepare on the server side, and if it is not supported by
              the server, it instead prepares it as a client-side
              emulated prepared statement. You can disable this feature
              by passing
              <span class="property">emulateUnsupportedPstmts=false</span> in
              your JDBC URL.
            </p><p>
              If your application encounters issues with server-side
              prepared statements, you can revert to the older
              client-side emulated prepared statement code that is still
              presently used for MySQL servers older than 4.1.0 with the
              connection property
              <span class="property">useServerPrepStmts=false</span>
            </p></li><li><p>
              <span class="bold"><strong>Datetimes</strong></span> with all-zero
              components (<code class="literal">0000-00-00 ...</code>) —
              These values can not be represented reliably in Java.
              Connector/J 3.0.x always converted them to NULL when being
              read from a ResultSet.
            </p><p>
              Connector/J 3.1 throws an exception by default when these
              values are encountered as this is the most correct
              behavior according to the JDBC and SQL standards. This
              behavior can be modified using the
              <span class="property">zeroDateTimeBehavior</span> configuration
              property. The allowable values are:
            </p><div class="itemizedlist"><ul type="circle"><li><p>
                  <code class="literal">exception</code> (the default), which
                  throws an SQLException with an SQLState of
                  <code class="literal">S1009</code>.
                </p></li><li><p>
                  <code class="literal">convertToNull</code>, which returns
                  <code class="literal">NULL</code> instead of the date.
                </p></li><li><p>
                  <code class="literal">round</code>, which rounds the date to the
                  nearest closest value which is
                  <code class="literal">0001-01-01</code>.
                </p></li></ul></div><p>
              Starting with Connector/J 3.1.7,
              <code class="literal">ResultSet.getString()</code> can be decoupled
              from this behavior via
              <span class="property">noDatetimeStringSync=true</span> (the
              default value is <code class="literal">false</code>) so that you can
              get retrieve the unaltered all-zero value as a String. It
              should be noted that this also precludes using any time
              zone conversions, therefore the driver will not allow you
              to enable <span class="property">noDatetimeStringSync</span> and
              <span class="property">useTimezone</span> at the same time.
            </p></li><li><p>
              <span class="bold"><strong>New SQLState Codes</strong></span>
              — Connector/J 3.1 uses SQL:1999 SQLState codes
              returned by the MySQL server (if supported), which are
              different from the legacy X/Open state codes that
              Connector/J 3.0 uses. If connected to a MySQL server older
              than MySQL-4.1.0 (the oldest version to return SQLStates
              as part of the error code), the driver will use a built-in
              mapping. You can revert to the old mapping by using the
              configuration property
              <span class="property">useSqlStateCodes=false</span>.
            </p></li><li><p>
              <span class="bold"><strong><code class="literal">ResultSet.getString()</code></strong></span>
              — Calling <code class="literal">ResultSet.getString()</code>
              on a BLOB column will now return the address of the byte[]
              array that represents it, instead of a String
              representation of the BLOB. BLOBs have no character set,
              so they can't be converted to java.lang.Strings without
              data loss or corruption.
            </p><p>
              To store strings in MySQL with LOB behavior, use one of
              the TEXT types, which the driver will treat as a
              java.sql.Clob.
            </p></li><li><p>
              <span class="bold"><strong>Debug builds</strong></span> —
              Starting with Connector/J 3.1.8 a debug build of the
              driver in a file named
              <code class="filename">mysql-connector-java-<em class="replaceable"><code>[version]</code></em>-bin-g.jar</code>
              is shipped alongside the normal binary jar file that is
              named
              <code class="filename">mysql-connector-java-<em class="replaceable"><code>[version]</code></em>-bin.jar</code>.
            </p><p>
              Starting with Connector/J 3.1.9, we don't ship the .class
              files unbundled, they are only available in the JAR
              archives that ship with the driver.
            </p><p>
              You should not use the debug build of the driver unless
              instructed to do so when reporting a problem or bug to
              MySQL AB, as it is not designed to be run in production
              environments, and will have adverse performance impact
              when used. The debug binary also depends on the Aspect/J
              runtime library, which is located in the
              <code class="filename">src/lib/aspectjrt.jar</code> file that comes
              with the Connector/J distribution.
            </p></li></ul></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h5 class="title"><a name="connector-j-installing-upgrading-issues"></a>1.2.3.2. JDBC-Specific Issues When Upgrading to MySQL Server 4.1 or Newer</h5></div></div></div><div class="itemizedlist"><ul type="disc"><li><p>
              <span class="emphasis"><em>Using the UTF-8 Character Encoding</em></span> -
              Prior to MySQL server version 4.1, the UTF-8 character
              encoding was not supported by the server, however the JDBC
              driver could use it, allowing storage of multiple
              character sets in latin1 tables on the server.
            </p><p>
              Starting with MySQL-4.1, this functionality is deprecated.
              If you have applications that rely on this functionality,
              and can not upgrade them to use the official Unicode
              character support in MySQL server version 4.1 or newer,
              you should add the following property to your connection
              URL:
            </p><p>
              <code class="computeroutput">useOldUTF8Behavior=true</code>
            </p></li><li><p>
              <span class="emphasis"><em>Server-side Prepared Statements</em></span> -
              Connector/J 3.1 will automatically detect and use
              server-side prepared statements when they are available
              (MySQL server version 4.1.0 and newer). If your
              application encounters issues with server-side prepared
              statements, you can revert to the older client-side
              emulated prepared statement code that is still presently
              used for MySQL servers older than 4.1.0 with the following
              connection property:
            </p><p>
              <code class="computeroutput">useServerPrepStmts=false</code>
            </p></li></ul></div></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="connector-j-installing-source"></a>1.2.4. Installing from the Development Source Tree</h4></div></div></div><p><b>Caution. </b>
          You should read this section only if you are interested in
          helping us test our new code. If you just want to get MySQL
          Connector/J up and running on your system, you should use a
          standard release distribution.
        </p><p>
        To install MySQL Connector/J from the development source tree,
        make sure that you have the following prerequisites:
      </p><div class="itemizedlist"><ul type="disc"><li><p>
            Subversion, to check out the sources from our repository
            (available from
            <a href="http://subversion.tigris.org/" target="_top">http://subversion.tigris.org/</a>).
          </p></li><li><p>
            Apache Ant version 1.6 or newer (available from
            <a href="http://ant.apache.org/" target="_top">http://ant.apache.org/</a>).
          </p></li><li><p>
            JDK-1.4.2 or later. Although MySQL Connector/J can be
            installed on older JDKs, to compile it from source you must
            have at least JDK-1.4.2.
          </p></li></ul></div><p>
        The Subversion source code repository for MySQL Connector/J is
        located at
        <a href="http://svn.mysql.com/svnpublic/connector-j" target="_top">http://svn.mysql.com/svnpublic/connector-j</a>. In
        general, you should not check out the entire repository because
        it contains every branch and tag for MySQL Connector/J and is
        quite large.
      </p><p>
        To check out and compile a specific branch of MySQL Connector/J,
        follow these steps:
      </p><div class="orderedlist"><ol type="1"><li><p>
            At the time of this writing, there are three active branches
            of Connector/J: <code class="literal">branch_3_0</code>,
            <code class="literal">branch_3_1</code> and
            <code class="literal">branch_5_0</code>. Check out the latest code
            from the branch that you want with the following command
            (replacing <em class="replaceable"><code>[major]</code></em> and
            <em class="replaceable"><code>[minor]</code></em> with appropriate version
            numbers):
          </p><pre class="programlisting">shell&gt; <strong class="userinput"><code>svn co »
http://svn.mysql.com/svnpublic/connector-j/branches/branch_<em class="replaceable"><code>[major]</code></em>_<em class="replaceable"><code>[minor]</code></em>/connector-j</code></strong></pre><p>
            This creates a <code class="filename">connector-j</code> subdirectory
            in the current directory that contains the latest sources
            for the requested branch.
          </p></li><li><p>
            Change location to the <code class="filename">connector-j</code>
            directory to make it your current working directory:
          </p><pre class="programlisting">shell&gt; <strong class="userinput"><code>cd connector-j</code></strong></pre></li><li><p>
            Issue the following command to compile the driver and create
            a <code class="filename">.jar</code> file suitable for installation:
          </p><pre class="programlisting">shell&gt; <strong class="userinput"><code>ant dist</code></strong></pre><p>
            This creates a <code class="filename">build</code> directory in the
            current directory, where all build output will go. A
            directory is created in the <code class="filename">build</code>
            directory that includes the version number of the sources
            you are building from. This directory contains the sources,
            compiled <code class="filename">.class</code> files, and a
            <code class="filename">.jar</code> file suitable for deployment. For
            other possible targets, including ones that will create a
            fully packaged distribution, issue the following command:
          </p><pre class="programlisting">shell&gt; <strong class="userinput"><code>ant --projecthelp</code></strong></pre></li><li><p>
            A newly created <code class="filename">.jar</code> file containing
            the JDBC driver will be placed in the directory
            <code class="filename">build/mysql-connector-java-<em class="replaceable"><code>[version]</code></em></code>.
          </p><p>
            Install the newly created JDBC driver as you would a binary
            <code class="filename">.jar</code> file that you download from MySQL
            by following the instructions in
            <a href="#connector-j-installing-classpath" title="1.2.2. Installing the Driver and Configuring the CLASSPATH">Section 1.2.2, “Installing the Driver and Configuring the <code class="literal">CLASSPATH</code>”</a>.
          </p></li></ol></div></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="connector-j-examples"></a>1.3. Connector/J Examples</h3></div></div></div><p>
      Examples of using Connector/J are located throughout this
      document, this section provides a summary and links to these
      examples.
    </p><div class="itemizedlist"><ul type="disc"><li><p>
          <a href="#connector-j-examples-connection-drivermanager" title="Example 1. Obtaining a connection from the DriverManager">Example 1, “Obtaining a connection from the <code class="literal">DriverManager</code>”</a>
        </p></li><li><p>
          <a href="#connector-j-examples-execute-select" title="Example 2. Using java.sql.Statement to execute a SELECT query">Example 2, “Using java.sql.Statement to execute a <code class="literal">SELECT</code> query”</a>
        </p></li><li><p>
          <a href="#connector-j-examples-stored-procedure" title="Example 3. Stored Procedures">Example 3, “Stored Procedures”</a>
        </p></li><li><p>
          <a href="#connector-j-examples-preparecall" title="Example 4. Using Connection.prepareCall()">Example 4, “Using <code class="literal">Connection.prepareCall()</code>”</a>
        </p></li><li><p>
          <a href="#connector-j-examples-output-param" title="Example 5. Registering output parameters">Example 5, “Registering output parameters”</a>
        </p></li><li><p>
          <a href="#connector-j-examples-callablestatement" title="Example 6. Setting CallableStatement input parameters">Example 6, “Setting <code class="literal">CallableStatement</code> input parameters”</a>
        </p></li><li><p>
          <a href="#connector-j-examples-retrieving-results-params" title="Example 7. Retrieving results and output parameter values">Example 7, “Retrieving results and output parameter values”</a>
        </p></li><li><p>
          <a href="#connector-j-examples-autoincrement-getgeneratedkeys" title="Example 8. Retrieving AUTO_INCREMENT column values using
              Statement.getGeneratedKeys()">Example 8, “Retrieving <code class="literal">AUTO_INCREMENT</code> column values using
              <code class="literal">Statement.getGeneratedKeys()</code>”</a>
        </p></li><li><p>
          <a href="#connector-j-examples-autoincrement-select" title="Example 9. Retrieving AUTO_INCREMENT column values using
              SELECT LAST_INSERT_ID()">Example 9, “Retrieving <code class="literal">AUTO_INCREMENT</code> column values using
              <code class="literal">SELECT LAST_INSERT_ID()</code>”</a>
        </p></li><li><p>
          <a href="#connector-j-examples-autoincrement-updateable-resultsets" title="Example 10. Retrieving AUTO_INCREMENT column values in
              Updatable ResultSets">Example 10, “Retrieving <code class="literal">AUTO_INCREMENT</code> column values in
              <code class="literal">Updatable ResultSets</code>”</a>
        </p></li><li><p>
          <a href="#connector-j-examples-connectionpool-j2ee" title="Example 11. Using a connection pool with a J2EE application server">Example 11, “Using a connection pool with a J2EE application server”</a>
        </p></li><li><p>
          <a href="#connector-j-examples-transaction-retry" title="Example 12. Example of transaction with retry logic">Example 12, “Example of transaction with retry logic”</a>
        </p></li></ul></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="connector-j-reference"></a>1.4. Connector/J (JDBC) Reference</h3></div></div></div><div class="toc"><dl><dt><span class="section"><a href="#connector-j-reference-configuration-properties">1.4.1. Driver/Datasource Class Names, URL Syntax and Configuration Properties
        for Connector/J</a></span></dt><dt><span class="section"><a href="#connector-j-reference-implementation-notes">1.4.2. JDBC API Implementation Notes</a></span></dt><dt><span class="section"><a href="#connector-j-reference-type-conversions">1.4.3. Java, JDBC and MySQL Types</a></span></dt><dt><span class="section"><a href="#connector-j-reference-charsets">1.4.4. Using Character Sets and Unicode</a></span></dt><dt><span class="section"><a href="#connector-j-reference-using-ssl">1.4.5. Connecting Securely Using SSL</a></span></dt><dt><span class="section"><a href="#connector-j-reference-replication-connection">1.4.6. Using Master/Slave Replication with ReplicationConnection</a></span></dt></dl></div><p>
      This section of the manual contains reference material for MySQL
      Connector/J, some of which is automatically generated during the
      Connector/J build process.
    </p><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="connector-j-reference-configuration-properties"></a>1.4.1. Driver/Datasource Class Names, URL Syntax and Configuration Properties
        for Connector/J</h4></div></div></div><p>
        The name of the class that implements java.sql.Driver in MySQL
        Connector/J is <code class="literal">com.mysql.jdbc.Driver</code>. The
        <code class="literal">org.gjt.mm.mysql.Driver</code> class name is also
        usable to remain backward-compatible with MM.MySQL. You should
        use this class name when registering the driver, or when
        otherwise configuring software to use MySQL Connector/J.
      </p><p>
        The JDBC URL format for MySQL Connector/J is as follows, with
        items in square brackets ([, ]) being optional:
      </p><pre class="programlisting">jdbc:mysql://[host][,failoverhost...][:port]/[database] »
[?propertyName1][=propertyValue1][&amp;propertyName2][=propertyValue2]...</pre><p>
        If the hostname is not specified, it defaults to 127.0.0.1. If
        the port is not specified, it defaults to 3306, the default port
        number for MySQL servers.
      </p><pre class="programlisting">jdbc:mysql://[host:port],[host:port].../[database] »
[?propertyName1][=propertyValue1][&amp;propertyName2][=propertyValue2]...</pre><p>
        If the database is not specified, the connection will be made
        with no default database. In this case, you will need to either
        call the <code class="literal">setCatalog()</code> method on the
        Connection instance or fully-specify table names using the
        database name (i.e. <code class="literal">SELECT dbname.tablename.colname
        FROM dbname.tablename...</code>) in your SQL. Not specifying
        the database to use upon connection is generally only useful
        when building tools that work with multiple databases, such as
        GUI database managers.
      </p><p>
        MySQL Connector/J has fail-over support. This allows the driver
        to fail-over to any number of slave hosts and still perform
        read-only queries. Fail-over only happens when the connection is
        in an <code class="literal">autoCommit(true)</code> state, because
        fail-over can not happen reliably when a transaction is in
        progress. Most application servers and connection pools set
        <code class="literal">autoCommit</code> to <code class="literal">true</code> at the
        end of every transaction/connection use.
      </p><p>
        The fail-over functionality has the following behavior:
      </p><div class="itemizedlist"><ul type="disc"><li><p>
            If the URL property <span class="property">autoReconnect</span> is
            false: Failover only happens at connection initialization,
            and failback occurs when the driver determines that the
            first host has become available again.
          </p></li><li><p>
            If the URL property <span class="property">autoReconnect</span> is
            true: Failover happens when the driver determines that the
            connection has failed (before <span class="emphasis"><em>every</em></span>
            query), and falls back to the first host when it determines
            that the host has become available again (after
            <code class="literal">queriesBeforeRetryMaster</code> queries have
            been issued).
          </p></li></ul></div><p>
        In either case, whenever you are connected to a "failed-over"
        server, the connection will be set to read-only state, so
        queries that would modify data will have exceptions thrown (the
        query will <span class="bold"><strong>never</strong></span> be processed
        by the MySQL server).
      </p><p>
        Configuration properties define how Connector/J will make a
        connection to a MySQL server. Unless otherwise noted, properties
        can be set for a DataSource object or for a Connection object.
      </p><p>
        Configuration Properties can be set in one of the following
        ways:
      </p><div class="itemizedlist"><ul type="disc"><li><p>
            Using the set*() methods on MySQL implementations of
            java.sql.DataSource (which is the preferred method when
            using implementations of java.sql.DataSource):
          </p><div class="itemizedlist"><ul type="circle"><li><p>
                com.mysql.jdbc.jdbc2.optional.MysqlDataSource
              </p></li><li><p>
                com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource
              </p></li></ul></div></li><li><p>
            As a key/value pair in the java.util.Properties instance
            passed to <code class="literal">DriverManager.getConnection()</code>
            or <code class="literal">Driver.connect()</code>
          </p></li><li><p>
            As a JDBC URL parameter in the URL given to
            <code class="literal">java.sql.DriverManager.getConnection()</code>,
            <code class="literal">java.sql.Driver.connect()</code> or the MySQL
            implementations of the
            <code class="literal">javax.sql.DataSource</code>
            <code class="literal">setURL()</code> method.
          </p><p><b>Note. </b>
              If the mechanism you use to configure a JDBC URL is
              XML-based, you will need to use the XML character literal
              &amp;amp; to separate configuration parameters, as the
              ampersand is a reserved character for XML.
            </p></li></ul></div><p>
        The properties are listed in the following tables.
      </p><p><b>Connection/Authentication. </b>
      </p><div class="informaltable"><table border="1"><colgroup><col><col><col><col></colgroup><tbody><tr><td>
                     <span class="bold"><strong>Property Name</strong></span>
                  </td><td>
                     <span class="bold"><strong>Definition</strong></span>
                  </td><td>
                     <span class="bold"><strong>Default Value</strong></span>
                  </td><td>
                     <span class="bold"><strong>Since Version</strong></span>
                  </td></tr><tr><td>user</td><td>The user to connect as</td><td>
                  </td><td>all</td></tr><tr><td>password</td><td>The password to use when connecting</td><td>
                  </td><td>all</td></tr><tr><td>socketFactory</td><td>The name of the class that the driver should use for creating socket connections to the server. This class must implement the interface 'com.mysql.jdbc.SocketFactory' and have public no-args constructor.</td><td>com.mysql.jdbc.StandardSocketFactory</td><td>3.0.3</td></tr><tr><td>connectTimeout</td><td>Timeout for socket connect (in milliseconds), with 0 being no timeout. Only works on JDK-1.4 or newer. Defaults to '0'.</td><td>0</td><td>3.0.1</td></tr><tr><td>socketTimeout</td><td>Timeout on network socket operations (0, the default means no timeout).</td><td>0</td><td>3.0.1</td></tr><tr><td>useConfigs</td><td>Load the comma-delimited list of configuration properties before parsing the URL or applying user-specified properties. These configurations are explained in the 'Configurations' of the documentation.</td><td>
                  </td><td>3.1.5</td></tr><tr><td>interactiveClient</td><td>Set the CLIENT_INTERACTIVE flag, which tells MySQL to timeout connections based on INTERACTIVE_TIMEOUT instead of WAIT_TIMEOUT</td><td>false</td><td>3.1.0</td></tr><tr><td>propertiesTransform</td><td>An implementation of com.mysql.jdbc.ConnectionPropertiesTransform that the driver will use to modify URL properties passed to the driver before attempting a connection</td><td>
                  </td><td>3.1.4</td></tr><tr><td>useCompression</td><td>Use zlib compression when communicating with the server (true/false)? Defaults to 'false'.</td><td>false</td><td>3.0.17</td></tr></tbody></table></div><p>
   </p><p><b>High Availability and Clustering. </b>
      </p><div class="informaltable"><table border="1"><colgroup><col><col><col><col></colgroup><tbody><tr><td>
                     <span class="bold"><strong>Property Name</strong></span>
                  </td><td>
                     <span class="bold"><strong>Definition</strong></span>
                  </td><td>
                     <span class="bold"><strong>Default Value</strong></span>
                  </td><td>
                     <span class="bold"><strong>Since Version</strong></span>
                  </td></tr><tr><td>autoReconnect</td><td>Should the driver try to re-establish stale and/or dead connections? If enabled the driver will throw an exception for a queries issued on a stale or dead connection, which belong to the current transaction, but will attempt reconnect before the next query issued on the connection in a new transaction. The use of this feature is not recommended, because it has side effects related to session state and data consistency when applications don'thandle SQLExceptions properly, and is only designed to be used when you are unable to configure your application to handle SQLExceptions resulting from dead andstale connections properly. Alternatively, investigate setting the MySQL server variable "wait_timeout"to some high value rather than the default of 8 hours.</td><td>false</td><td>1.1</td></tr><tr><td>autoReconnectForPools</td><td>Use a reconnection strategy appropriate for connection pools (defaults to 'false')</td><td>false</td><td>3.1.3</td></tr><tr><td>failOverReadOnly</td><td>When failing over in autoReconnect mode, should the connection be set to 'read-only'?</td><td>true</td><td>3.0.12</td></tr><tr><td>reconnectAtTxEnd</td><td>If autoReconnect is set to true, should the driver attempt reconnectionsat the end of every transaction?</td><td>false</td><td>3.0.10</td></tr><tr><td>roundRobinLoadBalance</td><td>When autoReconnect is enabled, and failoverReadonly is false, should we pick hosts to connect to on a round-robin basis?</td><td>false</td><td>3.1.2</td></tr><tr><td>queriesBeforeRetryMaster</td><td>Number of queries to issue before falling back to master when failed over (when using multi-host failover). Whichever condition is met first, 'queriesBeforeRetryMaster' or 'secondsBeforeRetryMaster' will cause an attempt to be made to reconnect to the master. Defaults to 50.</td><td>50</td><td>3.0.2</td></tr><tr><td>secondsBeforeRetryMaster</td><td>How long should the driver wait, when failed over, before attempting to reconnect to the master server? Whichever condition is met first, 'queriesBeforeRetryMaster' or 'secondsBeforeRetryMaster' will cause an attempt to be made to reconnect to the master. Time in seconds, defaults to 30</td><td>30</td><td>3.0.2</td></tr><tr><td>enableDeprecatedAutoreconnect</td><td>Auto-reconnect functionality is deprecated starting with version 3.2, and will be removed in version 3.3. Set this property to 'true' to disable the check for the feature being configured.</td><td>false</td><td>3.2.1</td></tr><tr><td>resourceId</td><td>A globally unique name that identifies the resource that this datasource or connection is connected to, used for XAResource.isSameRM() when the driver can't determine this value based on hostnames used in the URL</td><td>
                  </td><td>5.0.1</td></tr></tbody></table></div><p>
   </p><p><b>Security. </b>
      </p><div class="informaltable"><table border="1"><colgroup><col><col><col><col></colgroup><tbody><tr><td>
                     <span class="bold"><strong>Property Name</strong></span>
                  </td><td>
                     <span class="bold"><strong>Definition</strong></span>
                  </td><td>
                     <span class="bold"><strong>Default Value</strong></span>
                  </td><td>
                     <span class="bold"><strong>Since Version</strong></span>
                  </td></tr><tr><td>allowMultiQueries</td><td>Allow the use of ';' to delimit multiple queries during one statement (true/false, defaults to 'false'</td><td>false</td><td>3.1.1</td></tr><tr><td>useSSL</td><td>Use SSL when communicating with the server (true/false), defaults to 'false'</td><td>false</td><td>3.0.2</td></tr><tr><td>requireSSL</td><td>Require SSL connection if useSSL=true? (defaults to 'false').</td><td>false</td><td>3.1.0</td></tr><tr><td>allowUrlInLocalInfile</td><td>Should the driver allow URLs in 'LOAD DATA LOCAL INFILE' statements?</td><td>false</td><td>3.1.4</td></tr><tr><td>paranoid</td><td>Take measures to prevent exposure sensitive information in error messages and clear data structures holding sensitive data when possible? (defaults to 'false')</td><td>false</td><td>3.0.1</td></tr></tbody></table></div><p>
   </p><p><b>Performance Extensions. </b>
      </p><div class="informaltable"><table border="1"><colgroup><col><col><col><col></colgroup><tbody><tr><td>
                     <span class="bold"><strong>Property Name</strong></span>
                  </td><td>
                     <span class="bold"><strong>Definition</strong></span>
                  </td><td>
                     <span class="bold"><strong>Default Value</strong></span>
                  </td><td>
                     <span class="bold"><strong>Since Version</strong></span>
                  </td></tr><tr><td>metadataCacheSize</td><td>The number of queries to cacheResultSetMetadata for if cacheResultSetMetaData is set to 'true' (default 50)</td><td>50</td><td>3.1.1</td></tr><tr><td>prepStmtCacheSize</td><td>If prepared statement caching is enabled, how many prepared statements should be cached?</td><td>25</td><td>3.0.10</td></tr><tr><td>prepStmtCacheSqlLimit</td><td>If prepared statement caching is enabled, what's the largest SQL the driver will cache the parsing for?</td><td>256</td><td>3.0.10</td></tr><tr><td>useCursorFetch</td><td>If connected to MySQL &gt; 5.0.2, and setFetchSize() &gt; 0 on a statement, should that statement use cursor-based fetching to retrieve rows?</td><td>false</td><td>5.0.0</td></tr><tr><td>blobSendChunkSize</td><td>Chunk to use when sending BLOB/CLOBs via ServerPreparedStatements</td><td>1048576</td><td>3.1.9</td></tr><tr><td>cacheCallableStmts</td><td>Should the driver cache the parsing stage of CallableStatements</td><td>false</td><td>3.1.2</td></tr><tr><td>cachePrepStmts</td><td>Should the driver cache the parsing stage of PreparedStatements of client-side prepared statements, the "check" for suitability of server-side prepared and server-side prepared statements themselves?</td><td>false</td><td>3.0.10</td></tr><tr><td>cacheResultSetMetadata</td><td>Should the driver cache ResultSetMetaData for Statements and PreparedStatements? (Req. JDK-1.4+, true/false, default 'false')</td><td>false</td><td>3.1.1</td></tr><tr><td>cacheServerConfiguration</td><td>Should the driver cache the results of 'SHOW VARIABLES' and 'SHOW COLLATION' on a per-URL basis?</td><td>false</td><td>3.1.5</td></tr><tr><td>defaultFetchSize</td><td>The driver will call setFetchSize(n) with this value on all newly-created Statements</td><td>0</td><td>3.1.9</td></tr><tr><td>dontTrackOpenResources</td><td>The JDBC specification requires the driver to automatically track and close resources, however if your application doesn't do a good job of explicitly calling close() on statements or result sets, this can cause memory leakage. Setting this property to true relaxes this constraint, and can be more memory efficient for some applications.</td><td>false</td><td>3.1.7</td></tr><tr><td>dynamicCalendars</td><td>Should the driver retrieve the default calendar when required, or cache it per connection/session?</td><td>false</td><td>3.1.5</td></tr><tr><td>elideSetAutoCommits</td><td>If using MySQL-4.1 or newer, should the driver only issue 'set autocommit=n' queries when the server's state doesn't match the requested state by Connection.setAutoCommit(boolean)?</td><td>false</td><td>3.1.3</td></tr><tr><td>holdResultsOpenOverStatementClose</td><td>Should the driver close result sets on Statement.close() as required by the JDBC specification?</td><td>false</td><td>3.1.7</td></tr><tr><td>locatorFetchBufferSize</td><td>If 'emulateLocators' is configured to 'true', what size buffer should be used when fetching BLOB data for getBinaryInputStream?</td><td>1048576</td><td>3.2.1</td></tr><tr><td>rewriteBatchedStatements</td><td>Should the driver use multiqueries (irregardless of the setting of "allowMultiQueries") as well as rewriting of prepared statements for INSERT into multi-value inserts when executeBatch() is called? Notice that this has the potential for SQL injection if using plain java.sql.Statements and your code doesn't sanitize input correctly. Notice that for prepared statements, server-side prepared statements can not currently take advantage of this rewrite option, and that if you don't specify stream lengths when using PreparedStatement.set*Stream(),the driver won't be able to determine the optimium number of parameters per batch and you might receive an error from the driver that the resultant packet is too large. Statement.getGeneratedKeys() for these rewritten statements only works when the entire batch includes INSERT statements.</td><td>false</td><td>3.1.13</td></tr><tr><td>useFastIntParsing</td><td>Use internal String-&gt;Integer conversion routines to avoid excessive object creation?</td><td>true</td><td>3.1.4</td></tr><tr><td>useJvmCharsetConverters</td><td>Always use the character encoding routines built into the JVM, rather than using lookup tables for single-byte character sets? (The default of "true" for this is appropriate for newer JVMs</td><td>true</td><td>5.0.1</td></tr><tr><td>useLocalSessionState</td><td>Should the driver refer to the internal values of autocommit and transaction isolation that are set by Connection.setAutoCommit() and Connection.setTransactionIsolation(), rather than querying the database?</td><td>false</td><td>3.1.7</td></tr><tr><td>useReadAheadInput</td><td>Use newer, optimized non-blocking, buffered input stream when reading from the server?</td><td>true</td><td>3.1.5</td></tr></tbody></table></div><p>
   </p><p><b>Debuging/Profiling. </b>
      </p><div class="informaltable"><table border="1"><colgroup><col><col><col><col></colgroup><tbody><tr><td>
                     <span class="bold"><strong>Property Name</strong></span>
                  </td><td>
                     <span class="bold"><strong>Definition</strong></span>
                  </td><td>
                     <span class="bold"><strong>Default Value</strong></span>
                  </td><td>
                     <span class="bold"><strong>Since Version</strong></span>
                  </td></tr><tr><td>logger</td><td>The name of a class that implements 'com.mysql.jdbc.log.Log' that will be used to log messages to.(default is 'com.mysql.jdbc.log.StandardLogger', which logs to STDERR)</td><td>com.mysql.jdbc.log.StandardLogger</td><td>3.1.1</td></tr><tr><td>profileSQL</td><td>Trace queries and their execution/fetch times to the configured logger (true/false) defaults to 'false'</td><td>false</td><td>3.1.0</td></tr><tr><td>reportMetricsIntervalMillis</td><td>If 'gatherPerfMetrics' is enabled, how often should they be logged (in ms)?</td><td>30000</td><td>3.1.2</td></tr><tr><td>maxQuerySizeToLog</td><td>Controls the maximum length/size of a query that will get logged when profiling or tracing</td><td>2048</td><td>3.1.3</td></tr><tr><td>packetDebugBufferSize</td><td>The maximum number of packets to retain when 'enablePacketDebug' is true</td><td>20</td><td>3.1.3</td></tr><tr><td>slowQueryThresholdMillis</td><td>If 'logSlowQueries' is enabled, how long should a query (in ms) before it is logged as 'slow'?</td><td>2000</td><td>3.1.2</td></tr><tr><td>useUsageAdvisor</td><td>Should the driver issue 'usage' warnings advising proper and efficient usage of JDBC and MySQL Connector/J to the log (true/false, defaults to 'false')?</td><td>false</td><td>3.1.1</td></tr><tr><td>autoGenerateTestcaseScript</td><td>Should the driver dump the SQL it is executing, including server-side prepared statements to STDERR?</td><td>false</td><td>3.1.9</td></tr><tr><td>dumpMetadataOnColumnNotFound</td><td>Should the driver dump the field-level metadata of a result set into the exception message when ResultSet.findColumn() fails?</td><td>false</td><td>3.1.13</td></tr><tr><td>dumpQueriesOnException</td><td>Should the driver dump the contents of the query sent to the server in the message for SQLExceptions?</td><td>false</td><td>3.1.3</td></tr><tr><td>enablePacketDebug</td><td>When enabled, a ring-buffer of 'packetDebugBufferSize' packets will be kept, and dumped when exceptions are thrown in key areas in the driver's code</td><td>false</td><td>3.1.3</td></tr><tr><td>explainSlowQueries</td><td>If 'logSlowQueries' is enabled, should the driver automatically issue an 'EXPLAIN' on the server and send the results to the configured log at a WARN level?</td><td>false</td><td>3.1.2</td></tr><tr><td>logSlowQueries</td><td>Should queries that take longer than 'slowQueryThresholdMillis' be logged?</td><td>false</td><td>3.1.2</td></tr><tr><td>traceProtocol</td><td>Should trace-level network protocol be logged?</td><td>false</td><td>3.1.2</td></tr></tbody></table></div><p>
   </p><p><b>Miscellaneous. </b>
      </p><div class="informaltable"><table border="1"><colgroup><col><col><col><col></colgroup><tbody><tr><td>
                     <span class="bold"><strong>Property Name</strong></span>
                  </td><td>
                     <span class="bold"><strong>Definition</strong></span>
                  </td><td>
                     <span class="bold"><strong>Default Value</strong></span>
                  </td><td>
                     <span class="bold"><strong>Since Version</strong></span>
                  </td></tr><tr><td>useUnicode</td><td>Should the driver use Unicode character encodings when handling strings? Should only be used when the driver can't determine the character set mapping, or you are trying to 'force' the driver to use a character set that MySQL either doesn't natively support (such as UTF-8), true/false, defaults to 'true'</td><td>true</td><td>1.1g</td></tr><tr><td>characterEncoding</td><td>If 'useUnicode' is set to true, what character encoding should the driver use when dealing with strings? (defaults is to 'autodetect')</td><td>
                  </td><td>1.1g</td></tr><tr><td>characterSetResults</td><td>Character set to tell the server to return results as.</td><td>
                  </td><td>3.0.13</td></tr><tr><td>connectionCollation</td><td>If set, tells the server to use this collation via 'set collation_connection'</td><td>
                  </td><td>3.0.13</td></tr><tr><td>sessionVariables</td><td>A comma-separated list of name/value pairs to be sent as SET SESSION ... to the server when the driver connects.</td><td>
                  </td><td>3.1.8</td></tr><tr><td>allowNanAndInf</td><td>Should the driver allow NaN or +/- INF values in PreparedStatement.setDouble()?</td><td>false</td><td>3.1.5</td></tr><tr><td>autoClosePStmtStreams</td><td>Should the driver automatically call .close() on streams/readers passed as arguments via set*() methods?</td><td>false</td><td>3.1.12</td></tr><tr><td>autoDeserialize</td><td>Should the driver automatically detect and de-serialize objects stored in BLOB fields?</td><td>false</td><td>3.1.5</td></tr><tr><td>capitalizeTypeNames</td><td>Capitalize type names in DatabaseMetaData? (usually only useful when using WebObjects, true/false, defaults to 'false')</td><td>false</td><td>2.0.7</td></tr><tr><td>clobCharacterEncoding</td><td>The character encoding to use for sending and retrieving TEXT, MEDIUMTEXT and LONGTEXT values instead of the configured connection characterEncoding</td><td>
                  </td><td>5.0.0</td></tr><tr><td>clobberStreamingResults</td><td>This will cause a 'streaming' ResultSet to be automatically closed, and any outstanding data still streaming from the server to be discarded if another query is executed before all the data has been read from the server.</td><td>false</td><td>3.0.9</td></tr><tr><td>continueBatchOnError</td><td>Should the driver continue processing batch commands if one statement fails. The JDBC spec allows either way (defaults to 'true').</td><td>true</td><td>3.0.3</td></tr><tr><td>createDatabaseIfNotExist</td><td>Creates the database given in the URL if it doesn't yet exist. Assumes the configured user has permissions to create databases.</td><td>false</td><td>3.1.9</td></tr><tr><td>emptyStringsConvertToZero</td><td>Should the driver allow conversions from empty string fields to numeric values of '0'?</td><td>true</td><td>3.1.8</td></tr><tr><td>emulateLocators</td><td>N/A</td><td>false</td><td>3.1.0</td></tr><tr><td>emulateUnsupportedPstmts</td><td>Should the driver detect prepared statements that are not supported by the server, and replace them with client-side emulated versions?</td><td>true</td><td>3.1.7</td></tr><tr><td>ignoreNonTxTables</td><td>Ignore non-transactional table warning for rollback? (defaults to 'false').</td><td>false</td><td>3.0.9</td></tr><tr><td>jdbcCompliantTruncation</td><td>Should the driver throw java.sql.DataTruncation exceptions when data is truncated as is required by the JDBC specification when connected to a server that supports warnings(MySQL 4.1.0 and newer)?</td><td>true</td><td>3.1.2</td></tr><tr><td>maxRows</td><td>The maximum number of rows to return (0, the default means return all rows).</td><td>-1</td><td>all versions</td></tr><tr><td>noAccessToProcedureBodies</td><td>When determining procedure parameter types for CallableStatements, and the connected user can't access procedure bodies through "SHOW CREATE PROCEDURE" or select on mysql.proc should the driver instead create basic metadata (all parameters reported as INOUT VARCHARs) instead of throwing an exception?</td><td>false</td><td>5.0.3</td></tr><tr><td>noDatetimeStringSync</td><td>Don't ensure that ResultSet.getDatetimeType().toString().equals(ResultSet.getString())</td><td>false</td><td>3.1.7</td></tr><tr><td>noTimezoneConversionForTimeType</td><td>Don't convert TIME values using the server timezone if 'useTimezone'='true'</td><td>false</td><td>5.0.0</td></tr><tr><td>nullCatalogMeansCurrent</td><td>When DatabaseMetadataMethods ask for a 'catalog' parameter, does the value null mean use the current catalog? (this is not JDBC-compliant, but follows legacy behavior from earlier versions of the driver)</td><td>true</td><td>3.1.8</td></tr><tr><td>nullNamePatternMatchesAll</td><td>Should DatabaseMetaData methods that accept *pattern parameters treat null the same as '%' (this is not JDBC-compliant, however older versions of the driver accepted this departure from the specification)</td><td>true</td><td>3.1.8</td></tr><tr><td>overrideSupportsIntegrityEnhancementFacility</td><td>Should the driver return "true" for DatabaseMetaData.supportsIntegrityEnhancementFacility() even if the database doesn't support it to workaround applications that require this method to return "true" to signal support of foreign keys, even though the SQL specification states that this facility contains much more than just foreign key support (one such application being OpenOffice)?</td><td>false</td><td>3.1.12</td></tr><tr><td>pedantic</td><td>Follow the JDBC spec to the letter.</td><td>false</td><td>3.0.0</td></tr><tr><td>pinGlobalTxToPhysicalConnection</td><td>When using XAConnections, should the driver ensure that operations on a given XID are always routed to the same physical connection? This allows the XAConnection to support "XA START ... JOIN" after "XA END" has been called</td><td>false</td><td>5.0.1</td></tr><tr><td>processEscapeCodesForPrepStmts</td><td>Should the driver process escape codes in queries that are prepared?</td><td>true</td><td>3.1.12</td></tr><tr><td>relaxAutoCommit</td><td>If the version of MySQL the driver connects to does not support transactions, still allow calls to commit(), rollback() and setAutoCommit() (true/false, defaults to 'false')?</td><td>false</td><td>2.0.13</td></tr><tr><td>retainStatementAfterResultSetClose</td><td>Should the driver retain the Statement reference in a ResultSet after ResultSet.close() has been called. This is not JDBC-compliant after JDBC-4.0.</td><td>false</td><td>3.1.11</td></tr><tr><td>rollbackOnPooledClose</td><td>Should the driver issue a rollback() when the logical connection in a pool is closed?</td><td>true</td><td>3.0.15</td></tr><tr><td>runningCTS13</td><td>Enables workarounds for bugs in Sun's JDBC compliance testsuite version 1.3</td><td>false</td><td>3.1.7</td></tr><tr><td>serverTimezone</td><td>Override detection/mapping of timezone. Used when timezone from server doesn't map to Java timezone</td><td>
                  </td><td>3.0.2</td></tr><tr><td>strictFloatingPoint</td><td>Used only in older versions of compliance test</td><td>false</td><td>3.0.0</td></tr><tr><td>strictUpdates</td><td>Should the driver do strict checking (all primary keys selected) of updatable result sets (true, false, defaults to 'true')?</td><td>true</td><td>3.0.4</td></tr><tr><td>tinyInt1isBit</td><td>Should the driver treat the datatype TINYINT(1) as the BIT type (because the server silently converts BIT -&gt; TINYINT(1) when creating tables)?</td><td>true</td><td>3.0.16</td></tr><tr><td>transformedBitIsBoolean</td><td>If the driver converts TINYINT(1) to a different type, should it use BOOLEAN instead of BIT for future compatibility with MySQL-5.0, as MySQL-5.0 has a BIT type?</td><td>false</td><td>3.1.9</td></tr><tr><td>ultraDevHack</td><td>Create PreparedStatements for prepareCall() when required, because UltraDev is broken and issues a prepareCall() for _all_ statements? (true/false, defaults to 'false')</td><td>false</td><td>2.0.3</td></tr><tr><td>useGmtMillisForDatetimes</td><td>Convert between session timezone and GMT before creating Date and Timestamp instances (value of "false" is legacy behavior, "true" leads to more JDBC-compliant behavior.</td><td>false</td><td>3.1.12</td></tr><tr><td>useHostsInPrivileges</td><td>Add '@hostname' to users in DatabaseMetaData.getColumn/TablePrivileges() (true/false), defaults to 'true'.</td><td>true</td><td>3.0.2</td></tr><tr><td>useInformationSchema</td><td>When connected to MySQL-5.0.7 or newer, should the driver use the INFORMATION_SCHEMA to derive information used by DatabaseMetaData?</td><td>false</td><td>5.0.0</td></tr><tr><td>useJDBCCompliantTimezoneShift</td><td>Should the driver use JDBC-compliant rules when converting TIME/TIMESTAMP/DATETIME values' timezone information for those JDBC arguments which take a java.util.Calendar argument? (Notice that this option is exclusive of the "useTimezone=true" configuration option.)</td><td>false</td><td>5.0.0</td></tr><tr><td>useOldAliasMetadataBehavior</td><td>Should the driver use the legacy behavior for "AS" clauses on columns and tables, and only return aliases (if any) for ResultSetMetaData.getColumnName() or ResultSetMetaData.getTableName() rather than the original column/table name?</td><td>true</td><td>5.0.4</td></tr><tr><td>useOldUTF8Behavior</td><td>Use the UTF-8 behavior the driver did when communicating with 4.0 and older servers</td><td>false</td><td>3.1.6</td></tr><tr><td>useOnlyServerErrorMessages</td><td>Don't prepend 'standard' SQLState error messages to error messages returned by the server.</td><td>true</td><td>3.0.15</td></tr><tr><td>useServerPrepStmts</td><td>Use server-side prepared statements if the server supports them? (defaults to 'true').</td><td>true</td><td>3.1.0</td></tr><tr><td>useSqlStateCodes</td><td>Use SQL Standard state codes instead of 'legacy' X/Open/SQL state codes (true/false), default is 'true'</td><td>true</td><td>3.1.3</td></tr><tr><td>useStreamLengthsInPrepStmts</td><td>Honor stream length parameter in PreparedStatement/ResultSet.setXXXStream() method calls (true/false, defaults to 'true')?</td><td>true</td><td>3.0.2</td></tr><tr><td>useTimezone</td><td>Convert time/date types between client and server timezones (true/false, defaults to 'false')?</td><td>false</td><td>3.0.2</td></tr><tr><td>useUnbufferedInput</td><td>Don't use BufferedInputStream for reading data from the server</td><td>true</td><td>3.0.11</td></tr><tr><td>yearIsDateType</td><td>Should the JDBC driver treat the MySQL type "YEAR" as a java.sql.Date, or as a SHORT?</td><td>true</td><td>3.1.9</td></tr><tr><td>zeroDateTimeBehavior</td><td>What should happen when the driver encounters DATETIME values that are composed entirely of zeroes (used by MySQL to represent invalid dates)? Valid values are 'exception', 'round' and 'convertToNull'.</td><td>exception</td><td>3.1.4</td></tr></tbody></table></div><p>
   </p><p>
        Connector/J also supports access to MySQL via named pipes on
        Windows NT/2000/XP using the
        <span class="property">NamedPipeSocketFactory</span> as a plugin-socket
        factory via the <span class="property">socketFactory</span> property. If
        you don't use a <span class="property">namedPipePath</span> property, the
        default of '\\.\pipe\MySQL' will be used. If you use the
        <code class="literal">NamedPipeSocketFactory</code>, the hostname and port
        number values in the JDBC url will be ignored. You can enable
        this feature using:
      </p><pre class="programlisting">socketFactory=com.mysql.jdbc.NamedPipeSocketFactory
        </pre><p>
        Named pipes only work when connecting to a MySQL server on the
        same physical machine as the one the JDBC driver is being used
        on. In simple performance tests, it appears that named pipe
        access is between 30%-50% faster than the standard TCP/IP
        access.
      </p><p>
        You can create your own socket factories by following the
        example code in
        <code class="classname">com.mysql.jdbc.NamedPipeSocketFactory</code>, or
        <code class="classname">com.mysql.jdbc.StandardSocketFactory</code>.
      </p></div><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="connector-j-reference-implementation-notes"></a>1.4.2. JDBC API Implementation Notes</h4></div></div></div><p>
        MySQL Connector/J passes all of the tests in the
        publicly-available version of Sun's JDBC compliance test suite.
        However, in many places the JDBC specification is vague about
        how certain functionality should be implemented, or the
        specification allows leeway in implementation.
      </p><p>
        This section gives details on a interface-by-interface level
        about how certain implementation decisions may affect how you
        use MySQL Connector/J.
      </p><div class="itemizedlist"><ul type="disc"><li><p>
            Blob
          </p><p>
            The Blob implementation does not allow in-place modification
            (they are copies, as reported by the
            <code class="literal">DatabaseMetaData.locatorsUpdateCopies()</code>
            method). Because of this, you should use the corresponding
            <code class="literal">PreparedStatement.setBlob()</code> or
            <code class="literal">ResultSet.updateBlob()</code> (in the case of
            updatable result sets) methods to save changes back to the
            database.
          </p><p>
            Starting with Connector/J version 3.1.0, you can emulate
            Blobs with locators by adding the property
            'emulateLocators=true' to your JDBC URL. You must then use a
            column alias with the value of the column set to the actual
            name of the Blob column in the <code class="literal">SELECT</code>
            that you write to retrieve the Blob. The
            <code class="literal">SELECT</code> must also reference only one
            table, the table must have a primary key, and the
            <code class="literal">SELECT</code> must cover all columns that make
            up the primary key. The driver will then delay loading the
            actual Blob data until you retrieve the Blob and call
            retrieval methods (<code class="literal">getInputStream()</code>,
            <code class="literal">getBytes()</code>, and so forth) on it.
          </p></li><li><p>
            CallableStatement
          </p><p>
            Starting with Connector/J 3.1.1, stored procedures are
            supported when connecting to MySQL version 5.0 or newer via
            the <code class="classname">CallableStatement</code> interface.
            Currently, the <code class="literal">getParameterMetaData()</code>
            method of <code class="classname">CallableStatement</code> is not
            supported.
          </p></li><li><p>
            Clob
          </p><p>
            The Clob implementation does not allow in-place modification
            (they are copies, as reported by the
            <code class="literal">DatabaseMetaData.locatorsUpdateCopies()</code>
            method). Because of this, you should use the
            <code class="literal">PreparedStatement.setClob()</code> method to
            save changes back to the database. The JDBC API does not
            have a <code class="literal">ResultSet.updateClob()</code> method.
          </p></li><li><p>
            Connection
          </p><p>
            Unlike older versions of MM.MySQL the
            <code class="literal">isClosed()</code> method does not ping the
            server to determine if it is alive. In accordance with the
            JDBC specification, it only returns true if
            <code class="literal">closed()</code> has been called on the
            connection. If you need to determine if the connection is
            still valid, you should issue a simple query, such as
            <code class="literal">SELECT 1</code>. The driver will throw an
            exception if the connection is no longer valid.
          </p></li><li><p>
            DatabaseMetaData
          </p><p>
            Foreign Key information
            (<code class="literal">getImportedKeys()</code>/<code class="literal">getExportedKeys()</code>
            and <code class="literal">getCrossReference()</code>) is only
            available from InnoDB tables. However, the driver uses
            <code class="literal">SHOW CREATE TABLE</code> to retrieve this
            information, so when other storage engines support foreign
            keys, the driver will transparently support them as well.
          </p></li><li><p>
            PreparedStatement
          </p><p>
            PreparedStatements are implemented by the driver, as MySQL
            does not have a prepared statement feature. Because of this,
            the driver does not implement
            <code class="literal">getParameterMetaData()</code> or
            <code class="literal">getMetaData()</code> as it would require the
            driver to have a complete SQL parser in the client.
          </p><p>
            Starting with version 3.1.0 MySQL Connector/J, server-side
            prepared statements and binary-encoded result sets are used
            when the server supports them.
          </p><p>
            Take care when using a server-side prepared statement with
            <span class="bold"><strong>large</strong></span> parameters that are
            set via <code class="literal">setBinaryStream()</code>,
            <code class="literal">setAsciiStream()</code>,
            <code class="literal">setUnicodeStream()</code>,
            <code class="literal">setBlob()</code>, or
            <code class="literal">setClob()</code>. If you want to re-execute the
            statement with any large parameter changed to a non-large
            parameter, it is necessary to call
            <code class="literal">clearParameters()</code> and set all parameters
            again. The reason for this is as follows:
          </p><div class="itemizedlist"><ul type="circle"><li><p>
                The driver streams the large data out-of-band to the
                prepared statement on the server side when the parameter
                is set (before execution of the prepared statement).
              </p></li></ul></div><div class="itemizedlist"><ul type="circle"><li><p>
                Once that has been done, the stream used to read the
                data on the client side is closed (as per the JDBC
                spec), and can't be read from again.
              </p></li></ul></div><div class="itemizedlist"><ul type="circle"><li><p>
                If a parameter changes from large to non-large, the
                driver must reset the server-side state of the prepared
                statement to allow the parameter that is being changed
                to take the place of the prior large value. This removes
                all of the large data that has already been sent to the
                server, thus requiring the data to be re-sent, via the
                <code class="literal">setBinaryStream()</code>,
                <code class="literal">setAsciiStream()</code>,
                <code class="literal">setUnicodeStream()</code>,
                <code class="literal">setBlob()</code> or
                <code class="literal">setClob()</code> methods.
              </p></li></ul></div><p>
            Consequently, if you want to change the type of a parameter
            to a non-large one, you must call
            <code class="literal">clearParameters()</code> and set all parameters
            of the prepared statement again before it can be
            re-executed.
          </p></li><li><p>
            ResultSet
          </p><p>
            By default, ResultSets are completely retrieved and stored
            in memory. In most cases this is the most efficient way to
            operate, and due to the design of the MySQL network protocol
            is easier to implement. If you are working with ResultSets
            that have a large number of rows or large values, and can
            not allocate heap space in your JVM for the memory required,
            you can tell the driver to stream the results back one row
            at a time.
          </p><p>
            To enable this functionality, you need to create a Statement
            instance in the following manner:
          </p><pre class="programlisting">stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY,
              java.sql.ResultSet.CONCUR_READ_ONLY);
stmt.setFetchSize(Integer.MIN_VALUE);</pre><p>
            The combination of a forward-only, read-only result set,
            with a fetch size of <code class="literal">Integer.MIN_VALUE</code>
            serves as a signal to the driver to stream result sets
            row-by-row. After this any result sets created with the
            statement will be retrieved row-by-row.
          </p><p>
            There are some caveats with this approach. You will have to
            read all of the rows in the result set (or close it) before
            you can issue any other queries on the connection, or an
            exception will be thrown.
          </p><p>
            The earliest the locks these statements hold can be released
            (whether they be <code class="literal">MyISAM</code> table-level locks
            or row-level locks in some other storage engine such as
            <code class="literal">InnoDB</code>) is when the statement completes.
          </p><p>
            If the statement is within scope of a transaction, then
            locks are released when the transaction completes (which
            implies that the statement needs to complete first). As with
            most other databases, statements are not complete until all
            the results pending on the statement are read or the active
            result set for the statement is closed.
          </p><p>
            Therefore, if using streaming results, you should process
            them as quickly as possible if you want to maintain
            concurrent access to the tables referenced by the statement
            producing the result set.
          </p></li><li><p>
            ResultSetMetaData
          </p><p>
            The <code class="literal">isAutoIncrement()</code> method only works
            when using MySQL servers 4.0 and newer.
          </p></li><li><p>
            Statement
          </p><p>
            When using versions of the JDBC driver earlier than 3.2.1,
            and connected to server versions earlier than 5.0.3, the
            "setFetchSize()" method has no effect, other than to toggle
            result set streaming as described above.
          </p><p>
            MySQL does not support SQL cursors, and the JDBC driver
            doesn't emulate them, so "setCursorName()" has no effect.
          </p></li></ul></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="connector-j-reference-type-conversions"></a>1.4.3. Java, JDBC and MySQL Types</h4></div></div></div><p>
        MySQL Connector/J is flexible in the way it handles conversions
        between MySQL data types and Java data types.
      </p><p>
        In general, any MySQL data type can be converted to a
        java.lang.String, and any numerical type can be converted to any
        of the Java numerical types, although round-off, overflow, or
        loss of precision may occur.
      </p><p>
        Starting with Connector/J 3.1.0, the JDBC driver will issue
        warnings or throw DataTruncation exceptions as is required by
        the JDBC specification unless the connection was configured not
        to do so by using the property
        <span class="property">jdbcCompliantTruncation</span> and setting it to
        <code class="literal">false</code>.
      </p><p>
        The conversions that are always guaranteed to work are listed in
        the following table:
      </p><p><b>Connection Properties - Miscellaneous. </b>
          </p><div class="informaltable"><table border="1"><colgroup><col><col></colgroup><tbody><tr><td><span class="bold"><strong>These MySQL Data Types</strong></span></td><td><span class="bold"><strong>Can always be converted to these Java
                    types</strong></span></td></tr><tr><td><code class="literal">CHAR, VARCHAR, BLOB, TEXT, ENUM, and SET</code></td><td><code class="literal">java.lang.String, java.io.InputStream, java.io.Reader,
                    java.sql.Blob, java.sql.Clob</code></td></tr><tr><td><code class="literal">FLOAT, REAL, DOUBLE PRECISION, NUMERIC, DECIMAL, TINYINT,
                    SMALLINT, MEDIUMINT, INTEGER, BIGINT</code></td><td><code class="literal">java.lang.String, java.lang.Short, java.lang.Integer,
                    java.lang.Long, java.lang.Double,
                    java.math.BigDecimal</code></td></tr><tr><td><code class="literal">DATE, TIME, DATETIME, TIMESTAMP</code></td><td><code class="literal">java.lang.String, java.sql.Date, java.sql.Timestamp</code></td></tr></tbody></table></div><p>
        </p><p>
        <span class="bold"><strong>Note:</strong></span> round-off, overflow or
        loss of precision may occur if you choose a Java numeric data
        type that has less precision or capacity than the MySQL data
        type you are converting to/from.
      </p><p>
        The <code class="classname">ResultSet.getObject()</code> method uses the
        type conversions between MySQL and Java types, following the
        JDBC specification where appropriate. The value returned by
        <code class="classname">ResultSetMetaData.GetColumnClassName()</code> is
        also shown below. For more information on the
        <code class="literal">java.sql.Types</code> classes see
        <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/sql/Types.html" target="_top">Java
        2 Platform Types</a>.
      </p><p><b>MySQL Types to Java Types for ResultSet.getObject(). </b>
          </p><div class="informaltable"><table border="1"><colgroup><col><col></colgroup><tbody><tr><td><span class="bold"><strong>MySQL Type Name</strong></span></td><td><span class="bold"><strong>Return value of
                    <code class="literal">GetColumnClassName</code></strong></span></td><td><span class="bold"><strong>Returned as Java Class</strong></span></td></tr><tr><td><span class="type">BIT(1)</span> (new in MySQL-5.0)</td><td><span class="type">BIT</span></td><td><code class="classname">java.lang.Boolean</code></td></tr><tr><td><span class="type">BIT( &gt; 1)</span> (new in MySQL-5.0)</td><td><span class="type">BIT</span></td><td><code class="classname">byte[]</code></td></tr><tr><td><span class="type">TINYINT</span></td><td><span class="type">TINYINT</span></td><td><code class="classname">java.lang.Boolean</code> if the configuration property
                    <code class="literal">tinyInt1isBit</code> is set to
                    <code class="literal">true</code> (the default) and the
                    storage size is 1, or
                    <code class="classname">java.lang.Integer</code> if not.</td></tr><tr><td><span class="type">BOOL</span>, <span class="type">BOOLEAN</span></td><td><span class="type">TINYINT</span></td><td>See <span class="type">TINYINT</span>, above as these are aliases for
                    <span class="type">TINYINT(1)</span>, currently.</td></tr><tr><td><span class="type">SMALLINT[(M)] [UNSIGNED]</span></td><td><span class="type">SMALLINT [UNSIGNED]</span></td><td><code class="classname">java.lang.Integer</code> (regardless if UNSIGNED or not)</td></tr><tr><td><span class="type">MEDIUMINT[(M)] [UNSIGNED]</span></td><td><span class="type">MEDIUMINT [UNSIGNED]</span></td><td><code class="classname">java.lang.Integer,</code> if UNSIGNED
                    <code class="classname">java.lang.Long</code></td></tr><tr><td><span class="type">INT,INTEGER[(M)] [UNSIGNED]</span></td><td><span class="type">INTEGER [UNSIGNED]</span></td><td><code class="classname">java.lang.Integer</code>, if UNSIGNED
                    <code class="classname">java.lang.Long</code></td></tr><tr><td><span class="type">BIGINT[(M)] [UNSIGNED]</span></td><td><span class="type">BIGINT [UNSIGNED]</span></td><td><code class="classname">java.lang.Long</code>, if UNSIGNED
                    <code class="classname">java.math.BigInteger</code></td></tr><tr><td><span class="type">FLOAT[(M,D)]</span></td><td><span class="type">FLOAT</span></td><td><code class="classname">java.lang.Float</code></td></tr><tr><td><span class="type">DOUBLE[(M,B)]</span></td><td><span class="type">DOUBLE</span></td><td><code class="classname">java.lang.Double</code></td></tr><tr><td><span class="type">DECIMAL[(M[,D])]</span></td><td><span class="type">DECIMAL</span></td><td><code class="classname">java.math.BigDecimal</code></td></tr><tr><td><span class="type">DATE</span></td><td><span class="type">DATE</span></td><td><code class="classname">java.sql.Date</code></td></tr><tr><td><span class="type">DATETIME</span></td><td><span class="type">DATETIME</span></td><td><code class="classname">java.sql.Timestamp</code></td></tr><tr><td><span class="type">TIMESTAMP[(M)]</span></td><td><span class="type">TIMESTAMP</span></td><td><code class="classname">java.sql.Timestamp</code></td></tr><tr><td><span class="type">TIME</span></td><td><span class="type">TIME</span></td><td><code class="classname">java.sql.Time</code></td></tr><tr><td><span class="type">YEAR[(2|4)]</span></td><td><span class="type">YEAR</span></td><td>If <code class="literal">yearIsDateType</code> configuration property is set to
                    false, then the returned object type is
                    <code class="classname">java.sql.Short</code>. If set to
                    true (the default) then an object of type
                    <code class="classname">java.sql.Date</code> (with the date
                    set to January 1st, at midnight).</td></tr><tr><td><span class="type">CHAR(M)</span></td><td><span class="type">CHAR</span></td><td><code class="classname">java.lang.String</code> (unless the character set for
                    the column is <span class="type">BINARY</span>, then
                    <code class="classname">byte[]</code> is returned.</td></tr><tr><td><span class="type">VARCHAR(M) [BINARY]</span></td><td><span class="type">VARCHAR</span></td><td><code class="classname">java.lang.String</code> (unless the character set for
                    the column is <span class="type">BINARY</span>, then
                    <code class="classname">byte[]</code> is returned.</td></tr><tr><td><span class="type">BINARY(M)</span></td><td><span class="type">BINARY</span></td><td><code class="classname">byte[]</code></td></tr><tr><td><span class="type">VARBINARY(M)</span></td><td><span class="type">VARBINARY</span></td><td><code class="classname">byte[]</code></td></tr><tr><td><span class="type">TINYBLOB</span></td><td><span class="type">TINYBLOB</span></td><td><code class="classname">byte[]</code></td></tr><tr><td><span class="type">TINYTEXT</span></td><td><span class="type">VARCHAR</span></td><td><code class="classname">java.lang.String</code></td></tr><tr><td><span class="type">BLOB</span></td><td><span class="type">BLOB</span></td><td><code class="classname">byte[]</code></td></tr><tr><td><span class="type">TEXT</span></td><td><span class="type">VARCHAR</span></td><td><code class="classname">java.lang.String</code></td></tr><tr><td><span class="type">MEDIUMBLOB</span></td><td><span class="type">MEDIUMBLOB</span></td><td><code class="classname">byte[]</code></td></tr><tr><td><span class="type">MEDIUMTEXT</span></td><td><span class="type">VARCHAR</span></td><td><code class="classname">java.lang.String</code></td></tr><tr><td><span class="type">LONGBLOB</span></td><td><span class="type">LONGBLOB</span></td><td><code class="classname">byte[]</code></td></tr><tr><td><span class="type">LONGTEXT</span></td><td><span class="type">VARCHAR</span></td><td><code class="classname">java.lang.String</code></td></tr><tr><td><span class="type">ENUM('value1','value2',...)</span></td><td><span class="type">CHAR</span></td><td><code class="classname">java.lang.String</code></td></tr><tr><td><span class="type">SET('value1','value2',...)</span></td><td><span class="type">CHAR</span></td><td><code class="classname">java.lang.String</code></td></tr></tbody></table></div><p>
        </p></div><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="connector-j-reference-charsets"></a>1.4.4. Using Character Sets and Unicode</h4></div></div></div><p>
        All strings sent from the JDBC driver to the server are
        converted automatically from native Java Unicode form to the
        client character encoding, including all queries sent via
        <code class="literal">Statement.execute()</code>,
        <code class="literal">Statement.executeUpdate()</code>,
        <code class="literal">Statement.executeQuery()</code> as well as all

        <code class="interfacename">PreparedStatement</code>

        and

        <code class="interfacename">CallableStatement</code>

        parameters with the exclusion of parameters set using
        <code class="literal">setBytes()</code>,
        <code class="literal">setBinaryStream()</code>,
        <code class="literal">setAsciiStream()</code>,
        <code class="literal">setUnicodeStream()</code> and
        <code class="literal">setBlob()</code> .
      </p><p>
        Prior to MySQL Server 4.1, Connector/J supported a single
        character encoding per connection, which could either be
        automatically detected from the server configuration, or could
        be configured by the user through the
        <em class="parameter"><code>useUnicode</code></em> and
        "<em class="parameter"><code>characterEncoding</code></em>" properties.
      </p><p>
        Starting with MySQL Server 4.1, Connector/J supports a single
        character encoding between client and server, and any number of
        character encodings for data returned by the server to the
        client in <code class="classname">ResultSets</code>.
      </p><p>
        The character encoding between client and server is
        automatically detected upon connection. The encoding used by the
        driver is specified on the server via the
        <code class="literal">character_set</code> system variable for server
        versions older than 4.1.0 and
        <code class="literal">character_set_server</code> for server versions
        4.1.0 and newer. For more information, see
        ???.
      </p><p>
        To override the automatically-detected encoding on the client
        side, use the <em class="parameter"><code>characterEncoding</code></em> property
        in the URL used to connect to the server.
      </p><p>
        When specifying character encodings on the client side,
        Java-style names should be used. The following table lists
        Java-style names for MySQL character sets:
      </p><p><b>MySQL to Java Encoding Name Translations. </b>
          </p><div class="informaltable"><table border="1"><colgroup><col><col></colgroup><tbody><tr><td><span class="bold"><strong>MySQL Character Set Name</strong></span></td><td><span class="bold"><strong>Java-Style Character Encoding Name</strong></span></td></tr><tr><td>ascii</td><td>US-ASCII</td></tr><tr><td>big5</td><td>Big5</td></tr><tr><td>gbk</td><td>GBK</td></tr><tr><td>sjis</td><td>SJIS (or Cp932 or MS932 for MySQL Server &lt; 4.1.11)</td></tr><tr><td>cp932</td><td>Cp932 or MS932 (MySQL Server &gt; 4.1.11)</td></tr><tr><td>gb2312</td><td>EUC_CN</td></tr><tr><td>ujis</td><td>EUC_JP</td></tr><tr><td>euckr</td><td>EUC_KR</td></tr><tr><td>latin1</td><td>ISO8859_1</td></tr><tr><td>latin2</td><td>ISO8859_2</td></tr><tr><td>greek</td><td>ISO8859_7</td></tr><tr><td>hebrew</td><td>ISO8859_8</td></tr><tr><td>cp866</td><td>Cp866</td></tr><tr><td>tis620</td><td>TIS620</td></tr><tr><td>cp1250</td><td>Cp1250</td></tr><tr><td>cp1251</td><td>Cp1251</td></tr><tr><td>cp1257</td><td>Cp1257</td></tr><tr><td>macroman</td><td>MacRoman</td></tr><tr><td>macce</td><td>MacCentralEurope</td></tr><tr><td>utf8</td><td>UTF-8</td></tr><tr><td>ucs2</td><td>UnicodeBig</td></tr></tbody></table></div><p>
        </p><p><b>Warning. </b>
          Do not issue the query 'set names' with Connector/J, as the
          driver will not detect that the character set has changed, and
          will continue to use the character set detected during the
          initial connection setup.
        </p><p>
        To allow multiple character sets to be sent from the client, the
        UTF-8 encoding should be used, either by configuring
        <code class="literal">utf8</code> as the default server character set, or
        by configuring the JDBC driver to use UTF-8 through the
        <em class="parameter"><code>characterEncoding</code></em> property.
      </p></div><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="connector-j-reference-using-ssl"></a>1.4.5. Connecting Securely Using SSL</h4></div></div></div><p>
        SSL in MySQL Connector/J encrypts all data (other than the
        initial handshake) between the JDBC driver and the server. The
        performance penalty for enabling SSL is an increase in query
        processing time between 35% and 50%, depending on the size of
        the query, and the amount of data it returns.
      </p><p>
        For SSL Support to work, you must have the following:
      </p><div class="itemizedlist"><ul type="disc"><li><p>
            A JDK that includes JSSE (Java Secure Sockets Extension),
            like JDK-1.4.1 or newer. SSL does not currently work with a
            JDK that you can add JSSE to, like JDK-1.2.x or JDK-1.3.x
            due to the following JSSE bug:
            <a href="http://developer.java.sun.com/developer/bugParade/bugs/4273544.html" target="_top">http://developer.java.sun.com/developer/bugParade/bugs/4273544.html</a>
          </p></li><li><p>
            A MySQL server that supports SSL and has been compiled and
            configured to do so, which is MySQL-4.0.4 or later, see
            ???, for more information.
          </p></li><li><p>
            A client certificate (covered later in this section)
          </p></li></ul></div><p>
        You will first need to import the MySQL server CA Certificate
        into a Java truststore. A sample MySQL server CA Certificate is
        located in the <code class="filename">SSL</code> subdirectory of the
        MySQL source distribution. This is what SSL will use to
        determine if you are communicating with a secure MySQL server.
      </p><p>
        To use Java's <span><strong class="command">keytool</strong></span> to create a truststore
        in the current directory , and import the server's CA
        certificate (<code class="filename">cacert.pem</code>), you can do the
        following (assuming that <span><strong class="command">keytool</strong></span> is in your
        path. The <span><strong class="command">keytool</strong></span> should be located in the
        <code class="filename">bin</code> subdirectory of your JDK or JRE):
      </p><pre class="programlisting">shell&gt; keytool -import -alias mysqlServerCACert -file cacert.pem -keystore truststore
        </pre><p>
        Keytool will respond with the following information:
      </p><pre class="programlisting">Enter keystore password:  *********
Owner: EMAILADDRESS=walrus@example.com, CN=Walrus, O=MySQL AB, L=Orenburg, ST=Some
-State, C=RU
Issuer: EMAILADDRESS=walrus@example.com, CN=Walrus, O=MySQL AB, L=Orenburg, ST=Som
e-State, C=RU
Serial number: 0
Valid from: Fri Aug 02 16:55:53 CDT 2002 until: Sat Aug 02 16:55:53 CDT 2003
Certificate fingerprints:
         MD5:  61:91:A0:F2:03:07:61:7A:81:38:66:DA:19:C4:8D:AB
         SHA1: 25:77:41:05:D5:AD:99:8C:14:8C:CA:68:9C:2F:B8:89:C3:34:4D:6C
Trust this certificate? [no]:  yes
Certificate was added to keystore</pre><p>
        You will then need to generate a client certificate, so that the
        MySQL server knows that it is talking to a secure client:
      </p><pre class="programlisting"> shell&gt; keytool -genkey -keyalg rsa -alias mysqlClientCertificate -keystore keystore </pre><p>
        Keytool will prompt you for the following information, and
        create a keystore named <code class="filename">keystore</code> in the
        current directory.
      </p><p>
        You should respond with information that is appropriate for your
        situation:
      </p><pre class="programlisting">Enter keystore password:  *********
What is your first and last name?
  [Unknown]:  Matthews
What is the name of your organizational unit?
  [Unknown]:  Software Development
What is the name of your organization?
  [Unknown]:  MySQL AB
What is the name of your City or Locality?
  [Unknown]:  Flossmoor
What is the name of your State or Province?
  [Unknown]:  IL
What is the two-letter country code for this unit?
  [Unknown]:  US
Is &lt;CN=Matthews, OU=Software Development, O=MySQL AB,
 L=Flossmoor, ST=IL, C=US&gt; correct?
  [no]:  y

Enter key password for &lt;mysqlClientCertificate&gt;
        (RETURN if same as keystore password):</pre><p>
        Finally, to get JSSE to use the keystore and truststore that you
        have generated, you need to set the following system properties
        when you start your JVM, replacing
        <span class="property">path_to_keystore_file</span> with the full path to
        the keystore file you created,
        <span class="property">path_to_truststore_file</span> with the path to
        the truststore file you created, and using the appropriate
        password values for each property.
      </p><pre class="programlisting">-Djavax.net.ssl.keyStore=path_to_keystore_file
-Djavax.net.ssl.keyStorePassword=*********
-Djavax.net.ssl.trustStore=path_to_truststore_file
-Djavax.net.ssl.trustStorePassword=********* </pre><p>
        You will also need to set <span class="property">useSSL</span> to
        <code class="literal">true</code> in your connection parameters for MySQL
        Connector/J, either by adding <code class="literal">useSSL=true</code> to
        your URL, or by setting the property <span class="property">useSSL</span>
        to <code class="literal">true</code> in the
        <code class="classname">java.util.Properties</code> instance you pass to
        <code class="literal">DriverManager.getConnection()</code>.
      </p><p>
        You can test that SSL is working by turning on JSSE debugging
        (as detailed below), and look for the following key events:
      </p><pre class="programlisting">...
 *** ClientHello, v3.1
 RandomCookie:  GMT: 1018531834 bytes = { 199, 148, 180, 215, 74, 12, 54, 244, 0, 168, 55, 103, 215, 64, 16, 138, 225, 190, 132, 153, 2, 217, 219, 239, 202, 19, 121, 78 }
 Session ID:  {}
 Cipher Suites:  { 0, 5, 0, 4, 0, 9, 0, 10, 0, 18, 0, 19, 0, 3, 0, 17 }
 Compression Methods:  { 0 }
 ***
 [write] MD5 and SHA1 hashes:  len = 59
 0000: 01 00 00 37 03 01 3D B6   90 FA C7 94 B4 D7 4A 0C  ...7..=.......J.
 0010: 36 F4 00 A8 37 67 D7 40   10 8A E1 BE 84 99 02 D9  6...7g.@........
 0020: DB EF CA 13 79 4E 00 00   10 00 05 00 04 00 09 00  ....yN..........
 0030: 0A 00 12 00 13 00 03 00   11 01 00                 ...........
 main, WRITE:  SSL v3.1 Handshake, length = 59
 main, READ:  SSL v3.1 Handshake, length = 74
 *** ServerHello, v3.1
 RandomCookie:  GMT: 1018577560 bytes = { 116, 50, 4, 103, 25, 100, 58, 202, 79, 185, 178, 100, 215, 66, 254, 21, 83, 187, 190, 42, 170, 3, 132, 110, 82, 148, 160, 92 }
 Session ID:  {163, 227, 84, 53, 81, 127, 252, 254, 178, 179, 68, 63, 182, 158, 30, 11, 150, 79, 170, 76, 255, 92, 15, 226, 24, 17, 177, 219, 158, 177, 187, 143}
 Cipher Suite:  { 0, 5 }
 Compression Method: 0
 ***
 %% Created:  [Session-1, SSL_RSA_WITH_RC4_128_SHA]
 ** SSL_RSA_WITH_RC4_128_SHA
 [read] MD5 and SHA1 hashes:  len = 74
 0000: 02 00 00 46 03 01 3D B6   43 98 74 32 04 67 19 64  ...F..=.C.t2.g.d
 0010: 3A CA 4F B9 B2 64 D7 42   FE 15 53 BB BE 2A AA 03  :.O..d.B..S..*..
 0020: 84 6E 52 94 A0 5C 20 A3   E3 54 35 51 7F FC FE B2  .nR..\ ..T5Q....
 0030: B3 44 3F B6 9E 1E 0B 96   4F AA 4C FF 5C 0F E2 18  .D?.....O.L.\...
 0040: 11 B1 DB 9E B1 BB 8F 00   05 00                    ..........
 main, READ:  SSL v3.1 Handshake, length = 1712
 ...</pre><p>
        JSSE provides debugging (to STDOUT) when you set the following
        system property: <code class="literal">-Djavax.net.debug=all</code> This
        will tell you what keystores and truststores are being used, as
        well as what is going on during the SSL handshake and
        certificate exchange. It will be helpful when trying to
        determine what is not working when trying to get an SSL
        connection to happen.
      </p></div><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="connector-j-reference-replication-connection"></a>1.4.6. Using Master/Slave Replication with ReplicationConnection</h4></div></div></div><p>
        Starting with Connector/J 3.1.7, we've made available a variant
        of the driver that will automatically send queries to a
        read/write master, or a failover or round-robin loadbalanced set
        of slaves based on the state of
        <code class="literal">Connection.getReadOnly()</code> .
      </p><p>
        An application signals that it wants a transaction to be
        read-only by calling
        <code class="literal">Connection.setReadOnly(true)</code>, this
        replication-aware connection will use one of the slave
        connections, which are load-balanced per-vm using a round-robin
        scheme (a given connection is sticky to a slave unless that
        slave is removed from service). If you have a write transaction,
        or if you have a read that is time-sensitive (remember,
        replication in MySQL is asynchronous), set the connection to be
        not read-only, by calling
        <code class="literal">Connection.setReadOnly(false)</code> and the driver
        will ensure that further calls are sent to the master MySQL
        server. The driver takes care of propagating the current state
        of autocommit, isolation level, and catalog between all of the
        connections that it uses to accomplish this load balancing
        functionality.
      </p><p>
        To enable this functionality, use the "
        <code class="literal">com.mysql.jdbc.ReplicationDriver</code> " class when
        configuring your application server's connection pool or when
        creating an instance of a JDBC driver for your standalone
        application. Because it accepts the same URL format as the
        standard MySQL JDBC driver, <code class="literal">ReplicationDriver</code>
        does not currently work with
        <code class="literal">java.sql.DriverManager</code> -based connection
        creation unless it is the only MySQL JDBC driver registered with
        the <code class="literal">DriverManager</code> .
      </p><p>
        Here is a short, simple example of how ReplicationDriver might
        be used in a standalone application.
      </p><a name="connector-j-using-replication-driver-example"></a><pre class="programlisting">import java.sql.Connection;
import java.sql.ResultSet;
import java.util.Properties;

import com.mysql.jdbc.ReplicationDriver;

public class ReplicationDriverDemo {

    public static void main(String[] args) throws Exception {
        ReplicationDriver driver = new ReplicationDriver();

        Properties props = new Properties();

        // We want this for failover on the slaves
        props.put("autoReconnect", "true");

        // We want to load balance between the slaves
        props.put("roundRobinLoadBalance", "true");

        props.put("user", "foo");
        props.put("password", "bar");

        //
        // Looks like a normal MySQL JDBC url, with a comma-separated list
        // of hosts, the first being the 'master', the rest being any number
        // of slaves that the driver will load balance against
        //

        Connection conn =
            driver.connect("jdbc:mysql://master,slave1,slave2,slave3/test",
                props);

        //
        // Perform read/write work on the master
        // by setting the read-only flag to "false"
        //

        conn.setReadOnly(false);
        conn.setAutoCommit(false);
        conn.createStatement().executeUpdate("UPDATE some_table ....");
        conn.commit();

        //
        // Now, do a query from a slave, the driver automatically picks one
        // from the list
        //

        conn.setReadOnly(true);

        ResultSet rs = conn.createStatement().executeQuery("SELECT a,b,c FROM some_other_table");

         .......
    }
}
</pre></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="connector-j-usagenotes"></a>1.5. Connector/J Notes and Tips</h3></div></div></div><div class="toc"><dl><dt><span class="section"><a href="#connector-j-usagenotes-basic">1.5.1. Basic JDBC Concepts</a></span></dt><dt><span class="section"><a href="#connector-j-usagenotes-j2ee">1.5.2. Using Connector/J with J2EE and Other Java Frameworks</a></span></dt><dt><span class="section"><a href="#connector-j-usagenotes-troubleshooting">1.5.3. Common Problems and Solutions</a></span></dt></dl></div><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="connector-j-usagenotes-basic"></a>1.5.1. Basic JDBC Concepts</h4></div></div></div><p>
        This section provides some general JDBC background.
      </p><div class="section" lang="en"><div class="titlepage"><div><div><h5 class="title"><a name="connector-j-usagenotes-connect-drivermanager"></a>1.5.1.1. Connecting to MySQL Using the <code class="literal">DriverManager</code> Interface</h5></div></div></div><p>
          When you are using JDBC outside of an application server, the
          <code class="literal">DriverManager</code> class manages the
          establishment of Connections.
        </p><p>
          The <code class="literal">DriverManager</code> needs to be told which
          JDBC drivers it should try to make Connections with. The
          easiest way to do this is to use
          <code class="literal">Class.forName()</code> on the class that
          implements the <code class="literal">java.sql.Driver</code> interface.
          With MySQL Connector/J, the name of this class is
          <code class="literal">com.mysql.jdbc.Driver</code>. With this method,
          you could use an external configuration file to supply the
          driver class name and driver parameters to use when connecting
          to a database.
        </p><p>
          The following section of Java code shows how you might
          register MySQL Connector/J from the <code class="literal">main()</code>
          method of your application:
        </p><pre class="programlisting">import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

// Notice, do not import com.mysql.jdbc.*
// or you will have problems!

public class LoadDriver {
    public static void main(String[] args) {
        try {
            // The newInstance() call is a work around for some
            // broken Java implementations

            Class.forName("com.mysql.jdbc.Driver").newInstance();
        } catch (Exception ex) {
            // handle the error
        }
}</pre><p>
          After the driver has been registered with the
          <code class="literal">DriverManager</code>, you can obtain a
          <code class="literal">Connection</code> instance that is connected to a
          particular database by calling
          <code class="literal">DriverManager.getConnection()</code>:
        </p><div class="example"><a name="connector-j-examples-connection-drivermanager"></a><p class="title"><b>Example 1. Obtaining a connection from the <code class="literal">DriverManager</code></b></p><p>
            This example shows how you can obtain a
            <code class="literal">Connection</code> instance from the
            <code class="literal">DriverManager</code>. There are a few different
            signatures for the <code class="literal">getConnection()</code>
            method. You should see the API documentation that comes with
            your JDK for more specific information on how to use them.
          </p><pre class="programlisting">import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

    ... try {
            Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/test?user=monty&amp;password=greatsqldb");

            // Do something with the Connection

           ....
        } catch (SQLException ex) {
            // handle any errors
            System.out.println("SQLException: " + ex.getMessage());
            System.out.println("SQLState: " + ex.getSQLState());
            System.out.println("VendorError: " + ex.getErrorCode());
        }
</pre><p>
            Once a <code class="classname">Connection</code> is established, it
            can be used to create <code class="classname">Statement</code> and
            <code class="classname">PreparedStatement</code> objects, as well as
            retrieve metadata about the database. This is explained in
            the following sections.
          </p></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h5 class="title"><a name="connector-j-usagenotes-statements"></a>1.5.1.2. Using Statements to Execute SQL</h5></div></div></div><p>
          <code class="classname">Statement</code> objects allow you to execute
          basic SQL queries and retrieve the results through the
          <code class="literal">ResultSet</code> class which is described later.
        </p><p>
          To create a <code class="classname">Statement</code> instance, you
          call the <code class="literal">createStatement()</code> method on the
          <code class="literal">Connection</code> object you have retrieved via
          one of the <code class="literal">DriverManager.getConnection()</code> or
          <code class="literal">DataSource.getConnection()</code> methods
          described earlier.
        </p><p>
          Once you have a <code class="classname">Statement</code> instance, you
          can execute a <code class="literal">SELECT</code> query by calling the
          <code class="literal">executeQuery(String)</code> method with the SQL
          you want to use.
        </p><p>
          To update data in the database, use the
          <code class="literal">executeUpdate(String SQL)</code> method. This
          method returns the number of rows affected by the update
          statement.
        </p><p>
          If you don't know ahead of time whether the SQL statement will
          be a <code class="literal">SELECT</code> or an
          <code class="literal">UPDATE</code>/<code class="literal">INSERT</code>, then you
          can use the <code class="literal">execute(String SQL)</code> method.
          This method will return true if the SQL query was a
          <code class="literal">SELECT</code>, or false if it was an
          <code class="literal">UPDATE</code>, <code class="literal">INSERT</code>, or
          <code class="literal">DELETE</code> statement. If the statement was a
          <code class="literal">SELECT</code> query, you can retrieve the results
          by calling the <code class="literal">getResultSet()</code> method. If
          the statement was an <code class="literal">UPDATE</code>,
          <code class="literal">INSERT</code>, or <code class="literal">DELETE</code>
          statement, you can retrieve the affected rows count by calling
          <code class="literal">getUpdateCount()</code> on the
          <code class="classname">Statement</code> instance.
        </p><div class="example"><a name="connector-j-examples-execute-select"></a><p class="title"><b>Example 2. Using java.sql.Statement to execute a <code class="literal">SELECT</code> query</b></p><pre class="programlisting">// assume that conn is an already created JDBC connection
Statement stmt = null;
ResultSet rs = null;

try {
    stmt = conn.createStatement();
    rs = stmt.executeQuery("SELECT foo FROM bar");

    // or alternatively, if you don't know ahead of time that
    // the query will be a SELECT...

    if (stmt.execute("SELECT foo FROM bar")) {
        rs = stmt.getResultSet();
    }

    // Now do something with the ResultSet ....
} finally {
    // it is a good idea to release
    // resources in a finally{} block
    // in reverse-order of their creation
    // if they are no-longer needed

    if (rs != null) {
        try {
            rs.close();
        } catch (SQLException sqlEx) { // ignore }

        rs = null;
    }

    if (stmt != null) {
        try {
            stmt.close();
        } catch (SQLException sqlEx) { // ignore }

        stmt = null;
    }
}</pre></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h5 class="title"><a name="connector-j-usagenotes-statements-callable"></a>1.5.1.3. Using <code class="literal">CallableStatements</code> to Execute Stored Procedures</h5></div></div></div><p>
          Starting with MySQL server version 5.0 when used with
          Connector/J 3.1.1 or newer, the
          <code class="classname">java.sql.CallableStatement</code> interface is
          fully implemented with the exception of the
          <code class="literal">getParameterMetaData()</code> method.
        </p><p>
          See ???, for more information
          on MySQL stored procedures.
        </p><p>
          Connector/J exposes stored procedure functionality through
          JDBC's <code class="classname">CallableStatement</code> interface.
        </p><p><b>Note. </b>
            Current versions of MySQL server do not return enough
            information for the JDBC driver to provide result set
            metadata for callable statements. This means that when using
            <code class="literal">CallableStatement</code>,
            <code class="literal">ResultSetMetaData</code> may return
            <code class="literal">NULL</code>.
          </p><p>
          The following example shows a stored procedure that returns
          the value of <code class="varname">inOutParam</code> incremented by 1,
          and the string passed in via <code class="varname">inputParam</code> as
          a <code class="classname">ResultSet</code>:

          </p><div class="example"><a name="connector-j-examples-stored-procedure"></a><p class="title"><b>Example 3. Stored Procedures</b></p><pre class="programlisting">CREATE PROCEDURE demoSp(IN inputParam VARCHAR(255), INOUT inOutParam INT)
BEGIN
    DECLARE z INT;
    SET z = inOutParam + 1;
    SET inOutParam = z;

    SELECT inputParam;

    SELECT CONCAT('zyxw', inputParam);
END</pre></div><p>
        </p><p>
          To use the <code class="literal">demoSp</code> procedure with
          Connector/J, follow these steps:
        </p><div class="orderedlist"><ol type="1"><li><p>
              Prepare the callable statement by using
              <code class="literal">Connection.prepareCall()</code> .
            </p><p>
              Notice that you have to use JDBC escape syntax, and that
              the parentheses surrounding the parameter placeholders are
              not optional:
            </p><div class="example"><a name="connector-j-examples-preparecall"></a><p class="title"><b>Example 4. Using <code class="literal">Connection.prepareCall()</code></b></p><pre class="programlisting">import java.sql.CallableStatement;

...

    //
    // Prepare a call to the stored procedure 'demoSp'
    // with two parameters
    //
    // Notice the use of JDBC-escape syntax ({call ...})
    //

    CallableStatement cStmt = conn.prepareCall("{call demoSp(?, ?)}");



    cStmt.setString(1, "abcdefg");</pre></div><p><b>Note. </b>
                <code class="literal">Connection.prepareCall()</code> is an
                expensive method, due to the metadata retrieval that the
                driver performs to support output parameters. For
                performance reasons, you should try to minimize
                unnecessary calls to
                <code class="literal">Connection.prepareCall()</code> by reusing
                <code class="classname">CallableStatement</code> instances in
                your code.
              </p></li><li><p>
              Register the output parameters (if any exist)
            </p><p>
              To retrieve the values of output parameters (parameters
              specified as <code class="literal">OUT</code> or
              <code class="literal">INOUT</code> when you created the stored
              procedure), JDBC requires that they be specified before
              statement execution using the various
              <code class="literal">registerOutputParameter()</code> methods in
              the <code class="classname">CallableStatement</code> interface:

              </p><div class="example"><a name="connector-j-examples-output-param"></a><p class="title"><b>Example 5. Registering output parameters</b></p><pre class="programlisting">import java.sql.Types;
...
//
// Connector/J supports both named and indexed
// output parameters. You can register output
// parameters using either method, as well
// as retrieve output parameters using either
// method, regardless of what method was
// used to register them.
//
// The following examples show how to use
// the various methods of registering
// output parameters (you should of course
// use only one registration per parameter).
//

//
// Registers the second parameter as output, and
// uses the type 'INTEGER' for values returned from
// getObject()
//

cStmt.registerOutParameter(2, Types.INTEGER);

//
// Registers the named parameter 'inOutParam', and
// uses the type 'INTEGER' for values returned from
// getObject()
//

cStmt.registerOutParameter("inOutParam", Types.INTEGER);
...
</pre></div><p>
            </p></li><li><p>
              Set the input parameters (if any exist)
            </p><p>
              Input and in/out parameters are set as for
              <code class="classname">PreparedStatement</code> objects. However,
              <code class="classname">CallableStatement</code> also supports
              setting parameters by name:

              </p><div class="example"><a name="connector-j-examples-callablestatement"></a><p class="title"><b>Example 6. Setting <code class="literal">CallableStatement</code> input parameters</b></p><pre class="programlisting">...

    //
    // Set a parameter by index
    //

    cStmt.setString(1, "abcdefg");

    //
    // Alternatively, set a parameter using
    // the parameter name
    //

    cStmt.setString("inputParameter", "abcdefg");

    //
    // Set the 'in/out' parameter using an index
    //

    cStmt.setInt(2, 1);

    //
    // Alternatively, set the 'in/out' parameter
    // by name
    //

    cStmt.setInt("inOutParam", 1);

...</pre></div><p>
            </p></li><li><p>
              Execute the <code class="classname">CallableStatement</code>, and
              retrieve any result sets or output parameters.
            </p><p>
              Although <code class="classname">CallableStatement</code> supports
              calling any of the <code class="classname">Statement</code>
              execute methods (<code class="literal">executeUpdate()</code>,
              <code class="literal">executeQuery()</code> or
              <code class="literal">execute()</code>), the most flexible method to
              call is <code class="literal">execute()</code>, as you do not need
              to know ahead of time if the stored procedure returns
              result sets:

              </p><div class="example"><a name="connector-j-examples-retrieving-results-params"></a><p class="title"><b>Example 7. Retrieving results and output parameter values</b></p><pre class="programlisting">...

    boolean hadResults = cStmt.execute();

    //
    // Process all returned result sets
    //

    while (hadResults) {
        ResultSet rs = cStmt.getResultSet();

        // process result set
        ...

        hadResults = rs.getMoreResults();
    }

    //
    // Retrieve output parameters
    //
    // Connector/J supports both index-based and
    // name-based retrieval
    //

    int outputValue = cStmt.getInt(2); // index-based

    outputValue = cStmt.getInt("inOutParam"); // name-based

...</pre></div><p>
            </p></li></ol></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h5 class="title"><a name="connector-j-usagenotes-last-insert-id"></a>1.5.1.4. Retrieving <code class="literal">AUTO_INCREMENT</code> Column Values</h5></div></div></div><p>
          Before version 3.0 of the JDBC API, there was no standard way
          of retrieving key values from databases that supported auto
          increment or identity columns. With older JDBC drivers for
          MySQL, you could always use a MySQL-specific method on the
          <code class="classname">Statement</code> interface, or issue the query
          <code class="literal">SELECT LAST_INSERT_ID()</code> after issuing an
          <code class="literal">INSERT</code> to a table that had an
          <code class="literal">AUTO_INCREMENT</code> key. Using the
          MySQL-specific method call isn't portable, and issuing a
          <code class="literal">SELECT</code> to get the
          <code class="literal">AUTO_INCREMENT</code> key's value requires another
          round-trip to the database, which isn't as efficient as
          possible. The following code snippets demonstrate the three
          different ways to retrieve <code class="literal">AUTO_INCREMENT</code>
          values. First, we demonstrate the use of the new JDBC-3.0
          method <code class="literal">getGeneratedKeys()</code> which is now the
          preferred method to use if you need to retrieve
          <code class="literal">AUTO_INCREMENT</code> keys and have access to
          JDBC-3.0. The second example shows how you can retrieve the
          same value using a standard <code class="literal">SELECT
          LAST_INSERT_ID()</code> query. The final example shows how
          updatable result sets can retrieve the
          <code class="literal">AUTO_INCREMENT</code> value when using the
          <code class="literal">insertRow()</code> method.

          </p><div class="example"><a name="connector-j-examples-autoincrement-getgeneratedkeys"></a><p class="title"><b>Example 8. Retrieving <code class="literal">AUTO_INCREMENT</code> column values using
              <code class="literal">Statement.getGeneratedKeys()</code></b></p><pre class="programlisting">   Statement stmt = null;
   ResultSet rs = null;

   try {

    //
    // Create a Statement instance that we can use for
    // 'normal' result sets assuming you have a
    // Connection 'conn' to a MySQL database already
    // available

    stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY,
                                java.sql.ResultSet.CONCUR_UPDATABLE);

    //
    // Issue the DDL queries for the table for this example
    //

    stmt.executeUpdate("DROP TABLE IF EXISTS autoIncTutorial");
    stmt.executeUpdate(
            "CREATE TABLE autoIncTutorial ("
            + "priKey INT NOT NULL AUTO_INCREMENT, "
            + "dataField VARCHAR(64), PRIMARY KEY (priKey))");

    //
    // Insert one row that will generate an AUTO INCREMENT
    // key in the 'priKey' field
    //

    stmt.executeUpdate(
            "INSERT INTO autoIncTutorial (dataField) "
            + "values ('Can I Get the Auto Increment Field?')",
            Statement.RETURN_GENERATED_KEYS);

    //
    // Example of using Statement.getGeneratedKeys()
    // to retrieve the value of an auto-increment
    // value
    //

    int autoIncKeyFromApi = -1;

    rs = stmt.getGeneratedKeys();

    if (rs.next()) {
        autoIncKeyFromApi = rs.getInt(1);
    } else {

        // throw an exception from here
    }

    rs.close();

    rs = null;

    System.out.println("Key returned from getGeneratedKeys():"
        + autoIncKeyFromApi);
} finally {

    if (rs != null) {
        try {
            rs.close();
        } catch (SQLException ex) {
            // ignore
        }
    }

    if (stmt != null) {
        try {
            stmt.close();
        } catch (SQLException ex) {
            // ignore
        }
    }
}
</pre></div><p>

          </p><div class="example"><a name="connector-j-examples-autoincrement-select"></a><p class="title"><b>Example 9. Retrieving <code class="literal">AUTO_INCREMENT</code> column values using
              <code class="literal">SELECT LAST_INSERT_ID()</code></b></p><pre class="programlisting">   Statement stmt = null;
   ResultSet rs = null;

   try {

    //
    // Create a Statement instance that we can use for
    // 'normal' result sets.

    stmt = conn.createStatement();

    //
    // Issue the DDL queries for the table for this example
    //

    stmt.executeUpdate("DROP TABLE IF EXISTS autoIncTutorial");
    stmt.executeUpdate(
            "CREATE TABLE autoIncTutorial ("
            + "priKey INT NOT NULL AUTO_INCREMENT, "
            + "dataField VARCHAR(64), PRIMARY KEY (priKey))");

    //
    // Insert one row that will generate an AUTO INCREMENT
    // key in the 'priKey' field
    //

    stmt.executeUpdate(
            "INSERT INTO autoIncTutorial (dataField) "
            + "values ('Can I Get the Auto Increment Field?')");

    //
    // Use the MySQL LAST_INSERT_ID()
    // function to do the same thing as getGeneratedKeys()
    //

    int autoIncKeyFromFunc = -1;
    rs = stmt.executeQuery("SELECT LAST_INSERT_ID()");

    if (rs.next()) {
        autoIncKeyFromFunc = rs.getInt(1);
    } else {
        // throw an exception from here
    }

    rs.close();

    System.out.println("Key returned from " + "'SELECT LAST_INSERT_ID()': "
        + autoIncKeyFromFunc);

} finally {

    if (rs != null) {
        try {
            rs.close();
        } catch (SQLException ex) {
            // ignore
        }
    }

    if (stmt != null) {
        try {
            stmt.close();
        } catch (SQLException ex) {
            // ignore
        }
    }
}
   </pre></div><p>

          </p><div class="example"><a name="connector-j-examples-autoincrement-updateable-resultsets"></a><p class="title"><b>Example 10. Retrieving <code class="literal">AUTO_INCREMENT</code> column values in
              <code class="literal">Updatable ResultSets</code></b></p><pre class="programlisting">   Statement stmt = null;
   ResultSet rs = null;

   try {

    //
    // Create a Statement instance that we can use for
    // 'normal' result sets as well as an 'updatable'
    // one, assuming you have a Connection 'conn' to
    // a MySQL database already available
    //

    stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY,
                                java.sql.ResultSet.CONCUR_UPDATABLE);

    //
    // Issue the DDL queries for the table for this example
    //

    stmt.executeUpdate("DROP TABLE IF EXISTS autoIncTutorial");
    stmt.executeUpdate(
            "CREATE TABLE autoIncTutorial ("
            + "priKey INT NOT NULL AUTO_INCREMENT, "
            + "dataField VARCHAR(64), PRIMARY KEY (priKey))");

    //
    // Example of retrieving an AUTO INCREMENT key
    // from an updatable result set
    //

    rs = stmt.executeQuery("SELECT priKey, dataField "
       + "FROM autoIncTutorial");

    rs.moveToInsertRow();

    rs.updateString("dataField", "AUTO INCREMENT here?");
    rs.insertRow();

    //
    // the driver adds rows at the end
    //

    rs.last();

    //
    // We should now be on the row we just inserted
    //

    int autoIncKeyFromRS = rs.getInt("priKey");

    rs.close();

    rs = null;

    System.out.println("Key returned for inserted row: "
        + autoIncKeyFromRS);

} finally {

    if (rs != null) {
        try {
            rs.close();
        } catch (SQLException ex) {
            // ignore
        }
    }

    if (stmt != null) {
        try {
            stmt.close();
        } catch (SQLException ex) {
            // ignore
        }
    }
}


   </pre></div><p>

          When you run the preceding example code, you should get the
          following output: Key returned from
          <code class="literal">getGeneratedKeys()</code>: 1 Key returned from
          <code class="literal">SELECT LAST_INSERT_ID()</code>: 1 Key returned for
          inserted row: 2 You should be aware, that at times, it can be
          tricky to use the <code class="literal">SELECT LAST_INSERT_ID()</code>
          query, as that function's value is scoped to a connection. So,
          if some other query happens on the same connection, the value
          will be overwritten. On the other hand, the
          <code class="literal">getGeneratedKeys()</code> method is scoped by the
          <code class="classname">Statement</code> instance, so it can be used
          even if other queries happen on the same connection, but not
          on the same <code class="classname">Statement</code> instance.
        </p></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="connector-j-usagenotes-j2ee"></a>1.5.2. Using Connector/J with J2EE and Other Java Frameworks</h4></div></div></div><p>
        This section describes how to use Connector/J in several
        contexts.
      </p><div class="section" lang="en"><div class="titlepage"><div><div><h5 class="title"><a name="connector-j-usagenotes-j2ee-concepts"></a>1.5.2.1. General J2EE Concepts</h5></div></div></div><p>
          This section provides general background on J2EE concepts that
          pertain to use of Connector/J.
        </p><div class="section" lang="en"><div class="titlepage"><div><div><h6 class="title"><a name="connector-j-usagenotes-j2ee-concepts-connection-pooling"></a>1.5.2.1.1. Understanding Connection Pooling</h6></div></div></div><p>
            Connection pooling is a technique of creating and managing a
            pool of connections that are ready for use by any thread
            that needs them.
          </p><p>
            This technique of pooling connections is based on the fact
            that most applications only need a thread to have access to
            a JDBC connection when they are actively processing a
            transaction, which usually take only milliseconds to
            complete. When not processing a transaction, the connection
            would otherwise sit idle. Instead, connection pooling allows
            the idle connection to be used by some other thread to do
            useful work.
          </p><p>
            In practice, when a thread needs to do work against a MySQL
            or other database with JDBC, it requests a connection from
            the pool. When the thread is finished using the connection,
            it returns it to the pool, so that it may be used by any
            other threads that want to use it.
          </p><p>
            When the connection is loaned out from the pool, it is used
            exclusively by the thread that requested it. From a
            programming point of view, it is the same as if your thread
            called <code class="literal">DriverManager.getConnection()</code>
            every time it needed a JDBC connection, however with
            connection pooling, your thread may end up using either a
            new, or already-existing connection.
          </p><p>
            Connection pooling can greatly increase the performance of
            your Java application, while reducing overall resource
            usage. The main benefits to connection pooling are:
          </p><div class="itemizedlist"><ul type="disc"><li><p>
                Reduced connection creation time
              </p><p>
                Although this is not usually an issue with the quick
                connection setup that MySQL offers compared to other
                databases, creating new JDBC connections still incurs
                networking and JDBC driver overhead that will be avoided
                if connections are recycled.
              </p></li><li><p>
                Simplified programming model
              </p><p>
                When using connection pooling, each individual thread
                can act as though it has created its own JDBC
                connection, allowing you to use straight-forward JDBC
                programming techniques.
              </p></li><li><p>
                Controlled resource usage
              </p><p>
                If you don't use connection pooling, and instead create
                a new connection every time a thread needs one, your
                application's resource usage can be quite wasteful and
                lead to unpredictable behavior under load.
              </p></li></ul></div><p>
            Remember that each connection to MySQL has overhead (memory,
            CPU, context switches, and so forth) on both the client and
            server side. Every connection limits how many resources
            there are available to your application as well as the MySQL
            server. Many of these resources will be used whether or not
            the connection is actually doing any useful work!
          </p><p>
            Connection pools can be tuned to maximize performance, while
            keeping resource utilization below the point where your
            application will start to fail rather than just run slower.
          </p><p>
            Luckily, Sun has standardized the concept of connection
            pooling in JDBC through the JDBC-2.0 Optional interfaces,
            and all major application servers have implementations of
            these APIs that work fine with MySQL Connector/J.
          </p><p>
            Generally, you configure a connection pool in your
            application server configuration files, and access it via
            the Java Naming and Directory Interface (JNDI). The
            following code shows how you might use a connection pool
            from an application deployed in a J2EE application server:

            </p><div class="example"><a name="connector-j-examples-connectionpool-j2ee"></a><p class="title"><b>Example 11. Using a connection pool with a J2EE application server</b></p><pre class="programlisting">import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;

import javax.naming.InitialContext;
import javax.sql.DataSource;


public class MyServletJspOrEjb {

    public void doSomething() throws Exception {
        /*
         * Create a JNDI Initial context to be able to
         *  lookup  the DataSource
         *
         * In production-level code, this should be cached as
         * an instance or static variable, as it can
         * be quite expensive to create a JNDI context.
         *
         * Note: This code only works when you are using servlets
         * or EJBs in a J2EE application server. If you are
         * using connection pooling in standalone Java code, you
         * will have to create/configure datasources using whatever
         * mechanisms your particular connection pooling library
         * provides.
         */

        InitialContext ctx = new InitialContext();

         /*
          * Lookup the DataSource, which will be backed by a pool
          * that the application server provides. DataSource instances
          * are also a good candidate for caching as an instance
          * variable, as JNDI lookups can be expensive as well.
          */

        DataSource ds = (DataSource)ctx.lookup("java:comp/env/jdbc/MySQLDB");

        /*
         * The following code is what would actually be in your
         * Servlet, JSP or EJB 'service' method...where you need
         * to work with a JDBC connection.
         */

        Connection conn = null;
        Statement stmt = null;

        try {
            conn = ds.getConnection();

            /*
             * Now, use normal JDBC programming to work with
             * MySQL, making sure to close each resource when you're
             * finished with it, which allows the connection pool
             * resources to be recovered as quickly as possible
             */

            stmt = conn.createStatement();
            stmt.execute("SOME SQL QUERY");

            stmt.close();
            stmt = null;

            conn.close();
            conn = null;
        } finally {
            /*
             * close any jdbc instances here that weren't
             * explicitly closed during normal code path, so
             * that we don't 'leak' resources...
             */

            if (stmt != null) {
                try {
                    stmt.close();
                } catch (sqlexception sqlex) {
                    // ignore -- as we can't do anything about it here
                }

                stmt = null;
            }

            if (conn != null) {
                try {
                    conn.close();
                } catch (sqlexception sqlex) {
                    // ignore -- as we can't do anything about it here
                }

                conn = null;
            }
        }
    }
}</pre></div><p>

            As shown in the example above, after obtaining the JNDI
            InitialContext, and looking up the DataSource, the rest of
            the code should look familiar to anyone who has done JDBC
            programming in the past.
          </p><p>
            The most important thing to remember when using connection
            pooling is to make sure that no matter what happens in your
            code (exceptions, flow-of-control, and so forth),
            connections, and anything created by them (such as
            statements or result sets) are closed, so that they may be
            re-used, otherwise they will be stranded, which in the best
            case means that the MySQL server resources they represent
            (such as buffers, locks, or sockets) may be tied up for some
            time, or worst case, may be tied up forever.
          </p><p>
            What's the Best Size for my Connection Pool?
          </p><p>
            As with all other configuration rules-of-thumb, the answer
            is: it depends. Although the optimal size depends on
            anticipated load and average database transaction time, the
            optimum connection pool size is smaller than you might
            expect. If you take Sun's Java Petstore blueprint
            application for example, a connection pool of 15-20
            connections can serve a relatively moderate load (600
            concurrent users) using MySQL and Tomcat with response times
            that are acceptable.
          </p><p>
            To correctly size a connection pool for your application,
            you should create load test scripts with tools such as
            Apache JMeter or The Grinder, and load test your
            application.
          </p><p>
            An easy way to determine a starting point is to configure
            your connection pool's maximum number of connections to be
            unbounded, run a load test, and measure the largest amount
            of concurrently used connections. You can then work backward
            from there to determine what values of minimum and maximum
            pooled connections give the best performance for your
            particular application.
          </p></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h5 class="title"><a name="connector-j-usagenotes-tomcat"></a>1.5.2.2. Using Connector/J with Tomcat</h5></div></div></div><p>
          The following instructions are based on the instructions for
          Tomcat-5.x, available at
          <a href="http://jakarta.apache.org/tomcat/tomcat-5.0-doc/jndi-datasource-examples-howto.html" target="_top">http://jakarta.apache.org/tomcat/tomcat-5.0-doc/jndi-datasource-examples-howto.html</a>
          which is current at the time this document was written.
        </p><p>
          First, install the .jar file that comes with Connector/J in
          <code class="filename">$CATALINA_HOME/common/lib</code> so that it is
          available to all applications installed in the container.
        </p><p>
          Next, Configure the JNDI DataSource by adding a declaration
          resource to
          <code class="filename">$CATALINA_HOME/conf/server.xml</code> in the
          context that defines your web application:
        </p><pre class="programlisting">&lt;Context ....&gt;

  ...

  &lt;Resource name="jdbc/MySQLDB"
               auth="Container"
               type="javax.sql.DataSource"/&gt;

  &lt;!-- The name you used above, must match _exactly_ here!

       The connection pool will be bound into JNDI with the name
       "java:/comp/env/jdbc/MySQLDB"
  --&gt;

  &lt;ResourceParams name="jdbc/MySQLDB"&gt;
    &lt;parameter&gt;
      &lt;name&gt;factory&lt;/name&gt;
      &lt;value&gt;org.apache.commons.dbcp.BasicDataSourceFactory&lt;/value&gt;
    &lt;/parameter&gt;

    &lt;!-- Don't set this any higher than max_connections on your
         MySQL server, usually this should be a 10 or a few 10's
         of connections, not hundreds or thousands --&gt;

    &lt;parameter&gt;
      &lt;name&gt;maxActive&lt;/name&gt;
      &lt;value&gt;10&lt;/value&gt;
    &lt;/parameter&gt;

    &lt;!-- You don't want to many idle connections hanging around
         if you can avoid it, only enough to soak up a spike in
         the load --&gt;

    &lt;parameter&gt;
      &lt;name&gt;maxIdle&lt;/name&gt;
      &lt;value&gt;5&lt;/value&gt;
    &lt;/parameter&gt;

    &lt;!-- Don't use autoReconnect=true, it's going away eventually
         and it's a crutch for older connection pools that couldn't
         test connections. You need to decide whether your application is
         supposed to deal with SQLExceptions (hint, it should), and
         how much of a performance penalty you're willing to pay
         to ensure 'freshness' of the connection --&gt;

    &lt;parameter&gt;
      &lt;name&gt;validationQuery&lt;/name&gt;
      &lt;value&gt;SELECT 1&lt;/value&gt;
    &lt;/parameter&gt;

   &lt;!-- The most conservative approach is to test connections
        before they're given to your application. For most applications
        this is okay, the query used above is very small and takes
        no real server resources to process, other than the time used
        to traverse the network.

        If you have a high-load application you'll need to rely on
        something else. --&gt;

    &lt;parameter&gt;
      &lt;name&gt;testOnBorrow&lt;/name&gt;
      &lt;value&gt;true&lt;/value&gt;
    &lt;/parameter&gt;

   &lt;!-- Otherwise, or in addition to testOnBorrow, you can test
        while connections are sitting idle --&gt;

    &lt;parameter&gt;
      &lt;name&gt;testWhileIdle&lt;/name&gt;
      &lt;value&gt;true&lt;/value&gt;
    &lt;/parameter&gt;

    &lt;!-- You have to set this value, otherwise even though
         you've asked connections to be tested while idle,
         the idle evicter thread will never run --&gt;

    &lt;parameter&gt;
      &lt;name&gt;timeBetweenEvictionRunsMillis&lt;/name&gt;
      &lt;value&gt;10000&lt;/value&gt;
    &lt;/parameter&gt;

    &lt;!-- Don't allow connections to hang out idle too long,
         never longer than what wait_timeout is set to on the
         server...A few minutes or even fraction of a minute
         is sometimes okay here, it depends on your application
         and how much spikey load it will see --&gt;

    &lt;parameter&gt;
      &lt;name&gt;minEvictableIdleTimeMillis&lt;/name&gt;
      &lt;value&gt;60000&lt;/value&gt;
    &lt;/parameter&gt;

    &lt;!-- Username and password used when connecting to MySQL --&gt;

    &lt;parameter&gt;
     &lt;name&gt;username&lt;/name&gt;
     &lt;value&gt;someuser&lt;/value&gt;
    &lt;/parameter&gt;

    &lt;parameter&gt;
     &lt;name&gt;password&lt;/name&gt;
     &lt;value&gt;somepass&lt;/value&gt;
    &lt;/parameter&gt;

    &lt;!-- Class name for the Connector/J driver --&gt;

    &lt;parameter&gt;
       &lt;name&gt;driverClassName&lt;/name&gt;
       &lt;value&gt;com.mysql.jdbc.Driver&lt;/value&gt;
    &lt;/parameter&gt;

    &lt;!-- The JDBC connection url for connecting to MySQL, notice
         that if you want to pass any other MySQL-specific parameters
         you should pass them here in the URL, setting them using the
         parameter tags above will have no effect, you will also
         need to use &amp;amp; to separate parameter values as the
         ampersand is a reserved character in XML --&gt;

    &lt;parameter&gt;
      &lt;name&gt;url&lt;/name&gt;
      &lt;value&gt;jdbc:mysql://localhost:3306/test&lt;/value&gt;
    &lt;/parameter&gt;

  &lt;/ResourceParams&gt;
&lt;/Context&gt;</pre><p>
          In general, you should follow the installation instructions
          that come with your version of Tomcat, as the way you
          configure datasources in Tomcat changes from time-to-time, and
          unfortunately if you use the wrong syntax in your XML file,
          you will most likely end up with an exception similar to the
          following:
        </p><pre class="programlisting">Error: java.sql.SQLException: Cannot load JDBC driver class 'null ' SQL
state: null </pre></div><div class="section" lang="en"><div class="titlepage"><div><div><h5 class="title"><a name="connector-j-usagenotes-jboss"></a>1.5.2.3. Using Connector/J with JBoss</h5></div></div></div><p>
          These instructions cover JBoss-4.x. To make the JDBC driver
          classes available to the application server, copy the .jar
          file that comes with Connector/J to the
          <code class="filename">lib</code> directory for your server
          configuration (which is usually called
          <code class="filename">default</code>). Then, in the same configuration
          directory, in the subdirectory named deploy, create a
          datasource configuration file that ends with "-ds.xml", which
          tells JBoss to deploy this file as a JDBC Datasource. The file
          should have the following contents:
        </p><pre class="programlisting">&lt;datasources&gt;
    &lt;local-tx-datasource&gt;
        &lt;!-- This connection pool will be bound into JNDI with the name
             "java:/MySQLDB" --&gt;

        &lt;jndi-name&gt;MySQLDB&lt;/jndi-name&gt;
        &lt;connection-url&gt;jdbc:mysql://localhost:3306/dbname&lt;/connection-url&gt;
        &lt;driver-class&gt;com.mysql.jdbc.Driver&lt;/driver-class&gt;
        &lt;user-name&gt;user&lt;/user-name&gt;
        &lt;password&gt;pass&lt;/password&gt;

        &lt;min-pool-size&gt;5&lt;/min-pool-size&gt;

        &lt;!-- Don't set this any higher than max_connections on your
         MySQL server, usually this should be a 10 or a few 10's
         of connections, not hundreds or thousands --&gt;

        &lt;max-pool-size&gt;20&lt;/max-pool-size&gt;

        &lt;!-- Don't allow connections to hang out idle too long,
         never longer than what wait_timeout is set to on the
         server...A few minutes is usually okay here,
         it depends on your application
         and how much spikey load it will see --&gt;

        &lt;idle-timeout-minutes&gt;5&lt;/idle-timeout-minutes&gt;

        &lt;!-- If you're using Connector/J 3.1.8 or newer, you can use
             our implementation of these to increase the robustness
             of the connection pool. --&gt;

        &lt;exception-sorter-class-name&gt;com.mysql.jdbc.integration.jboss.ExtendedMysqlExceptionSorter&lt;/exception-sorter-class-name&gt;
        &lt;valid-connection-checker-class-name&gt;com.mysql.jdbc.integration.jboss.MysqlValidConnectionChecker&lt;/valid-connection-checker-class-name&gt;

    &lt;/local-tx-datasource&gt;
&lt;/datasources&gt; </pre></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="connector-j-usagenotes-troubleshooting"></a>1.5.3. Common Problems and Solutions</h4></div></div></div><p>
        There are a few issues that seem to be commonly encountered
        often by users of MySQL Connector/J. This section deals with
        their symptoms, and their resolutions.
      </p><p><span class="bold"><strong>Questions</strong></span></p><div class="itemizedlist"><ul type="disc"><li><p><a href="#qandaitem-1-5-3-1">1.5.3.1: </a>
              When I try to connect to the database with MySQL
              Connector/J, I get the following exception:
            </p><pre class="programlisting">SQLException: Server configuration denies access to data source
SQLState: 08001
VendorError: 0</pre><p>
              What's going on? I can connect just fine with the MySQL
              command-line client.
            </p></li><li><p><a href="#qandaitem-1-5-3-2">1.5.3.2: </a>
              My application throws an SQLException 'No Suitable
              Driver'. Why is this happening?
            </p></li><li><p><a href="#qandaitem-1-5-3-3">1.5.3.3: </a>
              I'm trying to use MySQL Connector/J in an applet or
              application and I get an exception similar to:
            </p><pre class="programlisting">SQLException: Cannot connect to MySQL server on host:3306.
Is there a MySQL server running on the machine/port you
are trying to connect to?

(java.security.AccessControlException)
SQLState: 08S01
VendorError: 0 </pre></li><li><p><a href="#qandaitem-1-5-3-4">1.5.3.4: </a>
              I have a servlet/application that works fine for a day,
              and then stops working overnight
            </p></li><li><p><a href="#qandaitem-1-5-3-5">1.5.3.5: </a>
              I'm trying to use JDBC-2.0 updatable result sets, and I
              get an exception saying my result set is not updatable.
            </p></li></ul></div><p><span class="bold"><strong>Questions and Answers</strong></span></p><p><a name="qandaitem-1-5-3-1"></a><span class="bold"><strong>1.5.3.1: </strong></span><span class="bold"><strong>
              When I try to connect to the database with MySQL
              Connector/J, I get the following exception:
            </strong></span></p><pre class="programlisting">SQLException: Server configuration denies access to data source
SQLState: 08001
VendorError: 0</pre><p><span class="bold"><strong>
              What's going on? I can connect just fine with the MySQL
              command-line client.
            </strong></span></p><p>
              MySQL Connector/J must use TCP/IP sockets to connect to
              MySQL, as Java does not support Unix Domain Sockets.
              Therefore, when MySQL Connector/J connects to MySQL, the
              security manager in MySQL server will use its grant tables
              to determine whether the connection should be allowed.
            </p><p>
              You must add the necessary security credentials to the
              MySQL server for this to happen, using the
              <code class="literal">GRANT</code> statement to your MySQL Server.
              See ???, for more information.
            </p><p><b>Note. </b>
                Testing your connectivity with the
                <span><strong class="command">mysql</strong></span> command-line client will not
                work unless you add the <code class="option">--host</code> flag,
                and use something other than
                <code class="literal">localhost</code> for the host. The
                <span><strong class="command">mysql</strong></span> command-line client will use
                Unix domain sockets if you use the special hostname
                <code class="literal">localhost</code>. If you are testing
                connectivity to <code class="literal">localhost</code>, use
                <code class="literal">127.0.0.1</code> as the hostname instead.
              </p><p><b>Warning. </b>
                Changing privileges and permissions improperly in MySQL
                can potentially cause your server installation to not
                have optimal security properties.
              </p><p><a name="qandaitem-1-5-3-2"></a><span class="bold"><strong>1.5.3.2: </strong></span><span class="bold"><strong>
              My application throws an SQLException 'No Suitable
              Driver'. Why is this happening?
            </strong></span></p><p>
              There are three possible causes for this error:
            </p><div class="itemizedlist"><ul type="disc"><li><p>
                  The Connector/J driver is not in your
                  <code class="literal">CLASSPATH</code>, see
                  <a href="#connector-j-installing" title="1.2. Installing Connector/J">Section 1.2, “Installing Connector/J”</a>.
                </p></li><li><p>
                  The format of your connection URL is incorrect, or you
                  are referencing the wrong JDBC driver.
                </p></li><li><p>
                  When using DriverManager, the
                  <code class="literal">jdbc.drivers</code> system property has
                  not been populated with the location of the
                  Connector/J driver.
                </p></li></ul></div><p><a name="qandaitem-1-5-3-3"></a><span class="bold"><strong>1.5.3.3: </strong></span><span class="bold"><strong>
              I'm trying to use MySQL Connector/J in an applet or
              application and I get an exception similar to:
            </strong></span></p><pre class="programlisting">SQLException: Cannot connect to MySQL server on host:3306.
Is there a MySQL server running on the machine/port you
are trying to connect to?

(java.security.AccessControlException)
SQLState: 08S01
VendorError: 0 </pre><p>
              Either you're running an Applet, your MySQL server has
              been installed with the "--skip-networking" option set, or
              your MySQL server has a firewall sitting in front of it.
            </p><p>
              Applets can only make network connections back to the
              machine that runs the web server that served the .class
              files for the applet. This means that MySQL must run on
              the same machine (or you must have some sort of port
              re-direction) for this to work. This also means that you
              will not be able to test applets from your local file
              system, you must always deploy them to a web server.
            </p><p>
              MySQL Connector/J can only communicate with MySQL using
              TCP/IP, as Java does not support Unix domain sockets.
              TCP/IP communication with MySQL might be affected if MySQL
              was started with the "--skip-networking" flag, or if it is
              firewalled.
            </p><p>
              If MySQL has been started with the "--skip-networking"
              option set (the Debian Linux package of MySQL server does
              this for example), you need to comment it out in the file
              /etc/mysql/my.cnf or /etc/my.cnf. Of course your my.cnf
              file might also exist in the <code class="filename">data</code>
              directory of your MySQL server, or anywhere else
              (depending on how MySQL was compiled for your system).
              Binaries created by MySQL AB always look in /etc/my.cnf
              and [datadir]/my.cnf. If your MySQL server has been
              firewalled, you will need to have the firewall configured
              to allow TCP/IP connections from the host where your Java
              code is running to the MySQL server on the port that MySQL
              is listening to (by default, 3306).
            </p><p><a name="qandaitem-1-5-3-4"></a><span class="bold"><strong>1.5.3.4: </strong></span><span class="bold"><strong>
              I have a servlet/application that works fine for a day,
              and then stops working overnight
            </strong></span></p><p>
              MySQL closes connections after 8 hours of inactivity. You
              either need to use a connection pool that handles stale
              connections or use the "autoReconnect" parameter (see
              <a href="#connector-j-reference-configuration-properties" title="1.4.1. Driver/Datasource Class Names, URL Syntax and Configuration Properties
        for Connector/J">Section 1.4.1, “Driver/Datasource Class Names, URL Syntax and Configuration Properties
        for Connector/J”</a>).
            </p><p>
              Also, you should be catching SQLExceptions in your
              application and dealing with them, rather than propagating
              them all the way until your application exits, this is
              just good programming practice. MySQL Connector/J will set
              the SQLState (see
              <code class="literal">java.sql.SQLException.getSQLState()</code> in
              your APIDOCS) to "08S01" when it encounters
              network-connectivity issues during the processing of a
              query. Your application code should then attempt to
              re-connect to MySQL at this point.
            </p><p>
              The following (simplistic) example shows what code that
              can handle these exceptions might look like:
            </p><p>
              </p><div class="example"><a name="connector-j-examples-transaction-retry"></a><p class="title"><b>Example 12. Example of transaction with retry logic</b></p><pre class="programlisting">public void doBusinessOp() throws SQLException {
        Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;

        //
        // How many times do you want to retry the transaction
        // (or at least _getting_ a connection)?
        //
        int retryCount = 5;

        boolean transactionCompleted = false;

        do {
            try {
                conn = getConnection(); // assume getting this from a
                                        // javax.sql.DataSource, or the
                                        // java.sql.DriverManager

                conn.setAutoCommit(false);

                //
                // Okay, at this point, the 'retry-ability' of the
                // transaction really depends on your application logic,
                // whether or not you're using autocommit (in this case
                // not), and whether you're using transacational storage
                // engines
                //
                // For this example, we'll assume that it's _not_ safe
                // to retry the entire transaction, so we set retry count
                // to 0 at this point
                //
                // If you were using exclusively transaction-safe tables,
                // or your application could recover from a connection going
                // bad in the middle of an operation, then you would not
                // touch 'retryCount' here, and just let the loop repeat
                // until retryCount == 0.
                //
                retryCount = 0;

                stmt = conn.createStatement();

                String query = "SELECT foo FROM bar ORDER BY baz";

                rs = stmt.executeQuery(query);

                while (rs.next()) {
                }

                rs.close();
                rs = null;

                stmt.close();
                stmt = null;

                conn.commit();
                conn.close();
                conn = null;

                transactionCompleted = true;
            } catch (SQLException sqlEx) {

                //
                // The two SQL states that are 'retry-able' are 08S01
                // for a communications error, and 40001 for deadlock.
                //
                // Only retry if the error was due to a stale connection,
                // communications problem or deadlock
                //

                String sqlState = sqlEx.getSQLState();

                if ("08S01".equals(sqlState) || "40001".equals(sqlState)) {
                    retryCount--;
                } else {
                    retryCount = 0;
                }
            } finally {
                if (rs != null) {
                    try {
                        rs.close();
                    } catch (SQLException sqlEx) {
                        // You'd probably want to log this . . .
                    }
                }

                if (stmt != null) {
                    try {
                        stmt.close();
                    } catch (SQLException sqlEx) {
                        // You'd probably want to log this as well . . .
                    }
                }

                if (conn != null) {
                    try {
                        //
                        // If we got here, and conn is not null, the
                        // transaction should be rolled back, as not
                        // all work has been done

                        try {
                            conn.rollback();
                        } finally {
                            conn.close();
                        }
                    } catch (SQLException sqlEx) {
                        //
                        // If we got an exception here, something
                        // pretty serious is going on, so we better
                        // pass it up the stack, rather than just
                        // logging it. . .

                        throw sqlEx;
                    }
                }
            }
        } while (!transactionCompleted &amp;&amp; (retryCount &gt; 0));
    }</pre></div><p>
            </p><p><b>Note. </b>
                Use of the <code class="option">autoReconnect</code> option is not
                recommended because there is no safe method of
                reconnecting to the MySQL server without risking some
                corruption of the connection state or database state
                information. Instead, you should use a connection pool
                which will enable your application to connect to the
                MySQL server using an available connection from the
                pool. The <code class="option">autoReconnect</code> facility is
                deprecated, and may be removed in a future release.
              </p><p><a name="qandaitem-1-5-3-5"></a><span class="bold"><strong>1.5.3.5: </strong></span><span class="bold"><strong>
              I'm trying to use JDBC-2.0 updatable result sets, and I
              get an exception saying my result set is not updatable.
            </strong></span></p><p>
              Because MySQL does not have row identifiers, MySQL
              Connector/J can only update result sets that have come
              from queries on tables that have at least one primary key,
              the query must select every primary key and the query can
              only span one table (that is, no joins). This is outlined
              in the JDBC specification.
            </p><p>
              Note that this issue only occurs when using updatable
              result sets, and is caused because Connector/J is unable
              to guarantee that it can identify the correct rows within
              the result set to be updated without having a unique
              reference to each row. There is no requirement to have a
              unique field on a table if you are using
              <code class="literal">UPDATE</code> or <code class="literal">DELETE</code>
              statements on a table where you can individually specify
              the criteria to be matched using a
              <code class="literal">WHERE</code> clause.
            </p></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="connector-j-support"></a>1.6. Connector/J Support</h3></div></div></div><div class="toc"><dl><dt><span class="section"><a href="#connector-j-support-community">1.6.1. Connector/J Community Support</a></span></dt><dt><span class="section"><a href="#connector-j-support-bug-report">1.6.2. How to Report Connector/J Bugs or Problems</a></span></dt><dt><span class="section"><a href="#connector-j-support-changelog">1.6.3. Connector/J Change History</a></span></dt></dl></div><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="connector-j-support-community"></a>1.6.1. Connector/J Community Support</h4></div></div></div><p>
        MySQL AB provides assistance to the user community by means of
        its mailing lists. For Connector/J related issues, you can get
        help from experienced users by using the MySQL and Java mailing
        list. Archives and subscription information is available online
        at <a href="http://lists.mysql.com/java" target="_top">http://lists.mysql.com/java</a>.
      </p><p>
        For information about subscribing to MySQL mailing lists or to
        browse list archives, visit
        <a href="http://lists.mysql.com/" target="_top">http://lists.mysql.com/</a>. See
        <a href="http://dev.mysql.com/doc/refman/5.1/en/mailing-lists.html" target="_top">MySQL Mailing Lists</a>.
      </p><p>
        Community support from experienced users is also available
        through the
        <a href="http://forums.mysql.com/list.php?39" target="_top">JDBC
        Forum</a>. You may also find help from other users in the
        other MySQL Forums, located at
        <a href="http://forums.mysql.com" target="_top">http://forums.mysql.com</a>. See
        <a href="http://dev.mysql.com/doc/refman/5.1/en/forums.html" target="_top">MySQL Community Support at the MySQL Forums</a>.
      </p></div><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="connector-j-support-bug-report"></a>1.6.2. How to Report Connector/J Bugs or Problems</h4></div></div></div><p>
        The normal place to report bugs is
        <a href="http://bugs.mysql.com/" target="_top">http://bugs.mysql.com/</a>, which is the
        address for our bugs database. This database is public, and can
        be browsed and searched by anyone. If you log in to the system,
        you will also be able to enter new reports.
      </p><p>
        If you have found a sensitive security bug in MySQL, you can
        send email to
        <a href="mailto:security_at_mysql.com" target="_top">security_at_mysql.com</a>.
      </p><p>
        Writing a good bug report takes patience, but doing it right the
        first time saves time both for us and for yourself. A good bug
        report, containing a full test case for the bug, makes it very
        likely that we will fix the bug in the next release.
      </p><p>
        This section will help you write your report correctly so that
        you don't waste your time doing things that may not help us much
        or at all.
      </p><p>
        If you have a repeatable bug report, please report it to the
        bugs database at <a href="http://bugs.mysql.com/" target="_top">http://bugs.mysql.com/</a>. Any bug
        that we are able to repeat has a high chance of being fixed in
        the next MySQL release.
      </p><p>
        To report other problems, you can use one of the MySQL mailing
        lists.
      </p><p>
        Remember that it is possible for us to respond to a message
        containing too much information, but not to one containing too
        little. People often omit facts because they think they know the
        cause of a problem and assume that some details don't matter.
      </p><p>
        A good principle is this: If you are in doubt about stating
        something, state it. It is faster and less troublesome to write
        a couple more lines in your report than to wait longer for the
        answer if we must ask you to provide information that was
        missing from the initial report.
      </p><p>
        The most common errors made in bug reports are (a) not including
        the version number of Connector/J or MySQL used, and (b) not
        fully describing the platform on which Connector/J is installed
        (including the JVM version, and the platform type and version
        number that MySQL itself is installed on).
      </p><p>
        This is highly relevant information, and in 99 cases out of 100,
        the bug report is useless without it. Very often we get
        questions like, “<span class="quote">Why doesn't this work for me?</span>”
        Then we find that the feature requested wasn't implemented in
        that MySQL version, or that a bug described in a report has
        already been fixed in newer MySQL versions.
      </p><p>
        Sometimes the error is platform-dependent; in such cases, it is
        next to impossible for us to fix anything without knowing the
        operating system and the version number of the platform.
      </p><p>
        If at all possible, you should create a repeatable, stanalone
        testcase that doesn't involve any third-party classes.
      </p><p>
        To streamline this process, we ship a base class for testcases
        with Connector/J, named
        '<code class="classname">com.mysql.jdbc.util.BaseBugReport</code>'. To
        create a testcase for Connector/J using this class, create your
        own class that inherits from
        <code class="classname">com.mysql.jdbc.util.BaseBugReport</code> and
        override the methods <code class="literal">setUp()</code>,
        <code class="literal">tearDown()</code> and <code class="literal">runTest()</code>.
      </p><p>
        In the <code class="literal">setUp()</code> method, create code that
        creates your tables, and populates them with any data needed to
        demonstrate the bug.
      </p><p>
        In the <code class="literal">runTest()</code> method, create code that
        demonstrates the bug using the tables and data you created in
        the <code class="literal">setUp</code> method.
      </p><p>
        In the <code class="literal">tearDown()</code> method, drop any tables you
        created in the <code class="literal">setUp()</code> method.
      </p><p>
        In any of the above three methods, you should use one of the
        variants of the <code class="literal">getConnection()</code> method to
        create a JDBC connection to MySQL:
      </p><div class="itemizedlist"><ul type="disc"><li><p>
            <code class="literal">getConnection()</code> - Provides a connection
            to the JDBC URL specified in <code class="literal">getUrl()</code>. If
            a connection already exists, that connection is returned,
            otherwise a new connection is created.
          </p></li><li><p>
            <code class="literal">getNewConnection()</code> - Use this if you need
            to get a new connection for your bug report (i.e. there's
            more than one connection involved).
          </p></li><li><p>
            <code class="literal">getConnection(String url)</code> - Returns a
            connection using the given URL.
          </p></li><li><p>
            <code class="literal">getConnection(String url, Properties
            props)</code> - Returns a connection using the given URL
            and properties.
          </p></li></ul></div><p>
        If you need to use a JDBC URL that is different from
        'jdbc:mysql:///test', override the method
        <code class="literal">getUrl()</code> as well.
      </p><p>
        Use the <code class="literal">assertTrue(boolean expression)</code> and
        <code class="literal">assertTrue(String failureMessage, boolean
        expression)</code> methods to create conditions that must be
        met in your testcase demonstrating the behavior you are
        expecting (vs. the behavior you are observing, which is why you
        are most likely filing a bug report).
      </p><p>
        Finally, create a <code class="literal">main()</code> method that creates
        a new instance of your testcase, and calls the
        <code class="literal">run</code> method:
      </p><pre class="programlisting">public static void main(String[] args) throws Exception {
      new MyBugReport().run();
 }</pre><p>
        Once you have finished your testcase, and have verified that it
        demonstrates the bug you are reporting, upload it with your bug
        report to <a href="http://bugs.mysql.com/" target="_top">http://bugs.mysql.com/</a>.
      </p></div><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="connector-j-support-changelog"></a>1.6.3. Connector/J Change History</h4></div></div></div><p>
        The Connector/J Change History (Changelog) is located with the
        main Changelog for MySQL. See <a href="http://dev.mysql.com/doc/refman/5.1/en/cj-news.html" target="_top">MySQL Connector/J Change History</a>.
      </p></div></div></div></body></html>