2012-06-01 18 views
0

JDBC를 통해 SQLite를 사용하여 지속성을 유지하는 Java 응용 프로그램을 작성하고 있습니다. 나는 응용 프로그램이 시작할 때해야 할 일은Java : 데이터베이스 검사 및 초기화

은 다음과 같습니다

  1. DB를이 DB가 권리를 가지고 있는지 확인, 올바른 스키마
  2. DB를가 존재하는 경우에 그것을 생성, 존재하지 않는 경우 스키마

DB를 만들려면 외부 파일에 구조 (예 : CREATE TABLE ...)를 생성하는 데 필요한 SQL 명령을 외부화하려고 할 때 런타임에로드하고 실행하십시오. BufferedReader을 사용하여 .readLine()으로 생각한 다음 각 SQL 명령을 Statement.executeUpdate()에 보냈습니다. 이 일을하는 더 똑똑한 방법이 있습니까?

데이터베이스 스키마의 시작 검사에 대해서는 "좋은 디자인"으로 생각해야하지만 사실 과장되거나 쓸모 없다는 것을 나는 모른다.

  1. 모든 구조의 이름에 대한 sqlite_master (예 : nwe_)
  2. 쿼리 알려진 접두사를 사용하여 DB를 만들기 : 하나의 솔루션은 내가 생각 해낸 만되는 단점이있다 "따라 공급 업체는"이있다 WHERE name LIKE 'nwe_%'
  3. 테이블 내가

다시 DB를 만드는 데 사용되는 SQL 명령 파일로 SQL 컬럼의 내용을 비교 할 수있는 몇 가지 현명한 방법이 이? (아마도 "공급 업체에 의존"하지는 않지만 당시에는별로 문제가되지 않았습니다.)

감사합니다.

+0

, 내가 SQL 명령의 텍스트 파일 읽기는 그 같은 SQL 명령을 퍼팅보다 다른 표시되지 않습니다 : 그래서 데이터베이스 구조를 확인하는 신속하고 더러운 방법이 'static final String'을 사용합니다. 당신은 어딘가에 SQL을 작성해야합니다. 코드 외부에서 가져온 것은 무엇입니까? – RustyTheBoyRobot

+0

두 번째 질문과 관련하여 처음에 작성한 DB 스키마와 프로그램 전체에서 사용했던 DB 스키마가 서로 다른 유스 케이스는 무엇입니까? – RustyTheBoyRobot

+0

@RustyTheBoyRobot 1- : 저는 하드 코드 된 문자열을 좋아하지 않습니다. 문자열의 내용을 변경해야 할 경우 응용 프로그램을 다시 작성해야하기 때문입니다. 내가 잘못? 2 : DB가 손상되었거나 사용자가 잘못된 DB 파일을 가리킬 수 있습니다. –

답변

1

메타 데이터 테이블을보고 데이터베이스를 직접 검증 할 수 있습니다. 이것은 불가능하지 않지만 유지 관리해야 할 코드가 많습니다. 또한 DDL 문을 많이 작성하여 데이터베이스 구조를 작성할 수도 있습니다. 불가능한 것은 아니지만 많은 코드를 유지해야합니다. 당신이 그런 경로를 따르는 경우

, 나는

if (!checkDatabase()) { 
    try { 
    if (wantsToInstall()) { 
     installDatabase(); 
    } 
    } catch (Exception e) { 
    exit(); 
    } 
} 

의 높은 수준의 논리 또는 특정 설치 (기존 항목 위에 설치의 가능성을 줄이기 위해) 좋습니다. 데이터 항목 삭제를 제공하는 확장을 수행 할 수 있지만 설치/업그레이드 중에 예기치 않은 기존 개체가 발생할 경우 수행 할 작업에 대한 의견이 다릅니다.

이제이 작업을 수행 할 몇 가지 라이브러리가 있습니다. 하지만이 기능을 추가 할 때는 그러한 라이브러리가 단순한 데이터베이스 구조 유지보다 훨씬 더을 처리합니다. JDO와 그 밖의 몇몇 사람들에게 DataNucleus의 환경은 데이터베이스 구조가 20 개가 넘는 다른 데이터베이스에서 잘 작동하도록 기꺼이 만들 것이라는 것을 알고 있습니다.

+0

'checkDatabase()'를 구현하는 것이 가치 있다고 생각합니까? 이 좋은 디자인인가요? 'installDatabase()'부분에 관해서, 하드 코딩 된 SQL과 외부 파일에 대해 어떻게 생각합니까? –

+1

블라인드 테이블을 설치 하시겠습니까? 수표가 없으면 이전 데이터베이스 릴리스를 언제 어떻게 처리 할 것인지 알 수 있습니까? "하드 코딩 된 SQL"에 이르기까지, 만약 당신이 그 경로를 간다면, 그것을 반 휴대용으로 만들어보십시오; 왜냐하면 어느 날 그들은 지원되지 않는 데이터베이스에서이를 원할 것이기 때문입니다. 외부 파일을 사용하는 경우 Java 코드를 작성하는 데 왜 두 가지 문제가 있습니까? 고객의 요구 사항을 평가하고 작업 노력과 사용 편의성을 조화 시키며 가장 적합한 것이 무엇인지 결정해야합니다. –

+0

파일에서 읽은 다음 SQL 문을 실행하려면 Java 코드를 작성해야합니다. 그렇지 않으면 어떻게 실행할 수 있습니까? 아는 한 메타 데이터에 액세스하면 이식성이 떨어집니다. 나는 DB를 점검 할 다른 방법을 모른다. 감사합니다. –

3

나는 전문 프로그래머가 아니며 이것은 나의 첫 번째 자바 애플리케이션이지만 데이터베이스 검증도하기로 결정했다. 다행히도 sqlite 데이터베이스에는 데이터베이스의 각 테이블에 대한 sql 문이있는 시스템 테이블이 있습니다.

첫 번째 질문에 관해서
public class Model { 
    private Map<String, String> tableSql; 

    Model(){ 
     // declare right database's tables syntax 
     tableSql = new HashMap<String, String>(); 
     tableSql.put("settings", "CREATE TABLE [settings] ([id]  INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, [item] ...)"); 
     tableSql.put("scheta",  "CREATE TABLE [scheta] ([id] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, [sname] ...)"); 
     tableSql.put("nomera",  "CREATE TABLE [nomera] ([id] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, [nvalue] ...)"); 
     tableSql.put("corr",  "CREATE TABLE [corr] ( [id] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, [cname] ...)"); 
     tableSql.put("category", "CREATE TABLE [category] ([id] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, [cname] ...)"); 
     tableSql.put("price",  "CREATE TABLE [price] ([id] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, [cdate] ...)"); 
    } 

    public void Connect(String path){ 
     File DBfile = new File (path); 
     boolean DBexists = DBfile.exists(); 
     Statement stmt = null; 
     ResultSet rs; 

     try { 
      Class.forName("org.sqlite.JDBC"); 
      c = DriverManager.getConnection("jdbc:sqlite:" + path); 
      c.setAutoCommit(true); 

      stmt = c.createStatement(); 
      if(DBexists){ 
       // check database structure 
       for (String tableName : tableSql.keySet()) { 
        rs = stmt.executeQuery("SELECT sql FROM sqlite_master WHERE type = 'table' AND name = '" + tableName + "'"); 
        if(rs.isBeforeFirst()){ 
         rs.next(); 
         // table and field names may be inside square brackets or inside quotes... 
         String table_schema_there = rs.getString(1).replaceAll("\\s+"," ").replaceAll("[\\[\\]'`]", "\""); 
         String table_schema_here = tableSql.get(tableName).replaceAll("\\s+"," ").replaceAll("[\\[\\]'`]", "\"");; 
         if(! table_schema_there.equals(table_schema_here)){ 
          notifyListeners(new ModelResponse(false, "Structure error. Wrong structure of table " + tableName)); 
          System.exit(0); 
         } 
        } 
        else{ 
         notifyListeners(new ModelResponse(false, "Structure error. The table is missing: " + tableName)); 
         System.exit(0); 
        } 
       } 
      } 
      else{ 
       // empty DB file created during connection so we need to create schema 
       for (String tableName : tableSql.keySet()) { 
        stmt.executeUpdate(tableSql.get(tableName)); 
       } 
      } 
     } 
     catch (Exception e) { 
      notifyListeners(new ModelResponse(false, e.getMessage())); 
      System.exit(0); 
     } 
    } 
}