如何在标准try catch中运行方法

时间:2013-05-15 22:59:43

标签: java

自从我完成任何Java编程以来已经有一段时间了。我发现自己有点卡住了。

我的问题是我在tomcat中有一个池数据库连接。这很好用。但是需要很多锅炉板。

    public void init() {
    Connection conn = null;
    ResultSet rst = null;
    Statement stmt = null;
    try {

        //SETUP 
        Context initContext = new InitialContext();
        Context envContext = (Context) initContext.lookup("java:/comp/env/jdbc");
        OracleDataSource ds = (OracleDataSource) envContext.lookup("tclsms");

        if (envContext == null) throw new Exception("Error: No Context");
        if (ds == null) throw new Exception("Error: No DataSource");
        if (ds != null) conn = ds.getConnection();
        if (conn == null) throw new Exception("Error: No Connection")

        message = "Got Connection " + conn.toString() + ", ";

        //BODY 
        stmt = conn.createStatement();
        rst = stmt.executeQuery("SELECT 'Success obtaining connection' FROM DUAL");

        if (rst.next()) message = rst.getString(1);



        //TEAR DOWN 
        rst.close();
        rst = null;
        stmt.close();
        stmt = null;
        conn.close(); // Return to connection pool
        conn = null; // Make sure we don't close it twice
    } catch (Exception e) {
        e.printStackTrace();
        //TODO proper error handling 
    } finally {
        // Always make sure result sets and statements are closed,
        // and the connection is returned to the pool
        if (rst != null) {
            try {
                rst.close();
            } catch (SQLException e) {;}
            rst = null;
        }

        if (stmt != null) {
            try {
                stmt.close();
            } catch (SQLException e) {;}
            stmt = null;
        }

        if (conn != null) {
            try {
                conn.close();
            } catch (SQLException e) {;}
            conn = null;
        }
    } //END FINALLY
} //END INIT

所以我想做的相当于将一个方法传递给将在函数体中运行的init。我知道我不能用Java做到这一点。但我相信必须有一个很好的方法来做到这一点。或者至少是这种事情的最佳实践。

任何帮助都非常感激。

4 个答案:

答案 0 :(得分:1)

abstract class UseDBConnectionTask extends Runnable {

    private Connection conn;

    public UseDBConnectionTask(){
        setUp();
    }

    // should probably refine this to specific exceptions
    public abstract void process() throws Exception; 

    public void run(){

        try{
            process()
            // this should catch specific exceptions
        } catch (Exception e){
            // handle
        } finally {
            tearDown();
        }
    }

    Connection getConnection(){
        return conn;
    }

    public void setUp(){
        // SETUP here
        // set the conn field
    }

    public void tearDown(){
        // TEAR DOWN here
    }
}

使用像:

UseDBConnectionTask dbTransaction = new UseDBConnectionTask(){

    public void process(){
        // do processing 
        // use conn via getConnection()
        // eg
        Statement stmt = conn.createStatement();
        ResultSet rst = stmt.executeQuery("SELECT 'Success obtaining connection' FROM DUAL");

        String message = null;
        if (rst.next()) message = rst.getString(1);
    }

}

new Thread(dbTransaction).start();

扩展Runnable的优点是您可以将此实例传递给线程池或类似的。 只需要小心线程问题。它还假设拆除总是相同的。

答案 1 :(得分:1)

您应该更喜欢委托继承。以上可以/将会工作,但没有深思熟虑。

在主类上实现Runnable会使其暴露,因为'run()'方法是公开的。

第二个改进是使用将您的活动委托给接口(这可以像函数指针那样传递,而不能扩展类)。此外,它使它春天友好

这允许动作实现者决定他们是否需要多线程行为。您可以注入复合,缓存委托等,而主要类是非常明智的。这符合关注点分离

的良好设计实践
public class MyClass {

    private Action action;

    public MyClass (Action action) {
        this.action = action;
    }

    public void connection() {

        try{
            action.perform()
        } catch (Exception e){
            // handle
        } finally {
            tearDown();
        }
    }

    Connection getConnection(){
        return conn;
    }

    private void setUp(){
        // SETUP here
        // set the conn field
    }

    private void tearDown(){
        // TEAR DOWN here
    }

}

答案 2 :(得分:0)

private void Todo(Context initContext, Context envContext, OracleDataSource ds){

            if (envContext == null) throw new Exception("Error: No Context");
            if (ds == null) throw new Exception("Error: No DataSource");
            if (ds != null) conn = ds.getConnection();
            if (conn == null) throw new Exception("Error: No Connection")

            message = "Got Connection " + conn.toString() + ", ";

            //BODY 
            stmt = conn.createStatement();
            rst = stmt.executeQuery("SELECT 'Success obtaining connection' FROM DUAL");

            if (rst.next()) message = rst.getString(1);



            //TEAR DOWN 
            rst.close();
            rst = null;
            stmt.close();
            stmt = null;
            conn.close(); // Return to connection pool
            conn = null; // Make sure we don't close it twice
        } catch (Exception e) {
            e.printStackTrace();
            //TODO proper error handling 
        } finally {
            // Always make sure result sets and statements are closed,
            // and the connection is returned to the pool
            if (rst != null) {
                try {
                    rst.close();
                } catch (SQLException e) {;}
                rst = null;
            }

            if (stmt != null) {
                try {
                    stmt.close();
                } catch (SQLException e) {;}
                stmt = null;
            }

            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {;}
                conn = null;
            }
        } //END FINALLY
}

然后从您的Init中调用它this. Todo(initContext,envContext , ds

答案 3 :(得分:0)

interface IDbAction {
    public DbActionResult runAction(Connection conn);
}

class DbActionResult {

    Statement statement;
    ResultSet resultSet;

    public DbActionResult(Statement statement, ResultSet resultSet){
        this.statement = statement;
        this.resultSet = resultSet;
    }

    public void getStatement(){ return this.statement; }
    public void getResultSet(){ return this.resultSet; }
}

public void runAgainstDB(IDbAction action) {

    Connection conn = null;
    ResultSet rst = null;
    Statement stmt = null;

    try {

        //SETUP 
        Context initContext = new InitialContext();
        Context envContext = (Context) initContext.lookup("java:/comp/env/jdbc");
        OracleDataSource ds = (OracleDataSource) envContext.lookup("tclsms");

        if (envContext == null) throw new Exception("Error: No Context");
        if (ds == null) throw new Exception("Error: No DataSource");
        if (ds != null) conn = ds.getConnection();
        if (conn == null) throw new Exception("Error: No Connection")

        message = "Got Connection " + conn.toString() + ", ";

        //BODY 
        DbActionResult actionResult = action.runAction(conn);

        //TEAR DOWN 

        if((rst = actionResult.getResultSet()) != null){
            rst.close();
            rst = null;
        }

        if((stmt = actionResult.getStatement()) != null){
            stmt.close();
            stmt = null;
        }

        actionResult = null;

        conn.close(); // Return to connection pool
        conn = null; // Make sure we don't close it twice
    } catch (Exception e) {
        e.printStackTrace();
        //TODO proper error handling 
    } finally {
        // Always make sure result sets and statements are closed,
        // and the connection is returned to the pool
        if (rst != null) {
            try {
                rst.close();
            } catch (SQLException e) {;}
            rst = null;
        }

        if (stmt != null) {
            try {
                stmt.close();
            } catch (SQLException e) {;}
            stmt = null;
        }

        if (conn != null) {
            try {
                conn.close();
            } catch (SQLException e) {;}
            conn = null;
        }
    } //END FINALLY
} //END 

使用类似:

IDbAction action = new IDbAction(){

    public DbActionResult prcoessAction(Connection conn){
        Statement stmt = conn.createStatement();
        ResultSet rst = stmt.executeQuery("SELECT 'Success obtaining connection' FROM DUAL");

        if (rst.next()) message = rst.getString(1);

        return new DbActionResult(stmt, rst);
    }

}

runAgainstDB(action);