﻿<?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-海鸥航际-文章分类-OpenSource Project  </title><link>http://www.blogjava.net/sgsoft/category/12.html</link><description>JAVA站</description><language>zh-cn</language><lastBuildDate>Tue, 27 Feb 2007 23:56:48 GMT</lastBuildDate><pubDate>Tue, 27 Feb 2007 23:56:48 GMT</pubDate><ttl>60</ttl><item><title>基于struts+spring+ibatis的 J2EE 开发</title><link>http://www.blogjava.net/sgsoft/articles/2257.html</link><dc:creator>海天一鸥</dc:creator><author>海天一鸥</author><pubDate>Sun, 20 Mar 2005 08:46:00 GMT</pubDate><guid>http://www.blogjava.net/sgsoft/articles/2257.html</guid><wfw:comment>http://www.blogjava.net/sgsoft/comments/2257.html</wfw:comment><comments>http://www.blogjava.net/sgsoft/articles/2257.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/sgsoft/comments/commentRss/2257.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sgsoft/services/trackbacks/2257.html</trackback:ping><description><![CDATA[1. 前言<BR><BR>Struts 是目前Java Web MVC框架中不争的王者。经过长达五年的发展，Struts已经逐渐成长为一个稳定、成熟的框架，并且占有了MVC框架中最大的市场份额。但是Struts某些技术特性上已经落后于新兴的MVC框架。面对Spring MVC、Webwork2 这些设计更精密，扩展性更强的框架，Struts受到了前所未有的挑战。但站在产品开发的角度而言，Struts仍然是最稳妥的选择。本文的原型例子JpetStore 4.0就是基于Struts开发的，但是不拘泥于Struts的传统固定用法，例如只用了一个自定义Action类，并且在form bean类的定义上也是开创性的，令人耳目一新，稍后将具体剖析一下。<BR><BR>Spring Framework 实际上是Expert One-on-One J2EE Design and Development 一书中所阐述的设计思想的具体实现。Spring Framework的功能非常多。包含AOP、ORM、DAO、Context、Web、MVC等几个部分组成。Web、MVC暂不用考虑，JpetStore 4.0用的是更成熟的Struts和JSP；DAO由于目前Hibernate、JDO、ibatis的流行，也不考虑，JpetStore 4.0用的就是ibatis。因此最需要用的是AOP、ORM、Context。Context中，最重要的是Beanfactory，它能将接口与实现分开，非常强大。目前AOP应用最成熟的还是在事务管理上。<BR><BR>ibatis 是一个功能强大实用的SQL Map工具，不同于其他ORM工具（如hibernate），它是将SQL语句映射成Java对象，而对于ORM工具，它的SQL语句是根据映射定义生成的。ibatis 以SQL开发的工作量和数据库移植性上的让步，为系统设计提供了更大的自由空间。有ibatis代码生成的工具，可以根据DDL自动生成ibatis代码，能减少很多工作量。<BR><BR>2. JpetStore简述<BR><BR>2.1. 背景<BR><BR>最初是Sun公司的J2EE petstore，其最主要目的是用于学习J2EE，但是其缺点也很明显，就是过度设计了。接着Oracle用J2EE petstore来比较各应用服务器的性能。微软推出了基于.Net平台的 Pet shop，用于竞争J2EE petstore。而JpetStore则是经过改良的基于struts的轻便框架J2EE web应用程序，相比来说，JpetStore设计和架构更优良，各层定义清晰，使用了很多最佳实践和模式，避免了很多"反模式"，如使用存储过程，在java代码中嵌入SQL语句，把HTML存储在数据库中等等。最新版本是JpetStore 4.0。<BR><BR>2.2. JpetStore开发运行环境的建立<BR><BR>1、开发环境<BR><BR>Java SDK 1.4.2<BR>Apache Tomcat 4.1.31<BR>Eclipse-SDK-3.0.1-win32<BR>HSQLDB 1.7.2<BR><BR>2、Eclipse插件<BR><BR>EMF SDK 2.0.1：Eclipse建模框架，lomboz插件需要，可以使用runtime版本。<BR>lomboz 3.0：J2EE插件，用来在Eclipse中开发J2EE应用程序<BR>Spring IDE 1.0.3：Spring Bean配置管理插件<BR>xmlbuddy_2.0.10：编辑XML，用免费版功能即可<BR>tomcatPluginV3：tomcat管理插件<BR>Properties Editor：编辑java的属性文件,并可以预览以及自动存盘为Unicode格式。免去了手工或者ANT调用native2ascii的麻烦。<BR>2.3. 架构<BR><BR>
<CENTER><IMG src="http://tech.ccidnet.com/pub/attachment/2005/2/397089.jpg"></CENTER><BR><BR>
<CENTER>图1 JpetStore架构图</CENTER><BR><BR>图1 是JPetStore架构图。参照这个架构图，让我们稍微剖析一下源代码，得出JpetStore 4.0的具体实现图（图2），思路一下子就豁然开朗了。前言中提到的非传统的struts开发模式，关键就在struts Action类和form bean类上。<BR><BR>struts Action类只有一个：BeanAction。没错，确实是一个！与传统的struts编程方式很不同。再仔细研究BeanAction类，发现它其实是一个通用类，利用反射原理，根据URL来决定调用formbean的哪个方法。BeanAction大大简化了struts的编程模式，降低了对struts的依赖（与struts以及WEB容器有关的几个类都放在com.ibatis.struts包下，其它的类都可以直接复用）。利用这种模式，我们会很容易的把它移植到新的框架如JSF，spring。<BR><BR>这样重心就转移到form bean上了，它已经不是普通意义上的form bean了。查看源代码，可以看到它不仅仅有数据和校验/重置方法，而且已经具有了行为，从这个意义上来说，它更像一个BO(Business Object)。这就是前文讲到的，BeanAction类利用反射原理，根据URL来决定调用form bean的哪个方法（行为）。form bean的这些方法的签名很简单，例如：<BR><BR>
<CENTER><CCID_NOBR>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=400 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code style="FONT-SIZE: 9pt" bgColor=#e6e6e6><PRE><CCID_CODE>public String myActionMethod() 
 {
   //..work
   return "success";
 }</CCID_CODE></PRE></TD></TR></TBODY></TABLE></CCID_NOBR></CENTER><BR><BR>方法的返回值直接就是字符串，对应的是forward的名称，而不再是ActionForward对象，创建ActionForward对象的任务已经由BeanAction类代劳了。另外，程序还提供了ActionContext工具类，该工具类封装了request 、response、form parameters、request attributes、session attributes和 application attributes中的数据存取操作，简单而线程安全，form bean类使用该工具类可以进一步从表现层框架解耦。在这里需要特别指出的是，BeanAction类是对struts扩展的一个有益尝试，虽然提供了非常好的应用开发模式，但是它还非常新，一直在发展中。 <BR><BR>
<CENTER><IMG src="http://tech.ccidnet.com/pub/attachment/2005/2/397091.gif"></CENTER><BR><BR>
<CENTER>图2 JpetStore 4.0具体实现<BR><BR>2.4. 代码剖析<BR><BR>下面就让我们开始进一步分析JpetStore4.0的源代码，为下面的改造铺路。BeanAction.java是唯一一个Struts action类，位于com.ibatis.struts包下。正如上文所言，它是一个通用的控制类，利用反射机制，把控制转移到form bean的某个方法来处理。详细处理过程参考其源代码，简单明晰。<BR><BR>Form bean类位于com.ibatis.jpetstore.presentation包下，命名规则为***Bean。Form bean类全部继承于BaseBean类，而BaseBean类实际继承于ActionForm，因此，Form bean类就是Struts的 ActionForm，Form bean类的属性数据就由struts框架自动填充。而实际上，JpetStore4.0扩展了struts中ActionForm的应用： Form bean类还具有行为，更像一个BO,其行为（方法）由BeanAction根据配置（struts-config.xml）的URL来调用。虽然如此，我们还是把Form bean类定位于表现层。Struts-config.xml的配置里有3种映射方式，来告诉BeanAction把控制转到哪个form bean对象的哪个方法来处理。以这个请求连接为例http://localhost/jpetstore4/shop/viewOrder.do<BR><BR>1. URL Pattern<BR><BR>
<CENTER><CCID_NOBR>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=400 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code style="FONT-SIZE: 9pt" bgColor=#e6e6e6><PRE><CCID_CODE>&lt;action path="/shop/viewOrder" type="com.ibatis.struts.BeanAction"
    name="orderBean" scope="session"
    validate="false"&gt;
    &lt;forward name="success" path="/order/ViewOrder.jsp"/&gt;
  &lt;/action&gt;</CCID_CODE></PRE></TD></TR></TBODY></TABLE></CCID_NOBR></CENTER><BR><BR>此种方式表示，控制将被转发到"orderBean"这个form bean对象 的"viewOrder"方法（行为）来处理。方法名取"path"参数的以"/"分隔的最后一部分。 <BR><BR>2. Method Parameter <BR><BR>
<CENTER><CCID_NOBR>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=400 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code style="FONT-SIZE: 9pt" bgColor=#e6e6e6><PRE><CCID_CODE>&lt;action path="/shop/viewOrder" type="com.ibatis.struts.BeanAction"
    name="orderBean" parameter="viewOrder" scope="session"
    validate="false"&gt;
    &lt;forward name="success" path="/order/ViewOrder.jsp"/&gt;
  &lt;/action&gt;</CCID_CODE></PRE></TD></TR></TBODY></TABLE></CCID_NOBR></CENTER><BR><BR>此种方式表示，控制将被转发到"orderBean"这个form bean对象的"viewOrder"方法（行为）来处理。配置中的"parameter"参数表示form bean类上的方法。"parameter"参数优先于"path"参数。 <BR><BR>3. No Method call <BR><BR>
<CENTER><CCID_NOBR>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=400 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code style="FONT-SIZE: 9pt" bgColor=#e6e6e6><PRE><CCID_CODE>&lt;action path="/shop/viewOrder" type="com.ibatis.struts.BeanAction"
    name="orderBean" parameter="*" scope="session"
    validate="false"&gt;
    &lt;forward name="success" path="/order/ViewOrder.jsp"/&gt;
  &lt;/action&gt;</CCID_CODE></PRE></TD></TR></TBODY></TABLE></CCID_NOBR></CENTER><BR><BR>此种方式表示，form bean上没有任何方法被调用。如果存在"name"属性，则struts把表单参数等数据填充到form bean对象后，把控制转发到"success"。否则，如果name为空，则直接转发控制到"success"。这就相当于struts内置的org.apache.struts.actions.ForwardAction的功能 <BR><BR>
<CENTER><CCID_NOBR>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=400 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code style="FONT-SIZE: 9pt" bgColor=#e6e6e6><PRE><CCID_CODE>&lt;action path="/shop/viewOrder" type="org.apache.struts.actions.ForwardAction"
    parameter="/order/ViewOrder.jsp " scope="session" validate="false"&gt;
 &lt;/action&gt;</CCID_CODE></PRE></TD></TR></TBODY></TABLE></CCID_NOBR></CENTER><BR><BR>Service类位于com.ibatis.jpetstore.service包下，属于业务层。这些类封装了业务以及相应的事务控制。Service类由form bean类来调用。 <BR><BR>com.ibatis.jpetstore.persistence.iface包下的类是DAO接口，属于业务层，其屏蔽了底层的数据库操作，供具体的Service类来调用。DaoConfig类是工具类（DAO工厂类），Service类通过DaoConfig类来获得相应的DAO接口，而不用关心底层的具体数据库操作，实现了如图2中{耦合2}的解耦。 <BR><BR>com.ibatis.jpetstore.persistence.sqlmapdao包下的类是对应DAO接口的具体实现，在JpetStore4.0中采用了ibatis来实现ORM。这些实现类继承BaseSqlMapDao类，而BaseSqlMapDao类则继承ibatis DAO 框架中的SqlMapDaoTemplate类。ibatis的配置文件存放在com.ibatis.jpetstore.persistence.sqlmapdao.sql目录下。这些类和配置文件位于数据层 <BR><BR>Domain类位于com.ibatis.jpetstore.domain包下，是普通的javabean。在这里用作数据传输对象（DTO），贯穿视图层、业务层和数据层，用于在不同层之间传输数据。剩下的部分就比较简单了，请看具体的源代码，非常清晰。 <BR><BR>2.5. 需要改造的地方<BR><BR>JpetStore4.0的关键就在struts Action类和form bean类上，这也是其精华之一（虽然该实现方式是试验性，待扩充和验证），在此次改造中我们要保留下来，即控制层一点不变，表现层获取相应业务类的方式变了（要加载spring环境），其它保持不变。要特别关注的改动是业务层和持久层，幸运的是JpetStore4.0设计非常好，需要改动的地方非常少，而且由模式可循，如下：<BR><BR>1. 业务层和数据层用Spring BeanFactory机制管理。<BR>2. 业务层的事务由spring 的aop通过声明来完成。<BR>3. 表现层（form bean）获取业务类的方法改由自定义工厂类来实现（加载spring环境）。<BR><BR>3. JPetStore的改造<BR><BR>3.1. 改造后的架构<BR><BR>
<CENTER><IMG src="http://tech.ccidnet.com/pub/attachment/2005/2/397093.gif"></CENTER><BR><BR>其中红色部分是要增加的部分，蓝色部分是要修改的部分。下面就让我们逐一剖析。<BR><BR>3.2. Spring Context的加载<BR>为了在Struts中加载Spring Context，一般会在struts-config.xml的最后添加如下部分：<BR><BR>
<CENTER><CCID_NOBR>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=400 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code style="FONT-SIZE: 9pt" bgColor=#e6e6e6><PRE><CCID_CODE>&lt;plug-in className="org.springframework.web.struts.ContextLoaderPlugIn"&gt;
&lt;set-property property="contextConfigLocation"
value="/WEB-INF/applicationContext.xml" /&gt;
&lt;/plug-in&gt;</CCID_CODE></PRE></TD></TR></TBODY></TABLE></CCID_NOBR></CENTER><BR><BR>Spring在设计时就充分考虑到了与Struts的协同工作，通过内置的Struts Plug-in在两者之间提供了良好的结合点。但是，因为在这里我们一点也不改动JPetStore的控制层(这是JpetStore4.0的精华之一)，所以本文不准备采用此方式来加载ApplicationContext。我们利用的是spring framework 的BeanFactory机制,采用自定义的工具类（bean工厂类）来加载spring的配置文件，从中可以看出Spring有多灵活，它提供了各种不同的方式来使用其不同的部分/层次，您只需要用你想用的，不需要的部分可以不用。 <BR><BR>具体的来说，就是在com.ibatis.spring包下创建CustomBeanFactory类，spring的配置文件applicationContext.xml也放在这个目录下。以下就是该类的全部代码，很简单： <BR><BR>
<CENTER><CCID_NOBR>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=400 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code style="FONT-SIZE: 9pt" bgColor=#e6e6e6><PRE><CCID_CODE>public final class CustomBeanFactory {
	static XmlBeanFactory factory = null;
	static {
		Resource is = new
InputStreamResource( CustomBeanFactory.class.getResourceAsStream("applicationContext.xml"));
		factory = new XmlBeanFactory(is);			
	}
	public static Object getBean(String beanName){
		return factory.getBean(beanName);
	}
}</CCID_CODE></PRE></TD></TR></TBODY></TABLE></CCID_NOBR></CENTER><BR><BR>实际上就是封装了Spring 的XMLBeanFactory而已，并且Spring的配置文件只需要加载一次，以后就可以直接用CustomBeanFactory.getBean("someBean")来获得需要的对象了(例如someBean)，而不需要知道具体的类。CustomBeanFactory类用于{耦合1}的解耦。CustomBeanFactory类在本文中只用于表现层的form bean对象获得service类的对象，因为我们没有把form bean对象配置在applicationContext.xml中。但是，为什么不把表现层的form bean类也配置起来呢，这样就用不着这CustomBeanFactory个类了，Spring会帮助我们创建需要的一切？问题的答案就在于form bean类是struts的ActionForm类！如果大家熟悉struts，就会知道ActionForm类是struts自动创建的：在一次请求中，struts判断，如果ActionForm实例不存在，就创建一个ActionForm对象，把客户提交的表单数据保存到ActionForm对象中。因此formbean类的对象就不能由spring来创建，但是service类以及数据层的DAO类可以，所以只有他们在spring中配置。所以，很自然的，我们就创建了CustomBeanFactory类，在表现层来衔接struts和spring。就这么简单，实现了另一种方式的{耦合一}的解耦。 <BR><BR>3.3. 表现层 <BR><BR>面分析到，struts和spring是在表现层衔接起来的，那么表现层就要做稍微的更改，即所需要的service类的对象创建上。以表现层的AccountBean类为例：原来的源代码如下 <BR><BR>
<CENTER><CCID_NOBR>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=400 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code style="FONT-SIZE: 9pt" bgColor=#e6e6e6><PRE><CCID_CODE>private static final AccountService accountService 
= AccountService.getInstance();
private static final CatalogService catalogService 
= CatalogService.getInstance();</CCID_CODE></PRE></TD></TR></TBODY></TABLE></CCID_NOBR></CENTER><BR><BR>改造后的源代码如下 <BR><BR>
<CENTER><CCID_NOBR>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=400 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code style="FONT-SIZE: 9pt" bgColor=#e6e6e6><PRE><CCID_CODE>private static final AccountService accountService 
= (AccountService)CustomBeanFactory.getBean("AccountService");
private static final CatalogService catalogService
= (CatalogService)CustomBeanFactory.getBean("CatalogService");</CCID_CODE></PRE></TD></TR></TBODY></TABLE></CCID_NOBR></CENTER><BR><BR>其他的几个presentation类以同样方式改造。这样，表现层就完成了。关于表现层的其它部分如JSP等一概不动。也许您会说，没有看出什么特别之处的好处啊？你还是额外实现了一个工厂类。别着急，帷幕刚刚开启，spring是在表现层引入，但您发没发现： <BR><BR>presentation类仅仅面向service类的接口编程，具体"AccountService"是哪个实现类，presentation类不知道，是在spring的配置文件里配置。（本例中，为了最大限度的保持原来的代码不作变化，没有抽象出接口）。Spring鼓励面向接口编程，因为是如此的方便和自然，当然您也可以不这么做。 <BR><BR>CustomBeanFactory这个工厂类为什么会如此简单，因为其直接使用了Spring的BeanFactory。Spring从其核心而言，是一个DI容器，其设计哲学是提供一种无侵入式的高扩展性的框架。为了实现这个目标，Spring 大量引入了Java 的Reflection机制，通过动态调用的方式避免硬编码方式的约束，并在此基础上建立了其核心组件BeanFactory，以此作为其依赖注入机制的实现基础。org.springframework.beans包中包括了这些核心组件的实现类，核心中的核心为BeanWrapper和BeanFactory类。 <BR>3.4. 持久层在讨论业务层之前，我们先看一下持久层，如下图所示：<BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR>
<CENTER><IMG src="http://tech.ccidnet.com/pub/attachment/2005/2/397095.jpg"></CENTER><BR><BR>在上文中，我们把iface包下的DAO接口归为业务层，在这里不需要做修改。ibatis的sql配置文件也不需要改。要改的是DAO实现类，并在spring的配置文件中配置起来。<BR><BR>1、修改基类<BR><BR>所有的DAO实现类都继承于BaseSqlMapDao类。修改BaseSqlMapDao类如下：<BR><BR>
<CENTER><CCID_NOBR>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=400 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code style="FONT-SIZE: 9pt" bgColor=#e6e6e6><PRE><CCID_CODE>public class BaseSqlMapDao extends SqlMapClientDaoSupport
{
  protected static final int PAGE_SIZE = 4;
  protected SqlMapClientTemplate smcTemplate 
  = this.getSqlMapClientTemplate();
  public BaseSqlMapDao()
  { 
	}
}</CCID_CODE></PRE></TD></TR></TBODY></TABLE></CCID_NOBR></CENTER><BR><BR>使BaseSqlMapDao类改为继承于Spring提供的SqlMapClientDaoSupport类，并定义了一个保护属性smcTemplate，其类型为SqlMapClientTemplate。 <BR><BR>2、修改DAO实现类 <BR><BR>所有的DAO实现类还是继承于BaseSqlMapDao类，实现相应的DAO接口，但其相应的DAO操作委托SqlMapClientTemplate来执行，以AccountSqlMapDao类为例，部分代码如下： <BR><BR>
<CENTER><CCID_NOBR>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=400 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code style="FONT-SIZE: 9pt" bgColor=#e6e6e6><PRE><CCID_CODE>public List getUsernameList() 
{
    return smcTemplate.queryForList("getUsernameList", null);
}
  public Account getAccount(String username, String password)
{
    Account account = new Account();
    account.setUsername(username);
    account.setPassword(password);
    return (Account)
	smcTemplate.queryForObject
	("getAccountByUsernameAndPassword", account);
}
  public void insertAccount(Account account)
{
 smcTemplate.update("insertAccount", account);
 smcTemplate.update("insertProfile", account);
 smcTemplate.update("insertSignon", account);
}</CCID_CODE></PRE></TD></TR></TBODY></TABLE></CCID_NOBR></CENTER><BR><BR>就这么简单，所有函数的签名都是一样的，只需要查找替换就可以了！<BR>、除去工厂类以及相应的配置文件<BR><BR>除去DaoConfig.java这个DAO工厂类和相应的配置文件dao.xml，因为DAO的获取现在要用spring来管理。<BR><BR>4、DAO在Spring中的配置（applicationContext.xml）<BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR>
<CENTER><CCID_NOBR>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=400 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code style="FONT-SIZE: 9pt" bgColor=#e6e6e6><PRE><CCID_CODE>&lt;bean id="dataSource" 
        class="org.springframework.jdbc.datasource.DriverManagerDataSource"&gt;
        &lt;property name="driverClassName"&gt;
            &lt;value&gt;org.hsqldb.jdbcDriver&lt;/value&gt;
        &lt;/property&gt;
        &lt;property name="url"&gt;
            &lt;value&gt;jdbc:hsqldb:hsql://localhost/xdb&lt;/value&gt;
        &lt;/property&gt;
        &lt;property name="username"&gt;
            &lt;value&gt;sa&lt;/value&gt;
        &lt;/property&gt;
        &lt;property name="password"&gt;
            &lt;value&gt;&lt;/value&gt;
        &lt;/property&gt;
    &lt;/bean&gt;    
    &lt;!-- ibatis sqlMapClient config --&gt;
    &lt;bean id="sqlMapClient" 
        class="org.springframework.orm.ibatis.SqlMapClientFactoryBean"&gt;
        &lt;property name="configLocation"&gt;
            &lt;value&gt; 
   classpath:com\ibatis\jpetstore\persistence\sqlmapdao\sql\sql-map-config.xml
            &lt;/value&gt;
        &lt;/property&gt;
        &lt;property name="dataSource"&gt;
            &lt;ref bean="dataSource"/&gt;
        &lt;/property&gt;    
    &lt;/bean&gt;
    &lt;!-- Transactions --&gt;
    &lt;bean id="TransactionManager" 
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager"&gt;
        &lt;property name="dataSource"&gt;
            &lt;ref bean="dataSource"/&gt;
        &lt;/property&gt;
    &lt;/bean&gt;
    &lt;!-- persistence layer --&gt;
    &lt;bean id="AccountDao" 
        class="com.ibatis.jpetstore.persistence.sqlmapdao.AccountSqlMapDao"&gt;
        &lt;property name="sqlMapClient"&gt;
            &lt;ref local="sqlMapClient"/&gt;
        &lt;/property&gt;
    &lt;/bean&gt;</CCID_CODE></PRE></TD></TR></TBODY></TABLE></CCID_NOBR></CENTER><BR><BR>1. 我们首先创建一个数据源dataSource，在这里配置的是hsqldb数据库。如果是ORACLE数据库，driverClassName的值是"oracle.jdbc.driver.OracleDriver"，URL的值类似于"jdbc:oracle:thin:@wugfMobile:1521:cdcf"。数据源现在由spring来管理，那么现在我们就可以去掉properties目录下database.properties这个配置文件了；还有不要忘记修改sql-map-config.xml，去掉<PROPERTIES resource="properties/database.properties" />对它的引用。 <BR><BR>2. sqlMapClient节点。这个是针对ibatis SqlMap的SqlMapClientFactoryBean配置。实际上配置了一个sqlMapClient的创建工厂类。configLocation属性配置了ibatis映射文件的名称。dataSource属性指向了使用的数据源，这样所有使用sqlMapClient的DAO都默认使用了该数据源，除非在DAO的配置中另外显式指定。 <BR><BR>3. TransactionManager节点。定义了事务，使用的是DataSourceTransactionManager。 <BR><BR>4. 下面就可以定义DAO节点了，如AccountDao，它的实现类是com.ibatis.jpetstore.persistence.sqlmapdao.AccountSqlMapDao，使用的SQL配置从sqlMapClient中读取，数据库连接没有特别列出，那么就是默认使用sqlMapClient配置的数据源datasource。 <BR><BR>这样，我们就把持久层改造完了，其他的DAO配置类似于AccountDao。怎么样？简单吧。这次有接口了：） AccountDao接口－&gt;AccountSqlMapDao实现。 <BR><BR>3.5. 业务层 <BR><BR>业务层的位置以及相关类，如下图所示：在这个例子中只有3个业务类，我们以OrderService类为例来改造，这个类是最复杂的，其中涉及了事务。 <BR><BR>1、在ApplicationContext配置文件中增加bean的配置： <BR><BR>
<CENTER><CCID_NOBR>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=400 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code style="FONT-SIZE: 9pt" bgColor=#e6e6e6><PRE><CCID_CODE>&lt;bean id="OrderService" 
        class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"&gt;
        &lt;property name="transactionManager"&gt;
            &lt;ref local="TransactionManager"&gt;&lt;/ref&gt;
        &lt;/property&gt;
        &lt;property name="target"&gt;
            &lt;bean class="com.ibatis.jpetstore.service.OrderService"&gt;
                &lt;property name="itemDao"&gt;
                    &lt;ref bean="ItemDao"/&gt;
                &lt;/property&gt;
                &lt;property name="orderDao"&gt;
                    &lt;ref bean="OrderDao"/&gt;
                &lt;/property&gt;
                &lt;property name="sequenceDao"&gt;
                    &lt;ref bean="SequenceDao"/&gt;
                &lt;/property&gt;
            &lt;/bean&gt;
        &lt;/property&gt;
        &lt;property name="transactionAttributes"&gt;
            &lt;props&gt;
                &lt;prop key="insert*"&gt;PROPAGATION_REQUIRED&lt;/prop&gt;
            &lt;/props&gt;
        &lt;/property&gt;
    &lt;/bean&gt;</CCID_CODE></PRE></TD></TR></TBODY></TABLE></CCID_NOBR></CENTER><BR><BR>定义了一个OrderService，还是很容易懂的。为了简单起见，使用了嵌套bean，其实现类是com.ibatis.jpetstore.service.OrderService，分别引用了ItemDao，OrderDao，SequenceDao。该bean的insert*实现了事务管理(AOP方式)。TransactionProxyFactoryBean自动创建一个事务advisor， 该advisor包括一个基于事务属性的pointcut,因此只有事务性的方法被拦截。 <BR><BR>2、业务类的修改，以OrderService为例： <BR><BR>
<CENTER><CCID_NOBR>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=400 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code style="FONT-SIZE: 9pt" bgColor=#e6e6e6><PRE><CCID_CODE>public class OrderService {

   /* Private Fields */
  private ItemDao itemDao;
  private OrderDao orderDao;
  private SequenceDao sequenceDao;

  /* Constructors */

  public OrderService() {
  }

/**
 * @param itemDao 要设置的 itemDao。
 */
public final void setItemDao(ItemDao itemDao) {
	this.itemDao = itemDao;
}
/**
 * @param orderDao 要设置的 orderDao。
 */
public final void setOrderDao(OrderDao orderDao) {
	this.orderDao = orderDao;
}
/**
 * @param sequenceDao 要设置的 sequenceDao。
 */
public final void setSequenceDao(SequenceDao sequenceDao) {
	this.sequenceDao = sequenceDao;
}
//剩下的部分
…….
}</CCID_CODE></PRE></TD></TR></TBODY></TABLE></CCID_NOBR></CENTER><BR><BR>红色部分为修改部分。Spring采用的是Type2的设置依赖注入，所以我们只需要定义属性和相应的设值函数就可以了，ItemDao，OrderDao，SequenceDao的值由spring在运行期间注入。构造函数就可以为空了，另外也不需要自己编写代码处理事务了（事务在配置中声明），daoManager.startTransaction();等与事务相关的语句也可以去掉了。和原来的代码比较一下，是不是处理精简了很多！可以更关注业务的实现。 <BR><BR>4. 结束语 <BR><BR>ibatis是一个功能强大实用的SQL Map工具，可以直接控制SQL,为系统设计提供了更大的自由空间。其提供的最新示例程序JpetStore 4.0,设计优雅，应用了迄今为止很多最佳实践和设计模式，非常适于学习以及在此基础上创建轻量级的J2EE WEB应用程序。JpetStore 4.0是基于struts的，本文在此基础上，最大程度保持了原有设计的精华以及最小的代码改动量，在业务层和持久化层引入了Spring。在您阅读了本文以及改造后的源代码后，会深切的感受到Spring带来的种种好处：自然的面向接口的编程，业务对象的依赖注入，一致的数据存取框架和声明式的事务处理，统一的配置文件…更重要的是Spring既是全面的又是模块化的，Spring有分层的体系结构，这意味着您能选择仅仅使用它任何一个独立的部分，就像本文，而它的架构又是内部一致。 <BR><BR>(T117) <BR></CENTER><img src ="http://www.blogjava.net/sgsoft/aggbug/2257.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sgsoft/" target="_blank">海天一鸥</a> 2005-03-20 16:46 <a href="http://www.blogjava.net/sgsoft/articles/2257.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用高效的日志工具—Log4J</title><link>http://www.blogjava.net/sgsoft/articles/2256.html</link><dc:creator>海天一鸥</dc:creator><author>海天一鸥</author><pubDate>Sun, 20 Mar 2005 08:36:00 GMT</pubDate><guid>http://www.blogjava.net/sgsoft/articles/2256.html</guid><wfw:comment>http://www.blogjava.net/sgsoft/comments/2256.html</wfw:comment><comments>http://www.blogjava.net/sgsoft/articles/2256.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sgsoft/comments/commentRss/2256.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sgsoft/services/trackbacks/2256.html</trackback:ping><description><![CDATA[<SPAN class=myp11><FONT id=zoom>大家在编程时经常不可避免地要使用到一些日志操作，比如开发阶段的调试信息、运行时的日志记录及审计。调查显示，日志代码占代码总量的4％。通常大家可以简单地使用System.out.println()语句输出日志信息，但是往往会有一些判断，比如： <BR><BR><CCID_NOBR>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=550 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code bgColor=#e6e6e6><PRE><CCID_CODE>if (someCondition) {
 System.out.println("some information.");
}</CCID_CODE></PRE></TD></TR></TBODY></TABLE></CCID_NOBR><BR><BR>这些判断造成正常的程序逻辑中混杂了大量的输出语句。而在开发阶段写下的这些判断仅为了调试的语句，在开发完成时需要查找并移除。部署运行后，尤其是在一些企业应用系统中，还经常需要进一步调试，这时就遇到了更大的麻烦。所以，我们需要一套完备的、灵活的、可配置的日志工具。Log4J就是优秀的选择。 <BR><BR>Log4J是Apache软件基金会Jakarta项目下的一个子项目，是用Java编写的优秀日志工具包。通过Log4J可以在不修改代码的情况下，方便、灵活地控制任意粒度的日志信息的开启或关闭，然后使用定制的格式，把日志信息输出到一个或多个需要的地方。并且，Log4J还有一条平滑的学习曲线，在三分钟内就可学会它的简单使用。随着使用深入，你会发现Log4J功能的强大，几乎可以满足日志方面的所有需要。 <BR><BR>
<CENTER><FONT color=#000099><STRONG>快速入门</STRONG></FONT></CENTER><BR><BR>先看一段代码，看看Log4J是多么易于上手，代码如下： <BR><BR><CCID_NOBR>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=550 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code bgColor=#e6e6e6><PRE><CCID_CODE>package org.javaresearch.log4j;
import org.apache.log4j.*;
public class TestLog4J {
 static Logger log = Logger.getLogger(TestLog4J.class.getName());
 public static void main(String args[]) {
  BasicConfigurator.configure();
  // logging的各种方法
  cat.debug("Start of main()");
  cat.info("Just testing a log message with priority set to INFO");
  cat.warn("Just testing a log message with priority set to WARN");
  cat.error("Just testing a log message with priority set to ERROR");
  cat.fatal("Just testing a log message with priority set to FATAL");
  // 另一种不方便的格式
  cat.log(Priority.DEBUG, "Testing a log message use a alternate form");
  log.debug("End of main().");
 }
}</CCID_CODE></PRE></TD></TR></TBODY></TABLE></CCID_NOBR><BR><BR>把这段代码保存在一个目录下，编译运行（注意要把log4j-1.2.7.jar包含入类路径中），程序输出如下： <BR><BR><CCID_NOBR>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=550 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code bgColor=#e6e6e6><PRE><CCID_CODE>0 [main] DEBUG TestLog4J  - Start of main()
10 [main] INFO TestLog4J  - Just testing a log message with priority set to INFO
20 [main] WARN TestLog4J  - Just testing a log message with priority set to WARN
30 [main] ERROR TestLog4J  - Just testing a log message with priority set to ERROR
30 [main] FATAL TestLog4J  - Just testing a log message with priority set to FATAL
40 [main] DEBUG TestLog4J  - Testing a log message use a alternate form
50 [main] DEBUG TestLog4J  - End of main().</CCID_CODE></PRE></TD></TR></TBODY></TABLE></CCID_NOBR><BR><BR>首先解释一下上面输出结果的意义。第一个数字是指程序开始运行到运行该日志语句所经历的毫秒数（用来做一点运行效率分析也不错），“[main]”是日志事件发生的线程，随后的“DEBUG”、“INFO”等信息是相应日志信息的优先级别，“TestLog4”是当前Logger的实例名，最后是日志信息。 <BR><BR>在这段程序中，使用了Log4J提供的一个基本配置类BasicConfigurator对Log4J进行初始化。但在实际使用时通常不这么做，因为这多少有点“硬”编码。今后如果要修改Log4J的配置，就需要修改、重新编译代码，这通常不是大家所希望的。通常，我们都提供一个名为log4j.properties的文件，在第一次调用到Log4J时，Log4J会在类路径中定位这个文件，并读入这个文件完成的配置。这个配置文件告诉Log4J以什么样的格式、把什么样的信息、输出到什么地方。我们来看一个简单的log4j.properties配置文件的示例，代码如下： <BR><BR><CCID_NOBR>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=550 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code bgColor=#e6e6e6><PRE><CCID_CODE>log4j.rootLogger=DEBUG, A1
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern= "%-4r [%t] %-5p %c %x - %m%n</CCID_CODE></PRE></TD></TR></TBODY></TABLE></CCID_NOBR><BR><BR>把上面的内容存储为log4j.properties，并放到和TestLog4J.class同一目录下（当然也可以放到其它任何目录，只要该目录被包含到类路径中即可）。具体这些配置文件中每行的意义，在以后章节会有详细的说明，现在可以先跳过。现在你可以注释掉上面程序中的“BasicConfigurator. configure();”语句，然后使用log4j.properties属性文件完成Log4J的配置，重新编译、运行，就得到和上面一样的结果。 <BR><BR>这样做有什么好处呢？现在就初步领略一些Log4J的灵活、强大功能。比如系统要上线了，希望输出一些警告和错误信息，这时仅需要修改log4j.properties文件中的“log4j.rootCategory=DEBUG, A1”即可，然后设置日志输出的最低级别是WARN，设置为“log4j.root Category=WARN, A1”。此时不需要修改任何代码，重新运行系统，输出结果就变成了： <BR><BR><CCID_NOBR>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=550 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code bgColor=#e6e6e6><PRE><CCID_CODE>20 [main] WARN TestLog4J  - Just testing a log message with priority set to WARN
30 [main] ERROR TestLog4J  - Just testing a log message with priority set to ERROR
30 [main] FATAL TestLog4J  - Just testing a log message with priority set to FATAL</CCID_CODE></PRE></TD></TR></TBODY></TABLE></CCID_NOBR><BR><BR>
<CENTER><FONT color=#000099><STRONG>原理分析</STRONG></FONT></CENTER><BR><BR>Log4J有三个主要部件，它们是记录器（Loggers）、输出源（Appenders）和布局（Logouts）。记录器按照布局中指定的格式把日志信息写入一个或多个输出源。输出源可以是控制台、文本文件、XML文件或Socket，甚至还可以把信息写入到Windows事件日志或通过电子邮件发送，这都需要相应的类来处理，这些相关的类是ConsoleAppender、FileAppender、SocketAppender、NtEventLogAppender和JMSAppender。 <BR><BR><B>记录器（Logger）</B> <BR><BR>首先让我们看Logger类，代码如下： <BR><BR><CCID_NOBR>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=550 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code bgColor=#e6e6e6><PRE><CCID_CODE>package org.apache.log4j;
public class Logger {
 //创建和恢复方法
 public static Logger getRootLogger();
 public static Logger getLogger(String name);
 public static Logger getLogger(Class clazz);
 // 打印方法
 public void debug(Object message);
 public void info(Object message);
 public void warn(Object message);
 public void error(Object message);
 public void fatal(Object message);
 // 常用打印方法
 public void log(Level l, Object message);
}</CCID_CODE></PRE></TD></TR></TBODY></TABLE></CCID_NOBR><BR><BR>从这段代码中可以看出Logger的基本使用。首先需要获取一个Logger对象，获取Logger对象的语句为： <BR><BR><CCID_NOBR>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=550 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code bgColor=#e6e6e6><PRE><CCID_CODE>Logger logger = Logger.getLogger(JavaLoggingExample.class.getName());</CCID_CODE></PRE></TD></TR></TBODY></TABLE></CCID_NOBR><BR><BR>有了这个Logger对象，就可以在需要的地方方便地输出日志信息。对于这些信息是否输出、输出的格式等，都可以通过配置文件方便地配置，而不需要修改代码，这就是Log4J带来的方便之处。 <BR><BR><B>记录器的层次结构</B> <BR><BR>使用Log4J的Logger.getLogger()方法时会得到一个Logger的实例。如果一个应用中包含了上千个类，那么也几乎需要上千个Logger实例。如何对这上千个Logger实例进行方便地配置，就是一个很重要的问题。Log4J采用了一种树状的继承层次巧妙地解决了这个问题。在Log4J中Logger是具有层次关系的。它有一个共同的根，位于最上层，其它Logger遵循类似包的层次，比如： <BR><BR><CCID_NOBR>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=550 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code bgColor=#e6e6e6><PRE><CCID_CODE>static Logger root = Logger.getRootLogger();
static Logger log1 = Logger.getLogger("org");
static Logger log2 = Logger.getLogger("org.javaresearch");
static Logger log3 = Logger.getLogger("org.javaresearch.log4j.TestLog4J");</CCID_CODE></PRE></TD></TR></TBODY></TABLE></CCID_NOBR><BR><BR>上面代码中，log1是log2的父亲，是log3的祖先，而root是所有log1、log2、log3的祖先，它们都从root中继承。所以，一般情况下，仅需要配置好rootLogger，其它子记录器都会从中继承rootLogger的配置。如果修改了rootLogger的配置，其它所有的子记录器也会继承这种变化。这样就大大地方便了配置。现在回头看看在“快速入门”中的配置文件，我们仅配置了rootLogger，就可以控制所有的Logger的行为。 <BR><BR><B>级别（Level）</B> <BR><BR>Log4J中的一个核心概念是日志级别是有序的。Log4J内置了5种日志级别为： <BR><BR><CCID_NOBR>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=550 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code bgColor=#e6e6e6><PRE><CCID_CODE>DEBUG  &lt;  INFO  &lt;  WARN  &lt;  ERROR  &lt;  FATAL</CCID_CODE></PRE></TD></TR></TBODY></TABLE></CCID_NOBR><BR><BR>右边的级别比左边的高。每一个Logger实例都有一个日志级别，上面的5种输出方法就是对应于5种不同级别的日志请求。比如，如果c是一个Logger实例，c.info("some information")就是一个INFO级别的日志请求。一个日志请求会不会输出，取决于该Logger实例的日志级别和该日志请求级别的比较。规则如下： <BR><BR>假如在一个级别为p的Logger实例中发生一个级别为q的日志请求，则当q &gt;= p时请求才会启用。 <BR><BR>我们先来看实例2代码如下： <BR><BR><CCID_NOBR>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=550 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code bgColor=#e6e6e6><PRE><CCID_CODE>// 得到一个logger 实例 "com.foo"
Logger  logger = Logger.getLogger("com.foo")
// 现在设置logger的级别，但正常情况是不需要刻意设置lgger级别的，因为它已经在配置文件中完成了
logger.setLevel(Level.INFO);
Logger barlogger = Logger.getLogger("com.foo.Bar");
//因为 WARN &gt;= INFO，这个请求是可以实现的
logger.warn("Low fuel level.");
// 因为DEBUG &lt; INFO，所以这个请求是无法实现的
logger.debug("Starting search for nearest gas station.");
// logger实例"com.foo.Bar"将从"com.foo"继承级别，这样，因为INFO &gt;= 
INFO，所以可以实现下面的请求
barlogger.info("Located nearest gas station.");
//因为DEBUG &lt; INFO，这个请求是不能实现的 
barlogger.debug("Exiting gas station search");</CCID_CODE></PRE></TD></TR></TBODY></TABLE></CCID_NOBR><BR><BR><B>布局（Layout）</B> <BR><BR>Log4J采用类似C语言中的printf函数的打印格式格式化日志信息，打印参数见表1如下： <BR><BR>
<CENTER><CCID_NOBR>
<TABLE class=content width=502 border=1>
<TBODY>
<TR>
<TD>%m</TD>
<TD>输出代码中指定的消息</TD></TR>
<TR>
<TD>%p</TD>
<TD>输出优先级，即DEBUG，INFO，WARN，ERROR，FATAL</TD></TR>
<TR>
<TD>%r</TD>
<TD>输出自应用启动到输出该log信息耗费的毫秒数</TD></TR>
<TR>
<TD>%c</TD>
<TD>输出所属的类目，通常就是所在类的全名</TD></TR>
<TR>
<TD>%t</TD>
<TD>输出产生该日志事件的线程名</TD></TR>
<TR>
<TD>%n</TD>
<TD>输出一个回车换行符，Windows平台为“\r\n”，Unix平台为“\n”</TD></TR>
<TR>
<TD>%d</TD>
<TD>输出日志时间点的日期或时间，默认格式为ISO8601，也可以在其后指定格式，比如：%d{yyy MMM dd HH:mm:ss,SSS}，输出类似：2002年10月18日 22：10：28，921</TD></TR>
<TR>
<TD>%l</TD>
<TD>输出日志事件的发生位置，包括类目名、发生的线程，以及在代码中的行数。举例：Testlog4.main(TestLog4.java:10)</TD></TR></TBODY></TABLE></CCID_NOBR></CENTER></FONT></SPAN>
<P align=center><BR><SPAN class=myp11><FONT id=zoom>&nbsp;</P>
<CENTER><FONT color=#000099><STRONG>基本应用</STRONG></FONT></CENTER>
<P align=center><BR><BR><B>Log4J的配置</B> <BR><BR>现在来看log4j.properties配置文件的意义。第一行指定了根Logger的级别是DEBUG，并将此指定输出到A1。A1就是第二行定义的org.apache.log4j.ConsoleAppender，此行表示将A1输出到控制台。第三行规定了输出到A1的格式为org.apache.log4j.PatternLayout。第四行规定了输出到A1格式的转换模式为org.javaresearch.log4j.TestLog4J。 <BR><BR>很多成熟的服务器类的软件日志信息会输出到控制台，同时输出到日志文件备查。使用Log4J可以在不改变任何代码的情况下，仅通过修改配置文件就可以轻松地完成这项功能。相关配置文件如下： <BR><BR><CCID_NOBR>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=550 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code bgColor=#e6e6e6><PRE><CCID_CODE>#### Use two appenders, one to log to console, another to log to a file
log4j.rootCategory=debug, stdout, R

# Print only messages of priority WARN or higher for your category
log4j.category.your.category.name=WARN

#### First appender writes to console
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout

# Pattern to output the caller's file name and line number.
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n

#### Second appender writes to a file
log4j.appender.R=org.apache.log4j.RollingFileAppender
log4j.appender.R.File=example.log

# Control the maximum log file size
log4j.appender.R.MaxFileSize=100KB
# Archive log files (one backup file here)
log4j.appender.R.MaxBackupIndex=1

log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n</CCID_CODE></PRE></TD></TR></TBODY></TABLE></CCID_NOBR><BR><BR>这个配置文件指定了两个输出源stdout和R。前者把日志信息输出到控制台，后者是一个轮转日志文件。最大的文件是100KB，当一个日志文件达到最大尺寸时，Log4J会自动把example.log重命名为example.log.1，然后重建一个新的example.log文件，依次轮转。 <BR><BR><B>在Web应用中使用</B> <BR><BR>在Web应用中，应该在哪儿对Log4J进行配置呢？首先要明确，Log4J必须在应用的其它代码执行前完成初始化。因为Servlet是在Web服务器启动时立即装入的，所以，在Web应用中一般使用一个专门的Servlet来完成Log4J的配置，并保证在web.xml的配置中，这个Servlet位于其它Servlet之前。下面是一个例子，代码如下： <BR><BR><CCID_NOBR>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=550 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code bgColor=#e6e6e6><PRE><CCID_CODE>package org.javaresearch.log4j;
import java.io.*;
import javax.servlet.*;
import org.apache.log4j.*;
public class Log4JInit extends HttpServlet {
 public void init() throws ServletException {
  String prefix = getServletContext().getRealPath("/");
  String file = getServletConfig().getInitParameter("log4j-config-file");
  // 从Servlet参数读取log4j的配置文件 
  if (file != null) {
   PropertyConfigurator.configure(prefix + file);
  }
 }
 public void doGet(HttpServletRequest request,HttpServletResponse response)throws 
IOException, ServletException {}
 public void doPost(HttpServletRequest request,HttpServletResponse response)throws 
IOException, ServletException {}
}</CCID_CODE></PRE></TD></TR></TBODY></TABLE></CCID_NOBR><BR><BR><CCID_NOBR>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=550 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code bgColor=#e6e6e6><PRE><CCID_CODE>&lt;servlet&gt;
  &lt;servlet-name&gt;log4jinit&lt;/servlet-name&gt; 
   &lt;servlet-class&gt;org.javaresearch. log4j.Log4JInit&lt;/servlet-class&gt;	  	
   &lt;init-param&gt;
   &lt;param-name&gt; log4j-config-file &lt;/param-name&gt; 
	&lt;param-value&gt;/properties/log4j.properties&lt;/param-value&gt; 
   &lt;/init-param&gt;
   &lt;load-on-startup&gt;1&lt;/load-on-startup&gt;
  &lt;/servlet&gt;</CCID_CODE></PRE></TD></TR></TBODY></TABLE></CCID_NOBR><BR><BR>注意：上面的load-on-startup应设为1，以便在Web容器启动时即装入该Servlet。log4j.properties文件放在根的properties子目录中，也可以把它放在其它目录中。应该把.properties文件集中存放，这样方便管理。 <BR><BR></P>
<CENTER><FONT color=#000099><STRONG>高级话题</STRONG></FONT></CENTER>
<P align=center><BR><BR><B>性能</B> <BR><BR>在记录一些日志信息时，会一定程度地影响系统的运行效率，这时日志工具是否高效就是一个关键。Log4J的首要设计目标就是高效，一些关键组件都重写过很多次以不断提高性能。根据Log4J项目小组的报告，在AMD Duron 800MHz ＋ JDK1.3.1的环境下，Log4J判断一条日志语句是否需要输出仅需要5纳秒。实际的日志语句执行的也非常快速，从使用SimpleLayout的21微秒（几乎与System.out.println一样快），到使用TTCCLayout的37微秒不等。 <BR><BR><B>嵌套诊断环境NDC</B> <BR><BR>在多用户并发的环境下，通常是由不同的线程分别处理不同的客户端请求。此时要在日志信息中区分出不同的客户端，你可以为每一个线程生成一个Logger，从而从一堆日志信息中区分出哪些信息是属于哪个线程的，但这种方式并不高效。Log4J巧妙地使用了Neil Harrison提出的“NDC（嵌套诊断环境）”机制来解决这个问题。Log4J为同一类别的线程生成一个Logger，多个线程共享使用，而它仅在日志信息中添加能够区分不同线程的信息。NDC是什么？举例来说，如果一个Servlet接到并发请求时，为每一个客户端创建一个新的线程，然后分配一个用于保存该请求上下文的NDC堆栈。该上下文可能是发出请求的主机名、IP地址或其它任何可以用于标识该请求的信息。这样，由于不同的客户端处理线程具有不同的NDC堆栈，即使这个Servlet同时生成多个线程处理不同的请求，这些日志信息仍然可以区分出来，就好像Log4J为每一个线程都单独生成了一个Logger实例一样。在Log4J中是通过org.apache.log4j.NDC实现这种机制的。使用NDC的方法也很简单，步骤如下： <BR><BR>1. 在进入一个环境时调用NDC.push(String)，然后创建一个NDC； <BR><BR>2. 所做的日志操作输出中包括了NDC的信息； <BR><BR>3. 离开该环境时调用NDC.pop方法； <BR><BR>4. 当从一个线程中退出时调用NDC.remove方法，以便释放资源。 <BR><BR>下面是一个模拟记录来自不同客户端请求事件的例子，代码如下： <BR><BR><CCID_NOBR>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=550 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code bgColor=#e6e6e6><PRE><CCID_CODE>import org.apache.log4j.Logger;
import org.apache.log4j.NDC;
public class TestNDC {
 static Logger log = Logger.getLogger(TestNDC.class.getName());
 public static void main(String[] args) {
  log.info("Make sure %x is in your layout pattern!");
  // 从客户端获得IP地址的例子
  String[] ips = {"192.168.0.10","192.168.0.27"};
  for (int i = 0; i&lt;ips.length ; i++)  // 模拟一个运行方法
  {
   // 将IP放进 NDC中
   NDC.push(ips[i]);
   log.info("A NEW client connected, who's ip should appear in this log message.");
   NDC.pop();
  }
  NDC.remove();
  log.info("Finished.");
 }
}</CCID_CODE></PRE></TD></TR></TBODY></TABLE></CCID_NOBR><BR><BR>注意配置文件中的布局格式中一定要加上%x。系统输出如下： <BR><BR><CCID_NOBR>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=550 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code bgColor=#e6e6e6><PRE><CCID_CODE>INFO   - Make sure %x is in your layout pattern!
INFO  192.168.0.10 - A NEW client connected, who's ip should appear in this log 
message.
INFO  192.168.0.27 - A NEW client connected, who's ip should appear in this log 
message.
INFO   - Finished.</CCID_CODE></PRE></TD></TR></TBODY></TABLE></CCID_NOBR><BR><BR><B>使用Log4J还是JDK logging API</B> <BR><BR>从JDK 1.4.0开始，引入了java.util.logging包。虽然Log4J小组曾竭力游说JCP（Java Community Process）采用Log4J作为JDK 1.4的“标准”日志API，虽然最终因Sun的日志API规范的负责人Graham Hamilton的一句“Merlin的开发已经到了最后阶段，这时不允许再对主要API做出改变”而没有被采纳，但Log4J还是对新的日志API产生了重要影响。那么，我们到底应该采用Log4J还是java.util.logging包呢？下面仅对两者做一简单的比较。 <BR><BR>1. Log4J更加成熟，从1999年10月开始至今已经有3年的时间，并且已经在许多项目中有着成熟的应用。而JDK中的logging包是在1.4之后才引入的，并且不能运行于JDK 1.3之前的版本。Log4J则可以良好地运行于JDK 1.1之后的所有版本。 <BR><BR>2. Log4J已经被移植到多种环境下，包括log4c（C）、log4cpp（C++）、log4perl（Perl）、log4net（.net）等。在这些环境下，可以感受到几乎一致的配置和使用方式。这是JDK中的logging API所不能比拟的。 <BR><BR>3. Log4J还具有更加强力的格式化系统，可以使记录输出时实现简单的模式。但是，它不会增加类而导致格式化工具的扩展。众多的附加程序和处理器使得Log4J数据包成为一个绝佳的选择，所有你所需要的都可能加以实现。 <BR><BR>4. Log4J在性能上做了最大的优化。 <BR><BR>Logging API对于简单的使用是足够的，但它缺少了许多Log4J所具有的功能。所以，如果你需要一个强力的logging机制，就应坚持使用Log4J；而如果只是需要一些简单的控制或文件记录，那么可以使用已经内建在JDK之中的logging API。 <BR><BR>虽然Log4J和JDK logging API是一种竞争关系，但在logging API还在JCP中讨论（JSR47）时，两者之间就已经开始相互影响了。 <BR><BR><B>FAQ</B> <BR><BR><B>1. 如何让Log4J使用指定的配置文件</B> <BR><BR>在启动你的应用时植入系统属性。例如，可以把上面的log4j.properties文件放到\properties的相对路径下，并改名为log.properties，此时如果让Log4J能够找到这个配置文件并正确地初始化，需要这样运行程序： <BR><BR><CCID_NOBR>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=550 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code bgColor=#e6e6e6><PRE><CCID_CODE>D:\..\java -Dlog4j.configuration=. \properties\log.properties YourAppName</CCID_CODE></PRE></TD></TR></TBODY></TABLE></CCID_NOBR><BR><BR>为什么一定要使用系统属性，而不在配置文件中指定呢？很显然，如果把它写入配置文件，那么，Log4J读到它时已经迟了。 <BR><BR><B>2. 如何查看到Log4J的配置过程</B> <BR><BR>可以类似1中的那样，设置系统属性log4j.debug=true，从而打开Log4J的Verbose模式，此时会输出Log4J的初始化过程，这样就会对Log4J的启动有一个更详细的了解。下面是Log4J启动信息的一个示例： <BR><BR><CCID_NOBR>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=550 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code bgColor=#e6e6e6><PRE><CCID_CODE>log4j: Trying to find [log4j.xml] using context classloader 
sun.misc.Launcher$AppClassLoader@92e78c.
log4j: Trying to find [log4j.xml] using sun.misc.Launcher$ExtClassLoader@9fbe93class 
loader.
log4j: Trying to find [log4j.xml] using ClassLoader.getSystemResource().
log4j: Trying to find [log4j.properties] using context classloader 
sun.misc.Launcher$AppClassLoader@92e78c.
log4j: Using URL [file:/D:/java/logging/src/log4j.properties] for automatic log4j 
configuration.
log4j: Reading configuration from URL file:/E:/java/logging/src/log4j.properties
log4j: Parsing for [root] with value=[DEBUG, A1].
log4j: Level token is [DEBUG].
log4j: Category root set to DEBUG
log4j: Parsing appender named "A1".
log4j: Parsing layout options for "A1".
log4j: Setting property [conversionPattern] to [%d %l %-5p %c [%t] - %m%n].
log4j: End of parsing for "A1".
log4j: Parsed "A1" options.
log4j: Finished configuring.
......  // 下面就是应用的日志信息，省略。</CCID_CODE></PRE></TD></TR></TBODY></TABLE></CCID_NOBR><BR></FONT></SPAN></P><img src ="http://www.blogjava.net/sgsoft/aggbug/2256.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sgsoft/" target="_blank">海天一鸥</a> 2005-03-20 16:36 <a href="http://www.blogjava.net/sgsoft/articles/2256.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>版本控制工具－－CVS</title><link>http://www.blogjava.net/sgsoft/articles/737.html</link><dc:creator>海天一鸥</dc:creator><author>海天一鸥</author><pubDate>Wed, 26 Jan 2005 11:11:00 GMT</pubDate><guid>http://www.blogjava.net/sgsoft/articles/737.html</guid><wfw:comment>http://www.blogjava.net/sgsoft/comments/737.html</wfw:comment><comments>http://www.blogjava.net/sgsoft/articles/737.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sgsoft/comments/commentRss/737.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sgsoft/services/trackbacks/737.html</trackback:ping><description><![CDATA[<P><STRONG>版本控制工具</STRONG><BR><STRONG>&nbsp;&nbsp;&nbsp; </STRONG>版本控制是程序开发、管理必不可少的工具，特别是在多人协作的团队中，适宜的版本控制工具可以提高开发效率，消除很多有代码版本带来的问题。本文首先列举没有版本控制工具时可能遇到的问题，再对主流版本控制工具做概要介绍，之后对作为Java开发者首选的版本控制工具CVS的历史、功能、概念做详细的介绍；最后在Eclipse＋CVS环境中，以CVS使用的一个完整流程为例，介绍如何正确的使用CVS工具。<BR><BR><STRONG>为什么要使用版本控制工具？</STRONG><BR>如果没有版本控制工具的协助，在开发中我们经常会遇到下面的一些问题：<BR>一、&nbsp;代码管理混乱。如果是别人添加或删除一个文件，你很难发现。没有办法对文件代码的修改追查跟踪。甚至出现文件丢失，或新版本代码被同伴无意覆盖等现象。<BR>二、&nbsp;解决代码冲突困难。当大家同时修改一个公共文件时，解决代码冲突是一件很头疼的事。最原始的办法是手工打开冲突文件，逐行比较，再手工粘贴复制。更高级的做法是使用文件比较工具，但仍省不了繁杂的手工操作，一不小心，甚至会引入新的bug。<BR>三、&nbsp;在代码整合期间引入深层BUG。例如开发者A写了一个公共函数，B觉得正好可以复用；后来A又对这个公共函数进行了修改，添加了新的逻辑，而这个改动的却是B不想要的。或者是A发现这个公共函数不够用，又新做了一个函数，B却没有及时获得通知。这些，都为深层BUG留下隐患。<BR>四、&nbsp;无法对代码的拥有者进行权限控制。代码完全暴露在所有的开发者面前，任何人都可以随意进行增、删、改操作，无法指定明确的人对代码进行负责。特别是产品的开发，这是极其危险的。<BR>五、&nbsp;项目不同版本发布困难。特别是对产品的开发，你会频繁的进行版本发布，这时如果没有一个有效的管理产品版本的工具，一切将变得非常艰难。<BR>&nbsp;&nbsp;&nbsp; 上面只是列举了一些没有版本控制系统可能带来的问题，特别是对大型项目和异地协同开发有了一个合适的版本控制工具，它可以有效解决因为代码版本不同引起的各种问题，让我们的开发人员能更多的把精力花费在开发上面。而不是每次都花费很多时间进行代码整合和解决版本不同带来的各种问题。</P>
<P><STRONG>主流版本控制工具介绍</STRONG><BR>&nbsp;&nbsp;&nbsp; 现在，有很多优秀的版本控制工具供我们选择，下面就五种主流的版本控制工具做简单的介绍。<BR><STRONG>Starteam</STRONG> <BR>&nbsp;&nbsp;&nbsp; 是一个集合了版本控制、构建管理（Build Management）和缺陷跟踪系统为一体的软件，并且具有强大的图形界面，易学易用；但管理复杂、维护困难。2002年底被Borland公司收购。<BR><STRONG>PVCS Version Manager<BR></STRONG>&nbsp;&nbsp;&nbsp;&nbsp; 是美国的MERANT公司软件配置管理工具PVCS 家族中的一个组成部分，它能够实现源代码、可执行文件、应用文件、图形文件和文档的版本管理；它能安全地支持软件并行开发，对多个软件版本的变更进行有效的控制管理。<BR><STRONG>ClearCase(CC)<BR></STRONG>&nbsp;&nbsp;&nbsp; 是ROSE构件的一部分，目前最牛的配置管理工具，主要应用于复杂的产品发放、分布式团队合作、并行的开发和维护任务。可以控制word, excel,powerpoint，visio等文件格式，对于不认识的格式可以自己定义一种类型来标识。<BR><STRONG>Visual SourceSafe（VSS）<BR></STRONG>&nbsp;&nbsp;&nbsp; 简单易用、方便高效、与Windows操作系统及微软开发工具高度集成。<BR><STRONG>CVS（Concurrent Versions System）<BR></STRONG>&nbsp;&nbsp;&nbsp; 是开发源码的并发版本系统,它是目前最流行的面向软件开发人员的源代码版本管理解决方案。它可用于各种平台，包括 Linux 、Unix和 Windows NT/2000/XP等等。<BR>&nbsp;&nbsp;&nbsp; 前面三种是重量级的商业版本控制工具，更适合庞大的团队和项目，并且价格不菲。Visual SourceSafe是微软的产品，当然只能用在windows平台并与微软的开发工具无缝集成。CVS免费开源，并且几乎所有开源项目都是使用CVS进行版本管理，无疑，它是我们Java开发者最优选择。<BR><BR><STRONG>CVS的历史、功能、基本概念的介绍<BR><BR>历史</STRONG><BR>&nbsp;&nbsp;&nbsp; CVS 诞生于 1986 年，当时作为一组 shell 脚本而出现；1989年3月，Brian Berlinor用C语言重新设计并编写了CVS的代码；1993年前后，Jim Kingdon最终将CVS设计成基于网络的平台，开发者们能从Internet任何地方获得程序源代码。截至目前最新版本是2004年12月13日发布的1.12.11。<BR><BR><STRONG>功能介绍</STRONG><BR>一、&nbsp;代码统一管理，保存所有代码文件更改的历史记录。对代码进行集中统一管理，可以方便查看新增或删除的文件，能够跟踪所有代码改动痕迹。可以随意恢复到以前任意一个历史版本。并避免了因为版本不同引入的深层BUG。<BR>二、&nbsp;完善的冲突解决方案，可以方便的解决文件冲突问题，而不需要借助其它的文件比较工具和手工的粘贴复制。<BR>三、&nbsp;代码权限的管理。可以为不同的用户设置不同的权限。可以设置访问用户的密码、只读、修改等权限，而且通过CVS ROOT目录下的脚本，提供了相应功能扩充的接口，不但可以完成精细的权限控制，还能完成更加个性化的功能。<BR>四、&nbsp;支持方便的版本发布和分支功能。</P>
<P><STRONG>基本概念<BR>资源库（Repository）</STRONG><BR>CVS的资源库存储全部的版本控制下的文件copy，通常不容许直接访问，只能通过cvs命令，获得一份本地copy，改动后再check in（commit）回资源库。而资源库通常为与工作目录分离的。CVS通过多种方式访问资源库。每种方法有不同目录表示形式。<BR><STRONG>版本（Revision）</STRONG><BR>每一个文件的各个版本都不相同，形如1.1, 1.2.1,一般1.1是该文件的第一个revision，后面的一个将自动增加最右面的一个整数，比如1.2, 1.3, 1.4...有时候会出现1.3.2.2，原因见后。revision总是偶数个数字。一般情况下将revision看作时CVS自己内部的一个编号，而tag则可以标志用户的特定信息。<BR><STRONG>标签（Tag）</STRONG><BR>用符号化的表示方法标志文件特定revision的信息。通常不需要对某一个孤立的文件作tag，而是对所有文件同时作一个tag，以后用户可以仅向特定tag的文件提交或者checkout。另外一个作用是在发布软件的时候表示哪些文件及其哪个版本是可用的；各文件不同revision可以包括在一个tag中。如果命名一个已存在的tag默认将不会覆盖原来的；<BR><STRONG>分支（Branch）<BR></STRONG>当用户修改一个branch时不会对另外的branch产生任何影响。可以在适当的时候通过合并的方法将两个版本合起来；branch总是在当前revision后面加上一个偶数整数（从2开始，到0结束），所以branch总是奇数个数字，比如1.2后面branch为1.2.2，该分支下revision可能为1.2.2.1,1.2.2.2,...<BR><STRONG>冲突（Conflct）<BR></STRONG>完全是纯文本的冲突，不包含逻辑上的矛盾。一般是一份文件，A做了改动，B在A提交之前也做了改动，这样最后谁commit就会出现冲突，需要手工解决冲突再提交。<BR><BR><STRONG>CVS与eclipse集成开发</STRONG><BR>&nbsp; 前面对CVS的历史、功能、概论等理论知识做了介绍。下面我们将使用最流行的Java IDE Eclipse中内置的CVS工具，以一个完整开发流程，介绍实际环境中CVS的正确使用。关于CVS系统的安装，不是本文的内容，您可以从附录的链接中获取安装的介绍资料。<BR><BR><STRONG>常用的CVS控制命令</STRONG><BR><STRONG>Check Out（检出）</STRONG><BR>把源文件从cvs源代码仓库中取出，缺省的版本是最新的版本，你也可以选择指定的版本。在每次更改源代码之前，需要Check Out最新的版本，再起基础之上对源代码进行修改。将代码目录checkout到指定目录下，所有文件都是read-write。<BR><STRONG>Check In（检入）</STRONG><BR>把源代码加入到cvs源代码仓库中，每一个添加进代码库中的文件的版本是 1.1。以后每次修改文件重新ci以后，此文件的版本递增为1.2 ，1.3.……。在每次对源代码修改之后，需要Check In，提交最新版本的源代码。<BR><STRONG>Synchronize with Repository(与资源库同步，简称同步)</STRONG><BR>使本地更改与资源库同步，它会列出本地和资源库之间不同的所有文件。<BR><STRONG>Add to Version Control</STRONG><BR>将新的文件加入到版本控制之中。<BR><STRONG>Add to .cvsIgnore</STRONG><BR>将文件设置到版本控制之外，这样该文件或目录中的文件的更改在CVS中不可见，即使同步也无法发现。</P>
<P><STRONG>CVS正确使用步骤<BR>一、&nbsp;同步（Synchronize）</STRONG><BR>就是将本地更改与服务器同步，同步之后可以清晰的看到上一捡出（Check Out）版本之后本地、服务器上的最新改动。这是非常有用的，特别是敏捷开发，强调集体拥有代码。有了同步功能，你可以全局把握项目的代码，可以很方便的跟踪公共模块代码的任何改动。<BR>具体操作：在Eclipse的资源视图（Resource Perspective）或者Java视图（Java Perspective）中，选中要同步的目录，点击右键选择"Synchronize with Repository",之后它将显示同步的视图。如下图：<BR>&nbsp;<IMG alt="" hspace=0 src="file:///F:/j2ee_s/csdn-java/synchronize_1.bmp" align=baseline border=0><BR>(图一、CVS同步视图)<BR>同步之后，它有四种Mode可以选择，见上图绿色框框里按钮。从做到右分别为：<BR>Incoming Mode：表示修改是来自服务器，对应于更新（update）操作。<BR>Outgoing Mode：表示修改是来自本地，对应提交（commit）操作。<BR>Incoming/ Outgoing Mode：本地和服务器修改都在该模式（Mode）中显示。<BR>Conflicts Mode：显示本地和服务器修改的冲突文件。<BR><STRONG>二、&nbsp;更新（update）<BR></STRONG>比较简单，选择Incoming Mode，再选中要更新的文件，右键选择update操作。<BR><STRONG>三、&nbsp;解决冲突并合并(solve conflct and merge)</STRONG><BR>如果有冲突文件，冲突文件不能更新。你必须先解决冲突再操作。选中冲突的文件，再点右键选择"Open in Compare Editor"，用比较工具打开该文件。如下图： <BR><IMG alt="" hspace=0 src="file:///F:/j2ee_s/csdn-java/cmpare.bmp" align=baseline border=0><BR>（图二、CVS比较器视图）</P>
<P>比较器（Compare）视图，左边版本底的是本地文件（Local File），右边是远程服务器文件（Remote File）。使用"Select Next Change"按钮（绿框中的第一箭头向下按钮），逐一查看不同点。如果不同点标识为黑色框框，则不用管它。如果是蓝色框框，则需要手工调整。如上图，不同点是蓝色框框，将鼠标放到两个不同点的中间小方框中，则凸出一个向右的按钮，并显示提示信息"Copy Current Change from Right to Left"，意思是将右边服务器的不同点覆盖到左边的本地文件。点中此按钮。重复这样的操作，将所有服务器上的更改拷贝到本地。<BR>如果有一行代码，本地和服务器都同时做了修改。这时，修改点则显示红色框框。这时，你就必须手工做正确的修改。全部修改完成，保存本地文件。<BR>此时，如果修改点没有了蓝色的框框，就可以开始做合并（merge）操作了。操作也很简单，选择该文件，点击右键，选择"Mark as merged"。<BR>注意：必须确保没有蓝色框框，即完全拷贝了服务器的修改才可以做合并（merge）操作，否则会覆盖服务器上的代码。<BR><STRONG>四、&nbsp;提交（commit）<BR></STRONG>更新服务器代码，解决冲突之后，首先要查看本地文件修改之后是否有错误。如果有，当然首先解决错误，再提交。<BR><BR><STRONG>附录：</STRONG><BR><A href="http://www.8848software.com/scmchina/scmtools.htm">http://www.8848software.com/scmchina/scmtools.htm</A> 由很多版本控制工具的文档链接。<BR><A href="http://www.perforce.com/perforce/reviews.html">http://www.perforce.com/perforce/reviews.html</A> Infrastructure Group对Perforce 和Clearcase, CVS, PVCS,Visual SourceSafe (VSS)几种CM工具进行了定量和定性的比较. 对于定性的比较，内容涉及工具支持的方法和环境；对于定量的比较，包括在不同的项目规模上，执行不同的活动所需要的时间。</P>
<P>---------------------------</P>
<P>讨论摘录：</P>
<P>单就功能来说，Subversion 比起 CVS 还是要多了一些东西的，有些还是不错的；至于“市场”，还是要看需求，现在已经有一些开元软件在使用 Subversion 了。 </P>
<P>觉得 WinCVS 不好用的，可以试试 TortoiseCVS，这是一个完全与资源管理器集成的 CVS 工具，比较符合 Windows 使用者的思路，很容易上手；主页是 <A href="http://tortoisecvs.sourceforge.net">http://tortoisecvs.sourceforge.net</A>。 </P>
<P>对于 Subversion，也有相似的工具 TortoiseSVN，使用方法几乎完全相同，主页是<A href="http://tortoisesvn.tigris.org">http://tortoisesvn.tigris.org</A>。 </P>
<P>&nbsp;</P>
<P>同样，网站上也提供了其他关于软件配置管理工具的部分学习资料下载： <BR>参考：<A href="http://www.askguoyu.com">http://www.askguoyu.com</A> <BR></P>
<P>&nbsp;</P>
<P><BR>&nbsp;</P><B>
<P><BR>&nbsp;</P>
<P>&nbsp;</P>
<P>&nbsp;</P></B><img src ="http://www.blogjava.net/sgsoft/aggbug/737.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sgsoft/" target="_blank">海天一鸥</a> 2005-01-26 19:11 <a href="http://www.blogjava.net/sgsoft/articles/737.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java Web开发资源 </title><link>http://www.blogjava.net/sgsoft/articles/545.html</link><dc:creator>海天一鸥</dc:creator><author>海天一鸥</author><pubDate>Fri, 21 Jan 2005 07:49:00 GMT</pubDate><guid>http://www.blogjava.net/sgsoft/articles/545.html</guid><wfw:comment>http://www.blogjava.net/sgsoft/comments/545.html</wfw:comment><comments>http://www.blogjava.net/sgsoft/articles/545.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sgsoft/comments/commentRss/545.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sgsoft/services/trackbacks/545.html</trackback:ping><description><![CDATA[下面是一些Java Web开发的资源，供参考： <BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<A href="http://jakarta.apache.org/" target=_new>http://jakarta.apache.org</A> tomcat的老家 <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<A href="http://struts.apache.org/" target=_new>http://struts.apache.org</A> Struts 一个 MVC 的开发框架 <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<A href="http://www.opensymphony.com/webwork/" target=_new>http://www.opensymphony.com/webwork/</A> WebWork官方网站，又一个流行的MVC开发框架 <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<A href="http://forum.javaeye.com/" target=_new>http://forum.javaeye.com</A> Java视线论坛，里面的Java牛人很多，值得一看。 <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<A href="http://www.springframework.com/" target=_new>http://www.springframework.com</A> Spring 是一个非常好的AOP框架 <BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;现在Java Web比较流行的开发形式有： <BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Freemarker + Webwork + Spring + Hibernate <BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;View层可参考的框架包括 Sitemesh/Freemarker/ECHO/Display Tag/JSTL/Velocity ... <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MVC框架包括：Struts/WebWork/Tapestry/Spring MVC/JSF ... <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;持久层框架包括：Hibernate/iBatis ... <BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;到各个论坛找找看，有不少资料，特别是去上面提到的Java视线论坛看看，会有不少收获。 <BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;一些开发好的应用，供参考： <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<A href="http://www.mvnforum.com/" target=_new>http://www.mvnforum.com</A>&nbsp; 一个开源论坛 <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<A href="http://www.opencms.org/" target=_new>http://www.opencms.org</A> 一个CMS <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<A href="http://www.magnolia.info/" target=_new>http://www.magnolia.info</A> 一个CMS <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<A href="http://www.laoer.com/" target=_new>http://www.laoer.com/</A> 开源社区，使用Hibernate+Spring+Struts <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<A href="http://www.fiyu.net/" target=_new>http://www.fiyu.net</A> 飞鱼论坛（开源） <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<A href="http://www.chinaz.com/" target=_new>http://www.chinaz.com/</A> 中国站长站 里面有JSP源码下载 <BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;希望上面的信息能给你一些帮助。 <img src ="http://www.blogjava.net/sgsoft/aggbug/545.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sgsoft/" target="_blank">海天一鸥</a> 2005-01-21 15:49 <a href="http://www.blogjava.net/sgsoft/articles/545.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>iBATIS SQL Maps（二）     选择自 rosen 的 Blog </title><link>http://www.blogjava.net/sgsoft/articles/424.html</link><dc:creator>海天一鸥</dc:creator><author>海天一鸥</author><pubDate>Tue, 18 Jan 2005 05:17:00 GMT</pubDate><guid>http://www.blogjava.net/sgsoft/articles/424.html</guid><wfw:comment>http://www.blogjava.net/sgsoft/comments/424.html</wfw:comment><comments>http://www.blogjava.net/sgsoft/articles/424.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/sgsoft/comments/commentRss/424.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sgsoft/services/trackbacks/424.html</trackback:ping><description><![CDATA[<SPAN style="mso-spacerun: yes"><FONT face=Arial>&nbsp;&nbsp;</FONT></SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">让我们重回到车辆管理系统和张三的故事中。</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial"><?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p></o:p></SPAN>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN></SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">在</SPAN><SPAN style="COLOR: black; FONT-FAMILY: Arial"> </SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt">iBATIS SQL Maps </SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt">的世界里也存在</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt"> one-to-many</SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt">、</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt">many-to-one </SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt">的关系，想必你已经对这些概念驾轻就熟了。好！还是每个</SPAN><SPAN style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt"> <SPAN lang=EN-US>People </SPAN></SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt">对应多条</SPAN><SPAN style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt"> <SPAN lang=EN-US>AutoInfo </SPAN></SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt">信息。</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN></SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt">本系列文章第一部分提到过</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt"> iBATIS SQL Maps </SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt">的映射文件个数可以人为设定，但是，把一组有共性的操作放在一起是首选策略。下面我们看看为张三首次买车所生成的映射文件是怎样的：</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="COLOR: black"><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="COLOR: black"><o:p>
<TABLE style="WIDTH: 523px; HEIGHT: 100px" height=100 cellSpacing=0 cellPadding=0 width=523 border=1>
<TBODY>
<TR>
<TD>
<P><FONT size=2>&lt;?xml version="1.0" encoding="UTF-8"?&gt;</FONT></P>
<P><FONT size=2>&lt;!DOCTYPE sqlMap<BR>&nbsp;&nbsp;&nbsp; PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN"<BR>&nbsp;&nbsp;&nbsp; "</FONT><A href="http://www.ibatis.com/dtd/sql-map-2.dtd"><FONT size=2>http://www.ibatis.com/dtd/sql-map-2.dtd</FONT></A><FONT size=2>"&gt;</FONT></P>
<P><FONT size=2>&lt;sqlMap namespace="AutoMag"&gt;</FONT></P>
<P><FONT size=2>&nbsp; &lt;insert id="insertPeople" parameterClass="bo.People"&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;![CDATA[ <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; insert into people (name, address) values (#name#, #address#)<BR>&nbsp;&nbsp;&nbsp; ]]&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;selectKey resultClass="java.lang.Integer" keyProperty="id"&gt; <BR>&nbsp;&nbsp;&nbsp; &lt;![CDATA[ <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; select last_insert_id(); <BR>&nbsp;&nbsp;&nbsp; ]]&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/selectKey&gt;<BR>&nbsp; &lt;/insert&gt;<BR>&nbsp; <BR>&nbsp; &lt;insert id="insertAutoInfo" parameterClass="bo.AutoInfo"&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;![CDATA[ <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; insert into auto_info (license_plate, owner_no) VALUES (#licensePlate#, #ownerNo.id#)<BR>&nbsp;&nbsp;&nbsp; ]]&gt;<BR>&nbsp; &lt;/insert&gt;<BR>&lt;/sqlMap&gt;</FONT></P></TD></TR></TBODY></TABLE>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><B style="mso-bidi-font-weight: normal"><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial">sqlMap<o:p></o:p></SPAN></B></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 20.6pt; TEXT-ALIGN: left; mso-char-indent-count: 1.96; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial">sqlMap<B style="mso-bidi-font-weight: normal"> </B></SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">元素拥有属性</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial"> namespace="…"</SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">，定义了该</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial"> XML </SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">文件命名空间。如果你在配置文件</SPAN><SPAN style="COLOR: black; FONT-FAMILY: Arial"> <SPAN lang=EN-US>SqlMapConfig.xml </SPAN></SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">中指定了</SPAN><SPAN style="COLOR: black; FONT-FAMILY: Arial"> </SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt">settings </SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt">元素的属性</SPAN><SPAN style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt"> <SPAN lang=EN-US>useStatementNamespaces="true"</SPAN></SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt">，那么就可以按照命名空间的方式访问</SPAN><SPAN style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt"> </SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">Mapped statement</SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">，比如</SPAN><SPAN style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"> </SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial">namespace="</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"> AutoMag</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial">"</SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">，相应</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial"> Java </SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">代码：</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">sqlMap.insert("AutoMag.insertPeople",people)</SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">。这样做是为了防止不同映射文件中出现同名</SPAN><SPAN style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"> <SPAN lang=EN-US>Mapped statement </SPAN></SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">而产生冲突。什么是</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"> Mapped statement </SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">？</SPAN><SPAN style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"> <SPAN lang=EN-US><o:p></o:p></SPAN></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><B style="mso-bidi-font-weight: normal"><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial"><o:p>&nbsp;</o:p></SPAN></B></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><B style="mso-bidi-font-weight: normal"><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt">Mapped statement</SPAN></B><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 20.6pt; TEXT-ALIGN: left; mso-char-indent-count: 1.96; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt">iBATIS SQL Maps </SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt">的核心概念就是</SPAN><SPAN style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt"> </SPAN><SPAN lang=EN-US style="COLOR: red; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt">Mapped statement</SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt">！</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt">Mapped Statement </SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt">可以使用任意的</SPAN><SPAN style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt"> <SPAN lang=EN-US>SQL </SPAN></SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt">语句，利用</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt"> POJO</SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt">、</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-size: 10.5pt">原始变量</SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt">及其</SPAN><SPAN style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt"> </SPAN><SPAN lang=EN-US style="mso-bidi-font-size: 10.5pt">Wrapper Class </SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt">作为输入（</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt">parameter class</SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt">）和输出（</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt">result class</SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt">）。</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt">Mapped Statement </SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt">包含以下几种类型：</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt"><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; TEXT-ALIGN: left; mso-char-indent-count: 2.0; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">insert </SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">对应数据库的</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"> insert </SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">操作，该操作返回本次操作插入记录的主键值。</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; TEXT-ALIGN: left; mso-char-indent-count: 2.0; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">select </SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">对应数据库的</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"> select </SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">操作，该操作返回特定的</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"> POJO </SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">或</SPAN><SPAN style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"> </SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">对象。</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; TEXT-ALIGN: left; mso-char-indent-count: 2.0; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">update </SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">对应数据库的</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"> update </SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">操作，该操作返回被更新的记录个数。</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; TEXT-ALIGN: left; mso-char-indent-count: 2.0; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">delete </SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">对应数据库的</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"> delete </SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">操作，该操作返回被删除的记录个数。</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; TEXT-ALIGN: left; mso-char-indent-count: 2.0; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">procedure </SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">对应数据库存储过程。</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; TEXT-ALIGN: left; mso-char-indent-count: 2.0; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">statement </SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">类型最为通用，可以代替以上所有的类型。但由于缺乏操作直观性故不推荐。</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; TEXT-ALIGN: left; mso-char-indent-count: 2.0; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><B style="mso-bidi-font-weight: normal"><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial">insert id="insertPeople" parameterClass="bo.People" </SPAN></B><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; TEXT-ALIGN: left; mso-char-indent-count: 2.0; mso-layout-grid-align: none" align=left><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">定义了</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial"> insert </SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">类型的</SPAN><SPAN style="COLOR: black; FONT-FAMILY: Arial"> </SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt">Mapped Statement</SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt">。属性</SPAN><SPAN style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt"> </SPAN><B style="mso-bidi-font-weight: normal"><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial">id="insertPeople"</SPAN></B><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt"> </SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt">定义操作名称，</SPAN><B style="mso-bidi-font-weight: normal"><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial">parameterClass="bo.People"</SPAN></B><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial"> </SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">定义传入参数为</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial"> People </SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">对象实例，框架可确保其属性持久化到数据库相应字段中。由于</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial"> SQL </SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">语句会包含</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial">“&lt;&gt;”</SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">这样的符号，容易和</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial"> XML </SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">产生</SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt">冲突，放进</SPAN><SPAN style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt"> </SPAN><B style="mso-bidi-font-weight: normal"><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">&lt;![CDATA[</SPAN></B><B style="mso-bidi-font-weight: normal"><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-fareast-font-family: CourierNew">……</SPAN></B><B style="mso-bidi-font-weight: normal"><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">]]&gt; </SPAN></B><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">区域就可避免。</SPAN><B style="mso-bidi-font-weight: normal"><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial">insert into people (name, address) values (#name#, #address#)</SPAN></B><B style="mso-bidi-font-weight: normal"><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">，</SPAN></B><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">是一条普通的</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial"> SQL </SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">语句，</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial">“#name#</SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">、</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial">#address#”</SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">利用</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial"> Java </SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">反射机制访问</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial"> People </SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">对象实例的相应属性。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Arial; mso-font-kerning: 0pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; TEXT-ALIGN: left; mso-char-indent-count: 2.0; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><B style="mso-bidi-font-weight: normal"><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial">selectKey resultClass="java.lang.Integer" keyProperty="id"</SPAN></B><B style="mso-bidi-font-weight: normal"><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><o:p></o:p></SPAN></B></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; TEXT-ALIGN: left; mso-char-indent-count: 2.0; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt">iBATIS SQL Maps</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial"> </SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">通过</SPAN><SPAN style="COLOR: black; FONT-FAMILY: Arial"> <SPAN lang=EN-US>&lt;insert&gt; </SPAN></SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">元素的子元素</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial"> &lt;<B style="mso-bidi-font-weight: normal"> </B>selectKey&gt; </SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">来支持主键自动生成。</SPAN><SPAN style="COLOR: black; FONT-FAMILY: Arial"> <B style="mso-bidi-font-weight: normal"><SPAN lang=EN-US>resultClass="java.lang.Integer" </SPAN></B></SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">定义返回对象为</SPAN><SPAN style="COLOR: black; FONT-FAMILY: Arial"> <SPAN lang=EN-US>int </SPAN></SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">的</SPAN><SPAN style="COLOR: black; FONT-FAMILY: Arial"> </SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt">Wrapper Class</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt">。</SPAN><B style="mso-bidi-font-weight: normal"><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial">keyProperty="id" </SPAN></B><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">定义了主键名称。本例是</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial"> MySQL </SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">主键生成方式，参考官方文档，</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial">MySQL </SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">的主键生成无需人为来控制，也就是说可不使用</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial"> &lt;selectKey&gt; </SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">而由数据库自动处理。但我测试发现，在执行</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial"> insert </SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">操作以后，程序没有返回</SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">本次操作插入记录的主键值。在官方论坛上也有很多用户提出这样的疑惑，作者的答复是：这和</SPAN><SPAN style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"> <SPAN lang=EN-US>JDBC Driver </SPAN></SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">有关系。不可能把驱动一一测试吧？一劳永逸的办法是使用</SPAN><SPAN style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"> </SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial">&lt;selectKey&gt; </SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">元素。以下是</SPAN><SPAN style="COLOR: black; FONT-FAMILY: Arial"> </SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">Oracle </SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">和</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"> SQL Server </SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">主键生成方法：</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; TEXT-ALIGN: left; mso-char-indent-count: 2.0; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><o:p>
<TABLE style="WIDTH: 529px; HEIGHT: 253px" height=253 cellSpacing=0 cellPadding=0 width=529 border=1>
<TBODY>
<TR>
<TD>
<P><FONT size=2>&lt; !- Oracle -&gt;<BR>&lt;insert id="insertProduct-ORACLE" parameterClass="com.domain.Product"&gt; <BR>&nbsp; &lt;selectKey resultClass="int" keyProperty="id" &gt;<BR>&nbsp;&nbsp;&nbsp; SELECT STOCKIDSEQUENCE.NEXTVAL AS ID FROM DUAL <BR>&nbsp; &lt;/selectKey&gt; <BR>&nbsp; insert into PRODUCT (PRD_ID,PRD_DESCRIPTION) values (#id#,#description#) <BR>&lt;/insert&gt; </FONT></P>
<P><FONT size=2>&lt;!- Microsoft SQL Server -&gt;<BR>&lt;insert id="insertProduct-MS-SQL" parameterClass="com.domain.Product"&gt;<BR>&nbsp; insert into PRODUCT (PRD_DESCRIPTION) values (#description#) <BR>&nbsp; &lt;selectKey resultClass="int" keyProperty="id" &gt; <BR>&nbsp; SELECT @@IDENTITY AS ID <BR>&nbsp; &lt;/selectKey&gt; <BR>&lt;/insert&gt;</FONT></P></TD></TR></TBODY></TABLE>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><B style="mso-bidi-font-weight: normal"><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial">insert into auto_info (license_plate, owner_no) VALUES (#licensePlate#, #ownerNo.id#)</SPAN></B><B style="mso-bidi-font-weight: normal"><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><o:p></o:p></SPAN></B></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; TEXT-ALIGN: left; mso-char-indent-count: 2.0; mso-layout-grid-align: none" align=left><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">在插入了</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"> people </SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">记录后，要为</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"> auto_info </SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">插入记录。基本原则和之前遇到过的一样，只是</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">”</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial">owner_no”</SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">这个字段值由</SPAN><SPAN style="COLOR: black; FONT-FAMILY: Arial"> </SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">AutoInfo </SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">对象属性</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">”</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial">ownerNo”</SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">获得，该属性类型为</SPAN><SPAN style="COLOR: black; FONT-FAMILY: Arial"> </SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">People</SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">。这是由于我沿用了</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial"> Hibernate </SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">产生的</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial"> POJO</SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">，如果你愿意，完全可以把</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">”</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial">ownerNo”</SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">替换为</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial"> Integer </SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">类型。</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><B style="mso-bidi-font-weight: normal"><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">编程中几个关键对象</SPAN></B><B style="mso-bidi-font-weight: normal"><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><o:p></o:p></SPAN></B></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>com.ibatis.common.resources.Resources<B style="mso-bidi-font-weight: normal"> </B></SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">对象负责从</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"> XML </SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">得到</SPAN><SPAN style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"> <SPAN lang=EN-US>java.io.Reader </SPAN></SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">抽象类的实例，供工厂方法调用。</SPAN><B style="mso-bidi-font-weight: normal"><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><o:p></o:p></SPAN></B></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; TEXT-ALIGN: left; mso-char-indent-count: 2.0; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">com.ibatis.sqlmap.client.SqlMapClientBuilder<B style="mso-bidi-font-weight: normal"> </B></SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">构造</SPAN><SPAN style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"> <SPAN lang=EN-US>SqlMapClient </SPAN></SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">实例。</SPAN><B style="mso-bidi-font-weight: normal"><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><o:p></o:p></SPAN></B></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>com.ibatis.sqlmap.client.SqlMapClient<B style="mso-bidi-font-weight: normal"> </B></SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">是</SPAN><SPAN style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"> </SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt">iBATIS SQL Maps </SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt">核心组件，可以说我们的编程工作都是围绕着它展开。</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; TEXT-ALIGN: left; mso-char-indent-count: 2.0; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; TEXT-ALIGN: left; mso-char-indent-count: 2.0; mso-layout-grid-align: none" align=left><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt">形成的</SPAN><SPAN style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt"> <SPAN lang=EN-US>one-to-many </SPAN></SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt">保存如下：</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; TEXT-ALIGN: left; mso-char-indent-count: 2.0; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; TEXT-ALIGN: left; mso-char-indent-count: 2.0; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><o:p>
<TABLE style="WIDTH: 520px; HEIGHT: 100px" height=100 cellSpacing=0 cellPadding=0 width=520 border=1>
<TBODY>
<TR>
<TD>
<P><FONT size=2>package test;</FONT></P>
<P><FONT size=2>import java.io.Reader;</FONT></P>
<P><FONT size=2>import com.ibatis.sqlmap.client.*;<BR>import com.ibatis.common.resources.*;</FONT></P>
<P><FONT size=2>import bo.*;</FONT></P>
<P><FONT size=2>public class AutoMag {</FONT></P>
<P><FONT size=2>&nbsp;private Reader reader;<BR>&nbsp;private SqlMapClient sqlMap;<BR>&nbsp;private String resource = "SqlMapConfig.xml";<BR>&nbsp;<BR>&nbsp;public void insertPeople() throws Exception{<BR>&nbsp;&nbsp;try{<BR>&nbsp;&nbsp;&nbsp;reader = Resources.getResourceAsReader(resource);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sqlMap=SqlMapClientBuilder.buildSqlMapClient(reader);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sqlMap.startTransaction();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; People people=new People();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; people.setName("张三");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; people.setAddress("中国");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sqlMap.insert("insertPeople",people);</FONT></P>
<P><FONT size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; AutoInfo autoInfo=new AutoInfo();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; autoInfo.setLicensePlate("A00001");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; autoInfo.setOwnerNo(people);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sqlMap.insert("insertAutoInfo",autoInfo);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sqlMap.commitTransaction();<BR>&nbsp;&nbsp;}finally{<BR>&nbsp;&nbsp;&nbsp;sqlMap.endTransaction();<BR>&nbsp;&nbsp;}<BR>&nbsp;}<BR>}</FONT></P></TD></TR></TBODY></TABLE>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">程序和</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"> Hibernate </SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">写法差不多，我感觉甚至比</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"> Hibernate </SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">更简单。我可以显示的进行</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"> insert </SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">操作，符合传统</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"> JDBC </SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">编程习惯。</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt">iBATIS SQL Maps </SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt">支持自动事务处理，可以不用写明</SPAN><SPAN style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt"> </SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">startTransaction</SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">、</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">commitTransaction</SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">。但如果</SPAN><SPAN style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"> <SPAN lang=EN-US>People insert </SPAN></SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">操作成功，而</SPAN><SPAN style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"> <SPAN lang=EN-US>AutoInfo insert </SPAN></SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">操作失败，就破坏了两次</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"> insert </SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">操作的原子性。最后</SPAN><SPAN style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"> <SPAN lang=EN-US>endTransaction </SPAN></SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">包含异常情况下的回滚事务和关闭连接池连接两种功能。<BR></SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><o:p><BR><BR><STRONG><FONT face=宋体 color=#ff0000 size=2>（请注意！引用、转贴本文应注明原作者：Rosen Jiang 以及出处：</FONT></STRONG><A href="http://blog.csdn.net/rosen"><FONT face=宋体 color=#ff0000 size=2><STRONG>http://blog.csdn.net/rosen</STRONG></FONT></A><FONT face=宋体 color=#ff0000 size=2><STRONG>）</STRONG></FONT></o:p></SPAN></P><img src ="http://www.blogjava.net/sgsoft/aggbug/424.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sgsoft/" target="_blank">海天一鸥</a> 2005-01-18 13:17 <a href="http://www.blogjava.net/sgsoft/articles/424.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>iBATIS SQL Maps（一）     选择自 rosen 的 Blog </title><link>http://www.blogjava.net/sgsoft/articles/423.html</link><dc:creator>海天一鸥</dc:creator><author>海天一鸥</author><pubDate>Tue, 18 Jan 2005 05:15:00 GMT</pubDate><guid>http://www.blogjava.net/sgsoft/articles/423.html</guid><wfw:comment>http://www.blogjava.net/sgsoft/comments/423.html</wfw:comment><comments>http://www.blogjava.net/sgsoft/articles/423.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/sgsoft/comments/commentRss/423.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sgsoft/services/trackbacks/423.html</trackback:ping><description><![CDATA[<SPAN id=ArticleContent1_ArticleContent1_lblContent>&nbsp;
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">前段时间写了些</SPAN><SPAN style="FONT-FAMILY: Arial"> <SPAN lang=EN-US>Hibernate </SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">方面的</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial"><A href="http://blog.csdn.net/rosen/archive/2004/11/12/179646.aspx"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial">系列文章</SPAN></A></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">，网友们反映还不错。在接下来的时间里，我将会引入另外一种</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial"> O/R Mapping </SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">解决方案</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial">——<B style="mso-bidi-font-weight: normal">iBATIS</B></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">，本系列将沿用</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial"> Hibernate </SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">系列文章的风格。</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial"><?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt"><o:p>&nbsp;</o:p></SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial"><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><B style="mso-bidi-font-weight: normal"><SPAN style="FONT-SIZE: 14pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">什么是</SPAN></B><B style="mso-bidi-font-weight: normal"><SPAN style="FONT-SIZE: 14pt; FONT-FAMILY: Arial"> <SPAN lang=EN-US><A href="http://www.ibatis.com/">iBATIS</A> </SPAN></SPAN></B><B style="mso-bidi-font-weight: normal"><SPAN style="FONT-SIZE: 14pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">？</SPAN></B><B style="mso-bidi-font-weight: normal"><SPAN lang=EN-US style="FONT-SIZE: 14pt; FONT-FAMILY: Arial"><o:p></o:p></SPAN></B></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt"><BR>&nbsp;&nbsp;&nbsp; 和众多的</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt"> SourceForge </SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt">开源项目一样，</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt">iBATIS </SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt">曾经也是其中的一员。在</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt">2004</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt">年</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt">11</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt">月</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt">3</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt">日成功地成为了</SPAN><SPAN style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt"> <SPAN lang=EN-US><A href="http://incubator.apache.org/projects/ibatis.html">Apache Incubator</A><SPAN style="COLOR: black"> </SPAN></SPAN></SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt">下的子项目。</SPAN><SPAN style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt"> </SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial">iBATIS </SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">包括</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial"> for Java </SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">和</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial"> for .NET </SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">两个版本，</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial">for Java </SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">版提供了</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial">SQL Maps </SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">和</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial"> DAO </SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">框架，</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial">for .NET </SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">只提供了</SPAN><SPAN style="FONT-FAMILY: Arial"> <SPAN lang=EN-US>SQL Maps </SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">框架。从现在开始我们只对</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial"> for Java </SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">版的</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial">SQL Maps </SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">展开讨论。</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><SPAN lang=EN-US style="FONT-FAMILY: Arial"><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">你可以在</SPAN><SPAN style="FONT-FAMILY: Arial"> <SPAN lang=EN-US><A href="http://www.ibatis.com/">http://www.ibatis.com</A> </SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">下载</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial"> iBATIS for Java</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">，目前最新版本是</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial">2.0.9</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">，压缩包里已经包含了</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial"> SQL Maps(ibatis-sqlmap-2.jar) </SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">和</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial"> DAO </SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">框架</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial">(ibatis-dao-2.jar)</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">。</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-FAMILY: Arial"><o:p><BR></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><B style="mso-bidi-font-weight: normal"><SPAN style="FONT-SIZE: 14pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">为什么选择</SPAN></B><B style="mso-bidi-font-weight: normal"><SPAN style="FONT-SIZE: 14pt; FONT-FAMILY: Arial"> <SPAN lang=EN-US><A href="http://www.ibatis.com/">iBATIS</A> </SPAN></SPAN></B><B style="mso-bidi-font-weight: normal"><SPAN style="FONT-SIZE: 14pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">？</SPAN></B><B style="mso-bidi-font-weight: normal"><SPAN lang=EN-US style="FONT-SIZE: 14pt; FONT-FAMILY: Arial"><o:p></o:p></SPAN></B></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial"><BR>&nbsp;&nbsp;&nbsp; 也许各位看官已在各种不同的技术资料上了解到它的优势。但是对于我来说，选择它的理由只有一个</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial">——“</SPAN><B style="mso-bidi-font-weight: normal"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">利用原有资源</SPAN></B><SPAN lang=EN-US style="FONT-FAMILY: Arial">”</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">。</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial">Hibernate </SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">的却优秀，但是用来整合原有系统，它却很难胜任。例如，以前在进行数据建模时使用了复合主键、跨越多表产生的几十甚至上百行的查询语句、利用原有存储过程</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial">… … </SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">当面临这一系列问题时</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial"> Hibernate </SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">就显得力不从心了，要想使用</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial"> Hibernate</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">就只能改造原有系统！</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><SPAN lang=EN-US style="FONT-FAMILY: Arial"><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">当我面临系统整合问题时（整合的要求很简单：只需要保留原有系统查询部分），</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial">iBATIS </SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">进入了我的视线。原有系统中除</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial"> SQL</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">语句需要小小的修改外，数据表、查询结果都不需要改变！也不用像</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial"> Hibernate </SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">那样映射出众多的配置文件、</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial">POJO</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">，一下子清爽了很多。</SPAN><B style="mso-bidi-font-weight: normal"><SPAN lang=EN-US style="COLOR: red; FONT-FAMILY: Arial">BTW</SPAN></B><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">：</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial">Hibernate </SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">这种做法没有错！只是我只需要查询功能，仅仅是取我所好而已，避免了杀鸡用牛刀。</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><SPAN lang=EN-US style="FONT-FAMILY: Arial"><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">目前，系统整合已经结束，花了一个月时间。如果使用</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial"> Hibernate</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">，恐怕我现在还在为怎么设计数据表、怎样下</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial">HQL</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">而和同事争论。</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt">&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><B style="mso-bidi-font-weight: normal"><SPAN style="FONT-SIZE: 14pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">开始另一次</SPAN></B><B style="mso-bidi-font-weight: normal"><SPAN style="FONT-SIZE: 14pt; FONT-FAMILY: Arial"> <SPAN lang=EN-US>O/R Mapping </SPAN></SPAN></B><B style="mso-bidi-font-weight: normal"><SPAN style="FONT-SIZE: 14pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">之旅</SPAN></B><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt"><BR>&nbsp;&nbsp;&nbsp; 上次</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt"> O/R Mapping </SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt">之旅的</SPAN><SPAN style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt"> <SPAN lang=EN-US>BO</SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt">、数据表还可以重用，只是把数据库迁移到了</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt"> MySQL</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt">。<SPAN style="COLOR: black">打开</SPAN></SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt"> Eclipse</SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt">，新建一个</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt"> Resin </SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt">项目。把</SPAN><SPAN style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt"> </SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial">ibatis-sqlmap-2.jar </SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">和</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial"> ibatis-common-2.jar </SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">拷贝到</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial"> lib </SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">目录下，再导入项目。和</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial"> Hibernate </SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">自动配置、自动映射相比，</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial">iBATIS </SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">的一切都是手工完成的。</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-FAMILY: Arial"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-FAMILY: Arial"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">在</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial"> src </SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">下建立配置文件</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial"> SqlMapConfig.xml</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">，数据库链接、连接池、</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial">SqlMap </SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">映射文件</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial">… … </SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">这些都要靠它了。官方参考手册对怎样进行设置有很详细的描述，我只对要用到的地方进行粗略说明。<BR></SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial"><o:p></o:p></SPAN></P>
<P>
<TABLE style="WIDTH: 509px; HEIGHT: 100px" height=100 cellSpacing=0 cellPadding=0 width=509 border=1>
<TBODY>
<TR>
<TD>
<P><FONT size=2>&lt;?xml version="1.0" encoding="UTF-8" ?&gt;<BR>&lt;!DOCTYPE sqlMapConfig<BR>&nbsp;&nbsp;&nbsp; PUBLIC "-//iBATIS.com//DTD SQL Map Config 2.0//EN"<BR>&nbsp;&nbsp;&nbsp; "</FONT><A href="http://www.ibatis.com/dtd/sql-map-config-2.dtd"><FONT size=2>http://www.ibatis.com/dtd/sql-map-config-2.dtd</FONT></A><FONT size=2>"&gt;</FONT></P>
<P><FONT size=2>&lt;sqlMapConfig&gt;</FONT></P>
<P><FONT size=2>&nbsp; &lt;settings<BR>&nbsp;&nbsp;&nbsp; cacheModelsEnabled="true"<BR>&nbsp;&nbsp;&nbsp; enhancementEnabled="true"<BR>&nbsp;&nbsp;&nbsp; lazyLoadingEnabled="true"<BR>&nbsp;&nbsp;&nbsp; errorTracingEnabled="false"<BR>&nbsp;&nbsp;&nbsp; maxRequests="32"<BR>&nbsp;&nbsp;&nbsp; maxSessions="10"<BR>&nbsp;&nbsp;&nbsp; maxTransactions="5"<BR>&nbsp;&nbsp;&nbsp; useStatementNamespaces="false"<BR>&nbsp;&nbsp;&nbsp; /&gt;</FONT></P>
<P><FONT size=2>&nbsp; &lt;transactionManager type="JDBC"&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;dataSource type="SIMPLE"&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="JDBC.Driver" value="org.gjt.mm.mysql.Driver"/&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="JDBC.ConnectionURL" value="jdbc:mysql://localhost/new_db?useUnicode=true"/&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="JDBC.Username" value="root"/&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="JDBC.Password" value=""/&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="JDBC.DefaultAutoCommit" value="true"/&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="Pool.MaximumActiveConnections" value="10"/&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="Pool.MaximumIdleConnections" value="5"/&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="Pool.MaximumCheckoutTime" value="120000"/&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="Pool.TimeToWait" value="500"/&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="Pool.PingQuery" value="select 1 from ACCOUNT"/&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="Pool.PingEnabled" value="false"/&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="Pool.PingConnectionsOlderThan" value="1"/&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="Pool.PingConnectionsNotUsedFor" value="1"/&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="Pool.QuietMode" value="true"/&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;/dataSource&gt;<BR>&nbsp; &lt;/transactionManager&gt;</FONT></P>
<P><FONT size=2>&nbsp; &lt;sqlMap resource="bo/mapping/AutoMag.xml"/&gt;<BR>&lt;/sqlMapConfig&gt;</FONT></P></TD></TR></TBODY></TABLE><B style="mso-bidi-font-weight: normal"><SPAN lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: Arial"><BR>transactionManager </SPAN></B><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt">元素定义了</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt"> iBATIS </SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt">事务管理器。</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt">type </SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt">可选项包括：</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt"><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.1pt; TEXT-ALIGN: left; mso-char-indent-count: 2.0; mso-layout-grid-align: none" align=left><B style="mso-bidi-font-weight: normal"><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">JDBC</SPAN></B><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">：通过传统</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"> JDBC </SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">来管理事务。</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.1pt; TEXT-ALIGN: left; mso-char-indent-count: 2.0; mso-layout-grid-align: none" align=left><B style="mso-bidi-font-weight: normal"><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">JTA</SPAN></B><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">：使用一个</SPAN><SPAN style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"> <SPAN lang=EN-US>JTA </SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">全局事务，使</SPAN><SPAN style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"> </SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt">iBATIS</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"> </SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">的事务包括在更大的事务范围内（跨数据库</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">Session</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">的），这个更大的事务范围可能包括了其他的数据库和事务资源。这个配置需要一个</SPAN><SPAN style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"> <SPAN lang=EN-US>UserTransaction </SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">属性，以便从</SPAN><SPAN style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"> <SPAN lang=EN-US>JNDI </SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">获得一个</SPAN><SPAN style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"> <SPAN lang=EN-US>UserTransaction</SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">。</SPAN><SPAN style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><SPAN lang=EN-US><SPAN style="mso-spacerun: yes">&nbsp;</SPAN></SPAN></SPAN></P>
<P class=a style="TEXT-JUSTIFY: inter-ideograph; MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 20.65pt; TEXT-ALIGN: justify; mso-char-indent-count: 1.96"><B style="mso-bidi-font-weight: normal"><SPAN lang=EN-US style="FONT-SIZE: 10.5pt; FONT-FAMILY: Arial">EXTERNAL</SPAN></B><SPAN style="FONT-SIZE: 10.5pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial"><FONT face=宋体>：调用</FONT></SPAN><SPAN style="FONT-SIZE: 10.5pt; FONT-FAMILY: Arial"> <SPAN lang=EN-US>iBATIS </SPAN></SPAN><FONT face=宋体><SPAN style="FONT-SIZE: 10.5pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">以外的其他事务管理器来管理事务。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10.5pt; FONT-FAMILY: Arial"><o:p></o:p></SPAN></FONT></P>
<P class=Default style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10.5pt; FONT-FAMILY: Arial"><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><B style="mso-bidi-font-weight: normal"><SPAN lang=EN-US style="FONT-SIZE: 12pt; COLOR: black; FONT-FAMILY: Arial">dataSource </SPAN></B><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt">元素是</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt"> transactionManager </SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt">的一部分。</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt">type </SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt">可选项包括：<BR></SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt"><SPAN style="mso-spacerun: yes"><BR>&nbsp;&nbsp;&nbsp; </SPAN></SPAN><B><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">SIMPLE</SPAN></B><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">：</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">SIMPLE </SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">是</SPAN><SPAN style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"> <SPAN lang=EN-US>iBATIS </SPAN></SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">内置的</SPAN><SPAN style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"> <SPAN lang=EN-US>dataSource </SPAN></SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">实现，其中实现了一个简单的数据库连接池，当无容器提供</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"> DataSource </SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">服务时可以使用该选项，对应</SPAN><SPAN style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"> <SPAN lang=EN-US>iBATIS </SPAN></SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">实现类为</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">com.ibatis.sqlmap.engine.datasource.SimpleDataSourceFactory</SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">。</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 5.25pt; TEXT-INDENT: -5.25pt; TEXT-ALIGN: left; mso-char-indent-count: -.5; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">?<SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN><B>DBCP:</B></SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">基于</SPAN><SPAN style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"> <SPAN lang=EN-US>Apache DBCP </SPAN></SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">连接池</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"> API </SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">实现的</SPAN><SPAN style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"> <SPAN lang=EN-US>DataSource</SPAN></SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">，当无容器提供</SPAN><SPAN style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"> <SPAN lang=EN-US>DataSource </SPAN></SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">服务时，可以使用该选项，对应</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"> iBATIS </SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">实现类为</SPAN><SPAN style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"> <SPAN lang=EN-US>com.ibatis.sqlmap.engine.datasource.DbcpDataSourceFactory</SPAN></SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">。</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; TEXT-ALIGN: left; mso-char-indent-count: 2.0; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">?<B style="mso-bidi-font-weight: normal">JNDI</B></SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">：使用</SPAN><SPAN style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"> <SPAN lang=EN-US>J2EE </SPAN></SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">容器提供的</SPAN><SPAN style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"> <SPAN lang=EN-US>DataSource </SPAN></SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">实现，</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">DataSource </SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">将通过指定的</SPAN><SPAN style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"> <SPAN lang=EN-US>JNDI Name </SPAN></SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">从容器中获取。对应</SPAN><SPAN style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"> <SPAN lang=EN-US>iBATIS </SPAN></SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">实现类为</SPAN><SPAN style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"> <SPAN lang=EN-US>com.ibatis.sqlmap.engine.datasource.JndiDataSourceFactory</SPAN></SPAN><SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">。</SPAN><SPAN lang=EN-US style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><o:p></o:p></SPAN></P>
<P class=Default style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10.5pt; FONT-FAMILY: Arial"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp; </SPAN><B style="mso-bidi-font-weight: normal"><SPAN style="mso-spacerun: yes">&nbsp;</SPAN></B></SPAN><FONT face=宋体><B style="mso-bidi-font-weight: normal"><SPAN style="FONT-SIZE: 10.5pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">注意！</SPAN></B><SPAN style="FONT-SIZE: 10.5pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">每种</SPAN></FONT><B style="mso-bidi-font-weight: normal"><SPAN style="FONT-SIZE: 10.5pt; FONT-FAMILY: Arial"> </SPAN></B><SPAN lang=EN-US style="FONT-SIZE: 10.5pt; FONT-FAMILY: Arial">dataSource </SPAN><SPAN style="FONT-SIZE: 10.5pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial"><FONT face=宋体>元素的</FONT></SPAN><SPAN lang=EN-US style="FONT-SIZE: 10.5pt; FONT-FAMILY: Arial"> property </SPAN><SPAN style="FONT-SIZE: 10.5pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial"><FONT face=宋体>都有不同的地方，不能光把</FONT></SPAN><SPAN lang=EN-US style="FONT-SIZE: 10.5pt; FONT-FAMILY: Arial"> type </SPAN><FONT face=宋体><SPAN style="FONT-SIZE: 10.5pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">名字改了了事。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10.5pt; FONT-FAMILY: Arial"><o:p></o:p></SPAN></FONT></P>
<P class=Default style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10.5pt; FONT-FAMILY: Arial"><o:p>&nbsp;</o:p></SPAN></P>
<P class=Default style="MARGIN: 0cm 0cm 0pt"><B style="mso-bidi-font-weight: normal"><SPAN lang=EN-US style="FONT-FAMILY: Arial">sqlMap </SPAN></B><SPAN style="FONT-SIZE: 10.5pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial"><FONT face=宋体>元素定义了映射文件的存放位置，配置文件中可包含多个</FONT></SPAN><SPAN lang=EN-US style="FONT-SIZE: 10.5pt; FONT-FAMILY: Arial"> sqlMap </SPAN><SPAN style="FONT-SIZE: 10.5pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial"><FONT face=宋体>元素，比如：</FONT></SPAN><SPAN lang=EN-US style="FONT-SIZE: 10.5pt; FONT-FAMILY: Arial"><o:p></o:p></SPAN></P>
<P>
<TABLE style="WIDTH: 514px; HEIGHT: 84px" height=84 cellSpacing=0 cellPadding=0 width=514 border=1>
<TBODY>
<TR>
<TD>
<P><FONT size=2>&lt;sqlMap resource="mapping/AutoMag1.xml"/&gt;<BR>&lt;sqlMap resource="bo/mapping/AutoMag2.xml"/&gt;</FONT></P>
<P><FONT size=2>&lt;sqlMap url="</FONT><A href="file:///c:/eclipse/workspace/iBATISTest/src/bo/"><FONT size=2>file:///c:/eclipse/workspace/iBATISTest/src/bo/</FONT></A><FONT size=2> AutoMag2.xml "/&gt;<BR>… …</FONT></P></TD></TR></TBODY></TABLE></P>
<P class=Default style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><SPAN style="FONT-SIZE: 10.5pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial"><FONT face=宋体>你也许已发现，我只定义了单个映射文件。不错，和</FONT></SPAN><SPAN lang=EN-US style="FONT-SIZE: 10.5pt; FONT-FAMILY: Arial"> Hibernate </SPAN><SPAN style="FONT-SIZE: 10.5pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial"><FONT face=宋体>的一个表一个映射文件不同，</FONT></SPAN><SPAN lang=EN-US style="FONT-SIZE: 10.5pt; FONT-FAMILY: Arial">iBATIS </SPAN><FONT face=宋体><SPAN style="FONT-SIZE: 10.5pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">的映射文件个数可以人为控制，颗粒度自己掌握。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10.5pt; FONT-FAMILY: Arial"><o:p></o:p></SPAN></FONT></P>
<P class=Default style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10.5pt; FONT-FAMILY: Arial"><o:p>&nbsp;</o:p></SPAN></P>
<P class=Default style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10.5pt; FONT-FAMILY: Arial"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN></SPAN><SPAN style="FONT-SIZE: 10.5pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial"><FONT face=宋体>光有</FONT></SPAN><SPAN lang=EN-US style="FONT-SIZE: 10.5pt; FONT-FAMILY: Arial"> BO </SPAN><SPAN style="FONT-SIZE: 10.5pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial"><FONT face=宋体>和配置文件还不行，还要为本次测试创建测试类</FONT></SPAN><SPAN style="FONT-SIZE: 10.5pt; FONT-FAMILY: Arial"> <SPAN lang=EN-US>AutoMag.java</SPAN></SPAN><SPAN style="FONT-SIZE: 10.5pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial"><FONT face=宋体>。完整的布局如下所示：<BR></FONT></SPAN><SPAN lang=EN-US style="FONT-SIZE: 10.5pt; FONT-FAMILY: Arial"><o:p><BR>&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;<IMG alt="" hspace=0 src="http://blog.csdn.net/images/blog_csdn_net/rosen/68948/r_structure.jpg" align=baseline border=0><BR></P>
<P class=Default style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><SPAN style="FONT-SIZE: 10.5pt"><FONT face=宋体><BR>&nbsp;&nbsp;&nbsp; 以下为<SPAN lang=EN-US> iBATIS SQL Maps 工作流程，对于理解概念很有帮助。大意是 1、你可以把 JavaBean、Map 类型、原始变量（或者它们的Wrapper Class）、XML 数据作为传入对象；2、通过配置文件载入映射文件；3、利用框架翻译成 JDBC 来访问数据库；4、执行结果可以是 JavaBean、Map 类型、原始变量（或者它们的Wrapper Class）、XML 数据。<BR></SPAN></FONT></SPAN><SPAN lang=EN-US style="FONT-SIZE: 10.5pt; FONT-FAMILY: Arial"><o:p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<IMG alt="" hspace=0 src="http://blog.csdn.net/images/blog_csdn_net/rosen/68948/r_map.jpg" align=baseline border=0><BR><BR><STRONG><FONT face=宋体 color=#ff0000 size=2>（请注意！引用、转贴本文应注明原作者：Rosen Jiang 以及出处：</FONT></STRONG><A href="http://blog.csdn.net/rosen"><FONT face=宋体 color=#ff0000 size=2><STRONG>http://blog.csdn.net/rosen</STRONG></FONT></A><FONT face=宋体 color=#ff0000 size=2><STRONG>）</STRONG></FONT></o:p></SPAN></P></o:p></SPAN></SPAN><img src ="http://www.blogjava.net/sgsoft/aggbug/423.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sgsoft/" target="_blank">海天一鸥</a> 2005-01-18 13:15 <a href="http://www.blogjava.net/sgsoft/articles/423.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>