?
This document uses PHP Chinese website manual Release
org.springframework.jca.cci.object
包中包含的支持類允許你以另一種風(fēng)格訪問(wèn)EIS:
通過(guò)可重用的操作對(duì)象,類似于Spring的JDBC操作對(duì)象(參見(jiàn)JDBC一章)。
它通常都封裝了 CCI 的API:將應(yīng)用級(jí)的輸入對(duì)象傳入到操作對(duì)象,
從而它能創(chuàng)建輸入record然后轉(zhuǎn)換接收到的record數(shù)據(jù)到一個(gè)應(yīng)用級(jí)輸出對(duì)象并返回它。
注意: 這種方法內(nèi)在地基于 CciTemplate
類和
RecordCreator
/ RecordExtractor
接口,重用了Spring核心CCI支持的機(jī)制。
MappingRecordOperation
本質(zhì)上與 CciTemplate
做的事情是一樣的,
但是它表達(dá)了一個(gè)明確的、預(yù)配置(pre-configured)的操作作為對(duì)象。它提供了兩個(gè)模板方法來(lái)指明如何將一個(gè)輸入對(duì)象轉(zhuǎn)換為輸入記錄,
以及如何將一個(gè)輸出記錄轉(zhuǎn)換為輸出對(duì)象(記錄映射):
createInputRecord(..)
指定了如何將一個(gè)輸入對(duì)象轉(zhuǎn)換為輸入Record
extractOutputData(..)
指定了如何從輸出 Record
中提取輸出對(duì)象
下面是這些方法的簽名:
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 { ... } ... }
此后,為了執(zhí)行一個(gè) EIS 操作,你需要使用一個(gè)單獨(dú)的execute方法,傳遞一個(gè)應(yīng)用級(jí)(application-level) 輸入對(duì)象,并接收一個(gè)應(yīng)用級(jí)輸出對(duì)象作為結(jié)果:
public abstract class MappingRecordOperation extends EisOperation { ... public Object execute(Object inputObject) throws DataAccessException { ... }
正如你所看到的,與 CciTemplate
類相反,
這個(gè)execute
方法并沒(méi)有 InteractionSpec
參數(shù),
然而,InteractionSpec
對(duì)操作是全局的。
下面的構(gòu)造方法必須使用指定的 InteractionSpec
來(lái)初始化一個(gè)操作對(duì)象:
InteractionSpec spec = ...; MyMappingRecordOperation eisOperation = new MyMappingRecordOperation(getConnectionFactory(), spec); ...
一些連接器使用了基于COMMAREA的記錄,該記錄包含了發(fā)送給EIS的參數(shù)和返回?cái)?shù)據(jù)的字節(jié)數(shù)組。
Spring提供了一個(gè)專門(mén)的操作類用于直接操作COMMAREA而不是操作記錄。
MappingCommAreaOperation
類擴(kuò)展了 MappingRecordOperation
類以提供這種專門(mén)的COMMAREA支持。
它隱含地使用了 CommAreaRecord
類作為輸入和輸出record類型,
并提供了兩個(gè)新的方法來(lái)轉(zhuǎn)換輸入對(duì)象到輸入COMMAREA,以及轉(zhuǎn)換輸出COMMAREA到輸出對(duì)象。
public abstract class MappingCommAreaOperation extends MappingRecordOperation { ... protected abstract byte[] objectToBytes(Object inObject) throws IOException, DataAccessException; protected abstract Object bytesToObject(byte[] bytes) throws IOException, DataAccessException; ... }
由于每個(gè) MappingRecordOperation
子類的內(nèi)部都是基于 CciTemplate
的,所以
用 CciTemplate
以相同的方式自動(dòng)生成輸出record都是有效的。
每個(gè)操作對(duì)象提供一個(gè)相應(yīng)的 setOutputRecordCreator(..)
方法。
更多的信息,請(qǐng)參見(jiàn)前面的第?21.3.4?節(jié) “自動(dòng)輸出記錄生成”一節(jié)。
操作對(duì)象方法使用了跟 CciTemplate
相同的方式來(lái)使用記錄。
表?21.2.?Usage of Interaction execute methods
MappingRecordOperation method
signature |
MappingRecordOperation
outputRecordCreator property |
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) |
在本節(jié)中,將通過(guò)展示使用 Blackbox CCI 連接器訪問(wèn)一個(gè)數(shù)據(jù)庫(kù)來(lái)說(shuō)明 MappingRecordOperation
的用法。
該連接器的最初版本是由SUN提供的J2EE SDK(1.3版本)。
首先,必須在 CCI InteractionSpec
中進(jìn)行一些初始化動(dòng)作來(lái)指定執(zhí)行哪些SQL請(qǐng)求。
在這個(gè)例子中,我們直接定義了將請(qǐng)求參數(shù)轉(zhuǎn)換為CCI record以及將CCI結(jié)果記錄轉(zhuǎn)換為一個(gè) Person
類的實(shí)例的方法。
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; } }
然后應(yīng)用程序會(huì)以person標(biāo)識(shí)符作為參數(shù)來(lái)得到操作對(duì)象。注意:操作對(duì)象可以被設(shè)為共享實(shí)例,因?yàn)樗蔷€程安全的。
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; } }
對(duì)應(yīng)的Spring beans的配置看起來(lái)類似于下面非托管模式(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)(也就是說(shuō),在一個(gè)J2EE環(huán)境中)),配置可能看起來(lái)像這樣:
<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>
在本節(jié)中,將展示 MappingCommAreaOperation
類的用法:通過(guò)IBM ECI連接器以ECI的模式訪問(wèn)一個(gè)CICS。
首先,CCI InteractionSpec
需要進(jìn)行初始化以指定那個(gè)CICS程序去訪問(wèn)它以及如何與它交互。
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
抽象類可以被子類化以指定自定義對(duì)象和 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)); } }
對(duì)應(yīng)的Spring beans的配置看起來(lái)類似于下面非托管模式(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)(也就是說(shuō),在一個(gè)J2EE環(huán)境中),配置可能看起來(lái)像這樣:
<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>