2013-04-08 2 views
15

저는 Libgdx에서 새로 왔으며 게임에서 데이터베이스를 사용하는 데 문제가 있습니다.Libgdx에서 SQLite 데이터베이스 사용

Libgdx를 사용하여 Android 및 데스크톱 응용 프로그램 모두에서 SQLite를 작동시키는 방법에 대한 자습서를 찾았지만 쉬운 것을 찾지 못했습니다.

마지막으로 Android에서 데이터베이스를 사용했을 때 SQLiteOpenHelper까지 확장되는 클래스를 만들었습니다.

Libgdx를 사용하여 동일한 작업을 수행하는 간단한 방법이 있습니까? 아니면 적어도 누군가가 단계별 자습서 나 비슷한 것을 가르쳐 줄 수 있습니까?

편집

은 내가 나를 SQLiteOpenHelper 같은 버전을 관리 할 수 ​​있도록 뭔가를 찾고 있어요 말을 잊어 버렸습니다. 즉, 코드에서 내 DB의 버전을 변경할 때 apk 설치시 안드로이드에서 데이터베이스를 다시 만들고 싶습니다.

솔루션

@42n4 대답에 따라, 나는 데스크톱 응용 프로그램에 안드로이드 응용 프로그램에 SQLiteOpenHelperJDBC를 사용하는 SQLite 데이터베이스에 연결하는 방법을 관리. 내가 데스크톱 응용 프로그램에 대한 DatabaseDesktop 클래스 생성, 그리고

//General class that needs to be implemented on Android and Desktop Applications 
public abstract class DataBase { 

    protected static String database_name="recycling_separation"; 
    protected static DataBase instance = null; 
    protected static int version=1; 

    //Runs a sql query like "create". 
    public abstract void execute(String sql); 

    //Identical to execute but returns the number of rows affected (useful for updates) 
    public abstract int executeUpdate(String sql); 

    //Runs a query and returns an Object with all the results of the query. [Result Interface is defined below] 
    public abstract Result query(String sql); 

    public void onCreate(){ 
     //Example of Highscore table code (You should change this for your own DB code creation) 
     execute("CREATE TABLE 'highscores' ('_id' INTEGER PRIMARY KEY NOT NULL , 'name' VARCHAR NOT NULL , 'score' INTEGER NOT NULL);"); 
     execute("INSERT INTO 'highscores'(name,score) values ('Cris',1234)"); 
     //Example of query to get DB data of Highscore table 
     Result q=query("SELECT * FROM 'highscores'"); 
     if (!q.isEmpty()){ 
      q.moveToNext(); 
      System.out.println("Highscore of "+q.getString(q.getColumnIndex("name"))+": "+q.getString(q.getColumnIndex("score"))); 
     } 
    } 

    public void onUpgrade(){ 
     //Example code (You should change this for your own DB code) 
     execute("DROP TABLE IF EXISTS 'highscores';"); 
     onCreate(); 
     System.out.println("DB Upgrade maded because I changed DataBase.version on code"); 
    } 

    //Interface to be implemented on both Android and Desktop Applications 
    public interface Result{ 
     public boolean isEmpty(); 
     public boolean moveToNext(); 
     public int getColumnIndex(String name); 
     public float getFloat(int columnIndex); 
     [...] 
    } 
} 

:

첫째, 나는 데스크톱 및 안드로이드 응용 프로그램 모두에 대해 "일반적인 클래스"를 만들어

public class DatabaseDesktop extends DataBase{ 
    protected Connection db_connection; 
    protected Statement stmt; 
    protected boolean nodatabase=false; 

    public DatabaseDesktop() { 
     loadDatabase(); 
     if (isNewDatabase()){ 
      onCreate(); 
      upgradeVersion(); 
     } else if (isVersionDifferent()){ 
      onUpgrade(); 
      upgradeVersion(); 
     } 

    } 

    public void execute(String sql){ 
     try { 
      stmt.execute(sql); 
     } catch (SQLException e) { 
      e.printStackTrace(); 
     } 
    } 

    public int executeUpdate(String sql){ 
     try { 
      return stmt.executeUpdate(sql); 
     } catch (SQLException e) { 
      e.printStackTrace(); 
     } 
     return 0; 
    } 

    public Result query(String sql) { 
     try { 
      return new ResultDesktop(stmt.executeQuery(sql)); 
     } catch (SQLException e) { 
      e.printStackTrace(); 
     } 
     return null; 
    } 

    private void loadDatabase(){ 
     File file = new File (database_name+".db"); 
     if(!file.exists()) 
      nodatabase=true; 
     try { 
      Class.forName("org.sqlite.JDBC"); 
      db_connection = DriverManager.getConnection("jdbc:sqlite:"+database_name+".db"); 
      stmt = db_connection.createStatement(); 
     } catch (ClassNotFoundException e) { 
      e.printStackTrace(); 
     } catch (SQLException e) { 
      e.printStackTrace(); 
     } 
    } 

    private void upgradeVersion() { 
     execute("PRAGMA user_version="+version); 
    } 

    private boolean isNewDatabase() { 
     return nodatabase; 
    } 

    private boolean isVersionDifferent(){ 
     Result q=query("PRAGMA user_version"); 
     if (!q.isEmpty()) 
      return (q.getInt(1)!=version); 
     else 
      return true; 
    } 

    public class ResultDesktop implements Result{ 

     ResultSet res; 
     boolean called_is_empty=false; 

     public ResultDesktop(ResultSet res) { 
      this.res = res; 
     } 

     public boolean isEmpty() { 
      try { 
       if (res.getRow()==0){ 
        called_is_empty=true; 
        return !res.next(); 
       } 
       return res.getRow()==0; 
      } catch (SQLException e) { 
       e.printStackTrace(); 
      } 
      return false; 
     } 

     public boolean moveToNext() { 
      try { 
       if (called_is_empty){ 
        called_is_empty=false; 
        return true; 
       } else 
        return res.next(); 
      } catch (SQLException e) { 
       e.printStackTrace(); 
      } 
      return false; 
     } 

     public int getColumnIndex(String name) { 
      try { 
       return res.findColumn(name); 
      } catch (SQLException e) { 
       e.printStackTrace(); 
      } 
      return 0; 
     } 

     public float getFloat(int columnIndex) { 
      try { 
       return res.getFloat(columnIndex); 
      } catch (SQLException e) { 
       e.printStackTrace(); 
      } 
      return 0; 
     } 

     [...] 

    } 

} 

을 그리고 DatabaseAndroid 안드로이드에 대한 신청서

public class DatabaseAndroid extends DataBase{ 
    protected SQLiteOpenHelper db_connection; 
    protected SQLiteDatabase stmt; 

    public DatabaseAndroid(Context context) { 
     db_connection = new AndroidDB(context, database_name, null, version); 
     stmt=db_connection.getWritableDatabase(); 
    } 

    public void execute(String sql){ 
     stmt.execSQL(sql); 
    } 

    public int executeUpdate(String sql){ 
     stmt.execSQL(sql); 
     SQLiteStatement tmp = stmt.compileStatement("SELECT CHANGES()"); 
     return (int) tmp.simpleQueryForLong(); 
    } 

    public Result query(String sql) { 
     ResultAndroid result=new ResultAndroid(stmt.rawQuery(sql,null)); 
     return result; 
    } 

    class AndroidDB extends SQLiteOpenHelper { 

     public AndroidDB(Context context, String name, CursorFactory factory, 
       int version) { 
      super(context, name, factory, version); 
     } 

     public void onCreate(SQLiteDatabase db) { 
      stmt=db; 
      DatabaseAndroid.this.onCreate(); 
     } 

     public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 
      stmt=db; 
      DatabaseAndroid.this.onUpgrade(); 
     } 

    } 

    public class ResultAndroid implements Result{ 
     Cursor cursor; 

     public ResultAndroid(Cursor cursor) { 
      this.cursor=cursor; 
     } 

     public boolean isEmpty() { 
      return cursor.getCount()==0; 
     } 

     public int getColumnIndex(String name) { 
      return cursor.getColumnIndex(name); 
     } 

     public String[] getColumnNames() { 
      return cursor.getColumnNames(); 
     } 

     public float getFloat(int columnIndex) { 
      return cursor.getFloat(columnIndex); 
     } 

     [...] 

    } 

} 

마지막으로, 나는 차

내가 PRAGMA user_version를 사용하여 SQLiteOpenHelper에서 일어나는 것과 같은 버전 관리를했다 : 것을

public class Main extends AndroidApplication { 

    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     initialize(new MyGame(new DatabaseAndroid(this.getBaseContext())), false); 
    } 
} 

public class Main { 

    public static void main(String[] args) { 
     new LwjglApplication(new MyGame(new DatabaseDesktop()), "Example", MyGame.SCREEN_WIDTH, MyGame.SCREEN_HEIGHT,false); 
    } 

} 

참고 : 모두 안드로이드 및 데스크톱 응용 프로그램의 메인 클래스 nged. 이 방법을 사용하면 업그레이드 할 때 DataBase 클래스의 버전을 변경하기 만하면됩니다.

내가 만든 모든 방법을 Result에 두지는 않았지만, 나는 그것이 더 중요하다고 생각하는 것을 넣었습니다. 더 중요합니다.

답변

3

http://marakana.com/techtv/android_bootcamp_screencast_series.html 클래스 4, 1 부 : 안드로이드 부트 캠프 - statusData, libgdx에 대한 : http://code.google.com/p/libgdx-users/wiki/SQLite

편집 : 내가 Udacity의에서 libgdx 게임 약 두 개의 새로운 코스를 언급해야한다 : https://github.com/udacity/ud405

https://github.com/udacity/ud406

+0

그래서 Android와 Desktop 모두에서'StatusData'라는 클래스를 만듭니다. 맞습니까? 안드로이드에서, 전에 사용했던 것처럼'SQLiteOpenHelper'를 사용할 수 있습니다. 그러나 데스크탑 응용 프로그램은 어떻습니까? 예를 들어'StatusData'에서 DB 버전이 바뀌면 데스크톱 애플리케이션이 DB를 다시 만들 수 있을까요? –

+0

어쩌면 도움이 될 것입니다 : http://code.google.com/p/libgdx-users/wiki/SQLite – 42n4

+0

그래서, 분명히하기 위해 Android에서 'SQLiteOpenHelper'를 사용할 수 있으며 데스크톱에서도 같은 것을 만들 수 있습니다. 'JDBC'를 사용하는 것이고, 둘 다'StatusData' 또는 비슷한 이름의 클래스에서 생성됩니다. 권리? –

6

필자가 요구하는 대부분의 작업을 수행 할 확장 기능 (gdx-sqlite라고 함)이 있습니다. 이 확장 기능의 최신 빌드는 here에서 다운로드 할 수 있습니다.소스 코드 및 읽기 주소는 다음 위치에 있습니다. https://github.com/mrafayaleem/gdx-sqlite

이 확장 프로그램은 현재 Android 및 데스크톱 플랫폼을 지원합니다. 또한 Android 앱의 assets 폴더에있는 데이터베이스를 열 수는 없습니다. 그러나 이것은 보류중인 기능이며 곧 추가 될 예정입니다.

데이터베이스 처리를 위해 프로젝트를 설정하려면 지침을 따르십시오. 다음은 예제 코드입니다 :

package com.mrafayaleem.gdxsqlitetest; 

import com.badlogic.gdx.Gdx; 
import com.badlogic.gdx.sql.Database; 
import com.badlogic.gdx.sql.DatabaseCursor; 
import com.badlogic.gdx.sql.DatabaseFactory; 
import com.badlogic.gdx.sql.SQLiteGdxException; 

public class DatabaseTest { 

    Database dbHandler; 

    public static final String TABLE_COMMENTS = "comments"; 
    public static final String COLUMN_ID = "_id"; 
    public static final String COLUMN_COMMENT = "comment"; 

    private static final String DATABASE_NAME = "comments.db"; 
    private static final int DATABASE_VERSION = 1; 

    // Database creation sql statement 
    private static final String DATABASE_CREATE = "create table if not exists " 
      + TABLE_COMMENTS + "(" + COLUMN_ID 
      + " integer primary key autoincrement, " + COLUMN_COMMENT 
      + " text not null);"; 

    public DatabaseTest() { 
     Gdx.app.log("DatabaseTest", "creation started"); 
     dbHandler = DatabaseFactory.getNewDatabase(DATABASE_NAME, 
       DATABASE_VERSION, DATABASE_CREATE, null); 

     dbHandler.setupDatabase(); 
     try { 
      dbHandler.openOrCreateDatabase(); 
      dbHandler.execSQL(DATABASE_CREATE); 
     } catch (SQLiteGdxException e) { 
      e.printStackTrace(); 
     } 

     Gdx.app.log("DatabaseTest", "created successfully"); 

     try { 
      dbHandler 
        .execSQL("INSERT INTO comments ('comment') VALUES ('This is a test comment')"); 
     } catch (SQLiteGdxException e) { 
      e.printStackTrace(); 
     } 

     DatabaseCursor cursor = null; 

     try { 
      cursor = dbHandler.rawQuery("SELECT * FROM comments"); 
     } catch (SQLiteGdxException e) { 
      e.printStackTrace(); 
     } 
     while (cursor.next()) { 
      Gdx.app.log("FromDb", String.valueOf(cursor.getString(1))); 
     } 

     try { 
      dbHandler.closeDatabase(); 
     } catch (SQLiteGdxException e) { 
      e.printStackTrace(); 
     } 
     dbHandler = null; 
     Gdx.app.log("DatabaseTest", "dispose"); 
    } 
} 
관련 문제