求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Modeler   Code  
会员   
 
  
 
 
     
   
分享到
Android游戏开发之数据库SQLite详细介绍(八)
 

发布于 2011-10-25

 

数据库SQLite介绍

数据库最经典的四个操作 添加、删除、修改、查找,在处理大量数据的时候使用数据库可以帮我们迅速定位当前须要处理的数据,举个例子 好比现在要实现一个搜索功能 用数据库的话只须要其中一个搜索条件 一个数据库语句就可以迅速的在N条数据中找到我们需要的数据,如果不使用数据库那么查找起来会非常麻烦,效率大打折扣,所以在处理大量数据的时候使用数据库是明确的选择,在Android的开发中使用的数据库是SQLite ,它是一个轻量级的数据库 、非常小 、 移植性好、效率高、可靠 ,嵌入式设备因为受到硬件条件的限制所以非常适合使用 SQLite 数据库。

创建与删除数据库

封装一个类去继承SQLiteOpenHelper 在构造函数中传入数据库名称与数据库版本号,数据库被创建的时候会调用onCreate(SQLiteDatabase db) 方法,数据库版本号发生改变的时候会调用onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)方法,可以方便的对软件游戏升级后做出相应处理避免覆盖安装数据库发生改变产生的错误。调用SQLiteOpenHelper 的getReadableDatabase()方法去创建数据库,如果数据库不存在则创建 并且返回SQLiteDatabase对象,如果数据库存在则不创建只返回SQLiteDatabase对象。调用deleteDatabase(DATABASE_NAME)方法 传入数据库名称则可删除数据库。

封装了一个DatabaseHelper类继承SQLiteOpenHelper 我使用了设计模式中的单例模式来处理这个类,这里说一下单例模式 单例模式是常见的代码设计模式之一 它的好处是在于避免在内存中频繁的实例化所以将它的对象写成static 静态 这样它的对象就只有一份存在静态内存区使用的时候只须要通过getInstance()就可以直接拿到这个静态对象。

public class DatabaseHelper extends SQLiteOpenHelper {  

    private static DatabaseHelper mInstance = null;  

    /** 数据库名称 **/  

    public static final String DATABASE_NAME = "xys.db";  

    /** 数据库版本号 **/  

    private static final int DATABASE_VERSION = 1;  

    /**数据库SQL语句 添加一个表**/  

    private static final String NAME_TABLE_CREATE = "create table test("  

        + "_id INTEGER PRIMARY KEY AUTOINCREMENT," + "name TEXT,"+"hp INTEGER DEFAULT 100,""mp INTEGER DEFAULT 100,"  

        + "number INTEGER);";  

    DatabaseHelper(Context context) {  

    super(context, DATABASE_NAME, null, DATABASE_VERSION);  

    } 

     /**单例模式**/  

    static synchronized DatabaseHelper getInstance(Context context) {  

    if (mInstance == null) {  

        mInstance = new DatabaseHelper(context);  

    }  

    return mInstance;  

    }  

    @Override  

    public void onCreate(SQLiteDatabase db) {  

    /**向数据中添加表**/  

    db.execSQL(NAME_TABLE_CREATE);  

    }  

    @Override  

    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {  

    /**可以拿到当前数据库的版本信息 与之前数据库的版本信息   用来更新数据库**/   

    }  

    /** 

     * 删除数据库 

     * @param context 

     * @return 

     */  

    public boolean deleteDatabase(Context context) {  

    return context.deleteDatabase(DATABASE_NAME);  

    }  

}  

在这个类中使用DatabaseHelper对象 实现创建与删除数据库、

public class NewSQLite extends Activity {  

    DatabaseHelper mDbHelper = null;  

    SQLiteDatabase mDb = null;  

    Context mContext = null;  

    @Override  

    protected void onCreate(Bundle savedInstanceState) {  

    setContentView(R.layout.create_sql);  

    mContext = this;  

    //创建DatabaseHelper对象        

    mDbHelper = DatabaseHelper.getInstance(mContext);  

    //调用getReadableDatabase方法如果数据库不存在 则创建  如果存在则打开  

    mDb= mDbHelper.getReadableDatabase();    

    Button button0 = (Button)findViewById(R.id.createDateBase);  

    button0.setOnClickListener(new OnClickListener() {  

        @Override  

        public void onClick(View arg0) {  

        Toast.makeText(NewSQLite.this"成功创建数据库", Toast.LENGTH_LONG).show();    

        }  

    });  

    Button button1 = (Button)findViewById(R.id.deleteDateBase);  

    button1.setOnClickListener(new OnClickListener() {  

        @Override  

        public void onClick(View arg0) {  

        mDbHelper = DatabaseHelper.getInstance(mContext);  

        // 调用getReadableDatabase方法如果数据库不存在 则创建 如果存在则打开  

        mDb = mDbHelper.getReadableDatabase();  

        // 关闭数据库  

        mDbHelper.close();  

        // 删除数据库  

        mDbHelper.deleteDatabase(mContext);  

        Toast.makeText(NewSQLite.this"成功删除数据库", Toast.LENGTH_LONG).show();    

        }  

    });  

    super.onCreate(savedInstanceState);  

    }  

创建的数据库会被保存在当前项目中 databases 路径下 具体如图所示

添加与删除数据库中的表

数据库是可以由多张数据表组成的 如果添加一张数据库的表的话 可以使用 数据库语句 create table 名称(内容) 来进行添加 。这里给出一条创建数据库的语句 。 意思是创建一张表 名称为gameInfo 表中包含的字段 为 _id 为INTEGER 类型 并且递增 name 为Text类型 hp mp 为INTEGER 默认数值为100 number 为INTEGER 类型。

/**创建一张表的SQL语句**/  

private static final String NAME_TABLE_CREATE = "create table gameInfo("  

 + "_id INTEGER PRIMARY KEY AUTOINCREMENT," + "name TEXT,""hp INTEGER DEFAULT 100,""mp INTEGER DEFAULT 100,"  

 + "number INTEGER);";  

数据库中删除一张表 直接使用DROP TABLE 表名称 就可以删除

/**删除一张表的SQL语句**/  

private static final String NAME_TABLE_DELETE = "DROP TABLE gameInfo";  

在代码中去执行一条SQL语句 使用SQLiteDatabase对象去调用execSQL() 传入SQL语句就OK了。

mDb.execSQL(NAME_TABLE_CREATE);

以创建一张名称为gameInfo的表为例 给出代码实现

public class NewTable extends Activity {  

    DatabaseHelper mDbHelper = null;  

    SQLiteDatabase mDb = null;  

    Context mContext = null;  

    /**创建一张表的SQL语句**/  

    private static final String NAME_TABLE_CREATE = "create table gameInfo("  

        + "_id INTEGER PRIMARY KEY AUTOINCREMENT," + "name TEXT,""hp INTEGER DEFAULT 100,""mp INTEGER DEFAULT 100,"  

        + "number INTEGER);";  

    /**删除一张表的SQL语句**/  

    private static final String NAME_TABLE_DELETE = "DROP TABLE gameInfo";  

    @Override  

    protected void onCreate(Bundle savedInstanceState) {  

    setContentView(R.layout.create_table);  

    mContext = this;  

    mDbHelper = DatabaseHelper.getInstance(mContext);  

    mDb= mDbHelper.getReadableDatabase();    

    Button button0 = (Button)findViewById(R.id.createTable);  

    button0.setOnClickListener(new OnClickListener() {  

        @Override  

        public void onClick(View arg0) {  

        try {  

            mDb.execSQL(NAME_TABLE_CREATE);  

            Toast.makeText(NewTable.this"成功添加数据表", Toast.LENGTH_LONG).show();    

        }catch(SQLiteException e) {  

            Toast.makeText(NewTable.this"数据库中已存此表", Toast.LENGTH_LONG).show();      

        }  

        }  

    });  

    Button button1 = (Button)findViewById(R.id.deleteTable);  

    button1.setOnClickListener(new OnClickListener() {  

        @Override  

        public void onClick(View arg0) {  

        try {  

            mDb.execSQL(NAME_TABLE_DELETE);  

            Toast.makeText(NewTable.this"成功删除数据表", Toast.LENGTH_LONG).show();   

        }catch(SQLiteException e) {  

            Toast.makeText(NewTable.this"数据库中已无此表", Toast.LENGTH_LONG).show();      

        }  

        }  

    });  

    super.onCreate(savedInstanceState);  

    }  

}  

增加 删除 修改 查询 数据库中的数据

使用SQLiteDatabase对象调用 insert()方法 传入标的名称与ContentValues 添加的内容 则可以向数据库表中写入一条数据 delete ()为删除一条数据 update()为更新一条数据。

我详细说一下查找一条数据使用的方法 query 中 跟了8个参数

public Cursor query(String table,String[] columns,String selection,String[] selectionArgs,String groupBy,String having,String orderBy,String limit);

参数说明:

  • table:数据库表的名称
  • columns:数据库列名称数组 写入后最后返回的Cursor中只能查到这里的列的内容
  • selection:查询条件
  • selectionArgs:查询结果
  • groupBy:分组列
  • having:分组条件
  • orderBy:排序列
  • limit:分页查询限制
  • Cursor:返回值,将查询到的结果都存在Cursor

Cursor是一个游标接口,每次查询的结果都会保存在Cursor中 可以通过遍历Cursor的方法拿到当前查询到的所有信息。

Cursor的方法

  • moveToFirst() //将Curor的游标移动到第一条
  • moveToLast()///将Curor的游标移动到最后一条
  • move(int offset)//将Curor的游标移动到指定ID
  • moveToNext()//将Curor的游标移动到下一条
  • moveToPrevious()//将Curor的游标移动到上一条
  • getCount() //得到Cursor 总记录条数
  • isFirst() //判断当前游标是否为第一条记录
  • isLast()//判断当前游标是否为最后一条数据
  • getInt(int columnIndex) //根据列名称获得列索引ID
  • getString(int columnIndex)//根据索引ID 拿到表中存的字段

这里给出一个例子遍历Cursor的例子

private void query(SQLiteDatabase db) {  

// 把整张表的所有数据query到cursor中  

Cursor cursor = db.query(TABLE_NAME, nullnullnullnullnullnull);  

//判断cursor不为空 这个很重要  

if (cursor != null) {  

    // 循环遍历cursor  

    while (cursor.moveToNext()) {  

    // 拿到每一行name 与hp的数值  

    String name = cursor.getString(cursor.getColumnIndex("name"));  

    String hp = cursor.getString(cursor.getColumnIndex("hp"));  

    Log.v("info""姓名是 " + name + "hp为 " + hp);  

    }  

    // 关闭  

    cursor.close();  

}  

   }  

向大家推荐一个查看数据库的软件非常好用, 名称是SQLiteSpy.exe 如图所示 打开xys.db 文件 可以清晰的看见数据库表中储存的内容并且该软件支持执行SQL语句 可以直接在软件中操作,我给出这款软件的下载地址。

下载地址:http://download.csdn.net/source/3481140

public class Newdate extends Activity {  

    DatabaseHelper mDbHelper = null;  

    SQLiteDatabase mDb = null;  

    Context mContext = null;  

    /** 数据库字段 **/  

    public final static String TABLE_NAME = "test";  

    public final static String ID = "_id";  

    public final static String NAME = "name";  

    public final static String HP = "hp";  

    public final static String MP = "mp";  

    @Override  

    protected void onCreate(Bundle savedInstanceState) {  

    setContentView(R.layout.create_date);  

    mContext = this;  

    // 创建DatabaseHelper对象  

    mDbHelper = DatabaseHelper.getInstance(mContext);  

    // 调用getReadableDatabase方法如果数据库不存在 则创建 如果存在则打开  

    mDb = mDbHelper.getReadableDatabase();  

    // 初始化 给数据库表写入一些信息  

    for (int i = 0; i < 10; i++) {  

        insert(NAME, "雨松MOMO" + i);  

    }  

    // 增加  

    Button button0 = (Button) findViewById(R.id.add);  

    button0.setOnClickListener(new OnClickListener() {  

        @Override  

        public void onClick(View arg0) {  

        insert(NAME, "新添加小可爱");  

        Toast.makeText(Newdate.this"添加一条数据名称为小可爱", Toast.LENGTH_LONG)  

            .show();  

        }  

    });  

    // 删除  

    Button button1 = (Button) findViewById(R.id.delete);  

    button1.setOnClickListener(new OnClickListener() {  

        @Override  

        public void onClick(View arg0) {  

        delete(ID, "1");  

        Toast.makeText(Newdate.this"删除一条_id=1的数据", Toast.LENGTH_LONG)  

            .show();  

        }  

    });  

    // 修改  

    Button button2 = (Button) findViewById(R.id.modify);  

    button2.setOnClickListener(new OnClickListener() {  

        @Override  

        public void onClick(View arg0) {  

        update(NAME, "雨松MOMO3""小可爱3");  

        Toast.makeText(Newdate.this"更新名称雨松MOMO3 为小可爱3",  

            Toast.LENGTH_LONG).show();  

        }  

    });  

    // 查找  

    Button button3 = (Button) findViewById(R.id.find);  

    button3.setOnClickListener(new OnClickListener() {  

        @Override  

        public void onClick(View arg0) {  

        Cursor cursor = find(ID, "5");  

        String name = cursor.getString(cursor.getColumnIndex(NAME));  

        Toast.makeText(Newdate.this"查找ID为5数据的名称是 " + name,  

            Toast.LENGTH_LONG).show();  

        }  

    });  

    super.onCreate(savedInstanceState);  

    }  

    /** 

     * 插入一条数据 

     *  

     * @param key 

     * @param date 

     */  

    public void insert(String key, String date) {  

    ContentValues values = new ContentValues();  

    values.put(key, date);  

    mDb.insert(TABLE_NAME, null, values);  

    }  

    /** 

     * 删除一掉数据 

     *  

     * @param key 

     * @param date 

     */  

    public void delete(String key, String date) {  

    mDb.delete(TABLE_NAME, key + "=?"new String[] { date });  

    }  

    /** 

     * 更新一条数据 

     *  

     * @param key 

     * @param oldDate 

     * @param newDate 

     */  

    public void update(String key, String oldDate, String newDate) {  

    ContentValues values = new ContentValues();  

    values.put(key, newDate);  

    mDb.update(TABLE_NAME, values, key + "=?"new String[] { oldDate });  

    }  

    /** 

     * 查找一条数据 

     *  

     * @param key 

     * @param date 

     * @return 

     */  

    public Cursor find(String key, String date) {  

    Cursor cursor = mDb.query(TABLE_NAME, null, key + "=?",  

        new String[] { date }, nullnullnull);  

    if (cursor != null) {  

        cursor.moveToFirst();  

    }  

    return cursor;  

    }  

}  

这里我在强调一下query中的第二个参数String [] columns , 举个例子 当前在数据中query 数值 如果我只想要数据中符合条件数据每一行的name字段和hp 字段 那么第二个参数就不要写成null了。

第二个参数我写成了new String[] {"name","hp"} 这样的话得到的Cursor 中的数据只会存有 数据库表中"name " 与 "hp"两个字段 因为其它字段我们根本不需要所以着么写可以大大提高代码的效率。如果写成null的话 Cursor 中的数据就会把数据库表中所以的字段都保存进去这样在计算Cursor 的时候代码就会消耗更多没用的时间。

cursor.getString(0); 的意思就是拿到对应new String[] {"name","hp"} 数组中的一个字段的内容 意思就是拿到 数据库字段"name"的值, cursor.getString(1);的意思就是拿到数据库字段"hp"的值 。cursor.getString()中的ID 是完全对应第二个参数String [] columns数组角标。

public void find() {  

Cursor cursor = mDb.query(TABLE_NAME, new String[] {"name","hp"}, null,  

    nullnullnullnull);  

while(cursor.moveToNext()) {  

    String name = cursor.getString(0);  

    String hp = cursor.getString(1);  

    Log.v("info""name is "+name);  

    Log.v("info""hp is "+hp);  

}  

   }


相关文章

深度解析:清理烂代码
如何编写出拥抱变化的代码
重构-使代码更简洁优美
团队项目开发"编码规范"系列文章
相关文档

重构-改善既有代码的设计
软件重构v2
代码整洁之道
高质量编程规范
相关课程

基于HTML5客户端、Web端的应用开发
HTML 5+CSS 开发
嵌入式C高质量编程
C++高级编程

 
分享到
 
 
     


android人机界面指南
Android手机开发(一)
Android手机开发(二)
Android手机开发(三)
Android手机开发(四)
iPhone消息推送机制实现探讨
手机软件测试用例设计实践
手机客户端UI测试分析
手机软件自动化测试研究报告
更多...   


Android高级移动应用程序
Android应用开发
Android系统开发
手机软件测试
嵌入式软件测试
Android软、硬、云整合


领先IT公司 android开发平台最佳实践
北京 Android开发技术进阶
某新能源领域企业 Android开发技术
某航天公司 Android、IOS应用软件开发
阿尔卡特 Linux内核驱动
艾默生 嵌入式软件架构设计
西门子 嵌入式架构设计
更多...