2013-05-13 2 views
0

저는 Java에 익숙하지 않으며 기본 데이터베이스 액세스 레이어를 구현하려고합니다. JDBC 보일러 플레이트 코드를 줄이기 위해 Apache DBUtils를 사용하고 있습니다.이 코드는 실제로 잘 작동합니다.데이터베이스 액세스 레이어에서 코드 중복을 줄이려면 어떻게해야합니까?

문제는 제 구현에서 데이터베이스의 각 테이블에 대해 CRUD에 대해 별도의 클래스를 사용하고 있으며 많은 기능을 복제하는 것이 잘못되었다고 생각합니다.

허용되는 설계입니까? 그렇지 않은 경우 코드 중복을 줄이려면 어떻게해야합니까?
내 방식으로 제네릭을 사용하도록 내 솔루션을 리팩터링 할 수 있습니까?

해결책으로 ORM (myBatis, Hibernate 등)을 사용할 수 있다는 것을 알았지 만, 도움이된다면 DBUtils 및 일반 JDBC를 사용하려고합니다.

단지 설명을위한

:
내가 2 개 테이블이 있다고하자 ... 내 현재 솔루션에

--------------------- 
User | File 
--------------------- 
userId | fileId 
name | path 
age  | size 
--------------------- 

내가 2 개 클래스 (UserStore, 파일 저장소) 및 을 만들 것입니다 각 클래스는 유사한 기본 CRUD를 구현하는 것이 방법 :

protected boolean Create(User newUser) 
{ 
    QueryRunner run = new QueryRunner(dataSource); 
    try 
    { 
     run.update("INSERT INTO User (name, age) " + 
       "VALUES (?, ?)", newUser.getName(), newUser.getAge()); 
    } 
    catch (SQLException ex) 
    { 
     Log.logException(ex); 
     return false; 
    } 
    return true; 
} 

protected User Read(int userId) 
{ 
    try 
    { 
     User user = run.query("SELECT * FROM User WHERE userId = ? ", userId); 
     return user; 
    } 
    catch (SQLException ex) 
    { 
     Log.logException(ex); 
     return null; 
    } 
} 

protected update(User user) 
{ 
    ... perform database query etc 
} 

protected delete(int userId) 
{ 
    ... perform database query etc 
} 
+0

그리고 ... 때문에 템플릿 방법이 작동하지 않습니다 ...? – kutschkem

+0

Spring JDBC 템플릿을 의미합니까? – Fade

+0

아니, 템플릿 패턴 의미 http://en.wikipedia.org/wiki/Template_method_pattern – kutschkem

답변

0

당신은 내가 어떻게 이것을 템플릿 방법으로 할 것인지 물어 보았습니다. 여기에 어떻게 할 수 있는지 예가 나와 있습니다.

public class AbstractDAO<T> { 
private String table; 
private String id_field; 

public AbstractDAO(String table, String id_field){ 
this.table = table; 
... 
} 

public T read(int id){ 
    try 
{ 
    T user = run.query("SELECT * FROM "+ table + " WHERE "+id_field +" = ? ", id); 
    return user; 
} 
catch (SQLException ex) 
{ 
    Log.logException(ex); 
    return null; 
} 
} 

작성 방법은 간단합니다.

public boolean Create(T user){ 
    QueryRunner run = new QueryRunner(dataSource); 
try 
{ 
    run.update("INSERT INTO "+table+ getFields() + 
      "VALUES " + getParameters(user)); 
} 
catch (SQLException ex) 
{ 
    Log.logException(ex); 
    return false; 
} 

    return true; 
} 

protected abstract String getFields(); 
protected abstract String getParameters(T user); 

추악하고 불안정하지만 아이디어를 전달하는 데는 문제가 없습니다. 1) 인터페이스 2A 개발)을 정의하는 MyBatis로 주석을 사용

<select id="mCount" resultType="hashmap"> select managerName, count(reportees) AS count from mgr_employee group by managerName; </select>

그래서 효과적으로이 같은 흐름에서 쓸 수 있습니다 :

0

귀하의 질문에 대한 간단한 제안을 드릴 수 있습니다.

1)

대신 당신이 무엇을하고 있는지와 같은 쿼리를 내부의 DAO를 관리, 사용자의 요구에 대한 쿼리의 목록이 공장 클래스를 확인합니다.

class QueryFactory { 
    static String INSERT_BOOK = "BLAH"; 
    static String DELETE_BOOK = "BLAH"; 
} 

처럼이 DAO 코드에서 쿼리를 분리하고 관리하기 쉽게 만들 것입니다.

2)

는 일반적인 DAO http://www.codeproject.com/Articles/251166/The-Generic-DAO-pattern-in-Java-with-Spring-3-and

3

) 위에서 언급 한 것처럼, 자신이 데이터베이스 및 더 많은 기능에 콩을 결합하기 위해 ORM을 사용을 구현합니다.

0

DBUtils를 사용하면 많은 상용구 코드를 이미 추상화했습니다. 남아있는 것은 주로 엔티티간에 다른 작업입니다. 올바른 SQL 문, 엔티티 객체를 UPDATE 매개 변수로 변환하거나 그 반대로 SELECT, 예외 처리를 사용합니다.

불행하게도 나머지 작업을 수행 할 수있을 정도로 유연한 일반적인 추상화를 만드는 것은 쉽지 않습니다. 그것이 바로 ORM 매퍼가하는 것입니다. 나는 아직도 이것들 중 하나를 조사 할 것을 제안 할 것이다. JPA API를 고수한다면 여전히 표준 영역에 있으며 ORM 제공자를 더 쉽게 전환 할 수 있습니다 (항상 커플 링이 있음에도 불구하고). SpringData의 저장소 추상화에 깊은 인상을 받았습니다. 간단히 사례에서 그들은 을 0으로 코드 DAO를 제공합니다. Spring을 이미 사용하고 있고 객체 모델을 유지하기를 원한다면 확실히 살펴 봐야합니다.

또는 jooq으로 좋은 경험을했습니다. 또한 스키마의 테이블을 기반으로 DTO 및 해당 DAO를 만들 수 있습니다. ORM 매퍼와 달리 관계형 스키마에 더 가깝기 때문에 이점 또는 단점이 될 수 있습니다.

0

의 MyBatis는 해시 맵으로 resulttype을 반환 할 수 있습니다 쿼리에 필요한 또는 2B)를 XML로 인터페이스를 연결하고 쿼리이 어떤 DAO를 포함되지 않습니다 및 기타 boilerplates 위와 같이

를 포함하는 것을

를 적어 두십시오 쓰기3210

관련 문제