gpt4 book ai didi

java - 在 Libgdx 中使用 SQLite 数据库

转载 作者:IT老高 更新时间:2023-10-28 23:13:27 26 4
gpt4 key购买 nike

我是 Libgdx 的新手,在我的游戏中使用数据库时遇到了麻烦。

我搜索了有关如何使用 Libgdx 使 SQLite 在 Android 和桌面应用程序上运行的教程,但没有找到一个简单的教程。

上次在 Android 中使用数据库时,我创建了一个从 SQLiteOpenHelper 扩展的类。

有没有一种简单的方法可以使用 Libgdx 来做同样的事情?或者至少,任何人都可以向我指出一个分步教程或类似的东西吗?

编辑

我忘了说我正在寻找可以让我管理像 SQLiteOpenHelper 这样的版本的东西。换句话说,当我在代码上更改我的数据库版本时,我想在安装 apk 时在 Android 中重新创建我的数据库。

解决方案

@42n4 回答之后,我管理了如何使用 Android 应用程序上的 SQLiteOpenHelper 和桌面应用程序上的 JDBC 连接到 SQLite 数据库。

首先,我为桌面和 Android 应用程序创建了一个“通用类”:

//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);
[...]
}
}

然后,我为桌面应用程序创建了一个 DatabaseDesktop 类:

    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 用于 Android 应用程序

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);
}

[...]

}

}

最后,我更改了 Android 和桌面应用程序的主要类:

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);
}

}

注意:

我使用 PRAGMA user_version 进行了类似于 SQLiteOpenHelper 中的版本管理。这样,我只需要在需要升级时更改 DataBase 类的版本即可。

我没有把我所做的所有方法都放在 Result 上,但是,我把我认为更重要的那些方法都放在了。那更重要。

最佳答案

我编写了一个扩展程序(称为 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");
}
}

关于java - 在 Libgdx 中使用 SQLite 数据库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15874824/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com