org.springframework.jca.cci.object 包中包含的支持类允许你以另一种风格访问EIS:
  通过可重用的操作对象,类似于Spring的JDBC操作对象(参见JDBC一章)。
  它通常都封装了 CCI 的API:将应用级的输入对象传入到操作对象,
  从而它能创建输入record然后转换接收到的record数据到一个应用级输出对象并返回它。
  
注意: 这种方法内在地基于 CciTemplate 类和
  RecordCreator / RecordExtractor 接口,重用了Spring核心CCI支持的机制。
 MappingRecordOperation 本质上与 CciTemplate 做的事情是一样的,
   但是它表达了一个明确的、预配置(pre-configured)的操作作为对象。它提供了两个模板方法来指明如何将一个输入对象转换为输入记录,
   以及如何将一个输出记录转换为输出对象(记录映射):
		
createInputRecord(..) 指定了如何将一个输入对象转换为输入Record
extractOutputData(..) 指定了如何从输出 Record 中提取输出对象
下面是这些方法的签名:
public abstract class MappingRecordOperation extends EisOperation {
 ...
 protected abstract Record createInputRecord(RecordFactory recordFactory, Object inputObject)
   throws ResourceException, DataAccessException { ... }
 protected abstract Object extractOutputData(Record outputRecord)
   throws ResourceException, SQLException, DataAccessException { ... }
 ...
}
此后,为了执行一个 EIS 操作,你需要使用一个单独的execute方法,传递一个应用级(application-level) 输入对象,并接收一个应用级输出对象作为结果:
public abstract class MappingRecordOperation extends EisOperation {
 ...
 public Object execute(Object inputObject) throws DataAccessException {
 ...
}
   正如你所看到的,与 CciTemplate 类相反,
   这个execute方法并没有 InteractionSpec 参数,
   然而,InteractionSpec 对操作是全局的。
   下面的构造方法必须使用指定的 InteractionSpec 来初始化一个操作对象:
   
InteractionSpec spec = ...; MyMappingRecordOperation eisOperation = new MyMappingRecordOperation(getConnectionFactory(), spec); ...
   一些连接器使用了基于COMMAREA的记录,该记录包含了发送给EIS的参数和返回数据的字节数组。
   Spring提供了一个专门的操作类用于直接操作COMMAREA而不是操作记录。
   MappingCommAreaOperation 类扩展了 MappingRecordOperation 类以提供这种专门的COMMAREA支持。
   它隐含地使用了 CommAreaRecord类作为输入和输出record类型,
   并提供了两个新的方法来转换输入对象到输入COMMAREA,以及转换输出COMMAREA到输出对象。
   
public abstract class MappingCommAreaOperation extends MappingRecordOperation {
 ...
 protected abstract byte[] objectToBytes(Object inObject)
   throws IOException, DataAccessException;
 protected abstract Object bytesToObject(byte[] bytes)
   throws IOException, DataAccessException;
 ...
}
	由于每个 MappingRecordOperation 子类的内部都是基于 CciTemplate 的,所以
	用 CciTemplate 以相同的方式自动生成输出record都是有效的。
	每个操作对象提供一个相应的 setOutputRecordCreator(..) 方法。
	更多的信息,请参见前面的第 21.3.4 节 “自动输出记录生成”一节。
			
操作对象方法使用了跟 CciTemplate 相同的方式来使用记录。
表 21.2. Usage of Interaction execute methods
| MappingRecordOperationmethod
        signature | MappingRecordOperationoutputRecordCreatorproperty | execute method called on the CCI Interaction | 
|---|---|---|
| Object execute(Object) | not set | Record execute(InteractionSpec, Record) | 
| Object execute(Object) | set | boolean execute(InteractionSpec, Record, Record) | 
	   在本节中,将通过展示使用 Blackbox CCI 连接器访问一个数据库来说明 MappingRecordOperation 的用法。
   
该连接器的最初版本是由SUN提供的J2EE SDK(1.3版本)。
   首先,必须在 CCI InteractionSpec 中进行一些初始化动作来指定执行哪些SQL请求。
	在这个例子中,我们直接定义了将请求参数转换为CCI record以及将CCI结果记录转换为一个 Person 类的实例的方法。
   
public class PersonMappingOperation extends MappingRecordOperation {
 public PersonMappingOperation(ConnectionFactory connectionFactory) {
  setConnectionFactory(connectionFactory);
  CciInteractionSpec interactionSpec = new CciConnectionSpec();
  interactionSpec.setSql("select * from person where person_id=?");
  setInteractionSpec(interactionSpec);
 }
 protected Record createInputRecord(RecordFactory recordFactory, Object inputObject)
   throws ResourceException {
  Integer id = (Integer) inputObject;
  IndexedRecord input = recordFactory.createIndexedRecord("input");
  input.add(new Integer(id));
  return input;
 }
 protected Object extractOutputData(Record outputRecord)
   throws ResourceException, SQLException {
  ResultSet rs = (ResultSet) outputRecord;
  Person person = null;
  if (rs.next()) {
   Person person = new Person();
   person.setId(rs.getInt("person_id"));
   person.setLastName(rs.getString("person_last_name"));
   person.setFirstName(rs.getString("person_first_name"));
  }
  return person;
 }
}
然后应用程序会以person标识符作为参数来得到操作对象。注意:操作对象可以被设为共享实例,因为它是线程安全的。
public class MyDaoImpl extends CciDaoSupport implements MyDao {
 public Person getPerson(int id) {
  PersonMappingOperation query = new PersonMappingOperation(getConnectionFactory());
  Person person = (Person) query.execute(new Integer(id));
  return person;
 }
}
对应的Spring beans的配置看起来类似于下面非托管模式(non-managed mode)的配置:
<bean id="managedConnectionFactory" class="com.sun.connector.cciblackbox.CciLocalTxManagedConnectionFactory"> <property name="connectionURL" value="jdbc:hsqldb:hsql://localhost:9001"/> <property name="driverName" value="org.hsqldb.jdbcDriver"/> </bean> <bean id="targetConnectionFactory" class="org.springframework.jca.support.LocalConnectionFactoryBean"> <property name="managedConnectionFactory" ref="managedConnectionFactory"/> </bean> <bean id="connectionFactory" class="org.springframework.jca.cci.connection.ConnectionSpecConnectionFactoryAdapter"> <property name="targetConnectionFactory" ref="targetConnectionFactory"/> <property name="connectionSpec"> <bean class="com.sun.connector.cciblackbox.CciConnectionSpec"> <property name="user" value="sa"/> <property name="password" value=""/> </bean> </property> </bean> <bean id="component" class="MyDaoImpl"> <property name="connectionFactory" ref="connectionFactory"/> </bean>
在托管模式(managed mode)(也就是说,在一个J2EE环境中)),配置可能看起来像这样:
<bean id="targetConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiName" value="eis/blackbox"/> </bean> <bean id="connectionFactory" class="org.springframework.jca.cci.connection.ConnectionSpecConnectionFactoryAdapter"> <property name="targetConnectionFactory" ref="targetConnectionFactory"/> <property name="connectionSpec"> <bean class="com.sun.connector.cciblackbox.CciConnectionSpec"> <property name="user" value="sa"/> <property name="password" value=""/> </bean> </property> </bean> <bean id="component" class="MyDaoImpl"> <property name="connectionFactory" ref="connectionFactory"/> </bean>
   在本节中,将展示 MappingCommAreaOperation类的用法:通过IBM ECI连接器以ECI的模式访问一个CICS。
   
   	首先,CCI InteractionSpec 需要进行初始化以指定那个CICS程序去访问它以及如何与它交互。
   
public abstract class EciMappingOperation extends MappingCommAreaOperation {
 public EciMappingOperation(ConnectionFactory connectionFactory, String programName) {
  setConnectionFactory(connectionFactory);
  ECIInteractionSpec interactionSpec = new ECIInteractionSpec(),
  interactionSpec.setFunctionName(programName);
  interactionSpec.setInteractionVerb(ECIInteractionSpec.SYNC_SEND_RECEIVE);
  interactionSpec.setCommareaLength(30);
  setInteractionSpec(interactionSpec);
  setOutputRecordCreator(new EciOutputRecordCreator());
 }
 private static class EciOutputRecordCreator implements RecordCreator {
  public Record createRecord(RecordFactory recordFactory) throws ResourceException {
   return new CommAreaRecord();
  }
 }
}
The abstract EciMappingOperation class can
   then be subclassed to specify mappings between custom objects and
			Records.
 EciMappingOperation 抽象类可以被子类化以指定自定义对象和 Records 之间的映射。
public class MyDaoImpl extends CciDaoSupport implements MyDao {
 public OutputObject getData(Integer id) {
  EciMappingOperation query = new EciMappingOperation(getConnectionFactory(), "MYPROG") {
   protected abstract byte[] objectToBytes(Object inObject) throws IOException {
    Integer id = (Integer) inObject;
    return String.valueOf(id);
   }
   protected abstract Object bytesToObject(byte[] bytes) throws IOException;
    String str = new String(bytes);
    String field1 = str.substring(0,6);
    String field2 = str.substring(6,1);
    String field3 = str.substring(7,1);
    return new OutputObject(field1, field2, field3);
   }
  });
  return (OutputObject) query.execute(new Integer(id));
 }
}
对应的Spring beans的配置看起来类似于下面非托管模式(non-managed mode)的配置:
<bean id="managedConnectionFactory" class="com.ibm.connector2.cics.ECIManagedConnectionFactory"> <property name="serverName" value="TXSERIES"/> <property name="connectionURL" value="local:"/> <property name="userName" value="CICSUSER"/> <property name="password" value="CICS"/> </bean> <bean id="connectionFactory" class="org.springframework.jca.support.LocalConnectionFactoryBean"> <property name="managedConnectionFactory" ref="managedConnectionFactory"/> </bean> <bean id="component" class="MyDaoImpl"> <property name="connectionFactory" ref="connectionFactory"/> </bean>
在托管模式(managed mode)(也就是说,在一个J2EE环境中),配置可能看起来像这样:
<bean id="connectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiName" value="eis/cicseci"/> </bean> <bean id="component" class="MyDaoImpl"> <property name="connectionFactory" ref="connectionFactory"/> </bean>