📄 using the j2ee connector architecture common client interface.htm
字号:
relational database. The example shows how to invoke stored procedures, which are business logic functions stored in a database and specific to an enterprise's operation. Stored procedures consist of SQL code to perform operations related to the business needs of an organization.They are kept in the database and can be invoked when needed, just as you might invoke a Java method. In addition to showing how to use the CCI to invoke stored procedures, the Example also illustrates how to pass parameters to stored procedures and how to map the parameter data types from SQL to Java.</p><p>You should have already installed the resource adapter for the EIS and its connection factory. Refer to the <a href="/products/j2ee">J2EE reference implementation documentation</a> for instructions on how to do this.</p><p>The example session bean<code>AcctManage</code> is like any other session bean. It has a home interface (<a href="/developer/technicalArticles/J2EE/connectorclient/AcctManageHome.java">AcctManageHome.java</a>), a remote interface (<a href="/developer/technicalArticles/J2EE/connectorclient/AcctManage.java">AcctManage.java</a>), and an implementation class (<a href="/developer/technicalArticles/J2EE/connectorclient/AcctManageEJB.java">AcctManageEJB.java</a>). The client is <a href="/developer/technicalArticles/J2EE/connectorclient/AcctManageClient.java">AcctManageClient.java</a>. </p><p>The <code>AcctManage</code> home interface is like any other session bean home interface it extends <code>EJBHome</code> and defines a <code>create</code> method to return a reference to its remote interface. The <code>AcctManage</code> remote interface defines the bean's two methods that may be called by a client:</p><pre>public void insertAcct(String acctName, int amt) throws RemoteException;public int getAcctAmt() throws RemoteException;</pre><h3>Using Database Stored Procedures</h3><p>Before going further, it is important to understand database stored procedures. This example shows you how to invoke a database stored procedure; it is the stored procedure that actually reads or writes to the database. </p><p>A stored procedure is a business logic method or function that is stored in a database and is specific for the enterprise's business. Typically, stored procedures are written in SQL code, though in certain cases (such as with Cloudscape) they may actually be written in Java code. Stored procedures perform operations related to the business needs of an organization. They are kept in the database and applications can invoke them when needed.</p><p>Stored procedures are typically SQL statements. This example calls two stored procedures: <code>GETAMT</code> and <code>ADDACCT</code>. The <code>GETAMT</code> procedure merely gets the account amounts from records in the Account table, as follows:</p><pre>SELECT AMT(*) FROM ACCOUNT</pre><p>The <code>ADDACCT</code> procedure adds an account record to the table. The record has two values, which are passed to the procedure as parameters:</p><pre>INSERT INTO ACCOUNT VALUES (?,?)</pre><h4>Defining Input and Output Parameters</h4><p>When you invoke a stored procedure from your application component, you may have to pass argument values to the procedure. For example, when you invoke the <code>ADDACCT</code> procedure, you pass it two values for the Account record elements. Likewise, you must be prepared to receive values that a stored procedure returns. </p><ul><li>The stored procedure, in turn, passes its set of parameters to the database manager (DBMS) to carry out its operation and may receive values back from the DBMS. </li><li>Database stored procedures specify, for each of their parameters, the SQL type of the parameter value and the mode of the parameter. </li><li>Mode can be input (<code>IN</code>), output (<code>OUT</code>), or both input and output (<code>INOUT</code>). </li><li>An input parameter only passes data in to the DBMS while an output parameter only receives data back from the DBMS. </li><li>An <code>INOUT</code> parameter accepts both input and output data.</li></ul> <p>When you use the CCI execute method to invoke a database stored procedure, you also create an instance of an <code>InputRecord</code> if you're passing a parameter to the stored procedure and, if the stored procedure you're executing returns data, possibly an <code>OutputRecord</code> instance. The <code>InputRecord</code> and <code>OutputRecord</code> are instances of the supported <code>Record</code> types: <code>IndexedRecord</code>, <code>MappedRecord</code>, or <code>ResultSet</code>. In this example, it instantiates an <code>InputRecord</code> and an <code>OutputRecord</code> that are both <code>IndexedRecord</code> instances.</p><p>The <code>InputRecord</code> maps the <code>IN</code> and <code>INOUT</code> parameters for the stored procedure, while the OutputRecord maps the <code>OUT</code> and <code>INOUT</code> parameters. Each element of an input or output record corresponds to a stored procedure parameter. That is, there is an entry in the <code>InputRecord</code> for each <code>IN</code> and <code>INOUT</code> parameter declared in the stored procedure. Not only does the <code>InputRecord</code> have the same number of elements as the procedure's input parameters, they are declared in the same order as in the procedure's parameter list. The same holds true for the <code>OutputRecord</code>, though its list of elements matches only the <code>OUT</code> and <code>INOUT</code> parameters. </p><p>For example, suppose you have a stored procedure X that declares three parameters. The first parameter is an <code>IN</code> parameter, the second is an <code>OUT</code> parameter, and the third is an <code>INOUT </code>parameter. Figure 1 shows how the elements of an <code>InputRecord</code> and an <code>OutputRecord</code> map to this stored procedure. </p><p><img src="/developer/technicalArticles/J2EE/connectorclient/cci-article-1.gif" width="439" height="132" alt="CCI"></p><p><font size="-1"><b>Figure 1: Mapping Stored Procedure Parameters to CCI Record Elements</b></font></p><p>You must declare the parameter type and mode before calling a stored procedure with parameters. Keep in mind, though, that you may have to declare the parameter mode differently depending on the underlying DBMS. Oracle designates the parameter's mode in the stored procedure declaration, along with the parameter's type declaration. For example, an Oracle <code>ADDACCT</code> procedure declares its two IN parameters as follows:</p><pre>procedure ADDACCT (acctname IN VARCHAR2, amt IN INTEGER)</pre><p>An Oracle <code>GETAMT</code> procedure declares its parameter <code>amt</code> as an <code>OUT</code> parameter:</p><pre>procedure GETAMT (amt OUT INTEGER)</pre><p>Cloudscape, which declares stored procedures using a standard Java method signature, indicates an <code>IN</code> parameter using a single value and an <code>INOUT</code> parameter as an array. The method's return value is the <code>OUT</code> parameter. For example, Cloudscape declares the <code>IN</code> parameters (<code>acctName</code> and <code>amt</code>) for <code>ADDACCT</code> and the <code>OUT</code> parameter (the method's return value) for <code>GETAMT</code> follows:</p><pre>public static void ADDACCT(String acctname, int amt)public int GETAMT()</pre><p>If <code>amt</code> was an <code>INOUT</code> parameter, then Cloudscape declares it as:</p><pre>public static void ADDACCT(String acctname, int[] amt)</pre><p>Oracle declares an <code>INOUT</code> parameter as:</p><pre>procedure ADDACCT (acctname IN VARCHAR2, amt INOUT INTEGER)</pre><h4>Mapping Java Types to SQL Types</h4><p>Remember to map the SQL type of each value to its corresponding Java type. Thus, if the SQL type is integer, then the <code>InputRecord</code> or <code>OutputRecord</code> element must be defined as a <code>Integer</code> object. If the SQL type is a <code>VARCHAR</code>, then the Java type must be a <code>String</code> object. When you add the element to the <code>Record</code>, you declare it to be an object of the proper type. For example, add an <code>integer</code> and a <code>string</code> element to an <code>InputRecord</code> as follows: </p><pre>iRec.add (new Integer (intval));iRec.add (new String ("Customer Account"));</pre><p><a href="/aboutJava/communityprocess/jsr/jsr_054_jdbc3.html">The JDBC specification</a> defines the complete SQL to Java type mapping.</p><h2>Programming with the CCI</h2><p>To illustrate how to use the CCI API, take a look at a session bean and a client of that bean. These pieces of code illustrate how clients invoke the different CCI methods that resource adapters built on CCI might make available. (This example uses the sample resource adapters supplied with the J2EE reference implementation.)</p><p>Now examine the session bean implementation class to see how it uses the CCI. To begin with, notice that <code>AcctManageEJB</code> imports the <code>javax.resource CCI</code> interfaces and classes, along with <code>javax.resource.ResourceException</code>: </p><pre>import javax.resource.cci.*;import javax.resource.ResourceException;</pre><h3>Getting the Connection</h3><p>Prior to obtaining a database connection, the <code>AcctManageEJB</code> session bean does some set up work in its <code>setSessionContext</code> method. Specifically, the <code>setSessionContext</code> method sets the user and password values, and instantiates a <code>ConnectionFactory</code>. These values and objects remain available to the other session bean methods. </p><!-- BEGIN VCD7 CODE SAMPLE COMPONENT --><table border="0" cellpadding="10" cellspacing="0" width="100%" class="grey4"><tr><td><pre>public void setSessionContext(SessionContext sc) { try { this.sc = sc; // Establish a JNDI initial context. Context ic = new InitialContext(); // Use the JNDI InitialContext.lookup //method to find the user // and password values. user = (String) ic.lookup("java:comp/env/user"); password = (String) ic.lookup("java:comp/env/password"); // Use the lookup method to locate the // ConnectionFactory for the CCI // resource adapter and obtain a reference to it. cf = (ConnectionFactory) ic.lookup("java:comp/env/CCIEIS");...</pre></td></tr></table><span class="sp20"> </span><br /><!-- END VCD7 CODE SAMPLE COMPONENT --><p><code>AcctManageEJB</code> uses its private method <code>getCCIConnection</code> to establish a connection to the underlying resource manager or database. An <code>AcctManage</code> client cannot invoke this method directly. Rather, the session bean uses this method internally to establish a connection to the database. The <code>getCCIConnection</code> method invokes the <code>getConnection</code> method to obtain the connection. Prior to this call, it instantiates a <code>CciConnectionSpec</code> object, which represents the implementation of the <code>ConnectionSpec</code> interface, with the user and password values. It uses this <code>CciConnectionSpec</code> object to pass the user and password values to the connection. </p><!-- BEGIN VCD7 CODE SAMPLE COMPONENT --><table border="0" cellpadding="10" cellspacing="0" width="100%" class="grey4"><tr><td><pre>private Connection getCCIConnection() { Connection con = null; try { // Instantiate a new CciConnectionSpec // object with the user and // password values obtained by the // setSessionContext method. The // CciConnectionSpec class is the // implementation of the // ConnectionSpec interface. ConnectionSpec spec = new CciConnectionSpec(user, password); // Call the ConnectionFactory's getConnection // method to obtain a connection to the database. // Use the CciConnectionSpec object to // pass the required properties to // the ConnectionFactory. The getConnection // method returns a Connection object. con = cf.getConnection(spec); } catch (ResourceException ex) { ... } return con;}</pre></td></tr></table>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -