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);