自从我完成任何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做到这一点。但我相信必须有一个很好的方法来做到这一点。或者至少是这种事情的最佳实践。
任何帮助都非常感激。
答案 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);