﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>语源科技BlogJava-点滴</title><link>http://www.blogjava.net/huaxiaoxi/</link><description /><language>zh-cn</language><lastBuildDate>Sun, 12 Apr 2026 13:13:12 GMT</lastBuildDate><pubDate>Sun, 12 Apr 2026 13:13:12 GMT</pubDate><ttl>60</ttl><item><title>Spring声明式处理</title><link>http://www.blogjava.net/huaxiaoxi/archive/2008/12/15/246510.html</link><dc:creator>developer</dc:creator><author>developer</author><pubDate>Mon, 15 Dec 2008 15:01:00 GMT</pubDate><guid>http://www.blogjava.net/huaxiaoxi/archive/2008/12/15/246510.html</guid><wfw:comment>http://www.blogjava.net/huaxiaoxi/comments/246510.html</wfw:comment><comments>http://www.blogjava.net/huaxiaoxi/archive/2008/12/15/246510.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/huaxiaoxi/comments/commentRss/246510.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/huaxiaoxi/services/trackbacks/246510.html</trackback:ping><description><![CDATA[关于spring事务管理以及异常处理的帖子，本论坛争论颇多，各有各的测试代码，也各有各的测试结果， <br />
不知道是spring版本的不同还是各测试的例子的不同而导致测试结果出现差异． <br />
本人也很想弄清楚spring是如何对Service进行事务管理的，并且还去看了一下spring框架关于事务管理几个相关类的源码，可惜由于本人功力有限，只看懂了皮毛． <br />
既然源代码看不懂，那么只有运用例子进行测试，虽然笨了点，不过管是白猫还是黑猫，能捉老鼠就是好猫．：） <br />
为引起不必要的争论，本帖子只针对本案例的测试结果进行小结，并保证此测试代码在本人的运行环境绝对正确． <br />
<br />
开发环境： <br />
ＯＳ：windows 2003 Server <br />
Web Server: jakarta-tomcat-5.0.28 <br />
DataBase Server: MS SQL Server 2000 (打了ＳＰ３补丁) <br />
IDE:&nbsp; Eclipse 3.2.0+MyEclipse 5.0GA <br />
<br />
测试案例系统结构： <br />
web层&lt;----&gt;Service层&lt;----&gt;DAO层 <br />
<br />
web层使用struts 1.1，DAO使用的spring的JDBC，spring版本1.2 <br />
<br />
数据库中有两张表： <br />
student1和Student2，表结构相同：id,name,address．其中id为主键且为自增长型. <br />
student1表中有一条记录： <br />
Java代码&nbsp; <br />
1.&nbsp;&nbsp;&nbsp; id&nbsp; name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; address&nbsp; <br />
2.&nbsp;&nbsp;&nbsp; 1&nbsp;&nbsp; xiaoming&nbsp;&nbsp;&nbsp; wuhan&nbsp; <br />
3.&nbsp;&nbsp;&nbsp; &nbsp; <br />
4.&nbsp;&nbsp;&nbsp; student2表中记录为空&nbsp; <br />
<br />
<br />
测试情形一： <br />
web层捕获异常并处理，DAO层不捕获异常，Service也不捕获异常． <br />
<br />
Service层接口： <br />
Java代码&nbsp; <br />
1.&nbsp;&nbsp;&nbsp; public interface StudentManagerService {&nbsp; <br />
2.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br />
3.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; public void&nbsp; bus_method();&nbsp; <br />
4.&nbsp;&nbsp;&nbsp; }&nbsp; <br />
<br />
<br />
DAO层接口 <br />
Java代码&nbsp; <br />
1.&nbsp;&nbsp;&nbsp; public interface StudentDAO {&nbsp; <br />
2.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br />
3.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; public void&nbsp; deleteStudent1();&nbsp; <br />
4.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; public void&nbsp; insertStudent2();&nbsp; <br />
5.&nbsp;&nbsp;&nbsp; }&nbsp; <br />
<br />
<br />
StudentDAO接口的实现： <br />
Java代码&nbsp; <br />
1.&nbsp;&nbsp;&nbsp; public class StudentDAOImp extends JdbcDaoSupport implements StudentDAO{&nbsp; <br />
2.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; //删除student1表中的id=1的记录&nbsp; <br />
3.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; public void&nbsp; deleteStudent1(){&nbsp; <br />
4.&nbsp;&nbsp;&nbsp; 　　　　　JdbcTemplate jt=this.getJdbcTemplate();&nbsp; <br />
5.&nbsp;&nbsp;&nbsp; 　　　　　jt.update("delete from student1 where id=1");&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
6.&nbsp;&nbsp;&nbsp; 　　　}&nbsp; <br />
7.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
8.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; //将student1表中删除的记录插入到student2中,但是此方法实现有错，因为&nbsp; <br />
9.&nbsp;&nbsp;&nbsp; 　　　//id字段设置为自增长的，所以在插入记录时我们不能指定值&nbsp; <br />
10.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 　 public void&nbsp; insertStudent2(){&nbsp; <br />
11.&nbsp;&nbsp;&nbsp; 　　　　　　　JdbcTemplate jt=this.getJdbcTemplate();&nbsp; <br />
12.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String arg[]=new String[3];&nbsp; <br />
13.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; arg[0]="1";&nbsp; <br />
14.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; arg[1]="xiaoming";&nbsp; <br />
15.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; arg[2]="wuhan";&nbsp; <br />
16.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jt.update("insert student2(id,name,address) values(?,?,?)",arg);&nbsp; <br />
17.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; }&nbsp; <br />
18.&nbsp;&nbsp;&nbsp; &nbsp; <br />
19.&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
<br />
<br />
StudentManagerService 接口的实现： <br />
Java代码&nbsp; <br />
1.&nbsp;&nbsp;&nbsp; public class StudentManagerServiceImp implements StudentManagerService{&nbsp; <br />
2.&nbsp;&nbsp;&nbsp; &nbsp; private StudentDAO&nbsp; stdDAO;&nbsp; <br />
3.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; <br />
4.&nbsp;&nbsp;&nbsp; &nbsp; public void setStdDAO(StudentDAO&nbsp;&nbsp; stdDAO){&nbsp; <br />
5.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; this.stdDAO=stdDAO;&nbsp; <br />
6.&nbsp;&nbsp;&nbsp; &nbsp; }&nbsp; <br />
7.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; <br />
8.&nbsp;&nbsp;&nbsp; &nbsp; //此方法为事务型的：删除student1中的记录成功且插入student2的记录也成功，&nbsp; <br />
9.&nbsp;&nbsp;&nbsp; 　//如果insertStudent2()方法执行失败，那么deleteStudent1()方法也应该会失败&nbsp; <br />
10.&nbsp;&nbsp;&nbsp; &nbsp; public void&nbsp; bus_method(){&nbsp; <br />
11.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; this.stdDAO.deleteStudent1();&nbsp; <br />
12.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; this.stdDAO.insertStudent2();&nbsp; <br />
13.&nbsp;&nbsp;&nbsp; &nbsp; }&nbsp; <br />
14.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br />
15.&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
<br />
<br />
<br />
web层: <br />
三个jsp,一个action: <br />
index.jsp ==&gt;首页面．上面仅仅有一个超链接&lt;a herf="test.do"&gt;执行&lt;/a&gt; <br />
chenggong.jsp ==&gt;Service执行成功后转向的JSP页面 <br />
shibai.jsp　====&gt;Service执行失败后转向的JSP页面 <br />
<br />
action实现： <br />
Java代码&nbsp; <br />
1.&nbsp;&nbsp;&nbsp; public class StudentManagerAction&nbsp; extends&nbsp; Action{&nbsp; <br />
2.&nbsp;&nbsp;&nbsp; &nbsp; <br />
3.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; public ActionForward execute(ActionMapping mapping, ActionForm form,&nbsp; <br />
4.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; HttpServletRequest request, HttpServletResponse response) {&nbsp; <br />
5.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try{&nbsp; <br />
6.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WebApplicationContext appContext=WebApplicationContextUtils.&nbsp;&nbsp; <br />
7.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; getWebApplicationContext(this.getServlet().getServletContext());&nbsp; <br />
8.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; StudentManagerService stdm=(StudentManagerService)appContext.&nbsp; <br />
9.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; getBean("stdServiceManager");&nbsp; <br />
10.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stdm.bus_method();&nbsp; <br />
11.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return mapping.findForward("chenggong");&nbsp; <br />
12.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; }&nbsp; <br />
13.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; catch(DataAccessException e){&nbsp; <br />
14.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.err.println("action execute service exception!");&nbsp; <br />
15.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return mapping.findForward("shibai");&nbsp; <br />
16.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp; <br />
17.&nbsp;&nbsp;&nbsp; &nbsp; <br />
18.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }&nbsp; <br />
19.&nbsp;&nbsp;&nbsp; }&nbsp; <br />
<br />
<br />
<br />
配置文件： <br />
<br />
web.xml <br />
Java代码&nbsp; <br />
1.&nbsp;&nbsp;&nbsp; &lt;?xml version="1.0" encoding="UTF-8"?&gt;&nbsp; <br />
2.&nbsp;&nbsp;&nbsp; &lt;web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.4" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee&nbsp;&nbsp; http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"&gt;&nbsp; <br />
3.&nbsp;&nbsp;&nbsp; &nbsp; &lt;context-param&gt;&nbsp; <br />
4.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;param-name&gt;log4jConfigLocation&lt;/param-name&gt;&nbsp; <br />
5.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;param-value&gt;/WEB-INF/log4j.properties&lt;/param-value&gt;&nbsp; <br />
6.&nbsp;&nbsp;&nbsp; &nbsp; &lt;/context-param&gt;&nbsp; <br />
7.&nbsp;&nbsp;&nbsp; &nbsp; &lt;context-param&gt;&nbsp; <br />
8.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;param-name&gt;contextConfigLocation&lt;/param-name&gt;&nbsp; <br />
9.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;param-value&gt;/WEB-INF/applicationContext.xml&lt;/param-value&gt;&nbsp; <br />
10.&nbsp;&nbsp;&nbsp; &nbsp; &lt;/context-param&gt;&nbsp; <br />
11.&nbsp;&nbsp;&nbsp; &nbsp; &lt;listener&gt;&nbsp; <br />
12.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;listener-class&gt;org.springframework.web.util.Log4jConfigListener&lt;/listener-class&gt;&nbsp; <br />
13.&nbsp;&nbsp;&nbsp; &nbsp; &lt;/listener&gt;&nbsp; <br />
14.&nbsp;&nbsp;&nbsp; &nbsp; &lt;listener&gt;&nbsp; <br />
15.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;listener-class&gt;org.springframework.web.context.ContextLoaderListener&lt;/listener-class&gt;&nbsp; <br />
16.&nbsp;&nbsp;&nbsp; &nbsp; &lt;/listener&gt;&nbsp; <br />
17.&nbsp;&nbsp;&nbsp; &nbsp; &lt;servlet&gt;&nbsp; <br />
18.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;servlet-name&gt;action&lt;/servlet-name&gt;&nbsp; <br />
19.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;servlet-class&gt;org.apache.struts.action.ActionServlet&lt;/servlet-class&gt;&nbsp; <br />
20.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;init-param&gt;&nbsp; <br />
21.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;param-name&gt;config&lt;/param-name&gt;&nbsp; <br />
22.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;param-value&gt;/WEB-INF/struts-config.xml&lt;/param-value&gt;&nbsp; <br />
23.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;/init-param&gt;&nbsp; <br />
24.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;init-param&gt;&nbsp; <br />
25.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;param-name&gt;debug&lt;/param-name&gt;&nbsp; <br />
26.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;param-value&gt;3&lt;/param-value&gt;&nbsp; <br />
27.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;/init-param&gt;&nbsp; <br />
28.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;init-param&gt;&nbsp; <br />
29.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;param-name&gt;detail&lt;/param-name&gt;&nbsp; <br />
30.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;param-value&gt;3&lt;/param-value&gt;&nbsp; <br />
31.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;/init-param&gt;&nbsp; <br />
32.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;load-on-startup&gt;0&lt;/load-on-startup&gt;&nbsp; <br />
33.&nbsp;&nbsp;&nbsp; &nbsp; &lt;/servlet&gt;&nbsp; <br />
34.&nbsp;&nbsp;&nbsp; &nbsp; &lt;servlet-mapping&gt;&nbsp; <br />
35.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;servlet-name&gt;action&lt;/servlet-name&gt;&nbsp; <br />
36.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;url-pattern&gt;*.do&lt;/url-pattern&gt;&nbsp; <br />
37.&nbsp;&nbsp;&nbsp; &nbsp; &lt;/servlet-mapping&gt;&nbsp; <br />
38.&nbsp;&nbsp;&nbsp; &lt;/web-app&gt;&nbsp; <br />
<br />
<br />
sturts-config.xml <br />
Java代码&nbsp; <br />
1.&nbsp;&nbsp;&nbsp; &lt;struts-config&gt;&nbsp; <br />
2.&nbsp;&nbsp;&nbsp; &nbsp; &lt;action-mappings &gt;&nbsp; <br />
3.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;action&nbsp; input="/index.jsp"&nbsp; path="/test"&nbsp; type="test.StudentManagerAction&nbsp;&nbsp; &gt;&nbsp; <br />
4.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;forward name="chenggong" path="/chenggong.jsp" /&gt;&nbsp; <br />
5.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;forward name="shibai" path="/shibai.jsp" /&gt;&nbsp; <br />
6.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;/action&gt;&nbsp; <br />
7.&nbsp;&nbsp;&nbsp; &nbsp; &lt;/action-mappings&gt;&nbsp; <br />
8.&nbsp;&nbsp;&nbsp; &nbsp; &lt;message-resources parameter="test.ApplicationResources" /&gt;&nbsp; <br />
9.&nbsp;&nbsp;&nbsp; &lt;/struts-config&gt;&nbsp; <br />
<br />
<br />
<br />
applicationContext.xml <br />
Java代码&nbsp; <br />
1.&nbsp;&nbsp;&nbsp; &lt;?xml version="1.0" encoding="UTF-8"?&gt;&nbsp; <br />
2.&nbsp;&nbsp;&nbsp; &lt;!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"&gt;&nbsp; <br />
3.&nbsp;&nbsp;&nbsp; &lt;beans&gt;&nbsp; <br />
4.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;bean id="dataSource"&nbsp; <br />
5.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" &gt;&nbsp; <br />
6.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="driverClassName" value="com.microsoft.jdbc.sqlserver.SQLServerDriver"&gt;&lt;/property&gt;&nbsp; <br />
7.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="url" value="jdbc:microsoft:sqlserver://127.0.0.1:1433;databasename=test"&gt;&lt;/property&gt;&nbsp; <br />
8.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="username" value="sa"&gt;&lt;/property&gt;&nbsp; <br />
9.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="password" value="sa"&gt;&lt;/property&gt;&nbsp; <br />
10.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;/bean&gt;&nbsp; <br />
11.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
12.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; &lt;bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"&gt;&nbsp; <br />
13.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="dataSource" ref="dataSource"/&gt;&nbsp; <br />
14.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; &lt;/bean&gt;&nbsp; <br />
15.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
16.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;bean id="baseTxProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"&nbsp; lazy-init="true"&gt;&nbsp; <br />
17.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="transactionManager"&gt;&nbsp; <br />
18.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;ref bean="transactionManager" /&gt;&nbsp; <br />
19.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/property&gt;&nbsp; <br />
20.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="transactionAttributes"&gt;&nbsp; <br />
21.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;props&gt;&nbsp; <br />
22.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;prop key="*"&gt;PROPAGATION_REQUIRED&lt;/prop&gt;&nbsp; <br />
23.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/props&gt;&nbsp; <br />
24.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/property&gt;&nbsp; <br />
25.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;/bean&gt;&nbsp; <br />
26.&nbsp;&nbsp;&nbsp; &nbsp; <br />
27.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;bean id="stdServiceManager"&nbsp; parent="baseTxProxy" &gt;&nbsp; <br />
28.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="target"&gt;&nbsp; <br />
29.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;bean class="test.StudentManagerServiceImp"&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
30.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="stdDAO"&gt;&nbsp; <br />
31.&nbsp;&nbsp;&nbsp; 　　　　　　　　　&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;ref bean="stdDAO"/&gt;&nbsp; <br />
32.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/property&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
33.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/bean&gt;&nbsp;&nbsp; <br />
34.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/property&gt;&nbsp;&nbsp; <br />
35.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;/bean&gt;&nbsp; <br />
36.&nbsp;&nbsp;&nbsp; &nbsp; <br />
37.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;bean id="stdDAO" class="test.StudentDAOImp"&gt;&nbsp; <br />
38.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="dataSource" ref="dataSource"/&gt;&nbsp; <br />
39.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;/bean&gt;&nbsp; <br />
40.&nbsp;&nbsp;&nbsp; &lt;/beans&gt;&nbsp; <br />
<br />
<br />
运行程序：启动服务器，并部署．进入index.jsp页面，点击"执行"超链接"----&gt;页面跳向shibai.jsp <br />
查看控制台：打印有：action execute service exception! <br />
查看数据库：　student1表中的[1 xiaoming&nbsp; wuhan] 记录仍然存在，student2表仍然为空． <br />
小结：如果DAO层和Service不捕获异常而在web层捕获异常，web成功捕获异常，spring事务管理成功！ <br />
<br />
<br />
测试情形二： <br />
web层捕获异常并处理，Service捕获异常并处理，DAO层不捕获异常． <br />
<br />
修改StudentManagerServiceImp类 <br />
Java代码&nbsp; <br />
1.&nbsp;&nbsp;&nbsp; public class StudentManagerServiceImp implements StudentManagerService{&nbsp; <br />
2.&nbsp;&nbsp;&nbsp; &nbsp; private StudentDAO&nbsp; stdDAO;&nbsp; <br />
3.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; <br />
4.&nbsp;&nbsp;&nbsp; &nbsp; public void setStdDAO(StudentDAO&nbsp;&nbsp; stdDAO){&nbsp; <br />
5.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; this.stdDAO=stdDAO;&nbsp; <br />
6.&nbsp;&nbsp;&nbsp; &nbsp; }&nbsp; <br />
7.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; <br />
8.&nbsp;&nbsp;&nbsp; &nbsp; //此方法为事务型的，删除student1中的记录成功且插入student2的记录也成功&nbsp; <br />
9.&nbsp;&nbsp;&nbsp; 　//如果insertStudent2()方法执行失败，那么deleteStudent1()也应该会失败&nbsp; <br />
10.&nbsp;&nbsp;&nbsp; &nbsp; public void&nbsp; bus_method(){&nbsp; <br />
11.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; try{&nbsp; <br />
12.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.stdDAO.deleteStudent1();&nbsp; <br />
13.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.stdDAO.insertStudent2();&nbsp; <br />
14.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; }&nbsp; <br />
15.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; catch(DataAccessException de)&nbsp; <br />
16.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.err.println("service execute exception!");&nbsp; <br />
17.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }&nbsp; <br />
18.&nbsp;&nbsp;&nbsp; &nbsp; }&nbsp; <br />
19.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br />
20.&nbsp;&nbsp;&nbsp; }&nbsp; <br />
<br />
<br />
运行程序：启动服务器，并部署．进入index.jsp页面，点击"执行"超链接"----&gt;页面跳向chenggong.jsp <br />
查看控制台：打印有：service execute exception! <br />
查看数据库：　student1表中的[1&nbsp; xiaoming&nbsp; wuhan] 记录不存在，student2表仍然为空． <br />
小结：如果Service捕获异常并处理而不向外抛出，web层捕获不到异常，spring事务管理失败！ <br />
<br />
<br />
测试情形(还原表中的数据)三： <br />
web层捕获异常，Service捕获异常，DAO层也捕获异常． <br />
<br />
修改StudentDAOImp类代码 <br />
Java代码&nbsp; <br />
1.&nbsp;&nbsp;&nbsp; public class StudentDAOImp extends JdbcDaoSupport implements StudentDAO{&nbsp; <br />
2.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; //删除student1表中的id=1的记录&nbsp; <br />
3.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; public void&nbsp; deleteStudent1(){&nbsp; <br />
4.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try{&nbsp; <br />
5.&nbsp;&nbsp;&nbsp; 　　　　　JdbcTemplate jt=this.getJdbcTemplate();&nbsp; <br />
6.&nbsp;&nbsp;&nbsp; 　　　　　jt.update("delete from student1 where id=1");&nbsp; <br />
7.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp; <br />
8.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch(DataAccessException e){&nbsp; <br />
9.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.err.println("dao deleteStudent1　execute exception!");&nbsp; <br />
10.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
11.&nbsp;&nbsp;&nbsp; 　　　}&nbsp; <br />
12.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
13.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; //将student1表中删除的记录插入到student2中,但是此方法实现有错，因为&nbsp; <br />
14.&nbsp;&nbsp;&nbsp; 　　　//id字段设置为自增长的，所以在插入记录时我们不能指定值&nbsp; <br />
15.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 　 public void&nbsp; insertStudent2(){&nbsp; <br />
16.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try{&nbsp; <br />
17.&nbsp;&nbsp;&nbsp; 　　　　　　　JdbcTemplate jt=this.getJdbcTemplate();&nbsp; <br />
18.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String arg[]=new String[3];&nbsp; <br />
19.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; arg[0]="1";&nbsp; <br />
20.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; arg[1]="xiaoming";&nbsp; <br />
21.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; arg[2]="wuhan";&nbsp; <br />
22.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jt.update("insert student2(id,name,address) values(?,?,?)",arg);&nbsp; <br />
23.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp; <br />
24.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch(DataAccessException&nbsp; e){&nbsp; <br />
25.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.err.println("dao insertStudent2&nbsp; execute exception!");&nbsp; <br />
26.&nbsp;&nbsp;&nbsp; &nbsp; <br />
27.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp; <br />
28.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; }&nbsp; <br />
29.&nbsp;&nbsp;&nbsp; &nbsp; <br />
30.&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
<br />
<br />
运行程序：启动服务器，并部署．进入index.jsp页面，点击"执行"超链接"----&gt;页面跳向chenggong.jsp <br />
查看控制台：打印有：dao insertStudent2&nbsp; execute exception! <br />
查看数据库：　student1表中的 1,xiaoming,wuhan 记录不存在，student2表仍然为空． <br />
小结如果DAO的每一个方法自己捕获异常并处理而不向外抛出，Service层捕获不到异常，Web层同样捕获不到异常，spring事务管理失败！ <br />
<br />
<br />
测试情形四： <br />
<br />
还原数据库中的数据 <br />
还原StudentDAOImp类中的方法为测试情形一中的实现 <br />
web层捕获异常Service抛出的自定义异常StudentManagerException <br />
Service捕获DataAccessException并抛出StudentManagerException， <br />
StudentManagerException为DataAccessException的子类 <br />
DAO层不捕获异常 <br />
<br />
修改StudentManagerServiceImp类的实现： <br />
Java代码&nbsp; <br />
1.&nbsp;&nbsp;&nbsp; public class StudentManagerServiceImp implements StudentManagerService{&nbsp; <br />
2.&nbsp;&nbsp;&nbsp; &nbsp; private StudentDAO&nbsp; stdDAO;&nbsp; <br />
3.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; <br />
4.&nbsp;&nbsp;&nbsp; &nbsp; public void setStdDAO(StudentDAO&nbsp;&nbsp; stdDAO){&nbsp; <br />
5.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; this.stdDAO=stdDAO;&nbsp; <br />
6.&nbsp;&nbsp;&nbsp; &nbsp; }&nbsp; <br />
7.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; <br />
8.&nbsp;&nbsp;&nbsp; &nbsp; //此方法为事务型的，删除student1中的记录成功且插入student2的记录也成功&nbsp; <br />
9.&nbsp;&nbsp;&nbsp; 　//如果insertStudent2()方法执行失败，那么deleteStudent1()也应该会失败&nbsp; <br />
10.&nbsp;&nbsp;&nbsp; &nbsp; public void&nbsp; bus_method() throws StudentManagerException{&nbsp; <br />
11.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; try{&nbsp; <br />
12.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.stdDAO.deleteStudent1();&nbsp; <br />
13.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.stdDAO.insertStudent2();&nbsp; <br />
14.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; }&nbsp; <br />
15.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; catch(DataAccessException de)&nbsp; <br />
16.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.err.println("service execute exception!");&nbsp; <br />
17.&nbsp;&nbsp;&nbsp; 　　　　　throw new StudentManagerException();//StudentManagerException类继承DataAcce　　　　　　　　　　　　　　　　　　　　　　　　　　//ssException异常&nbsp; <br />
18.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }&nbsp; <br />
19.&nbsp;&nbsp;&nbsp; &nbsp; }&nbsp; <br />
20.&nbsp;&nbsp;&nbsp; }&nbsp; <br />
<br />
<br />
<br />
修改StudentManagerAction&nbsp; <br />
Java代码&nbsp; <br />
1.&nbsp;&nbsp;&nbsp; public class StudentManagerAction&nbsp; extends&nbsp; Action{&nbsp; <br />
2.&nbsp;&nbsp;&nbsp; &nbsp; <br />
3.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; public ActionForward execute(ActionMapping mapping, ActionForm form,&nbsp; <br />
4.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; HttpServletRequest request, HttpServletResponse response) {&nbsp; <br />
5.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try{&nbsp; <br />
6.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WebApplicationContext appContext=WebApplicationContextUtils.&nbsp;&nbsp; <br />
7.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; getWebApplicationContext(this.getServlet().getServletContext());&nbsp; <br />
8.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; StudentManagerService stdm=(StudentManagerService)appContext.&nbsp; <br />
9.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; getBean("stdServiceManager");&nbsp; <br />
10.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stdm.bus_method();&nbsp; <br />
11.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return mapping.findForward("chenggong");&nbsp; <br />
12.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; }&nbsp; <br />
13.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; catch(StudentManagerException　e){&nbsp; <br />
14.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.err.println("action execute service exception!");&nbsp; <br />
15.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return mapping.findForward("shibai");&nbsp; <br />
16.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp; <br />
17.&nbsp;&nbsp;&nbsp; &nbsp; <br />
18.&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }&nbsp; <br />
19.&nbsp;&nbsp;&nbsp; }&nbsp; <br />
<br />
运行程序：启动服务器，并部署．进入index.jsp页面，点击"执行"超链接"----&gt;页面跳向shibai.jsp <br />
查看控制台：打印有：service execute exception! <br />
action execute service exception! <br />
查看数据库：　student1表中的 [1,xiaoming,wuhan] 记录仍然存在，student2表仍然为空． <br />
小结如果DAO的每一个方法不捕获异常,Service层捕获DataAccessException异常并抛出自己定义异常(自定义异常为DataAccessException的子类)，Web层可以捕获到异常，spring事务管理成功！ <br />
<br />
<br />
<br />
结合源码总结： <br />
1.spring在进行声明时事务管理时，通过捕获Service层方法的DataAccessException来提交和回滚事务的，而Service层方法的DataAccessException又是来自调用DAO层方法所产生的异常． <br />
<br />
2.我们一般在写DAO层代码时，如果继承JdbcDaoSupport 类，并使用此类所实现的JdbcTemplate来执行数据库操作，此类会自动把低层的SQLException转化成 DataAccessException以及DataAccessException <br />
的子类． <br />
<br />
3.一般在Service层我们可以自己捕获DAO方法所产成的DataAccessException，然后再抛出一个业务方法有意义的异常 (ps:此异常最好继承DataAccessException)，然后在Web层捕获，这样我们就可以手动编码的灵活实现通过业务方法执行的成功和失败 来向用户转发不同的页面．<br />
<br />
<img src ="http://www.blogjava.net/huaxiaoxi/aggbug/246510.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/huaxiaoxi/" target="_blank">developer</a> 2008-12-15 23:01 <a href="http://www.blogjava.net/huaxiaoxi/archive/2008/12/15/246510.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JDBC  笔记 </title><link>http://www.blogjava.net/huaxiaoxi/archive/2008/11/20/241623.html</link><dc:creator>developer</dc:creator><author>developer</author><pubDate>Thu, 20 Nov 2008 05:31:00 GMT</pubDate><guid>http://www.blogjava.net/huaxiaoxi/archive/2008/11/20/241623.html</guid><wfw:comment>http://www.blogjava.net/huaxiaoxi/comments/241623.html</wfw:comment><comments>http://www.blogjava.net/huaxiaoxi/archive/2008/11/20/241623.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/huaxiaoxi/comments/commentRss/241623.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/huaxiaoxi/services/trackbacks/241623.html</trackback:ping><description><![CDATA[<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="ProgId" content="Word.Document" />
<meta name="Generator" content="Microsoft Word 11" />
<meta name="Originator" content="Microsoft Word 11" />
<link rel="File-List" href="file:///C:%5CDOCUME%7E1%5Ca%5CLOCALS%7E1%5CTemp%5Cmsohtml1%5C01%5Cclip_filelist.xml" /><!--[if gte mso 9]><xml>
<w:WordDocument>
<w:View>Normal</w:View>
<w:Zoom>0</w:Zoom>
<w:PunctuationKerning/>
<w:DrawingGridVerticalSpacing>7.8 磅</w:DrawingGridVerticalSpacing>
<w:DisplayHorizontalDrawingGridEvery>0</w:DisplayHorizontalDrawingGridEvery>
<w:DisplayVerticalDrawingGridEvery>2</w:DisplayVerticalDrawingGridEvery>
<w:ValidateAgainstSchemas/>
<w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid>
<w:IgnoreMixedContent>false</w:IgnoreMixedContent>
<w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText>
<w:Compatibility>
<w:SpaceForUL/>
<w:BalanceSingleByteDoubleByteWidth/>
<w:DoNotLeaveBackslashAlone/>
<w:ULTrailSpace/>
<w:DoNotExpandShiftReturn/>
<w:AdjustLineHeightInTable/>
<w:BreakWrappedTables/>
<w:SnapToGridInCell/>
<w:WrapTextWithPunct/>
<w:UseAsianBreakRules/>
<w:DontGrowAutofit/>
<w:UseFELayout/>
</w:Compatibility>
<w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel>
</w:WordDocument>
</xml><![endif]--><!--[if gte mso 9]><xml>
<w:LatentStyles deflockedstate="false" latentstylecount="156">
</w:LatentStyles>
</xml><![endif]--><style>
<!-- /* Font Definitions */
@font-face
{font-family:宋体;
panose-1:2 1 6 0 3 1 1 1 1 1;
mso-font-alt:SimSun;
mso-font-charset:134;
mso-generic-font-family:auto;
mso-font-pitch:variable;
mso-font-signature:3 135135232 16 0 262145 0;}
@font-face
{font-family:"\@宋体";
panose-1:2 1 6 0 3 1 1 1 1 1;
mso-font-charset:134;
mso-generic-font-family:auto;
mso-font-pitch:variable;
mso-font-signature:3 135135232 16 0 262145 0;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{mso-style-parent:"";
margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
mso-pagination:none;
font-size:10.5pt;
mso-bidi-font-size:12.0pt;
font-family:"Times New Roman";
mso-fareast-font-family:宋体;
mso-font-kerning:1.0pt;}
/* Page Definitions */
@page
{mso-page-border-surround-header:no;
mso-page-border-surround-footer:no;}
@page Section1
{size:595.3pt 841.9pt;
margin:72.0pt 90.0pt 72.0pt 90.0pt;
mso-header-margin:42.55pt;
mso-footer-margin:49.6pt;
mso-paper-source:0;
layout-grid:15.6pt;}
div.Section1
{page:Section1;}
-->
</style><!--[if gte mso 10]>
<style>
/* Style Definitions */
table.MsoNormalTable
{mso-style-name:普通表格;
mso-tstyle-rowband-size:0;
mso-tstyle-colband-size:0;
mso-style-noshow:yes;
mso-style-parent:"";
mso-padding-alt:0cm 5.4pt 0cm 5.4pt;
mso-para-margin:0cm;
mso-para-margin-bottom:.0001pt;
mso-pagination:widow-orphan;
font-size:10.0pt;
font-family:"Times New Roman";
mso-fareast-font-family:"Times New Roman";
mso-ansi-language:#0400;
mso-fareast-language:#0400;
mso-bidi-language:#0400;}
</style>
<![endif]-->
<p class="MsoNormal"><span style="font-family: 宋体;">用</span><span lang="EN-US">Java</span><span style="font-family: 宋体;">编程语言和</span><span lang="EN-US">JDBC</span><span style="font-family: 宋体;">开发的程序是可以跨平台运行的</span><span lang="EN-US">,</span><span style="font-family: 宋体;">并且是不受供应商限制的</span><span lang="EN-US">.</span></p>
<p class="MsoNormal"><span lang="EN-US">4.1 JDBC</span><span style="font-family: 宋体;">的设计</span></p>
<p class="MsoNormal"><span lang="EN-US">JDBC</span><span style="font-family: 宋体;">由两层组成</span><span lang="EN-US">,</span><span style="font-family: 宋体;">上面一层是</span><span lang="EN-US">JDBC API,</span><span style="font-family: 宋体;">负责与</span><span lang="EN-US">JDBC</span><span style="font-family: 宋体;">管理器驱动程序</span><span lang="EN-US">API</span><span style="font-family: 宋体;">进行通信</span><span lang="EN-US">,</span><span style="font-family: 宋体;">将各个不同的</span><span lang="EN-US">SQL</span><span style="font-family: 宋体;">语句发送给它</span><span lang="EN-US">;</span><span style="font-family: 宋体;">该管理器</span><span lang="EN-US">(</span><span style="font-family: 宋体;">对程序员是透明的</span><span lang="EN-US">)</span><span style="font-family: 宋体;">再与实际连接到数据库的各个第三方驱动程序进行通信</span><span lang="EN-US">,</span><span style="font-family: 宋体;">并且返回查询的信息</span><span lang="EN-US">,</span><span style="font-family: 宋体;">或者执行由查询规定的操作</span><span lang="EN-US">.</span></p>
<p class="MsoNormal"><span lang="EN-US">JDBC</span><span style="font-family: 宋体;">驱动程序分为以下几种类型</span><span lang="EN-US">:</span></p>
<p class="MsoNormal"><span style="font-family: 宋体;">类型</span><span lang="EN-US">1</span><span style="font-family: 宋体;">驱动程序</span></p>
<p class="MsoNormal"><span style="font-family: 宋体;">负责将</span><span lang="EN-US">JDBC</span><span style="font-family: 宋体;">转换为</span><span lang="EN-US">ODBC,</span><span style="font-family: 宋体;">并且使用一个</span><span lang="EN-US">ODBC</span><span style="font-family: 宋体;">驱动程序与数据库进行通信</span></p>
<p class="MsoNormal"><span style="font-family: 宋体;">类型</span><span lang="EN-US">2</span><span style="font-family: 宋体;">驱动程序</span></p>
<p class="MsoNormal"><span style="font-family: 宋体;">部分使用</span><span lang="EN-US">Java</span><span style="font-family: 宋体;">编程语言编写的和部分使用本机代码编写的驱动程序</span><span lang="EN-US">,</span><span style="font-family: 宋体;">用于与数据库的客户机</span><span lang="EN-US">API</span><span style="font-family: 宋体;">进行通信</span></p>
<p class="MsoNormal"><span style="font-family: 宋体;">类型</span><span lang="EN-US">3</span><span style="font-family: 宋体;">驱动程序</span></p>
<p class="MsoNormal"><span style="font-family: 宋体;">纯粹的</span><span lang="EN-US">Java</span><span style="font-family: 宋体;">客户程序库</span><span lang="EN-US">,</span><span style="font-family: 宋体;">它使用跨数据库协议</span><span lang="EN-US">,</span><span style="font-family: 宋体;">将数据库访问请求传输给服务器组件</span><span lang="EN-US">,</span><span style="font-family: 宋体;">然后该服务器组件将访问请求转换成特定的数据库协议</span></p>
<p class="MsoNormal"><span style="font-family: 宋体;">类型</span><span lang="EN-US">4</span><span style="font-family: 宋体;">驱动程序</span></p>
<p class="MsoNormal"><span style="font-family: 宋体;">纯粹的</span><span lang="EN-US">Java</span><span style="font-family: 宋体;">库</span><span lang="EN-US">,</span><span style="font-family: 宋体;">用于</span><span lang="EN-US">JDBC</span><span style="font-family: 宋体;">访问请求直接转换成特定数据库协议</span></p>
<p class="MsoNormal"><span lang="EN-US">4.2 </span><span style="font-family: 宋体;">结构化查询语言</span></p>
<p class="MsoNormal"><span lang="EN-US">JDBC</span><span style="font-family: 宋体;">是个到</span><span lang="EN-US">SQL(</span><span style="font-family: 宋体;">结构化查询语言</span><span lang="EN-US">)</span><span style="font-family: 宋体;">的接口</span><span lang="EN-US">,</span><span style="font-family: 宋体;">而</span><span lang="EN-US">SQL</span><span style="font-family: 宋体;">实际上是与所有最新型的关系数据库之间的接口</span><span lang="EN-US">.</span></p>
<p class="MsoNormal"><span lang="EN-US">4.3 </span><span style="font-family: 宋体;">安装</span><span lang="EN-US">JDBC</span></p>
<p class="MsoNormal"><span style="font-family: 宋体;">建议最好不要使用</span><span lang="EN-US">Java2
SDK</span><span style="font-family: 宋体;">配备的</span><span lang="EN-US">JDBC/ODBC</span><span style="font-family: 宋体;">桥接器驱动程序</span><span lang="EN-US">,</span><span style="font-family: 宋体;">更加反对将该驱动程序用于</span><span lang="EN-US">Access</span><span style="font-family: 宋体;">这样的桌面数据库</span><span lang="EN-US">.</span></p>
<p class="MsoNormal"><span lang="EN-US">4.4 JDBC</span><span style="font-family: 宋体;">编程的基本概念</span></p>
<p class="MsoNormal"><span lang="EN-US">1. </span><span style="font-family: 宋体;">数据库</span><span lang="EN-US">URL</span></p>
<p class="MsoNormal"><span style="font-family: 宋体;">语法</span><span lang="EN-US">:
jdbc:subprotocol name:other stuff</span></p>
<p class="MsoNormal"><span style="font-family: 宋体;">其中</span><span lang="EN-US">subprotocol</span><span style="font-family: 宋体;">特定驱动程序</span><span lang="EN-US">, other stuff</span><span style="font-family: 宋体;">参数的格式要根据它使用的子协议而定</span><span lang="EN-US">.</span></p>
<p class="MsoNormal"><span lang="EN-US">2. </span><span style="font-family: 宋体;">建立连接</span></p>
<p class="MsoNormal"><span lang="EN-US">Class.forName(</span><span style="font-family: 宋体;">驱动程序类</span><span lang="EN-US">); </span><span style="font-family: 宋体;">注册驱动程序</span></p>
<p class="MsoNormal"><span lang="EN-US">String url = &#8230;;</span></p>
<p class="MsoNormal"><span lang="EN-US">String username = &#8230;;</span></p>
<p class="MsoNormal"><span lang="EN-US">String password = &#8230;;</span></p>
<p class="MsoNormal"><span lang="EN-US">Connetion conn =
DriverManager.getConnection(url, username, password);</span></p>
<p class="MsoNormal"><span style="font-family: 宋体;">读取属性文件建立连接</span></p>
<p class="MsoNormal"><span lang="EN-US">Properties props = new Properties();</span></p>
<p class="MsoNormal"><span lang="EN-US">FileInputStream in = new
FileInputStream(&#8220;database.properties&#8221;);</span></p>
<p class="MsoNormal"><span lang="EN-US">props.load(in);</span></p>
<p class="MsoNormal"><span lang="EN-US">in.close();</span></p>
<p class="MsoNormal"><span lang="EN-US">String drivers =
props.getProperty(&#8220;jdbc.drivers&#8221;);</span></p>
<p class="MsoNormal"><span lang="EN-US">String url =
props.getProperty(&#8220;jdbc.drivers&#8221;);</span></p>
<p class="MsoNormal"><span lang="EN-US">String username =
props.getProperty(&#8220;jdbc.username&#8221;);</span></p>
<p class="MsoNormal"><span lang="EN-US">String password =
props.getProperty(&#8220;jdbc.password&#8221;);</span></p>
<p class="MsoNormal"><span lang="EN-US">Connetion conn =
DriverManager.getConnection(url, username, password);</span></p>
<p class="MsoNormal"><span lang="EN-US">3. </span><span style="font-family: 宋体;">执行</span><span lang="EN-US">SQL</span><span style="font-family: 宋体;">命令</span></p>
<p class="MsoNormal"><span lang="EN-US">Statement stat = conn.createStatement();</span></p>
<p class="MsoNormal"><span lang="EN-US">String sql = &#8230;;</span></p>
<p class="MsoNormal"><span lang="EN-US">ResultSet rs =
stat.executeQuery(sql);/stat.executeUpdate(sql);</span></p>
<p class="MsoNormal"><span lang="EN-US">while(rs.next()){</span></p>
<p class="MsoNormal"><span lang="EN-US">&#8230;</span></p>
<p class="MsoNormal"><span lang="EN-US">}</span></p>
<p class="MsoNormal"><span lang="EN-US">4. </span><span style="font-family: 宋体;">高级</span><span lang="EN-US">SQL</span><span style="font-family: 宋体;">类型</span></p>
<p class="MsoNormal"><span lang="EN-US">Blob b=resultSet.getBlob(1); <br />
InputStream bin=b.getBinaryStryeam(); <br />
Clob c=resultSet.getClob(2); <br />
Reader cReader=c.getCharacterStream();</span></p>
<p class="MsoNormal"><span style="font-family: 宋体;">写入</span><span lang="EN-US">:</span></p>
<p class="MsoNormal"><span lang="EN-US">FileInputStream fis=new
FileInputStream(f,Connection conn); <br />
byte[] buffer=new byte[1024]; <br />
data=null; <br />
int sept=0;int len=0; <br />
<br />
while((sept=fis.read(buffer))!=-1){ <br />
if(data==null){ <br />
len=sept; <br />
data=buffer; <br />
}else{ <br />
byte[] temp; <br />
int tempLength; <br />
tempLength=len+sept; <br />
temp=new byte[tempLength]; <br />
data=temp; <br />
len=tempLength; <br />
} <br />
if(len!=data.length()){ <br />
byte temp=new byte[len]; <br />
data=temp; <br />
} <br />
} <br />
String sql="insert into fileData (filename,blobData) value(?,?)"; <br />
PreparedStatement ps=conn.prepareStatement(sql); <br />
ps.setString(1,f.getName()); <br />
ps.setObject(2,data); <br />
ps.executeUpdate();</span></p>
<p class="MsoNormal"><span style="font-family: 宋体;">读出</span><span lang="EN-US">:</span></p>
<p class="MsoNormal"><span lang="EN-US">try { </span></p>
<p class="MsoNormal"><span lang="EN-US">Clob c=resultSet.getClob(2); </span></p>
<p class="MsoNormal"><span lang="EN-US">Reader reader=c.getCharacterStream(): </span></p>
<p class="MsoNormal"><span lang="EN-US">if (reader == null) { </span></p>
<p class="MsoNormal"><span lang="EN-US">return null; </span></p>
<p class="MsoNormal"><span lang="EN-US">} </span></p>
<p class="MsoNormal"><span lang="EN-US">StringBuffer sb = new StringBuffer(); </span></p>
<p class="MsoNormal"><span lang="EN-US">char[] charbuf = new char[4096]; </span></p>
<p class="MsoNormal"><span lang="EN-US">for (int i = reader.read(charbuf); i &gt;
0; i = reader.read(charbuf)) { <br />
sb.append(charbuf, 0, i); </span></p>
<p class="MsoNormal"><span lang="EN-US">} </span></p>
<p class="MsoNormal"><span lang="EN-US">return sb.toString(); </span></p>
<p class="MsoNormal"><span lang="EN-US">} catch (Exception e) { </span></p>
<p class="MsoNormal"><span lang="EN-US">return ""; </span></p>
<p class="MsoNormal"><span lang="EN-US">}</span></p>
<p class="MsoNormal"><span lang="EN-US">4.5 </span><span style="font-family: 宋体;">执行查询操作</span></p>
<p class="MsoNormal"><span style="font-family: 宋体;">采用宿主变量方式</span><span lang="EN-US">:</span></p>
<p class="MsoNormal"><span lang="EN-US">String userId = 1;</span></p>
<p class="MsoNormal"><span lang="EN-US">String sql = &#8220;select * form user where
user_id=?&#8221;;</span></p>
<p class="MsoNormal"><span lang="EN-US">PreparedStatement pStat =
conn.prepareStatement(sql);</span></p>
<p class="MsoNormal"><span lang="EN-US">pStat.setString(1,userId);</span></p>
<p class="MsoNormal"><span lang="EN-US">ResultSet rs = pStat.executeQuery();</span></p>
<p class="MsoNormal"><span lang="EN-US">4.6 </span><span style="font-family: 宋体;">可滚动的和可更新的结果集</span></p>
<p class="MsoNormal"><span lang="EN-US">1. </span><span style="font-family: 宋体;">可滚动的结果集</span></p>
<p class="MsoNormal"><span lang="EN-US">Statement stat =
conn.createStatement(type,concurrency);</span></p>
<p class="MsoNormal"><span style="font-family: 宋体;">或</span></p>
<p class="MsoNormal"><span lang="EN-US">PreparedStatement stat =
conn.prepareStatement(command,type, concurrency);</span></p>
<p class="MsoNormal"><span style="font-family: 宋体;">其中</span></p>
<p class="MsoNormal"><span lang="EN-US">Type</span><span style="font-family: 宋体;">包括</span><span lang="EN-US">:</span></p>
<p class="MsoNormal"><span lang="EN-US">ResultSet.TYPE_FORWARD_ONLY </span><span style="font-family: 宋体;">不能滚动</span></p>
<p class="MsoNormal"><span lang="EN-US">ResultSet.TYPE_SCROLL_INSENSITIVE </span><span style="font-family: 宋体;">可以滚动</span><span lang="EN-US">,</span><span style="font-family: 宋体;">但变化不敏感</span></p>
<p class="MsoNormal"><span lang="EN-US">ResultSet.TYPE_SCROLL_SENSITIVE </span><span style="font-family: 宋体;">可以滚动</span><span lang="EN-US">,</span><span style="font-family: 宋体;">但变化敏感</span></p>
<p class="MsoNormal"><span lang="EN-US">Concurrency</span><span style="font-family: 宋体;">包括</span><span lang="EN-US">:</span></p>
<p class="MsoNormal"><span lang="EN-US">ResultSet.CONCUR_READ_ONLY </span><span style="font-family: 宋体;">不能更新</span></p>
<p class="MsoNormal"><span lang="EN-US">ResultSet.CONCUR_UPDATABLE </span><span style="font-family: 宋体;">可以更新</span></p>
<p class="MsoNormal"><span style="font-family: 宋体;">常用方法</span><span lang="EN-US">:</span></p>
<p class="MsoNormal"><span lang="EN-US">rs.previous() </span><span style="font-family: 宋体;">滚动结果集</span></p>
<p class="MsoNormal"><span lang="EN-US">rs.relative(n) </span><span style="font-family: 宋体;">将光标向后或向前移动</span><span lang="EN-US">n</span><span style="font-family: 宋体;">行</span></p>
<p class="MsoNormal"><span lang="EN-US">rs.absolute(n) </span><span style="font-family: 宋体;">将光标设置到某个特定的行号上</span></p>
<p class="MsoNormal"><span lang="EN-US">rs.getRow() </span><span style="font-family: 宋体;">获得当前的行号</span></p>
<p class="MsoNormal"><span lang="EN-US">2. </span><span style="font-family: 宋体;">可更新的结果集</span></p>
<p class="MsoNormal"><span style="font-family: 宋体;">常用方法</span><span lang="EN-US">:</span></p>
<p class="MsoNormal"><span lang="EN-US">rs.getConcurrency() </span><span style="font-family: 宋体;">查看结果集是否可更新</span></p>
<p class="MsoNormal"><span lang="EN-US">rs.updateXxx() </span><span style="font-family: 宋体;">只能用于修改行的值</span><span lang="EN-US">,</span><span style="font-family: 宋体;">不能修改数据库</span></p>
<p class="MsoNormal"><span lang="EN-US">rs.updateRow() </span><span style="font-family: 宋体;">将当前行中所有信息更新发送给数据库</span></p>
<p class="MsoNormal"><span lang="EN-US">rs.cancelRowUpdates() </span><span style="font-family: 宋体;">撤销对当前行的更新</span></p>
<p class="MsoNormal"><span lang="EN-US">rs.moveToInsertRow() </span><span style="font-family: 宋体;">将光标移到一个特定的位置</span></p>
<p class="MsoNormal"><span lang="EN-US">rs.insertRow() </span><span style="font-family: 宋体;">将该新行传递给数据库</span></p>
<p class="MsoNormal"><span lang="EN-US">rs.moveToCurrentRow() </span><span style="font-family: 宋体;">将光标移回之前位置</span></p>
<p class="MsoNormal"><span lang="EN-US">rs.deleteRow() </span><span style="font-family: 宋体;">删除光标下的行</span></p>
<p class="MsoNormal"><span style="font-family: 宋体;">例子</span><span lang="EN-US">:</span></p>
<p class="MsoNormal"><span lang="EN-US">rs. moveToInsertRow();</span></p>
<p class="MsoNormal"><span lang="EN-US">rs.updateString(&#8220;Title&#8221;,title);</span></p>
<p class="MsoNormal"><span lang="EN-US">rs.updateString(&#8220;Isbn&#8221;,isbn);</span></p>
<p class="MsoNormal"><span lang="EN-US">rs.insertRow();</span></p>
<p class="MsoNormal"><span lang="EN-US">rs.moveToCurrentRow();</span></p>
<p class="MsoNormal"><span lang="EN-US">4.7 </span><span style="font-family: 宋体;">元数据</span></p>
<p class="MsoNormal"><span style="font-family: 宋体;">元数据是在</span><span lang="EN-US">SQL</span><span style="font-family: 宋体;">中用于描述数据库或者它的各个部分之一的数据</span><span lang="EN-US">;</span><span style="font-family: 宋体;">分为关于数据库的元数据和关于结构集合的元数据</span><span lang="EN-US">.</span></p>
<p class="MsoNormal"><span lang="EN-US">DatabaseMetaData conn.getMetaData() </span><span style="font-family: 宋体;">用于提供关于数据库的元数据</span></p>
<p class="MsoNormal"><span lang="EN-US">ResultSetMetaData rs.getMetaData() </span><span style="font-family: 宋体;">用于提供关于结构集合的元数据</span></p>
<p class="MsoNormal"><span lang="EN-US">4.8 </span><span style="font-family: 宋体;">事务</span></p>
<p class="MsoNormal"><span style="font-family: 宋体;">如果将各个更新命令组合成一个事务</span><span lang="EN-US">,</span><span style="font-family: 宋体;">可以实现数据库数据的完整性</span><span lang="EN-US">;</span><span style="font-family: 宋体;">在提交事务时</span><span lang="EN-US">,</span><span style="font-family: 宋体;">如果在它中间某个位置上运行失败</span><span lang="EN-US">,</span><span style="font-family: 宋体;">它可以执行回退操作</span><span lang="EN-US">,</span><span style="font-family: 宋体;">并且该数据库将自动撤销提交事务以来进行的所有更新及所产生的影响</span><span lang="EN-US">.</span></p>
<p class="MsoNormal"><span style="font-family: 宋体;">在默认情况下</span><span lang="EN-US">,</span><span style="font-family: 宋体;">数据库连接处于自动提交方式</span><span lang="EN-US">,</span><span style="font-family: 宋体;">并且每个</span><span lang="EN-US">SQL</span><span style="font-family: 宋体;">命令一旦被执行</span><span lang="EN-US">,</span><span style="font-family: 宋体;">便被提交给该数据库</span><span lang="EN-US">.</span><span style="font-family: 宋体;">一旦命令被提交</span><span lang="EN-US">,</span><span style="font-family: 宋体;">就无法进行回退操作</span><span lang="EN-US">.</span></p>
<p class="MsoNormal"><span style="font-family: 宋体;">批量更新</span><span lang="EN-US">: </span><span style="font-family: 宋体;">一序列命令将作为一个批量来集中和提交</span><span lang="EN-US">,</span><span style="font-family: 宋体;">命令不包括</span><span lang="EN-US">Select</span><span style="font-family: 宋体;">查询</span><span lang="EN-US">.</span></p>
<p class="MsoNormal"><span lang="EN-US">String sql = &#8230;;</span></p>
<p class="MsoNormal"><span lang="EN-US">stat.addBatch(sql);</span></p>
<p class="MsoNormal"><span lang="EN-US">while(&#8230;){</span></p>
<p class="MsoNormal"><span lang="EN-US">sql = &#8230;</span></p>
<p class="MsoNormal"><span lang="EN-US">stat.addBatch(sql);</span></p>
<p class="MsoNormal"><span lang="EN-US">}</span></p>
<p class="MsoNormal"><span lang="EN-US">stat.executeBatch();</span></p>
<p class="MsoNormal"><span lang="EN-US">4.9&nbsp;&nbsp;&nbsp; </span><span style="font-family: 宋体;">高级连接管理</span></p>
<p class="MsoNormal"><span style="font-family: 宋体;">在企业级环境中部署</span><span lang="EN-US">JDBC</span><span style="font-family: 宋体;">应用程序时</span><span lang="EN-US">,</span><span style="font-family: 宋体;">数据库连接的管理纳入了</span><span lang="EN-US">JNDI(Java</span><span style="font-family: 宋体;">命令与目录接口</span><span lang="EN-US">)</span><span style="font-family: 宋体;">之中</span><span lang="EN-US">.</span><span style="font-family: 宋体;">一个目录负责管理整个企业中的数据源的位置</span><span lang="EN-US">.</span><span style="font-family: 宋体;">使用目录后</span><span lang="EN-US">,</span><span style="font-family: 宋体;">就可以对用户名、口令、数据库名字和</span><span lang="EN-US">JDBC URL</span><span style="font-family: 宋体;">实施集中管理</span><span lang="EN-US">.</span></p>
<p class="MsoNormal"><span lang="EN-US">Context jndi = &#8230;;</span></p>
<p class="MsoNormal"><span lang="EN-US">DataSource source =
(DataSource)jndi.lookup(&#8220;jdbc/corejava&#8221;);</span></p>
<p class="MsoNormal"><span lang="EN-US">Connection conn =
source.getConnection(username,password);</span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>
<img src ="http://www.blogjava.net/huaxiaoxi/aggbug/241623.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/huaxiaoxi/" target="_blank">developer</a> 2008-11-20 13:31 <a href="http://www.blogjava.net/huaxiaoxi/archive/2008/11/20/241623.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>安装金蝶K3 10.1的过程和引回帐套的过程</title><link>http://www.blogjava.net/huaxiaoxi/archive/2008/11/19/241312.html</link><dc:creator>developer</dc:creator><author>developer</author><pubDate>Wed, 19 Nov 2008 03:35:00 GMT</pubDate><guid>http://www.blogjava.net/huaxiaoxi/archive/2008/11/19/241312.html</guid><wfw:comment>http://www.blogjava.net/huaxiaoxi/comments/241312.html</wfw:comment><comments>http://www.blogjava.net/huaxiaoxi/archive/2008/11/19/241312.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/huaxiaoxi/comments/commentRss/241312.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/huaxiaoxi/services/trackbacks/241312.html</trackback:ping><description><![CDATA[1,先检测环境、如果有不符合的组建到K3 SOURCE这个文件夹下安装好，但是mdac这个东西在XP下<br />
好像总提示版本不兼容，就这样过去，不用管它，在安装其他组件的时候在跳过那打钩直接安装<br />
2，先安装数据库服务部件<br />
3，安装中间层，安装完毕后提示是否安装行业版，选择不安装，这个东西是干啥的目前未知<br />
然后它继续注册组件，要稍微等上一会，安装完毕后提示立即注册中间层，把那个勾挑掉，就代表<br />
不立即注册中间层，然后点击完成。<br />
4，安装客户端，选择完整安装，然后还问你是否安装行业版，选择不安装，之后又开始注册组件。完毕后重新启动机器。<br />
5，上面三项都安装完毕后，开始，金蝶-》中间层服务部件-》系统工具-》注册中间层，时间比较长<br />
6,引回帐套，在帐套管理里面点击恢复，找到需要引回的帐套，后缀名是DBB，然后起一个帐套号，比如001，确定就可以了<br />
比较慢，要是有两个帐套就引回两个帐套<br />
7，然后点击K3主控制台会发现需要输入用户名和密码，然后用户名就是administrator，但是此时<br />
由于你不知道密码，因此要到系统管理里面清楚一下密码，金蝶-》中间层服务部件-》帐套管理，<br />
点击帐套名，然后点击&#8220;用户&#8221;，然后清楚密码<br />
8，关闭相应的K3服务进程，然后打狗，类型选择supperpro，然后版本选择10.1，然后选择<br />
&#8220;加密单元数据设置&#8221;，把所有的访问码改为1，安装，就可以了。<br />
<img src ="http://www.blogjava.net/huaxiaoxi/aggbug/241312.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/huaxiaoxi/" target="_blank">developer</a> 2008-11-19 11:35 <a href="http://www.blogjava.net/huaxiaoxi/archive/2008/11/19/241312.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>在Windows下配置CVSNT</title><link>http://www.blogjava.net/huaxiaoxi/archive/2008/11/18/241169.html</link><dc:creator>developer</dc:creator><author>developer</author><pubDate>Tue, 18 Nov 2008 08:48:00 GMT</pubDate><guid>http://www.blogjava.net/huaxiaoxi/archive/2008/11/18/241169.html</guid><wfw:comment>http://www.blogjava.net/huaxiaoxi/comments/241169.html</wfw:comment><comments>http://www.blogjava.net/huaxiaoxi/archive/2008/11/18/241169.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/huaxiaoxi/comments/commentRss/241169.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/huaxiaoxi/services/trackbacks/241169.html</trackback:ping><description><![CDATA[下面先转载一个我在网上查询出来的资料，根据这个资料配置CVS基本上是没有问题的，写的很简单也很详细，如下：<br />
---------------------------------------------------------------------------------------------------------------------------------<br />
因为需要跨网络合作开发，公司决定使用CVS作为配置库管理工具。由于本人以前没有使用过CVS，而公司服务器又使用的是Window2003系统，所以上网开始找资料。<br />
经过搜索后，决定使用cvsNT+tortoisecvs来实现。<br />
从www.cvsnt.org 下了最新版CvsNT，默认只有2.0.58版的，其他版本找不到。<br />
从sourceforge.net 下了最新版的tortoisecvs<br />
然后从网上找了很多相关的资料，就开始安装了。<br />
<br />
其中经过若干尝试之后。还是无法正常使用。<br />
<br />
第二天，无意中把端口号去掉之后，竟然调用成功。<br />
<br />
现在把配置过程罗列如下：<br />
CvsNT设置<br />
1.安装CvsNT，并重新启动<br />
2.打开Service Control Panel<br />
3.设置Advabced-&gt;Temporary为任意一个空目录<br />
&nbsp;&nbsp; 钩选上所有选项<br />
&nbsp;&nbsp; 设置Lock地址为Localhost ，其他选项不要改动<br />
4.添加Repositories <br />
&nbsp;&nbsp; 点击Add按钮，选择一个准备好的空目录如Location= C:/cvsAdmin&nbsp;&nbsp; ;Name =/cvsAdmin<br />
&nbsp;&nbsp; 系统会提示是否初始化，点确定<br />
5.如果CvsService或CvsLock服务没有启动，请先启动他们<br />
<br />
测试服务器<br />
1.开始菜单-run-cmd,进入命令行环境<br />
2.输入Cvs ，会出现相应的帮助，如果没出现，说明环境变量中的Path值没有设置，你可以手动设置到你的Cvs.exe文件所在的目录<br />
3.set cvsroot=:sspi:localhost:/cvsAdmin<br />
4.输入cvs version ,显示当前CvsNt版本号<br />
&nbsp; Client: Concurrent Versions System (CVSNT) 2.0.58a (client/server<br />
&nbsp; Server: Concurrent Versions System (CVS) 1.11.2 (client/server)<br />
5.cvs login<br />
&nbsp;&nbsp; 输入你的Windows登陆密码<br />
&nbsp;6.cvs ls<br />
&nbsp;&nbsp;&nbsp; 显示所以module，至少会有一个CVSROOT<br />
&nbsp;7.如果以上步骤都没有错误，说明CVSNT配置成功<br />
<br />
添加用户<br />
1.使用cvs passwd命令可以添加用户和修改密码<br />
2.可以修改 C:/cvsAdmin/cvsroot目录下的passwd文件，如果没有的话，可以自己建一个<br />
&nbsp;&nbsp; 添加 test:,这样就添加了一个密码为空的test用户了。<br />
3.添加用户后可以使用:pserver:test@localhost:/cvsAdmin登录了<br />
<br />
tortoisecvs设置<br />
1.安装tortoisecvs选择完全安装<br />
2.重新启动计算机<br />
3.新建一个文件夹如（c:\test），右击，创建新模块，使用pserver协议输入机器IP地址和用户名（不要输入端口号，我可深受其害），<br />
&nbsp;&nbsp; Repositories folder为/cvsAdmin<br />
如果不出意外的话，一个新的模块test就建立了<br />
4.测试Checkout功能：右键菜单-〉cvs-&gt;checkout 选择一个模块名test,如果不知道的话，可以使用获取列表的功能<br />
5.ok,提示cvs操作成功，但是我们什么都没看到，自己查看输出信息，其中包含了cannot open CVS/Entries for reading: No such file or directory，什么意思呢，原来cvs中的模块为空时，它无法取得任何实体，就什么都不生成了，解决的方法很简单，就是在新建的模块中添加一个文件，并提交，再测试一下，果然，cvsAdmin自动为我们生成了。哎，这一点，可把我给害苦了。<br />
<br />
先写到这里吧！希望对大家有所帮助。<br />
-------------------------------------------------------------------------------------------------------------------------------<br />
<br />
&nbsp;&nbsp; 按照上面的步骤进行一次安装，安装完毕后发现服务虽然启动，但是环境仍然没有配置好，需要在控制台下执行set cvsroot=:sspi:localhost:/cvsAdmin，然后我在用客户端的myeclipse进行连接的时候需要输入用户名和密码，起初我以为用户名<br />
是cvsroot，密码是空，但是后来总提示我这样或者那样的错误，然后我就像用上面所说的方法执行命令修改密码，但是仍然不成功，<br />
我到cvsroot下面去找passwd这个文件，发现没有，需要新建一个这样的文件，但是虽然它用文本能够打开，但是在鼠标，右键的时候没有<br />
新建此类型的选项，于是乎我只能把config这个文件拷贝到cvsroot文件夹外面，改个名字为passwd，然后在拷贝回来，但是这个时候问题<br />
又出现了，按照上面的办法我把文件里面所有的文本内容都删除，然后写上test：，结果连接的时候告诉我没有test这个用户名，之后折腾<br />
了很久根据各种提示吧，把用户名改成了Administrator，（也就是在passwd这个文件写上Administrator：）然后在控制台下改密码为1234，在<br />
myeclipse上仍然连接不上，这个时候我突然意识到cvs应该是区分大小写的，于是把小写的administrator改成了Administrator，就成功的连接上了。<br />
<br />
&nbsp; 目前没有时间，以后有时间在仔细研究一下吧，希望对大家有所帮助。<br />
<br />
<img src ="http://www.blogjava.net/huaxiaoxi/aggbug/241169.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/huaxiaoxi/" target="_blank">developer</a> 2008-11-18 16:48 <a href="http://www.blogjava.net/huaxiaoxi/archive/2008/11/18/241169.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>学习jboss遭遇的第一个问题</title><link>http://www.blogjava.net/huaxiaoxi/archive/2008/11/13/240348.html</link><dc:creator>developer</dc:creator><author>developer</author><pubDate>Thu, 13 Nov 2008 08:50:00 GMT</pubDate><guid>http://www.blogjava.net/huaxiaoxi/archive/2008/11/13/240348.html</guid><wfw:comment>http://www.blogjava.net/huaxiaoxi/comments/240348.html</wfw:comment><comments>http://www.blogjava.net/huaxiaoxi/archive/2008/11/13/240348.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/huaxiaoxi/comments/commentRss/240348.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/huaxiaoxi/services/trackbacks/240348.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;这个项目打算用jboss做，无论如何，其他的中间件我都用的有点恶心了，听说jboss不错，也想尝试一下新鲜事物，但是刚一开始就出现了一个问题，建立一个简单的web程序，发布，发布地点都已经知晓，但是在启动jboss的时候，发现爆出error错误，如下：<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;16:16:41,884 ERROR [STDERR] log4j:ERROR A "org.jboss.logging.appender.FileAppender" object is not assignable to a "org.apache.log4j.Appender" variable.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;16:16:41,884 ERROR [STDERR] log4j:ERROR The class "org.apache.log4j.Appender" was loaded by&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;16:16:41,884 ERROR [STDERR] log4j:ERROR [WebappClassLoader<br />
&nbsp; delegate: false<br />
&nbsp; repositories:<br />
&nbsp;&nbsp;&nbsp; /WEB-INF/classes/<br />
----------&gt; Parent Classloader:<br />
java.net.FactoryURLClassLoader@8aa2d<br />
] whereas object of type&nbsp;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;而相同的项目在tomcat下面是不会报错的，查明原因后发现，原来jboss自己带了日志功能，而建立web项目的时候它自己本身也带着日志功能（你的项目中应该有spring），直接造成冲突。对于解决办法，下面转载一片文章。<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;
<div class="blog_content">
<p><font size="3">log4j是一个很好的开源的日志项目，下面就我在实际中使用的一些情况作一个小结（我所写的是以spring为框架的运用，之所以要提到这点，是因为在spring中专门有处理log4j的地方，而我也用到了这些地方）。</font></p>
<p><font size="3">&nbsp; 在使用的第一步你要明白你所发布的web项目所使用的服务器，因为不同的服务器对于使用log4j是有些不同的，我在实际使用中主要是用tomcat和 jboss两类，对于tomcat,它本身是没有<span class="hilite2">配置</span>log4j的，所以使用起来和常规的一样；而在jboss中它是本身<span class="hilite2">配置</span>了log4j的，所以有时候 我们在看项目代码时，其整个项目并没有log4j的<span class="hilite2">配置</span>文件，而在一些类中仍然定义了Logger,例如static Logger log = org.apache.log4j.Logger.getLogger(UserDaoImple.class);，这就表明开发者打算使用jboss默 认的log4j的<span class="hilite2">配置</span>，我们可以在jboss下的对应的log目录下的server.log中看到日志，jboss本身的log4j的<span class="hilite2">配置</span>是将 debug,info级的日志写在server.log中，而像error等级别比较高的日志打印到控制台上，而写到server.log中的日志比较多，并不方便查看。于是我们想到使用自己的log4j<span class="hilite2">配置</span>写到某个具体的文件中（注意文件要先建立，才能往里面写东西，log4j自己不能建立文件），但 这里因为jboss有它自己的log4j<span class="hilite2">配置</span>，所以如果我们<span class="hilite2">配置</span>的log4j包含Console的Appender时，就会出错，错误类似于</font></p>
<p><font size="3"><font color="#ff0000">ERROR: invalid console appender config detected, console stream is looping.</font><br />
解决方法一是不用Console的Appender,或者改jboss的<span class="hilite2">配置</span>文件，在jboss-service.xml文件里,把<br />
&lt;mbean code="org.jboss.logging.Log4jService" name="jboss.system:type=Log4jService,service=Logging"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;attribute name="ConfigurationURL"&gt;resource:log4j.xml&lt;/attribute&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>&lt;attribute name="CatchSystemOut"&gt;false&lt;/attribute&gt;</strong><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;attribute name="Log4jQuietMode"&gt;true&lt;/attribute&gt;<br />
&lt;/mbean&gt;。</font></p>
<p><font size="3">我建议不用Console的Appender，当然这是对jboss3.2.x是这样，对于jboss4.0.x如果我们要用自己的log4j<span class="hilite2">配置</span>照上述改还是会有问题，会有类似于</font><font color="#ff0000"><font size="3">log4j:ERROR A "org.jboss.logging.util.OnlyOnceErrorHandler" object is not assignable to a "org.apache.log4j.spi.ErrorHandler" variable</font><font color="#000000" size="3">的异常，解决方法是把/server/default/jbossweb-tomcat55.sar/META-INF/jboss-service.xml 中的以下两个熟悉改成true<br />
&lt;attribute name="Java2ClassLoadingCompliance"&gt;true&lt;/attribute&gt; <br />
&lt;attribute name="UseJBossWebLoader"&gt;true&lt;/attribute&gt; </font></font></p>
<p><font color="#ff0000"><font color="#000000" size="3">以上就是使用jboss服务器可能出现的问题，解决了这些再来使用log4j就比较简单了。</font></font></p>
<p><font color="#ff0000"><font color="#000000" size="3">下面说说对于采用了spring框架的项目如何使用log4j,在spring中使用log4j，有些方便的地方，</font></font></p>
<p><font color="#ff0000"><font color="#000000" size="3">1. 动态的改变记录级别和策略，即修改log4j.properties,不需要重启Web应用，这需要在web.xml中设置一下。<br />
2. 把log文件定在 /WEB-INF/logs/ 而不需要写绝对路径。 <br />
3. 可以把log4j.properties和其他properties一起放在/WEB-INF/ ，而不是Class-Path。</font></font></p>
<p><font color="#ff0000"><font color="#000000" size="3">首先我们在web.xml中需要设定一下</font></font></p>
<p><font color="#ff0000"><font color="#000000" size="3">&lt;context-param&gt; <br />
&lt;param-name&gt;log4jConfigLocation&lt;/param-name&gt; <br />
&lt;param-value&gt;WEB-INF/log4j.properties&lt;/param-value&gt; <br />
&lt;/context-param&gt; <br />
<br />
&lt;context-param&gt; <br />
&lt;param-name&gt;log4jRefreshInterval&lt;/param-name&gt; <br />
&lt;param-value&gt;60000&lt;/param-value&gt; <br />
&lt;/context-param&gt; <br />
<br />
&lt;listener&gt; <br />
&lt;listener-class&gt;org.springframework.web.util.Log4jConfigListener&lt;/listener-class&gt; <br />
&lt;/listener&gt;&nbsp;<br />
其中第二部分就是能够动态修改log4j.properties的关键，容器会每60秒扫描log4j的<span class="hilite2">配置</span>文件&nbsp;。</font></font><font color="#ff0000"><font color="#000000" size="3">对 于log4j的<span class="hilite2">配置</span>文件如何写，这就不多说了，大家可以去google，有一点就是我们如果用RollingFileAppender或者 FileAppender时，可以通过${webapp.root}来定位到服务器的发布的该项目下，这是spring把web目录的路径压入到了 webapp.root的系统变量。然后，在log4j.properties 里就可以这样定义logfile位置 <br />
log4j.appender.logfile.File=${webapp.root}/WEB-INF/logs/myfuse.log <br />
如果有多个web应用，怕webapp.root变量重复，可以在context-param里定义webAppRootKey。</font></font></p>
<font color="#ff0000"><font color="#000000" size="3"><font size="3">当我们定义完log4j.properties后，剩下的就是在需要记录的class中new 出Logger了</font></font></font>&nbsp;</div>
<div class="blog_content"></div>
<div class="blog_content"></div>
<div class="blog_content">
<h1><font size="4">常用log4j配置</font></h1>
<p><span class="content"><font size="3">常用log4j配置，一般可以采用两种方式，.properties和.xml,下面举两个简单的例子：<br />
一、log4j.properties<br />
### 设置org.zblog域对应的级别INFO,DEBUG,WARN,ERROR和输出地A1，A2 ##<br />
log4j.category.org.zblog=ERROR,A1 <br />
log4j.category.org.zblog=INFO,A2 <br />
log4j.appender.A1=org.apache.log4j.ConsoleAppender <br />
### 设置输出地A1，为ConsoleAppender(控制台) ##<br />
log4j.appender.A1.layout=org.apache.log4j.PatternLayout <br />
### 设置A1的输出布局格式PatterLayout,(可以灵活地指定布局模式）##<br />
log4j.appender.A1.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} [%c]-[%p] %m%n <br />
### 配置日志输出的格式##<br />
log4j.appender.A2=org.apache.log4j.RollingFileAppender <br />
### 设置输出地A2到文件（文件大小到达指定尺寸的时候产生一个新的文件）##<br />
log4j.appender.A2.File=E:/study/log4j/zhuwei.html <br />
### 文件位置##<br />
log4j.appender.A2.MaxFileSize=500KB <br />
### 文件大小##<br />
log4j.appender.A2.MaxBackupIndex=1 <br />
log4j.appender.A2.layout=org.apache.log4j.HTMLLayout <br />
##指定采用html方式输出<br />
二、log4j.xml<br />
&lt;?xml version="1.0" encoding="GB2312" ?&gt;<br />
&lt;!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"&gt;<br />
&lt;log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"&gt;<br />
&lt;appender name="org.zblog.all" class="org.apache.log4j.RollingFileAppender"&gt;<br />
&lt;!-- 设置通道ID:org.zblog.all和输出方式：org.apache.log4j.RollingFileAppender --&gt;<br />
&nbsp;&nbsp; &lt;param name="File" value="E:/study/log4j/all.output.log" /&gt;&lt;!-- 设置File参数：日志输出文件名 --&gt;<br />
&nbsp;&nbsp; &lt;param name="Append" value="false" /&gt;&lt;!-- 设置是否在重新启动服务时，在原有日志的基础添加新日志 --&gt;<br />
&nbsp;&nbsp; &lt;param name="MaxBackupIndex" value="10" /&gt; <br />
&nbsp;&nbsp; &lt;layout class="org.apache.log4j.PatternLayout"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;param name="ConversionPattern" value="%p (%c:%L)- %m%n" /&gt;&lt;!-- 设置输出文件项目和格式 --&gt;<br />
&nbsp;&nbsp; &lt;/layout&gt;<br />
&lt;/appender&gt;<br />
&lt;appender name="org.zblog.zcw" class="org.apache.log4j.RollingFileAppender"&gt;<br />
&nbsp;&nbsp; &lt;param name="File" value="E:/study/log4j/zhuwei.output.log" /&gt;<br />
&nbsp;&nbsp; &lt;param name="Append" value="true" /&gt;<br />
&nbsp;&nbsp; &lt;param name="MaxFileSize" value="10240" /&gt; &lt;!-- 设置文件大小 --&gt;<br />
&nbsp;&nbsp; &lt;param name="MaxBackupIndex" value="10" /&gt; <br />
&nbsp;&nbsp; &lt;layout class="org.apache.log4j.PatternLayout"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;param name="ConversionPattern" value="%p (%c:%L)- %m%n" /&gt;<br />
&nbsp;&nbsp; &lt;/layout&gt;<br />
&lt;/appender&gt;<br />
&lt;logger name="zcw.log"&gt; &lt;!-- 设置域名限制，即zcw.log域及以下的日志均输出到下面对应的通道中 --&gt;<br />
&nbsp;&nbsp; &lt;level value="debug" /&gt;&lt;!-- 设置级别 --&gt;<br />
&nbsp;&nbsp; &lt;appender-ref ref="org.zblog.zcw" /&gt;&lt;!-- 与前面的通道id相对应 --&gt;<br />
&lt;/logger&gt;<br />
&lt;root&gt; &lt;!-- 设置接收所有输出的通道 --&gt;<br />
&nbsp;&nbsp; &lt;appender-ref ref="org.zblog.all" /&gt;&lt;!-- 与前面的通道id相对应 --&gt;<br />
&lt;/root&gt;<br />
&lt;/log4j:configuration&gt;<br />
三、配置文件加载方法：<br />
import org.apache.log4j.Logger;<br />
import org.apache.log4j.PropertyConfigurator;<br />
import org.apache.log4j.xml.DOMConfigurator;<br />
public class Log4jApp {<br />
&nbsp;&nbsp; public static void main(String[] args) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DOMConfigurator.configure("E:/study/log4j/log4j.xml");//加载.xml文件<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //PropertyConfigurator.configure("E:/study/log4j/log4j.properties");//加载.properties文件<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Logger log=Logger.getLogger("org.zblog.test");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; log.info("测试");<br />
&nbsp;&nbsp; }<br />
}<br />
四、项目使用log4j<br />
在web 应用中，可以将配置文件的加载放在一个单独的servlet中，并在web.xml中配置该servlet在应用启动时候加载。对于在多人项目中，可以给每一个人设置一个输出通道，这样在每个人在构建Logger时，用自己的域名称，让调试信息输出到自己的log文件中。<br />
五、常用输出格式<br />
# -X号:X信息输出时左对齐；<br />
# %p:日志信息级别<br />
# %d{}:日志信息产生时间<br />
# %c:日志信息所在地（类名）<br />
# %m:产生的日志具体信息<br />
# %n:输出日志信息换行</font><br />
</span></p>
</div>
<div class="blog_content"></div>
<div class="blog_content">
<h3>Log4J 最佳实践之全能配置文件</h3>
<p>给出得Log4J配置文件实现了输出到控制台，文件，回滚文件，发送日志邮件，输出到数据库日志表，自定义标签等全套功能。<br />
<br />
log4j.rootLogger=DEBUG,CONSOLE,A1,im<br />
#DEBUG,CONSOLE,FILE,ROLLING_FILE,MAIL,DATABASE<br />
<br />
log4j.addivity.org.apache=true<br />
<br />
<br />
###################<br />
# Console Appender<br />
###################<br />
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender<br />
log4j.appender.Threshold=DEBUG<br />
log4j.appender.CONSOLE.Target=System.out<br />
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout<br />
log4j.appender.CONSOLE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n<br />
#log4j.appender.CONSOLE.layout.ConversionPattern=[start]%d{DATE}[DATE]%n%p[PRIORITY]%n%x[NDC]%n%t[THREAD] n%c[CATEGORY]%n%m[MESSAGE]%n%n<br />
<br />
<br />
#####################<br />
# File Appender<br />
#####################<br />
log4j.appender.FILE=org.apache.log4j.FileAppender<br />
log4j.appender.FILE.File=file.log<br />
log4j.appender.FILE.Append=false<br />
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout<br />
log4j.appender.FILE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n<br />
# Use this layout for LogFactor 5 analysis<br />
<br />
<br />
<br />
########################<br />
# Rolling File<br />
########################<br />
log4j.appender.ROLLING_FILE=org.apache.log4j.RollingFileAppender<br />
log4j.appender.ROLLING_FILE.Threshold=ERROR<br />
log4j.appender.ROLLING_FILE.File=rolling.log<br />
log4j.appender.ROLLING_FILE.Append=true<br />
log4j.appender.ROLLING_FILE.MaxFileSize=10KB<br />
log4j.appender.ROLLING_FILE.MaxBackupIndex=1<br />
log4j.appender.ROLLING_FILE.layout=org.apache.log4j.PatternLayout<br />
log4j.appender.ROLLING_FILE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n<br />
<br />
<br />
####################<br />
# Socket Appender<br />
####################<br />
log4j.appender.SOCKET=org.apache.log4j.RollingFileAppender<br />
log4j.appender.SOCKET.RemoteHost=localhost<br />
log4j.appender.SOCKET.Port=5001<br />
log4j.appender.SOCKET.LocationInfo=true<br />
# Set up for Log Facter 5<br />
log4j.appender.SOCKET.layout=org.apache.log4j.PatternLayout<br />
log4j.appender.SOCET.layout.ConversionPattern=[start]%d{DATE}[DATE]%n%p[PRIORITY]%n%x[NDC]%n%t[THREAD]%n%c[CATEGORY]%n%m[MESSAGE]%n%n<br />
<br />
<br />
########################<br />
# Log Factor 5 Appender<br />
########################<br />
log4j.appender.LF5_APPENDER=org.apache.log4j.lf5.LF5Appender<br />
log4j.appender.LF5_APPENDER.MaxNumberOfRecords=2000<br />
<br />
<br />
########################<br />
# SMTP Appender<br />
#######################<br />
log4j.appender.MAIL=org.apache.log4j.net.SMTPAppender<br />
log4j.appender.MAIL.Threshold=FATAL<br />
log4j.appender.MAIL.BufferSize=10<br />
log4j.appender.MAIL.From=chenyl@hollycrm.com<br />
log4j.appender.MAIL.SMTPHost=mail.hollycrm.com<br />
log4j.appender.MAIL.Subject=Log4J Message<br />
log4j.appender.MAIL.To=chenyl@hollycrm.com<br />
log4j.appender.MAIL.layout=org.apache.log4j.PatternLayout<br />
log4j.appender.MAIL.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n<br />
<br />
<br />
########################<br />
# JDBC Appender<br />
#######################<br />
log4j.appender.DATABASE=org.apache.log4j.jdbc.JDBCAppender<br />
log4j.appender.DATABASE.URL=jdbc:mysql://localhost:3306/test<br />
log4j.appender.DATABASE.driver=com.mysql.jdbc.Driver<br />
log4j.appender.DATABASE.user=root<br />
log4j.appender.DATABASE.password=<br />
log4j.appender.DATABASE.sql=INSERT INTO LOG4J (Message) VALUES ('[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n')<br />
log4j.appender.DATABASE.layout=org.apache.log4j.PatternLayout<br />
log4j.appender.DATABASE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n<br />
<br />
<br />
log4j.appender.A1=org.apache.log4j.DailyRollingFileAppender<br />
log4j.appender.A1.File=SampleMessages.log4j<br />
log4j.appender.A1.DatePattern=yyyyMMdd-HH'.log4j'<br />
log4j.appender.A1.layout=org.apache.log4j.xml.XMLLayout<br />
<br />
###################<br />
#自定义Appender<br />
###################<br />
log4j.appender.im = net.cybercorlin.util.logger.appender.IMAppender<br />
<br />
log4j.appender.im.host = mail.cybercorlin.net<br />
log4j.appender.im.username = username<br />
log4j.appender.im.password = password<br />
log4j.appender.im.recipient = corlin@cybercorlin.net<br />
<br />
log4j.appender.im.layout=org.apache.log4j.PatternLayout<br />
log4j.appender.im.layout.ConversionPattern =[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n<br />
</p>
</div>
<img src ="http://www.blogjava.net/huaxiaoxi/aggbug/240348.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/huaxiaoxi/" target="_blank">developer</a> 2008-11-13 16:50 <a href="http://www.blogjava.net/huaxiaoxi/archive/2008/11/13/240348.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>简单总结一下JDBC吧,还是很基础的内容.</title><link>http://www.blogjava.net/huaxiaoxi/archive/2007/09/14/145162.html</link><dc:creator>developer</dc:creator><author>developer</author><pubDate>Fri, 14 Sep 2007 08:06:00 GMT</pubDate><guid>http://www.blogjava.net/huaxiaoxi/archive/2007/09/14/145162.html</guid><wfw:comment>http://www.blogjava.net/huaxiaoxi/comments/145162.html</wfw:comment><comments>http://www.blogjava.net/huaxiaoxi/archive/2007/09/14/145162.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/huaxiaoxi/comments/commentRss/145162.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/huaxiaoxi/services/trackbacks/145162.html</trackback:ping><description><![CDATA[Java中对数据库的操作一般分为三个步骤<br />
一，加载驱动程序<br />
Class.forName("org.postgresql.Driver");<br />
二，打开连接<br />
String url="jdbc:postgresql:COREJAVA";<br />
String username="dbuser";<br />
String password="secret";<br />
Connection conn=DriverManager.getConnection(url,username,password);<br />
前面两个步骤非常的简单,对于任意的数据库来讲都是这些内容,而说道比较多的就是第三步了<br />
三，对数据库进行操作<br />
&nbsp;&nbsp;&nbsp; 显而易见对数据库的操作就是执行SQL命令，首先需要创建一个Statement对象。要创建statement对象，需要使用调用DriverManager.getConnection方法所获得的Connection对象。<br />
&nbsp;&nbsp;&nbsp; Statement stmt=conn.createStatatement();<br />
&nbsp;&nbsp;&nbsp; String command="UPDATE Books SET Price=Price-5.00 WHERE Title NOT LIKE '%Introduction%'";<br />
然后调用Statement类中的executeUpdate方法:&nbsp; stmt.executeUpdate(command);<br />
&nbsp;&nbsp;&nbsp; executeUpdate方法将返回受SQL命令影响的行数。列入，在先前的例子中调用本方法将返回那些降价5美元的图书的总数.<br />
&nbsp;&nbsp;&nbsp; executeUpdate方法既可以执行诸如INSERT，UPDATE和DELETE之类的操作，也可以执行诸如CREATE TABLE和DROP TABLE之类的数据命令。<br />
但是，执行SELECT查询时必须使用executeQuery方法。另外还有一个execute方法可以执行任意的SQL语句。此方法通常只用于用户提供的交互式查询。&nbsp; <br />
&nbsp;&nbsp;&nbsp; 当我们执行查询操作时，通常最感兴趣的是查询结果。executeQuery方法返回一个ResultSet对象，可以通过它来每次移行地迭代遍历所有查询结果。&nbsp;&nbsp;&nbsp; ResultSet rs=stmt.executeQuery("SELECT * FROM Books");<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; 另外当你看这点的时候，我可以告诉你SQL的数据类型和Java的数据类型并非完全一致，我不是很想完全列出所有的对照表，因为任意的书籍上面肯定都有相关的介绍。只是下面的这几种你最好还是记住，因为非常有可能就在你的程序中会出现错误，左边为SQL右边为Java数据类型<br />
Interger或INT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; int<br />
NUMERIC(m,n),DECIMAL(m,n)或DEC(m,n) &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; java.math.BigDecimal<br />
FLOAT(n) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  double<br />
REAL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; float<br />
DOUBLE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; double&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; 下面介绍一下java.sql.Statement的常用方法,我觉得这个挺重要的<br />
int&nbsp; executeUpdate(String sql) <br />
&nbsp;&nbsp;&nbsp; 执行字符串中指定的INSERT,UPDATE,DELETE等SQL语句。还可以执行数据定义语言（DLL）的语句，如CREATE TABLE.返回受影响的记录总数，如果是没有更新计数的语句，则返回-1.本着对大家和自己负责的任务我彻底用了这个函数，在执行INSERT,UPDATE,DELETE的操作的事后返回的的确是影响的函数，一般你执行一条INSERT语句的事后返回的肯定是1，此外当你执行CREATE TABLE操作的时候返回的是0.至于等于-1的情况我还没有遇到，等遇到的时候第一时间更新此文章。<br />
&nbsp;<br />
boolean execute(String sqlStatement)<br />
&nbsp; &nbsp; 执行字符串中指定的SQL语句。如果该语句返回一个结果集则该方法返回true；反之，返回false。使用getResultSet或getUpdateCount方法可以得到语句的执行结果。&nbsp;  <br />
<br />
int getUpdateCount() <br />
&nbsp;&nbsp;&nbsp; 返回受前一条更新语句影响的记录总数。如果前一条语句未更新数据库，则返回-1.对于每一条执行过的语句，该方法只能被调用一次。<br />
ResultSet&nbsp; getResultSet()<br />
&nbsp;&nbsp;&nbsp; 返回前一条查询语句的结果集。如果前一条语句未产生结果集，则返回null值。对于每一条执行过的语句，该方法只能被调用一次。<br />
<br />
接着简单的介绍一下PreparedStatement的用法吧，就不描述了仅给出代码，大家肯定都会明白的<br />
&nbsp;&nbsp; string&nbsp; sql&nbsp;=&nbsp;"select&nbsp;*&nbsp;from&nbsp;people&nbsp;p&nbsp;where&nbsp;p.id&nbsp;=&nbsp;?&nbsp;and&nbsp;p.name&nbsp;=&nbsp;?";<br />
&nbsp;&nbsp; PreparedStatement pStmt=conn.prepareStatement(sql);<br />
&nbsp;&nbsp; pStmt.setint(1,id);<br />
&nbsp;&nbsp; pStmt.setstring(2,name);<br />
&nbsp;&nbsp; resultset&nbsp;rs&nbsp;=&nbsp;pStmt.executequery(); <br />
==========================================================================================<br />
&nbsp;&nbsp; pStmt&nbsp;=&nbsp;con.prepareStatement("insert&nbsp;into&nbsp;tb_name&nbsp;(col1,col2,col2,col4)&nbsp;values&nbsp;(?,?,?,?)");<br />
&nbsp;&nbsp; pStmt.setString(1,var1);<br />
&nbsp;&nbsp; pStmt.setString(2,var2);<br />
&nbsp;&nbsp; pStmt.setString(3,var3);<br />
&nbsp;&nbsp; pStmt.setString(4,var4);<br />
&nbsp;&nbsp; pStmt.executeUpdate();<br />
<br />
<br />
<br />
<img src ="http://www.blogjava.net/huaxiaoxi/aggbug/145162.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/huaxiaoxi/" target="_blank">developer</a> 2007-09-14 16:06 <a href="http://www.blogjava.net/huaxiaoxi/archive/2007/09/14/145162.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>简单的java小知识点，比较容易忘记，不断更新中（1）</title><link>http://www.blogjava.net/huaxiaoxi/archive/2007/08/23/138861.html</link><dc:creator>developer</dc:creator><author>developer</author><pubDate>Thu, 23 Aug 2007 07:49:00 GMT</pubDate><guid>http://www.blogjava.net/huaxiaoxi/archive/2007/08/23/138861.html</guid><wfw:comment>http://www.blogjava.net/huaxiaoxi/comments/138861.html</wfw:comment><comments>http://www.blogjava.net/huaxiaoxi/archive/2007/08/23/138861.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/huaxiaoxi/comments/commentRss/138861.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/huaxiaoxi/services/trackbacks/138861.html</trackback:ping><description><![CDATA[<span style="font-size: 18pt;"><span style="font-size: 10pt;"><span style="font-size: 10pt;"><span style="font-size: 8pt;"><span style="font-size: 12pt;"><span style="font-size: 10pt;"><span style="font-size: 10pt;">public class CoreJava {<br>&nbsp;&nbsp;&nbsp; public int show(){<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; System.out.println("调用show函数");<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // System.exit(0);<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 1;<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; public static void main(String [] args){<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; CoreJava cj= new CoreJava();<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; System.out.println(cj.show());<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; System.out.println("执行到此");<br>&nbsp;&nbsp;&nbsp; }<br>}<br>对于上面的这个小程序来讲所要表现的就是System.exit(0)的用法,如果把System.exit(0)注释掉在编译器中运行会出现如下结果:<br>&nbsp;&nbsp; 调用show函数<br>&nbsp;&nbsp; 1 <br>&nbsp;&nbsp; 执行到此<br>如果加入注释之后就会出现下面的结果:<br>&nbsp;&nbsp; 调用show函数 <br></span>也就是说System.exit()这个方法就是退出系统甚至如果在return之前调用的话连return语句都不会执行，此时也许你会想那么在return语句后面调用会怎么样呢，呵呵，很简单连编译都无法通过，会出现 <span style="color: red;">Unreachable code</span> 的错误，那下面的代码呢？有会如何。<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; try{<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; System.out.println("执行方法的第一步");<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //System.exit(0); <br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return ;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }finally{<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; System.out.println("看看finally程序块是否执行");<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>这个程序和最上面的程序有明显的区别就是加入了finally程序块,那么执行的情况是怎么样的呢?真会像我们一般情况下理解的finally块的程序都会执行吗？答案是否定的，如果把System.exit()注释掉输出这下面这样的:<br>&nbsp;&nbsp;&nbsp; 执行方法的第一步<br>&nbsp;&nbsp;&nbsp; 看看finally程序块是否执行<br>也就是说执行了finally程序块里面的代码，但是如果把注释删除掉就不会输出finally块的代码了<br>&nbsp;&nbsp;&nbsp; 执行方法的第一步<br>总结:相信看了上面的说明你会对exit()这个函数有了一个比较形象的认识了吧.并且也对finally一个比较容易范的误区有了理解了吧，简单一句话 return仍然执行，exit后不执行。<br></span></span></span></span></span></span><img src ="http://www.blogjava.net/huaxiaoxi/aggbug/138861.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/huaxiaoxi/" target="_blank">developer</a> 2007-08-23 15:49 <a href="http://www.blogjava.net/huaxiaoxi/archive/2007/08/23/138861.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>