| S2DBCP offers database connection pooling using POJO. By integrating with JTA, transactions are maintained even after connections are opened and closed several times. Hence, it is no longer necessary to have several classes pass connections to maintain JDBC transactions. Furthermore, it is possible to use S2Tx, to automatically manage transactions with Aspect. ## Configuration It is necessary to configure XADataSource and ConnectionPool to use S2DBCP. XADataSource may be use if it is supported by the JDBC driver. If it is not supported, S2's XADataSourceImpl interface may be used to emulate XA. ### org.seasar.extension.dbcp.impl.XADataSourceImpl
Property | Description | Example
--- | --- | ---
driverClassName | JDBC Driver class name | "oracle.jdbc.driver.OracleDriver"
URL | Oracle database URL | "jdbc:oracle:thin:@xxx:1521:yyy"
user | User name to connect to database | "hoge"
password | Password of user to connect to database | "password"
### org.seasar.extension.dbcp.impl.ConnectionPoolImpl
Property | Description | Example
--- | --- | ---
XADataSource | XADataSource instance. When using S2Container, set to component name of XADataSource. | xaDataSource
transactionManager | TransactionManager instance. When using S2Container, set to component name of TransactionManager. | transactionManager
timeout | Time interval in seconds for unused connections which are returned to the pool to be closed and destroyed. Default value is 600 seconds (10 minutes). | 600
maxPoolSize | Maximum number of concurrent connections. When number of connections exceeds this number, a new request are blocked until a connection is returned to the pool. Default value is 10 connections. | 10
Connections are set as follows. Please modify it as needed to make it specific for your application. ### j2ee.dicon
    <components namespace="j2ee">
        <component name="transactionManager"
            class="org.seasar.extension.jta.TransactionManagerImpl"/>
        <component name="requiredTx"
            class="org.seasar.extension.tx.RequiredAdvice"/>
        <component name="requiresNewTx"
            class="org.seasar.extension.tx.RequiresNewAdvice"/>
        <component name="mandatoryTx"
            class="org.seasar.extension.tx.MandatoryAdvice"/>

        <component name="xaDataSource"
            class="org.seasar.extension.dbcp.impl.XADataSourceImpl">
            <property name="driverClassName">
                "oracle.jdbc.driver.OracleDriver"
            </property>
            <property name="URL">
                "jdbc:oracle:thin:@xxx:1521:yyy"
            </property>
            <property name="user">"aaa"</property>
            <property name="password">"bbb"</property>
        </component>
        <component name="connectionPool"
            class="org.seasar.extension.dbcp.impl.ConnectionPoolImpl">
            <property name="timeout">600</property>
            <property name="maxPoolSize">10</property>
            <destroyMethod name="close"/>
        </component>
        <component name="dataSource"
            class="org.seasar.extension.dbcp.impl.DataSourceImpl"/>

    </components>
## Example ### EmployeeDao.java
    package examples.dbcp;

    import java.sql.SQLException;

    public interface EmployeeDao {

        public String getEmployeeName(int empno) throws SQLException;
    }
#### EmployeeDaoImpl.java
    package examples.dbcp;

    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;

    import javax.sql.DataSource;

    public class EmployeeDaoImpl implements EmployeeDao {

        private DataSource dataSource_;

        public EmployeeDaoImpl(DataSource dataSource) {
            dataSource_ = dataSource;
        }

        public String getEmployeeName(int empno) throws SQLException {
            String ename = null;
            Connection con = dataSource_.getConnection();
            try {
                PreparedStatement ps = con.prepareStatement(
                    "SELECT ename FROM emp WHERE empno = ?");
                try {
                    ps.setInt(1, empno);
                    ResultSet rs = ps.executeQuery();
                    try {
                        if (rs.next()) {
                            ename = rs.getString("ename");
                        }
                    } finally {
                        rs.close();
                    }
                } finally {
                    ps.close();
                }
            } finally {
                con.close();
            }
            return ename;
        }
    }
### EmployeeService.java
    package examples.dbcp;

    import java.sql.SQLException;

    public interface EmployeeService {

        public String getEmployeeName(int empno) throws SQLException;
    }
### EmployeeServiceImpl.java
    package examples.dbcp;

    import java.sql.SQLException;

    public class EmployeeServiceImpl implements EmployeeService {

        private EmployeeDao dao_;

        public EmployeeServiceImpl(EmployeeDao dao) {
            dao_ = dao;
        }

        public String getEmployeeName(int empno) throws SQLException {
            return dao_.getEmployeeName(empno);
        }
    }
### Employee.dicon
    <components>
        <include path="j2ee.dicon"/>
        <component class="examples.dbcp.EmployeeDaoImpl"/>
        <component class="examples.dbcp.EmployeeServiceImpl">
            <aspect>j2ee.requiredTx</aspect>
        </component>
    </components>
### EmployeeClient.java
    package examples.dbcp;

    import java.sql.SQLException;

    import org.seasar.framework.container.S2Container;
    import org.seasar.framework.container.factory.S2ContainerFactory;

    public class EmployeeClient {

        private static final String PATH =
            "examples/dbcp/Employee.dicon";

        public static void main(String[] args) {
            S2Container container = S2ContainerFactory.create(PATH);
            container.init();
            try {
                EmployeeService service = (EmployeeService)
                container.getComponent(EmployeeService.class);
                System.out.println(service.getEmployeeName(7788));
            } catch (SQLException ex) {
                ex.printStackTrace();
            } finally {
                container.destroy();
            }
        }
    }
### Result
    DEBUG 2004-03-21 12:51:35,653 [main] Transaction.begin()
    DEBUG 2004-03-21 12:51:37,075 [main] Transaction.commit()
    SCOTT
As you can see, it is much easier to write codes using POJO than writing JTA codes to handle database connection pooling. |
Trans. by H.Ozawa | Copyright© 2004-2005, The Seasar Foundation and the others. All rights reserved.