Spring建模CCI访问为操作对象

org.springframework.jca.cci.object 包中包含的支持类允许你以另一种风格访问EIS: 通过可重用的操作对象,类似于Spring的JDBC操作对象。 它通常都封装了 CCI 的API:将应用级的输入对象传入到操作对象, 从而它能创建输入record然后转换接收到的record数据到一个应用级输出对象并返回它。

MappingRecordOperation
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);
...

MappingCommAreaOperation
一些连接器使用了基于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(..) 方法。

MappingRecordOperation 使用示例
在本节中,将通过展示使用 Blackbox CCI 连接器访问一个数据库来说明 MappingRecordOperation 的用法。

首先,必须在 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)(也就是说,在一个JAVA EE环境中)),配置可能看起来像这样:

<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 使用示例
在本节中,将展示 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)(也就是说,在一个JAVA EE环境中),配置可能看起来像这样:

<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>

你可能感兴趣的:(spring,sql,jdbc,IBM)