2012-06-18 5 views
1

데이터베이스를 조작하는 많은 메소드가있는 DAO 클래스가 있습니다.Java에서 여러 메소드에 대해 하나의 데이터베이스 연결을 만드는 방법은 무엇입니까?

class ExampleDAOImpl implements ExampleDAO{ 
    private Connection con = null; 

    public void method1() { 
    con = Database.connect(); 
    .... 
    con.close(); 
    } 

    public void method2() { 
    con = Database.connect(); 
    .... 
    con.close(); 
    } 

public void method1() { 
    con = Database.connect(); 
    .... 
    con.close(); 
    } 
} 

이 각각의 방법에 대한 새로운 연결을 인스턴스화하고 닫습니다하는 것이 좋습니다 : 나는() Database.connect (연결 개체를 반환)이 같은 모든 방법에 대해 하나의 연결 개체를 사용하고? 나는 지금 "연결이 닫힌 후에 아무 작업도 허용하지 않는다"는 오류가 발생했습니다. 각 메서드의 시작 부분에서 연결을 초기화하고 끝에 닫는 중이지만. 또는 동일한 연결 개체를 사용하고 호출 할 때이를 닫는 별도의 메서드를 사용하는 것이 좋습니다.

+3

추상 클래스와 람다를 사용하는 경우 봄. –

+0

예외에 대한 자세한 내용을 제공해야합니다! 예를 들어 StackTrace 또는 Line Number가 도움이 될 것입니다! – adranale

+0

가능한 복제본 [JDBC Best practice] (http://stackoverflow.com/questions/6169301/jdbc-best-practice) –

답변

0

disconnection() 

통화

connection() 

서로에 대한 모든 방법

function method() 
{ 
    //call 

    connection(); 

    //code; 

    //call 

    disconnection(); 
    } 
0

에서 그 방법을 두 가지 기능을 만들 당신이 연결을 열 때 글로벌 연결을 지점 각 방법에서. method1에서 method2를 호출하면 method1에 의해 사용되는 연결이 닫힙니다.

일반적으로 응용 프로그램 수명에서 연결을 한 번 만들고 응용 프로그램 닫기/종료시 연결을 닫는 것이 좋습니다. 개폐 연결.

+0

그러면 연결을 종료 할시기를 어떻게 결정할 수 있습니까? 아니면 안전한 출구의 예를 들어 줄 수 있습니까? – iozee

0

jdbc 연결을 동시에 사용할 수 없으므로 코드가 스레드로부터 안전하지 않습니다.! ThreadLocal에 연결 con을 변경하고 연결 및 연결 해제를위한 두 가지 메소드를 추가하십시오.

코드는 될 것 같은 :

당신의 DAO에
public class ConnectionHelper 
{ 
private static ThreadLocal<Connection> con = new ThreadLocal<Connection>(); 

protected Connection getConnection() 
{ 
if(con.get() ==null) 
{ 
con.set(Database.connect()); 
} 
return con.get(); 
} 

protected Connection closeConnection() 
{ 
if(con.get() !=null) 
{ 
con.get().close; 
} 
} 
} 

: 공공 무효 방법 항목() { 이 { 연결 콘을 시도 = ConnectionHelper.getConnection(); } 마지막으로 { ConnectionHelper.closeConnection(); } }

+0

동기화 기능이 제공됩니까? – alaster

+1

ThreadLocal에 대한 동기화가 필요하지 않습니다. 스레드 범위의 변수입니다. –

2

ExampleDAOImpl의 개체는 스레드로부터 안전하지 않습니다. 따라서 두 개 이상의 스레드가 같은 ExampleDAOImpl 개체를 사용하고 동시에 메서드를 호출하면 다른 스레드가 연결을 닫고 사용하려고 할 수 있습니다.

가능한 해결책 :

  • ExampleDAOImpl 객체는 다중 스레드 환경에서 사용되지 않습니다 있는지 확인하십시오. 여전히 오류가 발생하기 쉽습니다.
  • 더 나은 제안 : Connection 개체 하나를 사용하는 대신 ConnectionPool을 사용하여 각 방법의 시작 부분에 연결하고 완료 한 후에 연결을 해제하십시오.
0

당신이 BoneCP 같은 연결 풀 구현을 사용하는 경우, 각 방법에 대한 새로운 연결을 열 단지 방법은 인스턴스 변수를 참조하지 않도록 완벽하게 괜찮지 만, 오히려 지역 변수.

한편 연결 풀을 사용할 수없고 하나의 연결로만 작업하는 경우 풀없이 새 풀을 가져 오는 것이 비용이 많이 들기 때문에 연결을 닫을 수있는 적절한 위치를 찾아야합니다.

0

코드를 건조 무엇 당신이 원하는, 다음이 방법은 서로를 호출 할 경우, 내부 호출이 조기에 연결을 종료하여 당신이있어 오류가 발생합니다

class ExampleDAOImpl implements ExampleDAO{ 

    // With lambdas 
    public void method1() { 
     withConnection((Connection con) -> { 
      // do whatever you want with the connection 
      // no need to open or close it 
     }) 
    } 

    // Old style abstract class 
    public void method2() { 
     withConnection(new TaskExecutor(){ 
      void doStuff(Connection con){ 
      // do whatever you want with the connection 
      // no need to open or close it 
      } 
     }) 
    } 

    // This is the magic you have to add. 
    private void withConnection(TaskExecutor executer){ 
     // Instantiate it to avoid race conditions 
     // good thing this is the only place 
     // you have to worry about opening and closing it 
     Connection con = Database.connect(); 
     executer.doStuff(con); 
     con.close(); 
    } 

    private abstract class TaskExecutor{ 
     abstract void doStuff(Connection con); 
    } 

} 
관련 문제