??xml version="1.0" encoding="utf-8" standalone="yes"?>
原因是缺?jar文g
至于是缺standard.jarq是servlet-api.jarq是两个都缺那就看你引了(jin)哪个?/p>
丑և个这个方法实用的例子(注释是输出结?Q?/p>
CODE:
long now = System.currentTimeMillis();
String s = String.format("%tR", now); // "15:12"
CODE:
// Current month/day/year
Date d = new Date(now);
s = String.format("%tD", d); // "07/13/04"
CODE:
s = String.format("%,d", Integer.MAX_VALUE); // "2,147,483,647"
CODE:
s = String.format("%05d", 123); // "00123"
是不是很方便Q让人动?j)啊Q哈哈,q有更多的效?
其实format函数有些cMc语言中printf函数Q一些格式字W串?C cMQ但已进行了(jin)某些定制Q以适应 Java 语言Qƈ且利用了(jin)其中一些特性。此Ҏ(gu)提供?jin)对布局寚w和排列的支持Q以?qing)对数倹{字W串和日?旉数据的常规格式和特定于语a环境的输出的支持。支持诸?byte、BigDecimal ?Calendar {常?Java cd?/p>
产生格式化输出的每个Ҏ(gu)都需要格式字W串 和参数列表。格式字W串是一?StringQ它可以包含固定文本以及(qing)一个或多个嵌入的格式说明符。请考虑以下CZQ?/p>
Calendar c = ...;
String s = String.format("Duke's Birthday: %1$tm %1$te,%1$tY", c);
格式字符串是 format Ҏ(gu)的第一个参数。它包含三个格式说明W?"%1$tm"?%1$te" ?"%1$tY"Q它们指出应该如何处理参C?qing)在文本的什么地Ҏ(gu)入它们。格式字W串的其余部分是包括 "Dukes Birthday: " 和其他Q何空格或标点W号的固定文本?参数列表׃递给位于格式字符串之后的Ҏ(gu)的所有参数组成。在上述CZ中,参数列表的大ؓ(f) 1Q由新对?Calendar l成?/p>
1.常规cd、字W类型和数值类型的格式说明W的语法如下Q?[argument_index$][flags][width][.precision]conversion
可选的 argument_index 是一个十q制整数Q用于表明参数在参数列表中的位置。第一个参数由 "1$" 引用Q第二个参数?"2$" 引用Q依此类推?br />可选的 flags 是修改输出格式的字符集。有效标志的集合取决于{换类型?br />可?width 是一个非负十q制整数Q表明要向输Z写入的最字W数?br />可?precision 是一个非负十q制整数Q通常用来限制字符数。特定行为取决于转换cd?br />所需?conversion 是一个表明应该如何格式化参数的字W。给定参数的有效转换集合取决于参数的数据cd?/p>
2.用来表示日期和时间类型的格式说明W的语法如下:
%[argument_index$][flags][width]conversion
可选的 argument_index、flags ?width 的定义同上?br />所需?conversion 是一个由两字W组成的序列。第一个字W是 't' ?'T'。第二个字符表明所使用的格式。这些字W类g但不完全{同于那些由 GNU date ?POSIX strftime(3c) 定义的字W?/p>
3.与参C对应的格式说明符的语法如下:(x)
%[flags][width]conversion
可?flags ?width 的定义同上?br />所需?conversion 是一个表明要在输Z所插内容的字符?/p>
转换
转换可分Z下几c:(x)
1. 常规 - 可应用于M参数cd
2. 字符 - 可应用于表示 Unicode 字符的基本类型:(x)char、Character、byte、Byte、short ?Short。当 Character.isValidCodePoint(int) q回 true Ӟ可将此{换应用于 int ?Integer cd
3. 数?br /> 1. 整数 - 可应用于 Java 的整数类型:(x)byte、Byte、short、Short、int、Integer、long、Long ?BigInteger
2. 点 - 可用?Java 的Q点类型:(x)float、Float、double、Double ?BigDecimal
4. 日期/旉 - 可应用于 Java 的、能够对日期或时间进行编码的cdQlong、Long、Calendar ?Date?br />5. 癑ֈ?- 产生字面?'%' ('\u0025')
6. 行分隔符 - 产生特定于^台的行分隔符
下表ȝ?jin)受支持的{换。由大写字符Q如 'B'?H'?S'?C'?X'?E'?G'?A' ?'T'Q表C的转换与由相应的小写字W的转换{同Q根据流行的 Locale 规则结果{换ؓ(f)大写形式除外。后者等同于 String.toUpperCase() 的以下调?
转换 参数cd 说明
'b', 'B' 常规 如果参数 arg ?nullQ则l果?"false"。如?arg 是一?boolean 值或 BooleanQ则l果?String.valueOf() q回的字W串。否则结果ؓ(f) "true"?
'h', 'H' 常规 如果参数 arg ?nullQ则l果?"null"。否则,l果?Integer.toHexString(arg.hashCode()) 得到的结果?
's', 'S' 常规 如果参数 arg ?nullQ则l果?"null"。如?arg 实现 FormattableQ则调用 arg.formatTo。否则,l果?arg.toString() 得到的结果?
'c', 'C' 字符 l果是一?Unicode 字符
'd' 整数 l果被格式化为十q制整数
'o' 整数 l果被格式化为八q制整数
'x', 'X' 整数 l果被格式化为十六进制整?
'e', 'E' 点 l果被格式化为用计算机科学记数法表示的十q制?
'f' 点 l果被格式化为十q制?
'g', 'G' 点 Ҏ(gu)_ֺ和舍入运后的|使用计算机科学记数Ş式或十进制格式对l果q行格式化?
'a', 'A' 点 l果被格式化为带有效位数和指数的十六q制点?
't', 'T' 日期/旉 日期和时间{换字W的前缀。请参阅日期/旉转换?
'%' 癑ֈ?l果为字面?'%' ('\u0025')
'n' 行分隔符 l果为特定于q_的行分隔W?
M未明定义ؓ(f)转换的字W都是非法字W,q且都被保留Q以供将来扩展用?/p>
日期/旉转换
以下日期和时间{换的后缀字符是ؓ(f) 't' ?'T' 转换定义的。这些类型相g但不完全{同于那些由 GNU date ?POSIX strftime(3c) 定义的类型。提供其他{换类型是Z(jin)讉K特定?Java 的功能(如将 'L' 用作U中的毫U)(j)?/p>
以下转换字符用来格式化时_(d)(x)
'H' 24 时制的时Q被格式化ؓ(f)必要时带前导零的两位敎ͼ?00 - 23?
'I' 12 时制的时Q被格式化ؓ(f)必要时带前导零的两位敎ͼ?01 - 12?
'k' 24 时制的时Q即 0 - 23?
'l' 12 时制的时Q即 1 - 12?
'M' 时中的分钟Q被格式化ؓ(f)必要时带前导零的两位敎ͼ?00 - 59?
'S' 分钟中的U,被格式化为必要时带前导零的两位数Q即 00 - 60 Q?60" 是支持闰U所需的一个特D|(j)?
'L' U中的毫U,被格式化为必要时带前导零的三位数Q即 000 - 999?
'N' U中的毫微秒Q被格式化ؓ(f)必要时带前导零的?ji)位敎ͼ?000000000 - 999999999?
'p' 特定于语a环境?上午或下?标记以小写Ş式表C,例如 "am" ?"pm"。用{换前~ 'T' 可以此输出转换为大写Ş式?
'z' 相对?GMT ?RFC 822 格式的数字时区偏U量Q例?-0800?
'Z' 表示时区~写形式的字W串。Formatter 的语a环境?yu)取代参数的语言环境Q如果有Q?
's' 自协调世界时 (UTC) 1970 q?1 ?1 ?00:00:00 至现在所l过的秒敎ͼ?Long.MIN_VALUE/1000 ?Long.MAX_VALUE/1000 之间的差倹{?
'Q' 自协调世界时 (UTC) 1970 q?1 ?1 ?00:00:00 至现在所l过的毫U数Q即 Long.MIN_VALUE ?Long.MAX_VALUE 之间的差倹{?
以下转换字符用来格式化日期:(x)
'B' 特定于语a环境的月份全Uͼ例如 "January" ?"February"?
'b' 特定于语a环境的月份简Uͼ例如 "Jan" ?"Feb"?
'h' ?'b' 相同?
'A' 特定于语a环境的星期几全称Q例?"Sunday" ?"Monday"
'a' 特定于语a环境的星期几Uͼ例如 "Sun" ?"Mon"
'C' 除以 100 的四位数表示的年份,被格式化为必要时带前导零的两位数Q即 00 - 99
'Y' q䆾Q被格式化ؓ(f)必要时带前导零的四位敎ͼ臛_Q,例如Q?092 {于格里高利历的 92 CE?
'y' q䆾的最后两位数Q被格式化ؓ(f)必要时带前导零的两位敎ͼ?00 - 99?
'j' 一q中的天敎ͼ被格式化为必要时带前导零的三位数Q例如,对于格里高利历是 001 - 366?
'm' 月䆾Q被格式化ؓ(f)必要时带前导零的两位敎ͼ?01 - 13?
'd' 一个月中的天数Q被格式化ؓ(f)必要时带前导零两位数Q即 01 - 31
'e' 一个月中的天数Q被格式化ؓ(f)两位敎ͼ?1 - 31?
以下转换字符用于格式化常见的日期/旉l合?/p>
'R' 24 时制的旉Q被格式化ؓ(f) "%tH:%tM"
'T' 24 时制的旉Q被格式化ؓ(f) "%tH:%tM:%tS"?
'r' 12 时制的旉Q被格式化ؓ(f) "%tI:%tM:%tS %Tp"。上午或下午标记 ('%Tp') 的位|可能与语言环境有关?
'D' 日期Q被格式化ؓ(f) "%tm/%td/%ty"?
'F' ISO 8601 格式的完整日期,被格式化?"%tY-%tm-%td"?
'c' 日期和时_(d)被格式化?"%ta %tb %td %tT %tZ %tY"Q例?"Sun Jul 20 16:17:00 EDT 1969"?
M未明定义ؓ(f)转换的字W都是非法字W,q且都被保留Q以供将来扩展用?/p>
标志
下表ȝ?jin)受支持的标志。y 表示该标志受指示参数cd支持?/p>
标志 常规 字符 整数 点 日期/旉 说明
'-' y y y y y l果是左对齐的?
'#' y1 - y3 y - l果应该使用依赖于{换类型的替换形式
'+' - - y4 y - l果L包括一个符?
' ' - - y4 y - 对于正|l果中将包括一个前导空?
'0' - - y y - l果用零来填充
',' - - y2 y5 - l果包括特定于语言环境的组分隔W?
'(' - - y4 y5 - l果是用圆括号括v来的负数
1 取决?Formattable 的定义?/p>
2 只适用?'d' 转换?/p>
3 只适用?'o'?x' ?'X' 转换?/p>
4 ?BigInteger 应用 'd'?o'?x' ?'X' 转换Ӟ或者对 byte ?Byte、short ?Short、int ?Integer、long ?Long 分别应用 'd' 转换旉用?/p>
5 只适用?'e'?E'?f'?g' ?'G' 转换?/p>
M未显式定义ؓ(f)标志的字W都是非法字W,q且都被保留Q以供扩展用?/p>
宽度 宽度是将向输Z写入的最字W数。对于行分隔W{换,不适用宽度Q如果提供宽度,则会(x)抛出异常?br />_ֺ 对于常规参数cdQ精度是向输出中写入的最多字W数?br />对于点转换 'e'?E' ?'f'Q精度是数点分隔符后的位数。如果{换是 'g' ?'G'Q那么精度是舍入计算后所得数值的所有位数。如果{换是 'a' ?'A'Q则不必指定_ֺ?br />对于字符、整数和日期/旉参数cd转换Q以?qing)百分比和行分隔W{换,_ֺ是不适用的;如果提供_ֺQ则?x)抛出异常?br />参数索引 参数索引是一个十q制整数Q用于表明参数在参数列表中的位置。第一个参数由 "1$" 引用Q第二个参数?"2$" 引用Q依此类推?br />Ҏ(gu)位置引用参数的另一U方法是使用 '<' ('\u003c') 标志Q这会(x)重用以前格式说明W的参数。例如,以下两条语句产生的字W相同:(x)
Calendar c = ...;
String s1 = String.format("Duke's Birthday: %1$tm %1$te,%1$tY", c);
String s2 = String.format("Duke's Birthday: %1$tm %<$te,%<$tY", c);
在JDK1.5中,Stringcd加了(jin)一个非常有用的?rn)态函数format(String format, Objece... argues)Q可以将各类数据格式化ؓ(f)字符串ƈ输出。其中format参数指定?jin)输出的格式Q是最复杂也是最难掌握的一点,而argues则是一pd{待被格式化的对象。该函数对c语言中printf函数的用法进行了(jin)一定的模仿Q因此有c语言基础的h学v来会(x)L许多。下面我们着重讨Z下format 参数的格式及(qing)含义?br /> format参数中可以包含不需要{化的字符Ԍq些字符串是你写什么,最l就输出什么。同时还包含一些特D格式的内容Q来指定哪个对象来转换Q以?qing){换成什么Ş式。这U特D的格式通通以%index$开_(d)index?开始取|表示第index个参数拿q来q行格式化。这一Ҏ(gu)c语言要强一点, c语言只能按照参数的顺序依ơ格式化Q而java可以选择Wn个参数来格式化。由于该函数可以对Q意一个对象进行格式化Q不同的对象适用的参C不同Q因此我们下面分cL讨论?/p>
1.Ҏ(gu)数进行格式化Q?[index$][标识][最宽度]转换方式
我们可以看到Q格式化字符串由4部分l成Q其?[index$]的含义我们上面已l讲q,[最宽度]的含义也很好理解Q就是最l该整数转化的字W串最包含多位数字。我们来看看剩下2个部分的含义吧:(x)
标识Q?
'-' 在最宽度内左对齐,不可以与“?填充”同时使用
'#' 只适用?q制?6q制Q?q制时在l果前面增加一?Q?6q制时在l果前面增加0x
'+' l果L包括一个符P一般情况下只适用?0q制Q若对象为BigInteger才可以用?q制?6q制Q?br />' ' 正值前加空|负值前加负P一般情况下只适用?0q制Q若对象为BigInteger才可以用?q制?6q制Q?br />'0' l果用零来填充
',' 只适用?0q制Q每3位数字之间用“Q?#8221;分隔
'(' 若参数是负数Q则l果中不d负号而是用圆括号把数字括hQ同‘+’h同样的限Ӟ(j)
转换方式Q?br />d-十进?nbsp; o-八进?nbsp; x或X-十六q制 上面的说明过于枯燥,我们来看几个具体的例子。需要特别注意的一Ҏ(gu)Q大部分标识字符可以同时使用?
System.out.println(String.format("%1$,09d", -3123));
System.out.println(String.format("%1$9d", -31));
System.out.println(String.format("%1$-9d", -31));
System.out.println(String.format("%1$(9d", -31));
System.out.println(String.format("%1$#9x", 5689));
//l果为:(x)
//-0003,123
// -31
//-31
// (31)
// 0x1639
2.Ҏ(gu)QҎ(gu)q行格式化:(x)%[index$][标识][最宽度][._ֺ]转换方式
我们可以看到QQҎ(gu)的{换多?jin)一?#8220;_ֺ”选项Q可以控制小数点后面的位数?
标识Q?
'-' 在最宽度内左对齐,不可以与“?填充”同时使用
'+' l果L包括一个符?br />' ' 正值前加空|负值前加负?br />'0' l果用零来填充
',' ?位数字之间用“Q?#8221;分隔Q只适用于fgG的{换)(j)
'(' 若参数是负数Q则l果中不d负号而是用圆括号把数字括hQ只适用于eEfgG的{换)(j)
转换方式Q?br />'e', 'E' -- l果被格式化为用计算机科学记数法表示的十q制?br />'f' -- l果被格式化为十q制普通表C方?br />'g', 'G' -- Ҏ(gu)具体情况Q自动选择用普通表C方式还是科学计数法方式
'a', 'A' -- l果被格式化为带有效位数和指数的十六q制点?/p>
3.对字W进行格式化Q?br /> 对字W进行格式化是非常简单的Qc表示字符Q标识中'-'表示左对齐,其他没什么了(jin)?/p>
4.对百分比W号q行格式化:(x)
看了(jin)上面的说明,大家?x)发现百分比W号“%”是特D格式的一个前~。那么我们要输入一个百分比W号该怎么办呢Q肯定是需要{义字W的,但是要注意的是,在这里{义字W不?#8220;\”Q而是“%”。换句话_(d)下面q条语句可以输出一?#8220;12%”Q?br />System.out.println(String.format("%1$d%%", 12));
5.取得q_独立的行分隔W:(x)
System.getProperty("line.separator")可以取得q_独立的行分隔W,但是用在format中间未免昑־q于?ch)琐了(jin)。于是format函数自带?jin)一个^台独立的行分隔符那就是String.format("%n")?/p>
6.Ҏ(gu)期类型进行格式化Q?br /> 以下日期和时间{换的后缀字符是ؓ(f) 't' ?'T' 转换定义的。这些类型相g但不完全{同于那些由 GNU date ?POSIX strftime(3c) 定义的类型。提供其他{换类型是Z(jin)讉K特定?Java 的功能(如将 'L' 用作U中的毫U)(j)?/p>
以下转换字符用来格式化时_(d)(x)
'H' 24 时制的时Q被格式化ؓ(f)必要时带前导零的两位敎ͼ?00 - 23?br />'I' 12 时制的时Q被格式化ؓ(f)必要时带前导零的两位敎ͼ?01 - 12?br />'k' 24 时制的时Q即 0 - 23?br />'l' 12 时制的时Q即 1 - 12?br />'M' 时中的分钟Q被格式化ؓ(f)必要时带前导零的两位敎ͼ?00 - 59?br />'S' 分钟中的U,被格式化为必要时带前导零的两位数Q即 00 - 60 Q?60" 是支持闰U所需的一个特D|(j)?br />'L' U中的毫U,被格式化为必要时带前导零的三位数Q即 000 - 999?br />'N' U中的毫微秒Q被格式化ؓ(f)必要时带前导零的?ji)位敎ͼ?000000000 - 999999999?br />'p' 特定于语a环境的上午或下午 标记以小写Ş式表C,例如 "am" ?"pm"。用{换前~ 'T' 可以此输出转换为大写Ş式?br />'z' 相对?GMT ?RFC 822 格式的数字时区偏U量Q例?-0800?br />'Z' 表示时区~写形式的字W串。Formatter 的语a环境?yu)取代参数的语言环境Q如果有Q?br />'s' 自协调世界时 (UTC) 1970 q?1 ?1 ?00:00:00 至现在所l过的秒敎ͼ?Long.MIN_VALUE/1000 ?Long.MAX_VALUE/1000 之间的差倹{?br />'Q' 自协调世界时 (UTC) 1970 q?1 ?1 ?00:00:00 至现在所l过的毫U数Q即 Long.MIN_VALUE ?Long.MAX_VALUE 之间的差倹{?/p>
以下转换字符用来格式化日期:(x)
'B' 特定于语a环境的月份全Uͼ例如 "January" ?"February"?br />'b' 特定于语a环境的月份简Uͼ例如 "Jan" ?"Feb"?br />'h' ?'b' 相同?br />'A' 特定于语a环境的星期几全称Q例?"Sunday" ?"Monday"
'a' 特定于语a环境的星期几Uͼ例如 "Sun" ?"Mon"
'C' 除以 100 的四位数表示的年份,被格式化为必要时带前导零的两位数Q即 00 - 99
'Y' q䆾Q被格式化ؓ(f)必要时带前导零的四位敎ͼ臛_Q,例如Q?092 {于格里高利历的 92 CE?br />'y' q䆾的最后两位数Q被格式化ؓ(f)必要时带前导零的两位敎ͼ?00 - 99?br />'j' 一q中的天敎ͼ被格式化为必要时带前导零的三位数Q例如,对于格里高利历是 001 - 366?br />'m' 月䆾Q被格式化ؓ(f)必要时带前导零的两位敎ͼ?01 - 13?br />'d' 一个月中的天数Q被格式化ؓ(f)必要时带前导零两位数Q即 01 - 31
'e' 一个月中的天数Q被格式化ؓ(f)两位敎ͼ?1 - 31?/p>
以下转换字符用于格式化常见的日期/旉l合?br />'R' 24 时制的旉Q被格式化ؓ(f) "%tH:%tM"
'T' 24 时制的旉Q被格式化ؓ(f) "%tH:%tM:%tS"?br />'r' 12 时制的旉Q被格式化ؓ(f) "%tI:%tM:%tS %Tp"。上午或下午标记 ('%Tp') 的位|可能与语言环境有关?br />'D' 日期Q被格式化ؓ(f) "%tm/%td/%ty"?br />'F' ISO 8601 格式的完整日期,被格式化?"%tY-%tm-%td"?br />'c' 日期和时_(d)被格式化?"%ta %tb %td %tT %tZ %tY"Q例?"Sun Jul 20 16:17:00 EDT 1969"?br />文章出处Q飞诺网(www.firnow.com):http://dev.firnow.com/course/3_program/java/javashl/2008107/148918.html
新徏一个AVD以后Q第一ơ跑hOK的,关闭以后重新跑,又有问题?sh)(jin),N我每跑一ơ就重新建AVDQ这个不是解决问题的Ҏ(gu)办法...很多QSD card size 不要讄Q可以避免这个问题出现?/p>
本文来自CSDN博客Q{载请标明出处Qhttp://blog.csdn.net/jincf2011/archive/2011/04/22/6342906.aspx
当hql{查询方式不能满x(chng)能或灵zL的要求Q必M用SQLӞ大家有三U选择Q?/p>
W一、用Hibernate 的sql 查询函数Q将查询l果对象转ؓ(f)Entity对象?/p>
W二、用Hibernate Session的getConnection 获得JDBC ConnectionQ然后进行纯JDBC API操作Q?/p>
W三、选择把Spring的JDBCTemplate作ؓ(f)一U很不错的JDBC Utils来用?/p>
JDBCTemplate的用很单,只要在ApplicationContext文g里定义一个jdbcTemplate节点QPOJO获得注入后可以直接执行操作,不需要承什么基c,详见JDBCTemplate参考文?sup>?/p>
AplicationContext定义Q?/p>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>
实际使用Q?nbsp;
SqlRowSet rs = jdbcTemplate.queryForRowSet(sql, params);
Tips1Q?/strong> jdbcTemplate有很多的ORM化回调操作将q回l果转ؓ(f)对象列表Q但很多时候还是需要返回ResultSetQSpring有提供一个类似ResultSet?Spring SqlRowSet对象?/p>
Tips2Q?/strong>.注意jdbcTemplate量只执行查询操作,莫要q行更新Q否则很Ҏ(gu)破坏Hibernate的二U缓存(sh)pR?/p>
Spring JDBC抽象框架所带来的h(hun)值将在以下几个方面得以体玎ͼ(x)Q注Q用了(jin)Spring JDBC抽象框架之后Q应用开发h员只需要完成斜体字部分的编码工作。)(j) 指定数据库连接参?/p>
打开数据库连?/p>
声明SQL语句 预编译ƈ执行SQL语句 遍历查询l果Q如果需要的话)(j) 处理每一ơ遍历操?/em> 处理抛出的Q何异?/p>
处理事务 关闭数据库连?/p>
Spring替我们完成所有单调乏味的JDBC底层l节处理工作? Spring JDBC抽象框架由四个包构成Q?tt class="literal">core?dataSource?tt class="literal">object以及(qing)support? org.springframework.jdbc.core包由JdbcTemplatecM?qing)相关的回调接口Qcallback interfaceQ和cȝ成? org.springframework.jdbc.datasource包由一些用来简?tt class="interfacename">DataSource讉K的工L(fng)Q以?qing)各U?tt class="interfacename">DataSource接口的简单实?主要用于单元试以及(qing)在J2EE容器之外使用JDBC)l成。工L(fng)提供?jin)一些静(rn)态方法,诸如通过JNDI获取数据q接以及(qing)在必要的情况下关闭这些连接。它支持l定U程的连接,比如被用?tt class="classname">DataSourceTransactionManager的连接? 接下来,org.springframework.jdbc.object包由装?jin)查询、更C?qing)存储过E的cȝ成,q些cȝ对象都是U程安全q且可重复用的。它们类gJDOQ与JDO的不同之处在于查询结果与数据库是“断开q接”的。它们是?tt class="literal">org.springframework.jdbc.core包的基础上对JDBC更高层次的抽象? 最后,org.springframework.jdbc.support包提供了(jin)一?tt class="classname">SQLException的{换类以及(qing)相关的工L(fng)? 在JDBC处理q程中抛出的异常被转换?tt class="literal">org.springframework.dao包中定义的异常。因此用Spring JDBCq行开发将不需要处理JDBC或者特定的RDBMS才会(x)抛出的异常。所有的异常都是unchecked exceptionQ这h们就可以对传递到调用者的异常q行有选择的捕莗? JdbcTemplate是core包的核心(j)cR它替我们完成了(jin)资源的创Z?qing)释攑ַ作,从而简化了(jin)我们对JDBC的用。它q可以帮助我们避免一些常见的错误Q比如忘记关闭数据库q接。JdbcTemplate完成JDBC核心(j)处理程Q比如SQL语句的创建、执行,而把SQL语句的生成以?qing)查询结果的提取工作留给我们的应用代码。它可以完成SQL查询、更C?qing)调用存储过E,可以?tt class="interfacename">ResultSetq行遍历q加以提取。它q可以捕获JDBC异常q将其{换成org.springframework.dao包中定义的,通用的,信息更丰富的异常? 使用JdbcTemplateq行~码只需要根据明定义的一l契U来实现回调接口?tt class="interfacename">PreparedStatementCreator回调接口通过l定?tt class="interfacename">Connection创徏一个PreparedStatementQ包含SQL和Q何相关的参数?tt class="literal">CallableStatementCreateor实现同样的处理,只不q它创徏的是CallableStatement?tt class="literal">RowCallbackHandler接口则从数据集的每一行中提取倹{? 我们可以在一个service实现cM通过传递一?tt class="interfacename">DataSource引用来完成JdbcTemplate的实例化Q也可以在application context中配|一个JdbcTemplate beanQ来供service使用。需要注意的?tt class="interfacename">DataSource在application contextL配制成一个beanQ第一U情况下Q?tt class="interfacename">DataSource bean传递给serviceQ第二种情况?tt class="interfacename">DataSource bean传递给JdbcTemplate bean。因为JdbcTemplate使用回调接口?tt class="interfacename">SQLExceptionTranslator接口作ؓ(f)参数Q所以一般情况下没有必要通过l承JdbcTemplate来定义其子类? JdbcTemplate中用的所有SQL会(x)?#8220;DEBUG”U别记入日志Q一般情况下日志的category?tt class="classname">JdbcTemplate相应的全限定cdQ不q如果需要对JdbcTemplateq行定制的话Q可能是它的子类名)(j)? NamedParameterJdbcTemplatecd加了(jin)在SQL语句中用命名参数的支持。在此之前,在传l的SQL语句中,参数都是?tt class="literal">'?'占位W来表示的?NamedParameterJdbcTemplatecd部封装了(jin)一个普通的JdbcTemplateQƈ作ؓ(f)其代理来完成大部分工作。下面的内容主要针对NamedParameterJdbcTemplate?tt class="classname">JdbcTemplate的不同之处来加以说明Q即如何在SQL语句中用命名参数? 通过下面的例子我们可以更好地?jin)?tt class="classname">NamedParameterJdbcTemplate的用模式(在后面我们还有更好的使用方式Q? 在上面例子中Q?tt class="literal">sql变量使用?jin)命名参数占位?#8220;first_name”Q与其对应的值存?tt class="literal">namedParameters变量中(cd?tt class="classname">MapSqlParameterSourceQ? 如果你喜Ƣ的话,也可以用基于Map风格的名值对命名参C递给NamedParameterJdbcTemplateQ?tt class="classname">NamedParameterJdbcTemplate实现?tt class="interfacename">NamedParameterJdbcOperations接口Q剩下的工作由调用该接口的相应Ҏ(gu)来完成,q里我们׃再赘qͼ(j)Q? 另外一个值得一提的Ҏ(gu)是?tt class="classname">NamedParameterJdbcTemplate位于同一个包中的SqlParameterSource接口。在前面的代码片断中我们已经看到?jin)该接口的实玎ͼ?tt class="classname">MapSqlParameterSourcec)(j)Q?tt class="interfacename">SqlParameterSource可以用来作ؓ(f)NamedParameterJdbcTemplate命名参数的来源?tt class="classname">MapSqlParameterSourcecL一个非常简单的实现Q它仅仅是一?tt class="interfacename">java.util.Map适配器,当然其用法也׃a自明?jin)(如果q有不明?jin)的Q可以在Spring的JIRApȝ中要求提供更多的相关资料Q? SqlParameterSource接口的另一个实玎ͼQ?tt class="classname">BeanPropertySqlParameterSource为我们提供了(jin)更有的功能。该cd装一个类似JavaBean的对象,所需要的命名参数值将由包装对象提供,下面我们使用一个例子来更清楚地说明它的用法? 大家必须牢记一点:(x)NamedParameterJdbcTemplatecd?span class="emphasis">包装?jin)一个标准的JdbcTemplatecR如果你需要访问其内部?tt class="classname">JdbcTemplate实例Q比如访?tt class="classname">JdbcTemplate的一些方法)(j)那么你需要?tt class="literal">getJdbcOperations()Ҏ(gu)q回?span class="emphasis">JdbcOperations接口。(JdbcTemplate实现?tt class="interfacename">JdbcOperations接口Q? NamedParameterJdbcTemplatecLU程安全的,该类的最佳用方式不是每ơ操作的时候实例化一个新?tt class="classname">NamedParameterJdbcTemplateQ而是针对每个DataSource只配|一?tt class="classname">NamedParameterJdbcTemplate实例Q比如在Spring IoC容器中用Spring IoC来进行配|)(j)Q然后在那些使用该类的DAO中共享该实例? h意该cL提供的功能仅适用于Java 5 (Tiger)?/em> SimpleJdbcTemplatecLJdbcTemplatecȝ一个包装器QwrapperQ,它利用了(jin)Java 5的一些语aҎ(gu),比如Varargs和Autoboxing。对那些用惯?jin)Java 5的程序员Q这些新的语aҎ(gu)还是很好用的? SimpleJdbcTemplate cd用Java 5的语法特性带来的好处可以通过一个例子来说明。在下面的代码片断中我们首先使用标准?tt class="classname">JdbcTemplateq行数据讉KQ接下来使用SimpleJdbcTemplate做同L(fng)事情? 下面是同一Ҏ(gu)的另一U实玎ͼ惟一不同之处是我们用了(jin)SimpleJdbcTemplateQ这样代码显得更加清晰? Z(jin)从数据库中取得数据,我们首先需要获取一个数据库q接?Spring通过DataSource对象来完成这个工作?DataSource是JDBC规范的一部分Q?它被视ؓ(f)一个通用的数据库q接工厂。通过使用DataSourceQ?Container或Framework可以连接池以及(qing)事务理的细节从应用代码中分d来?作ؓ(f)一个开发h员,在开发和试产品的过E中Q你可能需要知道连接数据库的细节?但在产品实施Ӟ你不需要知道这些细节。通常数据库管理员?sh)(x)帮你设|好数据源? 在用Spring JDBCӞ你既可以通过JNDI获得数据源,也可以自行配|数据源Q?使用Spring提供的DataSource实现c)(j)。用后者可以更方便的脱Web容器来进行单元测试?q里我们?tt class="classname">DriverManagerDataSourceQ不qDataSource有多U实玎ͼ 后面我们?x)讲到。?tt class="classname">DriverManagerDataSource和你以前获取一个JDBCq接 的做法没什么两栗你首先必须指定JDBC驱动E序的全限定名,q样DriverManager 才能加蝲JDBC驱动c,接着你必L供一个urlQ因JDBC驱动而异Qؓ(f)?jin)保证设|正请参考相关JDBC驱动的文档)(j)Q?最后你必须提供一个用戯接数据库的用户名和密码。下面我们将通过一个例子来说明如何配置一?DriverManagerDataSourceQ? SQLExceptionTranslator是一个接口,如果你需要在 SQLException?tt class="classname">org.springframework.dao.DataAccessException之间作{换,那么必须实现该接口? 转换器类的实现可以采用一般通用的做?比如使用JDBC的SQLState code)Q如果ؓ(f)?jin)转换更准,也可以进行定Ӟ比如使用Oracle的error codeQ? SQLErrorCodeSQLExceptionTranslator是SQLExceptionTranslator的默认实现?该实C用指定数据库厂商的error codeQ比采用SQLState更精?转换q程Z一个JavaBeanQ类型ؓ(f)SQLErrorCodesQ中的error code?q个JavaBean?tt class="classname">SQLErrorCodesFactory工厂cd建,其中的内Ҏ(gu)自于 "sql-error-codes.xml"配置文g。该文g中的数据库厂商代码基于Database MetaData信息中的 DatabaseProductNameQ从而配合当前数据库的用? SQLErrorCodeSQLExceptionTranslator使用以下的匹配规则:(x) 首先(g)查是否存在完成定制{换的子类实现。通常SQLErrorCodeSQLExceptionTranslator q个cd以作Z个具体类使用Q不需要进行定Ӟ那么q个规则不适用? 接着SQLException的error code与错误代码集中的error codeq行匚w?默认情况下错误代码集从SQLErrorCodesFactory取得?错误代码集来自classpath下的sql-error-codes.xml文gQ?它们与数据库metadata信息中的database nameq行映射? 如果仍然无法匚wQ最后将调用fallbackTranslator属性的translateҎ(gu)Q?tt class="classname">SQLStateSQLExceptionTranslatorcd例是默认的fallbackTranslator? SQLErrorCodeSQLExceptionTranslator可以采用下面的方式进行扩展:(x) 在上面的q个例子中,error code?tt class="literal">'-12345'的SQLException 采用该转换器进行{换,而其他的error code由默认的{换器q行转换?Z(jin)使用该{换器Q必d其作为参C递给JdbcTemplatec??tt class="literal">setExceptionTranslatorҎ(gu)Qƈ在需要用这个{换器器的数据 存取操作中用该JdbcTemplate?下面的例子演CZ(jin)如何使用该定制{换器Q? 在上面的定制转换器中Q我们给它注入了(jin)一个数据源Q因为我们仍焉?使用默认的{换器?tt class="literal">sql-error-codes.xml中获取错误代码集? 我们仅需要非常少的代码就可以辑ֈ执行SQL语句的目的,一旦获得一?DataSource和一?tt class="classname">JdbcTemplateQ?我们可以?tt class="classname">JdbcTemplate提供的丰富功能实现我们的操作?下面的例子用了(jin)极少的代码完成创Z张表的工作? 除了(jin)executeҎ(gu)之外Q?tt class="classname">JdbcTemplateq提供了(jin)大量的查询方法?在这些查询方法中Q有很大一部分是用来查询单值的。比如返回一个汇总(countQ结?或者从q回行结果中取得指定列的倹{这时我们可以?tt class="literal">queryForInt(..)?queryForLong(..)或?tt class="literal">queryForObject(..)Ҏ(gu)?queryForObjectҎ(gu)用来返回的JDBCcd对象转换成指定的Java对象Q如果类型{换失败将抛出 InvalidDataAccessApiUsageException异常?下面的例子演CZ(jin)两个查询的用法,一个返?tt class="literal">int|另一个返?String? 除了(jin)q回单值的查询Ҏ(gu)Q?tt class="classname">JdbcTemplateq提供了(jin)一l返回Listl果 的方法。List中的每一对应查询返回结果中的一行。其中最单的?tt class="literal">queryForListҎ(gu)Q?该方法将q回一?tt class="interfacename">ListQ该List中的每一?记录是一?tt class="interfacename">Map对象Q对应应数据库中某一行;而该Map 中的每一对应该数据库行中的某一列倹{下面的代码片断接着上面的例子演CZ(jin)如何用该Ҏ(gu)q回表中 所有记录:(x) q回的结果集cM下面q种形式Q? JdbcTemplateq提供了(jin)一些更新数据库的方法?在下面的例子中,我们Ҏ(gu)l定的主键值对指定的列q行更新?例子中的SQL语句中用了(jin)“?”占位W来接受参数Q这U做法在更新和查询SQL语句中很常见Q?传递的参数g于一个对象数l中Q基本类型需要被包装成其对应的对象类型)(j)? DataSourceUtils作ؓ(f)一个帮助类提供易用且强大的数据库访问能力, 我们可以使用该类提供?tt class="literal">?rn)?/tt>Ҏ(gu)从JNDI获取数据库连接以?qing)在必要的时候关闭之?它提供支持线E绑定的数据库连接(比如使用DataSourceTransactionManager 的时候,把数据库连接绑定到当前的线E上Q? 注:(x)getDataSourceFromJndi(..)Ҏ(gu)主要用于那些没有使用bean factory 或者application context的场合。如果用application contextQ那么最好是?JndiObjectFactoryBean中配|bean或者直接?JdbcTemplate实例?tt class="classname">JndiObjectFactoryBean 能够通过JNDI获取DataSourceq将 DataSource作ؓ(f)引用参数传递给其他bean?q样Q在不同?tt class="interfacename">DataSource之间切换只需要修攚w|文件即可, 甚至我们可以用一个非JNDI?tt class="interfacename">DataSource来替?FactoryBean定义Q? SmartDataSource?tt class="interfacename">DataSource 接口的一个扩展,用来提供数据库连接。用该接口的类在指定的操作之后可以(g)查是否需要关闭连接?该接口在某些情况下非常有用,比如有些情况需要重用数据库q接? AbstractDataSource是一个实C(jin)DataSource 接口?tt class="literal">abstract基类。它实现?tt class="interfacename">DataSource接口?一些无关痛痒的Ҏ(gu)Q如果你需要实现自qDataSourceQ那么?该类是个好主意? SingleConnectionDataSource?tt class="literal">SmartDataSource接口 的一个实玎ͼ其内部包装了(jin)一个单q接。该q接在用之后将不会(x)关闭Q很昄它不能在多线E?的环境下使用? 当客L(fng)代码调用closeҎ(gu)的时候,如果它L假设数据库连接来自连接池Q就像用持久化工具时一P(j)Q?你应该将suppressClose讄为true?q样Q通过该类获取的将是代理连接(止关闭Q而不是原有的物理q接?需要注意的是,我们不能把用该c获取的数据库连接造型QcastQؓ(f)Oracle Connection之类的本地数据库q接? SingleConnectionDataSource主要在测试的时候用?它得测试代码很Ҏ(gu)q应用服务器而在一个简单的JNDI环境下运行??tt class="classname">DriverManagerDataSource不同的是Q它始终只会(x)使用同一个数据库q接Q?从而避免每ơ徏立物理连接的开销? DriverManagerDataSourcecdC(jin) SmartDataSource接口。在applicationContext.xml中可以?bean properties来设|JDBC Driver属性,该类每次q回的都是一个新的连接? 该类主要在测试以?qing)脱J2EE容器的独立环境中使用。它既可以用来在application context中作Z?DataSource beanQ也可以在简单的JNDI环境下用?׃Connection.close()仅仅只是单的关闭数据库连接,因此M能够获取 DataSource的持久化代码都能很好的工作。不q用JavaBean风格的连接池 Q比如commons-dbcpQ也q难事。即使是在测试环境下Q用连接池也是一U比使用 DriverManagerDataSource更好的做法? TransactionAwareDataSourceProxy作ؓ(f)目标DataSource的一个代理, 在对目标DataSource包装的同Ӟq增加了(jin)Spring的事务管理能力, 在这一点上Q这个类的功能非常像J2EE服务器所提供的事务化的JNDI DataSource? 该类几乎很少被用刎ͼ除非现有代码在被调用的时候需要一个标准的 JDBC DataSource接口实现作ؓ(f)参数?q种情况下,q个cd以现有代码参与Spring的事务管理。通常最好的做法是用更高层的抽?来对数据源进行管理,比如JdbcTemplate?tt class="classname">DataSourceUtils{等? 如果需要更详细的资料,请参?tt class="classname">TransactionAwareDataSourceProxy JavaDoc ?/em> DataSourceTransactionManagercL PlatformTransactionManager接口的一个实玎ͼ用于处理单JDBC数据源?它将从指定DataSource取得的JDBCq接l定到当前线E,因此它也支持?jin)每个数据源对应C个线E? 我们推荐在应用代码中使用DataSourceUtils.getConnection(DataSource)来获?JDBCq接Q而不是用J2EE标准?tt class="literal">DataSource.getConnection。因为前者将抛出 unchecked?tt class="literal">org.springframework.dao异常Q而不是checked?SQLException异常。Spring Framework中所有的c(比如 JdbcTemplateQ都采用q种做法。如果不需要和q个 DataSourceTransactionManagercM起用,DataSourceUtils 提供的功能跟一般的数据库连接策略没有什么两P因此它可以在M场景下用? DataSourceTransactionManagercL持定刉ȝ别,以及(qing)对SQL语句查询时的设定?Z(jin)支持后者,应用代码必须使用JdbcTemplate或者在每次创徏SQL语句时调?DataSourceUtils.applyTransactionTimeoutҎ(gu)? 在用单个数据源的情形下Q你可以?tt class="classname">DataSourceTransactionManager来替?tt class="classname">JtaTransactionManagerQ?因ؓ(f)DataSourceTransactionManager不需要容器支持JTA。如果你使用DataSourceUtils.getConnection(DataSource)来获?JDBCq接Q二者之间的切换只需要更改一些配|。最后需要注意的一点就?tt class="classname">JtaTransactionManager不支持隔ȝ别的定制Q? org.springframework.jdbc.object包下的类允许用户以更?面向对象的方式去讉K数据库。比如说Q用户可以执行查询ƈq回一个listQ?该list作ؓ(f)一个结果集把从数据库中取出的列数据映到业务对象的属性上?用户也可以执行存储过E,以及(qing)q行更新、删除以?qing)插入SQL语句? 在许多Spring开发h员(sh)间存在有一U观点,那就是下面将要提到的各种RDBMS操作c?Q?a title="11.4.4. StoredProcedurec? >StoredProcedurec除外)(j) 通常也可以直接?tt class="classname">JdbcTemplate相关的方法来替换?相对于把一个查询操作封装成一个类而言Q直接调?tt class="classname">JdbcTemplateҎ(gu)更?而且更容易理解? 必须说明的一点就是,q仅仅只是一U?span class="emphasis">观点而已Q?如果你认Z可以从直接用RDBMS操作cM获取一些额外的好处Q?你不妨根据自q需要和喜好q行不同的选择? SqlQuery是一个可重用、线E安全的c,它封装了(jin)一个SQL查询?其子cdd?tt class="literal">newResultReader()Ҏ(gu)Q该Ҏ(gu)用来在遍?ResultSet的时候能使用一个类来保存结果?我们很少需要直接?tt class="classname">SqlQueryQ因为其子类 MappingSqlQuery作ؓ(f)一个更加易用的实现能够结果集中的行映ؓ(f)Java对象?SqlQueryq有另外两个扩展分别?MappingSqlQueryWithParameters?tt class="classname">UpdatableSqlQuery? MappingSqlQuery是一个可重用的查询抽象类Q其具体cdd?mapRow(ResultSet, int)抽象Ҏ(gu)来将l果集中的每一行{换成Java对象? ?tt class="interfacename">SqlQuery的各U实CQ?MappingSqlQuery是最常用也是最Ҏ(gu)使用的一个? 下面q个例子演示?jin)一个定制查询,它将从客戯中取得的数据映射C?Customercd例? 在上面的例子中,我们为用h询提供了(jin)一个构造函数ƈ为构造函C递了(jin)一?DataSource参数。在构造函数里面我们把 DataSource和一个用来返回查询结果的SQL语句作ؓ(f)参数 调用父类的构造函数。SQL语句被用于生成一?tt class="interfacename">PreparedStatement对象Q?因此它可以包含占位符来传递参数。而每一个SQL语句的参数必通过调用 declareParameterҎ(gu)来进行声明,该方法需要一?SqlParameterQ封装了(jin)一个字D名字和一?java.sql.Types中定义的JDBCcdQ对象作为参数?所有参数定义完之后Q我们调?tt class="literal">compile()Ҏ(gu)来对SQL语句q行预编译? 下面让我们看看该定制查询初始化ƈ执行的代码:(x) 在上面的例子中,getCustomerҎ(gu)通过传递惟一参数id来返回一个客户对象?该方法内部在创徏CustomerMappingQuery实例之后Q?我们创徏?jin)一个对象数l用来包含要传递的查询参数。这里我们只有唯一的一?Integer参数。执?tt class="classname">CustomerMappingQuery?executeҎ(gu)之后Q我们得C(jin)一?tt class="literal">ListQ该List中包含一?Customer对象Q如果有对象满查询条g的话? SqlUpdatecd装了(jin)一个可重复使用的SQL更新操作?跟所?tt class="classname">RdbmsOperationcMPSqlUpdate可以在SQL中定义参数? 该类提供?jin)一pdupdate()Ҏ(gu)Q就像SqlQuery提供的一pdexecute()Ҏ(gu)一栗? SqlUpdate是一个具体的cR通过在SQL语句中定义参敎ͼq个cd以支?不同的更新方法,我们一般不需要通过l承来实现定制? StoredProcedurecL一个抽象基c,它是对RDBMS存储q程的一U抽象?该类提供?jin)多U?tt class="literal">execute(..)Ҏ(gu)Q不q这些方法的讉Kcd都是protected的? 从父cȝ承的sql属性用来指定RDBMS存储q程的名字?管该类提供?jin)许多必dJDBC3.0下用的功能Q但是我们更x(chng)的是JDBC 3.0中引入的命名参数Ҏ(gu)? 下面的程序演CZ(jin)如何调用Oracle中的sysdate()函数?q里我们创徏?jin)一个?tt class="classname">StoredProcedure的子c,虽然它没有输入参敎ͼ 但是我必通过使用SqlOutParameter来声明一个日期类型的输出参数?execute()Ҏ(gu)返回一个mapQmap中的每个entry是一个用参数名作keyQ?以输出参Cؓ(f)value的名值对? 下面?tt class="classname">StoredProcedure的另一个例子,它用了(jin)两个Oracle游标cd的输出参数? 值得注意的是TitlesAndGenresStoredProcedure构造函C declareParameter(..)?tt class="classname">SqlOutParameter参数Q?该参C用了(jin)RowMapper接口的实现?q是一U非常方便而强大的重用方式?下面我们来看一?tt class="interfacename">RowMapper的两个具体实现? 首先?tt class="classname">TitleMapperc,它简单的?tt class="interfacename">ResultSet中的每一行映ؓ(f)一?tt class="classname">Title Domain Object? 另一个是GenreMapperc,也是非常单的?tt class="interfacename">ResultSet中的每一行映ؓ(f)一?tt class="classname">Genre Domain Object? 如果你需要给存储q程传输入参敎ͼq些输入参数是在RDBMS存储q程中定义好?jin)的Q, 则需要提供一个指定类型的execute(..)Ҏ(gu)Q?该方法将调用基类?tt class="literal">protected execute(Map parameters)Ҏ(gu)?例如Q? SqlFunction RDBMS操作cd装了(jin)一个SQL“函数”包装器(wrapperQ, 该包装器适用于查询ƈq回一个单行结果集。默认返回的是一?tt class="literal">int| 不过我们可以采用cMJdbcTemplate中的queryForXxx 做法自己实现来返回其它类型?tt class="classname">SqlFunction优势在于我们不必创徏 JdbcTemplateQ这些它都在内部替我们做?jin)? 该类的主要用途是调用SQL函数来返回一个单值的l果集,比如cM“select user()”?“select sysdate from dual”的查询。如果需要调用更复杂的存储函敎ͼ 可以使用StoredProcedure?tt class="classname">SqlCall? SqlFunction是一个具体类Q通常我们不需要它的子cR?其用法是创徏该类的实例,然后声明SQL语句以及(qing)参数可以调用相关的runҎ(gu)dơ执行函数?下面的例子用来返回指定表的记录行敎ͼ(x)
// some JDBC-backed DAO class...
public int countOfActorsByFirstName(String firstName) {
String sql = "select count(0) from T_ACTOR where first_name = :first_name";
NamedParameterJdbcTemplate template = new NamedParameterJdbcTemplate(this.getDataSource());
SqlParameterSource namedParameters = new MapSqlParameterSource("first_name", firstName);
return template.queryForInt(sql, namedParameters);
}
// some JDBC-backed DAO class...
public int countOfActorsByFirstName(String firstName) {
String sql = "select count(0) from T_ACTOR where first_name = :first_name";
NamedParameterJdbcTemplate template = new NamedParameterJdbcTemplate(this.getDataSource());
Map namedParameters = new HashMap();
namedParameters.put("first_name", firstName);
return template.queryForInt(sql, namedParameters);
}
// some JavaBean-like class...
public class Actor {
private Long id;
private String firstName;
private String lastName;
public String getFirstName() {
return this.firstName;
}
public String getLastName() {
return this.lastName;
}
public Long getId() {
return this.id;
}
// setters omitted...
}
// some JDBC-backed DAO class...
public int countOfActors(Actor exampleActor) {
// notice how the named parameters match the properties of the above 'Actor' class
String sql = "select count(0) from T_ACTOR where first_name = :firstName and last_name = :lastName";
NamedParameterJdbcTemplate template = new NamedParameterJdbcTemplate(this.getDataSource());
SqlParameterSource namedParameters = new BeanPropertySqlParameterSource(exampleActor);
return template.queryForInt(sql, namedParameters);
}
Note
// classic JdbcTemplate-style...
public Actor findActor(long id) {
String sql = "select id, first_name, last_name from T_ACTOR where id = ?";
RowMapper mapper = new RowMapper() {
public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
Actor actor = new Actor();
actor.setId(rs.getLong(Long.valueOf(rs.getLong("id"))));
actor.setFirstName(rs.getString("first_name"));
actor.setLastName(rs.getString("last_name"));
return actor;
}
};
// normally this would be dependency injected of course...
JdbcTemplate jdbcTemplate = new JdbcTemplate(this.getDataSource());
// notice the cast, and the wrapping up of the 'id' argument
// in an array, and the boxing of the 'id' argument as a reference type
return (Actor) jdbcTemplate.queryForObject(sql, mapper, new Object[] {Long.valueOf(id)});
}
// SimpleJdbcTemplate-style...
public Actor findActor(long id) {
String sql = "select id, first_name, last_name from T_ACTOR where id = ?";
ParameterizedRowMapper<Actor> mapper = new ParameterizedRowMapper<Actor>() {
// notice the return type with respect to Java 5 covariant return types
public Actor mapRow(ResultSet rs, int rowNum) throws SQLException {
Actor actor = new Actor();
actor.setId(rs.getLong("id"));
actor.setFirstName(rs.getString("first_name"));
actor.setLastName(rs.getString("last_name"));
return actor;
}
};
// again, normally this would be dependency injected of course...
SimpleJdbcTemplate simpleJdbcTemplate = new SimpleJdbcTemplate(this.getDataSource());
return simpleJdbcTemplate.queryForObject(sql, mapper, id);
}
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("org.hsqldb.jdbcDriver");
dataSource.setUrl("jdbc:hsqldb:hsql://localhost:");
dataSource.setUsername("sa");
dataSource.setPassword("");
public class MySQLErrorCodesTranslator extends SQLErrorCodeSQLExceptionTranslator {
protected DataAccessException customTranslate(String task, String sql, SQLException sqlex) {
if (sqlex.getErrorCode() == -12345) {
return new DeadlockLoserDataAccessException(task, sqlex);
}
return null;
}
}
// create a JdbcTemplate and set data source
JdbcTemplate jt = new JdbcTemplate();
jt.setDataSource(dataSource);
// create a custom translator and set the DataSource for the default translation lookup
MySQLErrorCodesTransalator tr = new MySQLErrorCodesTransalator();
tr.setDataSource(dataSource);
jt.setExceptionTranslator(tr);
// use the JdbcTemplate for this SqlUpdate
SqlUpdate su = new SqlUpdate();
su.setJdbcTemplate(jt);
su.setSql("update orders set shipping_charge = shipping_charge * 1.05");
su.compile();
su.update();
import javax.sql.DataSource;
import org.springframework.jdbc.core.JdbcTemplate;
public class ExecuteAStatement {
private JdbcTemplate jt;
private DataSource dataSource;
public void doExecute() {
jt = new JdbcTemplate(dataSource);
jt.execute("create table mytable (id integer, name varchar(100))");
}
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
}
import javax.sql.DataSource;
import org.springframework.jdbc.core.JdbcTemplate;
public class RunAQuery {
private JdbcTemplate jt;
private DataSource dataSource;
public int getCount() {
jt = new JdbcTemplate(dataSource);
int count = jt.queryForInt("select count(*) from mytable");
return count;
}
public String getName() {
jt = new JdbcTemplate(dataSource);
String name = (String) jt.queryForObject("select name from mytable", String.class);
return name;
}
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
}
public List getList() {
jt = new JdbcTemplate(dataSource);
List rows = jt.queryForList("select * from mytable");
return rows;
}
[{name=Bob, id=1}, {name=Mary, id=2}]
import javax.sql.DataSource;
import org.springframework.jdbc.core.JdbcTemplate;
public class ExecuteAnUpdate {
private JdbcTemplate jt;
private DataSource dataSource;
public void setName(int id, String name) {
jt = new JdbcTemplate(dataSource);
jt.update("update mytable set name = ? where id = ?", new Object[] {name, new Integer(id)});
}
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
}
Note
Note
private class CustomerMappingQuery extends MappingSqlQuery {
public CustomerMappingQuery(DataSource ds) {
super(ds, "SELECT id, name FROM customer WHERE id = ?");
super.declareParameter(new SqlParameter("id", Types.INTEGER));
compile();
}
public Object mapRow(ResultSet rs, int rowNumber) throws SQLException {
Customer cust = new Customer();
cust.setId((Integer) rs.getObject("id"));
cust.setName(rs.getString("name"));
return cust;
}
}
public Customer getCustomer(Integer id) {
CustomerMappingQuery custQry = new CustomerMappingQuery(dataSource);
Object[] parms = new Object[1];
parms[0] = id;
List customers = custQry.execute(parms);
if (customers.size() > 0) {
return (Customer) customers.get(0);
}
else {
return null;
}
}
import java.sql.Types;
import javax.sql.DataSource;
import org.springframework.jdbc.core.SqlParameter;
import org.springframework.jdbc.object.SqlUpdate;
public class UpdateCreditRating extends SqlUpdate {
public UpdateCreditRating(DataSource ds) {
setDataSource(ds);
setSql("update customer set credit_rating = ? where id = ?");
declareParameter(new SqlParameter(Types.NUMERIC));
declareParameter(new SqlParameter(Types.NUMERIC));
compile();
}
/**
* @param id for the Customer to be updated
* @param rating the new value for credit rating
* @return number of rows updated
*/
public int run(int id, int rating) {
Object[] params =
new Object[] {
new Integer(rating),
new Integer(id)};
return update(params);
}
}
import java.sql.Types;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import javax.sql.DataSource;
import org.springframework.jdbc.core.SqlOutParameter;
import org.springframework.jdbc.datasource.*;
import org.springframework.jdbc.object.StoredProcedure;
public class TestStoredProcedure {
public static void main(String[] args) {
TestStoredProcedure t = new TestStoredProcedure();
t.test();
System.out.println("Done!");
}
void test() {
DriverManagerDataSource ds = new DriverManagerDataSource();
ds.setDriverClassName("oracle.jdbc.OracleDriver");
ds.setUrl("jdbc:oracle:thin:@localhost:1521:mydb");
ds.setUsername("scott");
ds.setPassword("tiger");
MyStoredProcedure sproc = new MyStoredProcedure(ds);
Map results = sproc.execute();
printMap(results);
}
private class MyStoredProcedure extends StoredProcedure {
private static final String SQL = "sysdate";
public MyStoredProcedure(DataSource ds) {
setDataSource(ds);
setFunction(true);
setSql(SQL);
declareParameter(new SqlOutParameter("date", Types.DATE));
compile();
}
public Map execute() {
// the 'sysdate' sproc has no input parameters, so an empty Map is supplied...
return execute(new HashMap());
}
}
private static void printMap(Map results) {
for (Iterator it = results.entrySet().iterator(); it.hasNext(); ) {
System.out.println(it.next());
}
}
}
import oracle.jdbc.driver.OracleTypes;
import org.springframework.jdbc.core.SqlOutParameter;
import org.springframework.jdbc.object.StoredProcedure;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
public class TitlesAndGenresStoredProcedure extends StoredProcedure {
private static final String SPROC_NAME = "AllTitlesAndGenres";
public TitlesAndGenresStoredProcedure(DataSource dataSource) {
super(dataSource, SPROC_NAME);
declareParameter(new SqlOutParameter("titles", OracleTypes.CURSOR, new TitleMapper()));
declareParameter(new SqlOutParameter("genres", OracleTypes.CURSOR, new GenreMapper()));
compile();
}
public Map execute() {
// again, this sproc has no input parameters, so an empty Map is supplied...
return super.execute(new HashMap());
}
}
import com.foo.sprocs.domain.Title;
import org.springframework.jdbc.core.RowMapper;
import java.sql.ResultSet;
import java.sql.SQLException;
public final class TitleMapper implements RowMapper {
public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
Title title = new Title();
title.setId(rs.getLong("id"));
title.setName(rs.getString("name"));
return title;
}
}
import org.springframework.jdbc.core.RowMapper;
import java.sql.ResultSet;
import java.sql.SQLException;
import com.foo.domain.Genre;
public final class GenreMapper implements RowMapper {
public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
return new Genre(rs.getString("name"));
}
}
import oracle.jdbc.driver.OracleTypes;
import org.springframework.jdbc.core.SqlOutParameter;
import org.springframework.jdbc.object.StoredProcedure;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
public class TitlesAfterDateStoredProcedure extends StoredProcedure {
private static final String SPROC_NAME = "TitlesAfterDate";
private static final String CUTOFF_DATE_PARAM = "cutoffDate";
public TitlesAfterDateStoredProcedure(DataSource dataSource) {
super(dataSource, SPROC_NAME);
declaraParameter(new SqlParameter(CUTOFF_DATE_PARAM, Types.DATE);
declareParameter(new SqlOutParameter("titles", OracleTypes.CURSOR, new TitleMapper()));
compile();
}
public Map execute(Date cutoffDate) {
Map inputs = new HashMap();
inputs.put(CUTOFF_DATE_PARAM, cutoffDate);
return super.execute(inputs);
}
}
public int countRows() {
SqlFunction sf = new SqlFunction(dataSource, "select count(*) from mytable");
sf.compile();
return sf.run();
}
试Qtomcat5+jprofiler_windows_5_1_4 它的注册码可到官|上注册一个,免费试用Q当然是有期限的
有的时候Tomcat跑Web应用?x)慢慢死掉,CPU 100%占用。一般情况下是程序哪里出?jin)问题,慢慢的DEBUGQ几乎翻遍所有的代码Q是不是很篏Q这里介l一下JProfilerQ比较优U的性能监控和分析工兗?br /> JProfiler我用的是4.3.3版本Q他是收费的Q不qgoogle上面很多注册码可供用?br /> 安装的时候会(x)提示一些比如寻找JVM{过E,q里׃多说?jin)。安装完JProfilerQ运行,出现如下界面Q?/p>
׃我们是要创徏Ҏ(gu)地tomcat的监控,选择an application server,locally or remotely.
在接下来的窗口中Q选择tomcat?qing)版本?/p>
下一步,选择本地Q?/p>
下一步,选择启动批处理文?/p>
注意Q这里的选择如果你是TOMCAT5的话Q如果选择startup.bat跑不hQ你不防把它配置成tomcat.exe我就是在q里卡住?/span>
下一步,选择JVMcdQ?/p>
接着选择JProfiler的监听端口:(x)
接着Q选择直接启动Q?/p>
下面?x)有一个很重要的提C,可能很多人在q里都没有注意而L配置不好JProfilerQ?/p>
上面标红的配|好后,q下面的Ҏ(gu)不用配置可以跑h?/span>
W一Q需要把
-agentlib:jprofilerti=port=8849,nowait,id=103,config=C:\Documents and Settings\stefanie_wu\.jprofiler4\config.xml"
"-Xbootclasspath/a:D:\Program Files\jprofiler4\bin\agent.jar" -Xbootclasspath/a:D:\usr\agent.jar
两个参数加蝲启动中Q?br />
W二Q要把D:\Program Files\jprofiler4\bin\windows攑֜PATH中?/p>
我是使用.bat来启动tomcat的,所以在startup.bat中加入一D代码:(x)
set JAVA_OPTS=%JAVA_OPTS% -agentlib:jprofilerti=port=8849,nowait,id=103,config=C:\Documents and Settings\stefanie_wu\.jprofiler4\config.xml -Xbootclasspath/a:D:\Program Files\jprofiler4\bin\agent.jar" -Xbootclasspath/a:D:\usr\agent.jar
但是q样启动?x)有问题Q因为其中\径包含了(jin)I格Q?br />
所以拷贝comfig.xml和agent.jarC个新的\径下面,比如Q?br />
set JAVA_OPTS=%JAVA_OPTS% -agentlib:jprofilerti=port=8849,nowait,id=102,config=D:\usr\config.xml -Xbootclasspath/a:D:\usr\agent.jar
q里的jprofilerti=port=8849是刚才讄的jprofiler监控端口?br /> 讄完这些,通过startup.bat启动tomcatQ然?/p>
点OK
window.onbeforeunload = function()
{ var n = window.event.screenX - window.screenLeft;
var b = n > document.documentElement.scrollWidth-20;
if(b && window.event.clientY < 0 || window.event.altKey)
{
//window.event.returnValue = "1111";
userBaseDAO.upIsLogin(${adminbean.id});
}
}
三大L览器中firefox和IE都支持onbeforeunload事g,opera未支持?/strong>
用法Q?/p>
描述Q?br /> 事g触发的时候弹Z个有定和取消的对话框,定则离开面Q取消则l箋(hu)待在本页?br /> handler可以设一个返回g对话框的昄文本?/p>
触发于:(x)
可以用在以下元素Q?br /> BODY, FRAMESET, window
q_支持Q?br /> IE4+/Win, Mozilla 1.7a+, Netscape 7.2+, Firefox0.9+