2016-12-06 11 views
-1

DAOメソッドで人々がfinally{}を使用するデータベース接続を閉じる例がたくさんありましたが、私の場合、DAOメソッド(例:insertUsers())では、呼び出されたメソッドに例外がスローされます。この場合、どうやって接続を閉じることができますか?Java SQLite - 接続を閉じるには?

SELECT + INSERTにしようとすると、「SQLiteException - データベースはロックされています」というエラーが表示されます。

ここに私のコードです:

DAO

public static Connection con = null; 
private static boolean hasData = false; 

private void getConnection() throws ClassNotFoundException, SQLException { 
    Class.forName("org.sqlite.JDBC"); 
    con = DriverManager.getConnection("jdbc:sqlite:ProjFarmacia.db"); 
    initialise(); 
} 

private void initialise() throws SQLException { 
    if(!hasData){ 
     hasData = true; 
     Statement state = con.createStatement(); 
     ResultSet res = state.executeQuery("SELECT name FROM sqlite_master WHERE type='table' AND name='caixa'"); 
     if(!res.next()){ 
      Statement state2 = con.createStatement(); 
      state2.execute("CREATE TABLE caixa(id integer, timestamp integer, valorTotal double, notas1 integer, notas2 integer," 
        + " notas5 integer, notas10 integer, notas20 integer" 
        + "notas50 integer, notas100 integer, moedas1 integer, moedas5 integer, moedas10 integer, moedas25 integer" 
        + "moedas50 integer, moedas1R integer, primary key(id));"); 
     } 
    } 
} 




public ResultSet getCaixaByDate(long timestamp) throws ClassNotFoundException, SQLException{ 
    if(con == null){ 
     getConnection(); 
    } 

    Statement state = con.createStatement(); 
    ResultSet res = state.executeQuery("SELECT * FROM caixa WHERE timestamp=" + "'" + timestamp + "'" + ";"); 
    return res; 
} 


public void createCaixa(Caixa caixa) throws ClassNotFoundException, SQLException{ 
    if(con == null){ 
     getConnection(); 
    } 
    PreparedStatement prep = con.prepareStatement("INSERT INTO caixa VALUES(?,?);"); 
    prep.setLong(1, caixa.getTimestamp()); 
    prep.setDouble(2, caixa.getValorTotal()); 
    con.close(); 
} 

メインアプリケーション

try { 
     ResultSet rs = caixaDAO.getCaixaByDate(timestamp); 

     //If not exists in database 
     if(!rs.next()){ 
      Caixa caixa = new Caixa(); 
      caixa.setTimestamp(timestamp); 
      caixa.setValorTotal(venda.getValorDaVenda()); 

      //Inserting new Caixa 
      caixaDAO.createCaixa(caixa); 
     }else{ 
      System.out.println("Caixa already created!!!"); 
     } 

    } catch (ClassNotFoundException | SQLException ex) { 
     Logger.getLogger(VendaMedicamento.class.getName()).log(Level.SEVERE, null, ex); 
} 
+0

また、エラーを修正する方法を知りたいですか? – XtremeBaumer

+0

あなたのコードは間違いがひどいです。より多くのコードを書く前に、チュートリアル(または2つ)を読むことをお勧めします。あなたはそのような非標準コードを書くのに苦労します。 – Kayaman

+0

@Kayamanはあなたの意見を分かち合うことに感謝しますが、何の助けもないコメントであるので無視しなければなりません。 –

答えて

0
Connection conn = null; 
PreparedStatement ps = null; 
ResultSet rs = null; 

try { 
    // Do stuff 
    ... 

} catch (SQLException ex) { 
    // Exception handling stuff 
    ... 
} finally { 
    if (rs != null) { 
     try { 
      rs.close(); 
     } catch (SQLException e) { /* ignored */} 
    } 
    if (ps != null) { 
     try { 
      ps.close(); 
     } catch (SQLException e) { /* ignored */} 
    } 
    if (conn != null) { 
     try { 
      conn.close(); 
     } catch (SQLException e) { /* ignored */} 
    } 
} 

出典:私はDAOのメソッドを実装する方法をのJava7-try-with-resources

try (Connection conn = DriverManager.getConnection("DB_URL","DB_USER","DB_PASSWORD"); 
      PreparedStatement ps = conn.prepareStatement("SQL"); 
      ResultSet rs = ps.executeQuery()) { 

     // Do stuff with your ResultSet 

    } catch (SQLException ex) { 
     // Exception handling stuff 
    } 

例と@ JaLe29の

+0

Java7では、定型コードがはるかに少ないのでこれが可能です!どのJavaバージョンで@henriqueを使用しますか –

+0

1.8、非定型コードには 'DbUtils'を使用できます:-) –

+0

私はtry-with-resourcesを考えていました –

0

例:

Caixa getCaixaByDate(long timestamp) { 
    Caixa result = null; 
    try(Connection con = getConnection(); 
      PreparedStatement statement = con.prepareStatement("SELECT * FROM caixa WHERE timestamp=?")) { 
     statement.setLong(1, timestamp); 

     try (ResultSet res = statement.executeQuery()) { 
      result = new Caixa(); 
      result.setTimestamp(res.getLong("timestamp")); // this is just an example 
      //TODO: mapping the other input from the ResultSet into the caixa object 
     } catch (SQLException e) { 
      result = null; 
      Logger.getLogger("MyLogger").log(Level.SEVERE, "error while mapping ResultSet to Caixa: {0}", e.getMessage()); 
     } 
    } catch (SQLException e) { 
     Logger.getLogger("MyLogger").log(Level.SEVERE, "error while reading Caixa by date: {0}", e.getMessage()); 
    } 
    return result; 
} 

ビジネスロジックはこのようになりますこの方法:

public void createCaixaIfNotExist(long timestamp, double valorDaVenda) { 
    if (caixaDao.getCaixaByDate(timestamp) == null) { 
     Caixa newCaixa = new Caixa(); 
     newCaixa.setTimestamp(timestamp); 
     newCaixa.setValorTotal(valorDaVenda); 
     caixaDao.createCaixa(newCaixa); 
    } 
} 
+0

Niklasありがとう!しかし、私のコードでは、try/catchはConnectionオブジェクトと同じクラスにはありません。あなたの提案はありますか? –

+0

ResultSetの処理がDAOメソッド/クラスの外にある理由はわかりません。私はそれをしないだろう。 DAOメソッド内でResultSetを処理すると、すべてのDAOメソッドが独自の接続を使用し、すべてが最後に閉じられるように、 '(connect conn = getConnection())'ですべてのDAOメソッドを開始します。このようなクローズドアクションはすべてDAO内で実行する必要があります。そうしないと、ResultSet、StatementsまたはConnectionsがまったく閉じられないことがあります。 –

+0

が非常によく観察された。私はJavaに多くの経験がないので、私はDAOを作成するためのチュートリアルに従っていました。私はすべてのメソッドが閉じられていることを確認するためにリファクタリングします。 –