Java 这是一个很好的编码实践——传递连接吗?

Java 这是一个很好的编码实践——传递连接吗?,java,jdbc,Java,Jdbc,这是我的故事。我有myCon=getUnusedConnection()从连接池获取连接的方法。我还有一个releaseConnection(myCon)方法,用于在使用完池后释放与池的连接 好的,当编码时,我需要多次从数据库中选择数据&因为我想重用我的代码,所以我想为一个动作使用许多方法。前, public static List<String[]> getData(){ Connection myCon=null; PreparedStatement prepar

这是我的故事。我有
myCon=getUnusedConnection()从连接池获取连接的方法。我还有一个
releaseConnection(myCon)方法,用于在使用完池后释放与池的连接

好的,当编码时,我需要多次从数据库中选择数据&因为我想重用我的代码,所以我想为一个动作使用许多方法。前,

public static List<String[]> getData(){
    Connection myCon=null;
    PreparedStatement preparedStmt=null;
    try{
        myCon=getUnusedConnection();
        String sql="select ........";
        preparedStmt=myCon.prepareStatement(sql);
        ResultSet results=preparedStmt.executeQuery();
        String str="";
        if(results.next()){
             str=results.getString(1);
        }
        if(!str.equals("")){
             List<String[]> list=getData2(myCon, preparedStmt, str);
        }
        return list;
    }
    catch (SQLException ex) {
        while (ex != null) {
            System.out.println ("SQL Exception:  " +
                              ex.getMessage ());
            ex = ex.getNextException ();
        }
    }catch (java.lang.Exception e) {
        System.out.println("***ERROR-->" + e.toString());   
    }
    finally{
        releaseConnection (myCon);
        closeStatement (preparedStmt);
    }
    return null;
}

public static List<String[]> getData2(Connection myCon, PreparedStatement preparedStmt, String str){

     try{
         List<String[]> list=new ArrayList<String[]>();
         String sql="c.......";
         preparedStmt=myCon.prepareStatement(sql);
         ResultSet results=preparedStmt.executeQuery();
         while(results.next()){
             list.add(results.getString(1));
         }
         return list;
     }catch (SQLException ex) {
        while (ex != null) {
            System.out.println ("SQL Exception:  " +
                              ex.getMessage ());
            ex = ex.getNextException ();
        }
    }catch (java.lang.Exception e) {
        System.out.println("***ERROR-->" + e.toString());   
    }
    finally {

        closeStatement(preparedStmt);
        releaseConnection(myCon); 
    }
    return null;
}
公共静态列表getData(){
连接myCon=null;
PreparedStatement preparedStmt=null;
试一试{
myCon=getUnusedConnection();
字符串sql=“选择……”;
preparedStmt=myCon.prepareStatement(sql);
ResultSet results=preparedStmt.executeQuery();
字符串str=“”;
if(results.next()){
str=results.getString(1);
}
如果(!str.equals(“”){
列表=获取数据2(myCon、preparedStmt、str);
}
退货清单;
}
catch(SQLException-ex){
while(ex!=null){
System.out.println(“SQL异常:”+
例如getMessage());
ex=ex.getNextException();
}
}catch(java.lang.e异常){
System.out.println(“***错误-->”+e.toString());
}
最后{
释放连接(myCon);
结算单(已编制);
}
返回null;
}
公共静态列表getData2(连接myCon、PreparedStatement、preparedStmt、String str){
试一试{
列表=新的ArrayList();
字符串sql=“c……”;
preparedStmt=myCon.prepareStatement(sql);
ResultSet results=preparedStmt.executeQuery();
while(results.next()){
list.add(results.getString(1));
}
退货清单;
}catch(SQLException-ex){
while(ex!=null){
System.out.println(“SQL异常:”+
例如getMessage());
ex=ex.getNextException();
}
}catch(java.lang.e异常){
System.out.println(“***错误-->”+e.toString());
}
最后{
结算单(已编制);
释放连接(myCon);
}
返回null;
}
我是否需要在getData2中包含
try-catch-finally
? 由于我正在传递myCon&prepareStatement,所以我不确定这是正确的编码方式

这是我编写代码的标准方式吗?还是你做得更好

我是否需要在
getData2
中包含
try
-
catch
-
finally

答案取决于您调用的其他位置
getData2

  • 如果
    getData
    是唯一的地方,那么答案是“否”,那么一次
    尝试
    /
    最后
    就足够了
  • 如果还有其他地方都希望出现
    SQLException
    并以相同的方式处理它,那么出于同样的原因,答案也是“否”(不需要使用
    catch
  • 如果还有其他地方,其中一些地方不希望出现
    SQLException
    ,那么您需要保留
    try
    -
    catch
    -
    finally
但是,对
getData2
调用进行编码的方式有一个问题:由于
getData2
有一个
最终释放连接,因此
getData
会释放连接两次。您需要添加一个
useExistingConnection(conn)
并修改
releaseConnection
,以计数对同一连接的引用,或者传递一个指示是否应关闭连接的标志


一般来说,我更愿意构造代码,以相同的方法打开和关闭连接,将连接传递给其他方法,并使用
try
/
最终
仅关闭在从属方法中打开的
PreparedStatements
,例如
getData2

我将您的方法
getData2()
设为私有,不进行捕获(如果它处理异常与父级相同),如果您在顶层执行,则最终关闭资源。如果您无法更改它,请将另一个方法设为私有,例如
getData3()
而不使用
try catch finally

但是,如果所有方法都遵循相同的模板,我会做另一个更改

用于调用的可调用接口

public interface Queryable<T>{
    T execute();
} 
公共接口可查询{
T执行();
} 
然后是util类

public final class SQLUtil {

    private SQLUtil() { }

    public static Connection getConnection() {
        return getUnusedConnection();
    }

    public <T> static  T query(Queryable queryable) {
        T toReturn = null;
        try {

            toReturn = queryable.execute();
        } catch (SQLException ex) {
            while (ex != null) {
                System.err.println ("SQL Exception:  " +
                ex.getMessage ());
                ex = ex.getNextException ();
            }
        } catch (java.lang.Exception e) {
            System.out.println("***ERROR-->" + e.toString());   
        } finally {
            releaseConnection (myCon);
            closeStatement (preparedStmt);
        }    
    }

    //add code for getUnusedConnection, releaseConnection, closeStatement    
}
公共最终类SQLUtil{
私有SQLUtil(){}
公共静态连接getConnection(){
返回getUnusedConnection();
}
公共静态T查询(可查询可查询){
T toReturn=null;
试一试{
toReturn=queryable.execute();
}catch(SQLException-ex){
while(ex!=null){
System.err.println(“SQL异常:”+
例如getMessage());
ex=ex.getNextException();
}
}catch(java.lang.e异常){
System.out.println(“***错误-->”+e.toString());
}最后{
释放连接(myCon);
结算单(已编制);
}    
}
//添加getUnusedConnection、releaseConnection、closeStatement的代码
}
您的客户机代码如下所示:

public List<String[]> getData(){
    return SQLUtil.query(new Queryable<List<String[]>>() {
        @Override
        public List<String[]> execute() {
            Connection myCon=getUnusedConnection();
            String sql="select ........";
            PreparedStatement preparedStmt=myCon.prepareStatement(sql);
            ResultSet results=preparedStmt.executeQuery();
            String str="";
            if(results.next()) {
                str=results.getString(1);
            }
            List<String[]> list = null;
            if(!str.equals("")) {
                list=getData2(myCon, preparedStmt, str);
            }
            return list;
        }
    });
}
public List getData(){
返回SQLUtil.query(新的Queryable(){
@凌驾
公共列表执行(){
Connection myCon=getUnusedConnection();
字符串sql=“选择……”;
PreparedStatement preparedStmt=myCon.prepareStatement(sql);
ResultSet results=preparedStmt.executeQuery();
字符串str=“”;
if(results.next()){
str=results.getString(1);
}
List=null;
如果(!str.equals(“”){
列表=获取数据2(myCon、preparedStmt、str);