android数据库操作

来源:互联网 发布:linux运维日志 编辑:程序博客网 时间:2024/06/05 07:22

Android 为了让我们能够更加方便地管理数据库,专门提供了一个SQLiteOpenHelper 帮助类,借助这个类就可以非常简单地对数据库进行创建和升级。


首先,SQLiteOpenHelper 是一个抽象类,如果需要使用它的话,就需要创建一个自己的帮助类去继承它,SQLiteOpenHelper 类有两个重要的方法,分别是 onCreat() 和 onUpgrade() ,也就是创建数据库和升级数据库的方法,我们必须在自己的帮助类中重写这两个方法,然后分别在这俩个方法中去实现创建,升级数据库的逻辑。

SQLiteOpenHelper 中还有两个非常重要的实例方法,getReadableDatabase() 和 getWritableDatabase() 方法,这两个方法都可以创建或者打开一个现有的数据库(如果存在则就打开,否则就创建),并返回一个可以对数据库进行读写操作的对象,他们都可以进行读和写的操作,但是不同的是,当数据库不可写入的时候(如磁盘控件已满),getReadableDatabase() 会返回的对象将以只读的方式去打开数据库,而 getWritableDatabase() 则会出现异常。

首先创建一个自己的帮助类,MyDataBaseHleper, 这里使用了参数较少的那个构造方法,表名为 book, 字段有 author 作者,price 加个,pages 页数,name 书名。

public class MyDataBaseHelper extends SQLiteOpenHelper {    /**     * primary key 将 id 设为主键     * <p/>     * autoincrement 表示 id 列是自增长的     * <p/>     * real 表示浮点型     * <p/>     * blob 表示二进制类型     */    private final String CREATE_BOOK = "create table book ("            + "id integer primary key autoincrement, "            + "author text, "            + "price real, "            + "pages integer, "            + "name text)";    private Context context;    /**     * @param context context     * @param name    数据名     * @param factory 允许在查询数据的时候返回一个自定义的 Cursor,一般传 null     * @param version 数据库版本号     */    public MyDataBaseHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {        super(context, name, factory, version);        this.context = context;    }    /**创建*/    @Override    public void onCreate(SQLiteDatabase db) {        db.execSQL(CREATE_BOOK);        Toast.makeText(context, "数据库创建成功", Toast.LENGTH_SHORT).show();    }    /**升级*/    @Override    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {    }}

接下来就可以去创建数据库了,我是在一个 Activity 里面写的,

public class DdActivity extends AppCompatActivity{    @Override    protected void onCreate(@Nullable Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_mvp);        final MyDataBaseHelper dataBaseHelper = new MyDataBaseHelper(this,"BookStore.db",null,1);        Button button = (Button) findViewById(R.id.btn);        if (button != null)        button.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                                dataBaseHelper.getWritableDatabase();            }        });    }}

首先创建了一个自己的帮助类 MyDataBaseHelper 的实例,传入了一个 上下文,数据库的名字,cursor 为 null ,版本号是 1,然后在 Button 中执行 getWritableDatabase() 方法,然后点击的时候就会有数据库创建成功的提示,再次点击的时候因为数据库已经被创建,所以没有任何的提示。

如果想要查看数据文件,在虚拟机上的话,可以直接打开 DDMS 然后在上面的 File Explore 选项卡中的 data/data/你的包名/databases 就会发现你创建的数据库文件,以.db 结尾的那个,导出之后,用查看数据库的工具就可以查看了,至于真机上,因为一些权限的问题 ,有时间在补上吧。。。

接下来我们来说说,数据库的升级操作,这个分为两种情况,一种是不保留原始数据,一种是保留原始数据,先看看第一种情况

不保留原始数据的情况

比如,我们还需要一张表,首先,写一个 SQL 语句

public  final String CREATE_CATEGORY = "create table Category ("        + "id integer primary key autoincrement, "        + "category_name text, "        + "category_code integer)";
这个跟上面的那个语句差不多,名字真机随意就好了。然后在 onCreate() 方法中添加执行这个语句

/**创建*/@Overridepublic void onCreate(SQLiteDatabase db) {    db.execSQL(CREATE_BOOK);    /**新添加的*/   db.execSQL(CREATE_CATEGORY)Toast.makeText(context, "数据库创建成功", Toast.LENGTH_SHORT).show();}

在onUpgrade() 方法中写一下逻辑

/**升级*/@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {    db.execSQL("drop table if exists Book");    db.execSQL("drop table if exists Category");    onCreate(db);}
这个语句的意思就是,如果存在这张表就删除,然后执行 onCreate() 方法,当然不要忘了把数据库的版本号改一下,大于之前的就好。

 new MyDataBaseHelper(this,"BookStore.db",null,2);
OK,这样就可以了,再次点击的时候,就会有提示创建成功


再来说说第二种情况,保留原始数据的,其实远离也很简单,就是把原来的表名改成临时表,然后新建一张表(名字看你自己喽)把临时表的数据导入道这张新表中就可以了。

我们还需要几个 SQL 语句


创建一张临时表

private final String CREATE_TEMP_BOOK = "alter table book rename to _temp_book";

创建一个新的 book 表

private final String CREATE_NEW_BOOK = "create table book ("        + "id integer primary key autoincrement, "        + "author text, "        + "pages integer, "        + "name text)";

把临时表中的所有列都复制道新的 book 表中

private String INSERT_DATA = "insert into book select * from _temp_book";

有选择行的把临时表中的列复制道新的 book 表中

private final String INSERT_DATA = "insert into book select id,author,pages,name from _temp_book";

上面的两条语句根据自己的需求使用就好,如果两张表的格式相同就可以选择上面的那个,否则就可以添加一些字段名来控制

删除临时表

private final String DROP_TEMP_BOOK = "drop table _temp_book";
然后从新编写 onUpgrade() 方法

/**升级*/@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {        switch (newVersion){        case 3:            db.execSQL(CREATE_TEMP_BOOK);            db.execSQL(CREATE_NEW_BOOK);            db.execSQL(INSERT_DATA);            db.execSQL(DROP_TEMP_BOOK);            break;    }}
最后别忘了更改版本号,再次点击创建就升级完成了,其实原理还是很简单的,就是一些 SQL 语句,其实我也不是搞数据库的。。。

终于到了增删改查的环节了

dataBaseHelper.getWritableDatabase()
这个方法会返回一个 SQLiteDatabase 对象 我们可以利用这个对象来就行一些数据的操作,好了,上代码,这个刚开始的时候版本号是 2 ,如果想要升级测试需要改成 3

public class DdActivity extends AppCompatActivity {    @Override    protected void onCreate(@Nullable Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_mvp);        final MyDataBaseHelper dataBaseHelper = new MyDataBaseHelper(this, "BookStore.db", null, 2);        Button btnCreate = (Button) findViewById(R.id.btn_create);        Button btnAdd = (Button) findViewById(R.id.btn_add);        Button btnDelete = (Button) findViewById(R.id.btn_delete);        Button btnUp = (Button) findViewById(R.id.btn_up);        Button btnQuery = (Button) findViewById(R.id.btn_query);        /**创建*/        assert btnCreate != null;        btnCreate.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                dataBaseHelper.getWritableDatabase();            }        });        /**添加*/        assert btnAdd != null;        btnAdd.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                SQLiteDatabase sqLiteDatabase = dataBaseHelper.getWritableDatabase();                ContentValues values = new ContentValues();                // 开始组装第一条数据                values.put("name", "MyBook");                values.put("author", "wy");                values.put("pages", 100);                //values.put("price", 30.96);                /**                 * 参数1:表名                 * 参数2:用于在未指定添加数据的情况下给某些可为空的列自动赋值NULL,                 *        就是当 values为 null 或者 values.size() 为 0 的时候,可以                 *        添加一个列的名字,然后就会给这个列的值赋值为 null.                 * 参数3:没啥说的,以键值对存数据的一个对象                 * */                sqLiteDatabase.insert("book", null, values);            }        });        /**删除*/        assert btnDelete != null;        btnDelete.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                SQLiteDatabase db = dataBaseHelper.getWritableDatabase();                /**pages > ?  删除pages是大于 100 的书 */                /** 所有符合条件的都会生效 */                db.delete("book", "pages > ?", new String[] {"90"});            }        });        /**更新*/        assert btnUp != null;        btnUp.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                SQLiteDatabase db = dataBaseHelper.getWritableDatabase();                ContentValues contentValues = new ContentValues();                contentValues.put("author","wlq");                /**                 * 第三、第四个参数来指定具                 * 体更新哪几行。第三个参数对应的是SQL 语句的where 部分,表示去更新所有name 等于?                 * 的行,而?是一个占位符,可以通过第四个参数提供的一个字符串数组为第三个参数中的每                 * 个占位符指定相应的内容                 *                 *  所有符合条件的都会生效                  * */                db.update("book",contentValues,"name = ?",new String[]{"MyBook"});            }        });        /**查询*/        assert btnQuery != null;        btnQuery.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                SQLiteDatabase db = dataBaseHelper.getWritableDatabase();                //参数解释                /**                 * String table 哪个表 table,要查询的哪个表                 *                 * String[] columns 返回哪一列,如果参数是null,则返回所有列                 *                 * String selection 返回哪一行的过滤器,格式是SQL的WHERE,
                 * 设置为null,返回这个table的所有行
                 *
                 * String[] selectionArgs 在selection字段中可能会用'?'的形式来加一些额外的参数,
                 * 这个的selectionArgs字段就是把selection字段的条件填充好
*
                 * String groupBy 一个过滤器,如何来分组---设置为null则不分组
                 *
                 * String having 分组后聚合的过滤条件
                 * 
* String orderBy 排序,格式是SQL的ORDER一样.设置null使用默认
                 *
* String limit 返回的行数(几行),设置为null表示没有限制.
                 */
                //查询所有列                Cursor cursor = db.query("book", null, null, null, null, null, null);

//添加限制条件 查询 name 列的 author = wy 的数据,返回 name 列数据,不返回其他列
                Cursor cursor = db.query("book",new String[]{"name"},                                         "author = ?",new String[]{"wy"},null,null,null);


 
if (cursor.moveToFirst()) {

  do {
String name = cursor.getString(cursor.getColumnIndex("name"));
String author = cursor.getString(cursor.getColumnIndex("author"));
int
pages = cursor.getInt(cursor.getColumnIndex("pages"));
//double price = cursor.getDouble(cursor.getColumnIndex("price"));

Log.e("MainActivity", "book name is " + name);
Log.e("MainActivity", "book author is " + author);
Log.e("MainActivity", "book pages is " + pages);
// Log.e("MainActivity", "book price is " + price);

} while (cursor.moveToNext());

cursor.close();
}
}
});
}
}

收工



0 0