数据存储(4):Android数据库的操作,SQLiteOpenHelper类的使用


SQLiteOpenHelper是Android提供的用于在Android上实现数据库操作的一个抽象类。从类名就可以看出数据库打开帮助类起就是用于帮助实现数据的一个类。
SQLite是一款轻型的数据库,在Android中主要用于快速管理结构比较复杂的数据,如前面几篇文章所以讲的数据储存与处理,都只适用于数据的结构比较简单的情形,如果遇到大型项目或者数据比较复杂,数据库一般是首选。主要特点有:轻量级、单一文件。
转载请注出处:http://blog.csdn.net/Zou_pl/article/details/76034217


SQLiteOpenHelper的构建


SQLiteOpenHelper是一个抽象类,使用这个类的时候需要新建一个类继承SQLiteOpenHelper,如public class MyDatabaseHelper extends SQLiteOpenHelper,然后实现1、构造方法,2、onCreate,3、onUpgrade.

1.构造方法:

public MyDatabaseHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
        super(context, name, factory, version);
        mContext = context;
    }
context:上下文环境
name:数据库的名字,如"Media.db"
factory:用于创建Cursor,一般填null即可
version:数据库的版本号
实例:
private MyDatabaseHelper mMyDataBaseHelper = null;
...
mMyDataBaseHelper = new MyDatabaseHelper(mContext,"Media.db",null,1);

在调用构造方法之后,并不会执行SQLiteOpenHelper类的onCreate()方法,只有在调用getWritableDatabase()或者getReadableDatabase()方法之后,如果检测到没有创建数据库,才会调用onCreate(),所以执行构造方法会很快就返回对象。

2.onCreate(SQLiteDatabase db)方法:

数据库被构建的时候回调到这个方法,在这个方法中一般执行建表语句构建数据库。如:

@Override
    public void onCreate(SQLiteDatabase db) {
      /**执行建表语句,建表Media*/
        db.execSQL(CREATE_MEDIA);
        Toast.makeText(mContext, "MyDatabaseHelper , onCreate , create Table Media!", Toast.LENGTH_SHORT).show();
    }

其中建表语句如下:以下例子基本所有类型的数据都有包含到

 /**建表语句*/
    private static final String CREATE_MEDIA = "create table Media (" + //      创建表Media
            "id integer primary key autoincrement," +    //id,整型,将id设为主键,id列自增长
            "mediaId text," +        //媒资列,文本类型
            "title text," +          //名称,文本类型
            "year integer," +        //年份,整型
            "length integer," +      //时长,整型
            "price real," +          //价格,浮点型
            "overseas blob )";        //是否海外影片,二进制类型

3.onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)方法


第一个方法中我们讲到在构建对象的时候需要传一个版本号,MyDatabaseHelper(mContext,”Media.db”,null,1),当我们需要升级数据库的时候,升级版本号再次调用构造方法即可,如MyDatabaseHelper(mContext,”Media.db”,null,2),升级版本号之后,并不会直接调用onUpgrade,而同样是只有在调用getWritableDatabase()或者getReadableDatabase()方法之后才会被调用。
在onUpgrade方法中一般用于操作新建表,插入一些数据等,如:

/**
     * 更新数据库的内容
     */
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // TODO Auto-generated method stub
        if(oldVersion==1&&newVersion==2)
        {
            Log.i(tag, "数据库更新了");
            //在表中添加一个余额列
            db.execSQL("alter table Media add balance interger;");
        }else if(oldVersion==2&&newVersion==3)
        {
            //其他操作
        }

    }

SQLiteOpenHelper的使用:新建数据库、升级数据库、增删改查


1.新建SQLiteOpenHelper对象

mCreateBaseBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                /********************************创建数据库*******************************************/
                /**新建一个MyDatabaseHelper,一般传四个参数
                 * 1、上下文
                 * 2、数据库名,一般储存在/data/data/包名/databases目录下,但首先需要获取设备的root权限
                 * 3、自定义的Cursor,一般填空
                 * 4、当前数据库的版本号
                 * */
                Toast.makeText(mContext, "click create database btn !", Toast.LENGTH_SHORT).show();
                mMyDataBaseHelper = new MyDatabaseHelper(mContext,"Media.db",null,1);
                /**新建MyDatabaseHelper对象之后,如果调用MyDatabaseHelper的getWritableDatabase()或者getReadableDatabase()方法
                 * 之后如果数据库存在则不会调用MyDatabaseHelper的onCreate方法执行建表语句
                 * 如果数据库不存在则不会调用MyDatabaseHelper的onCreate方法执行建表语句*/
            }
        });

2.升级数据库

mUpdateBaseBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                /********************************升级数据库*******************************************/
                /**新建一个MyDatabaseHelper,一般传四个参数
                 * 1、2、3同上
                 * 4、数据库的版本号,因为数据库已经存在,为了更新,则更新版本号为更高版本
                 *      当调用构建方法时。检测到本地有数据库则不会新建,即不会调用MyDatabaseHelper类的onCreate()
                 *      当版本号高于老版本时,则会调用MyDatabaseHelper类的onUpgrade()
                 * */
                mMyDataBaseHelper = new MyDatabaseHelper(mContext,"Media.db",null,2);
                /**升级数据库,新建MyDatabaseHelper对象之后,如果调用MyDatabaseHelper的getWritableDatabase()或者getReadableDatabase()方法
                 * 之后如果数据库是最新版本号则不会调用MyDatabaseHelper的onUpgrade方法
                 * 如果数据库不是最新版本号则不会调用MyDatabaseHelper的onUpgrade方法*/
            }
        });

3.向数据库中放入数据

:以以下建表语句为例

/**建表语句*/
    private static final String CREATE_MEDIA = "create table Media (" + //      创建表Media
            "id integer primary key autoincrement," +    //id,整型,将id设为主键,id列自增长
            "mediaId text," +        //媒资列,文本类型
            "title text," +          //名称,文本类型
            "year integer," +        //年份,整型
            "length integer," +      //时长,整型
            "price real," +          //价格,浮点型
            "overseas blob )";        //是否海外影片,二进制类型

首先获取可写的数据库,将数据封装到ContentValues对象中,然后调用数据库的insert方法,将数据插入。

mAddDataBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                SQLiteDatabase db = mMyDataBaseHelper.getWritableDatabase();
                db.beginTransaction();
                ContentValues values = new ContentValues();
                values.put("mediaId","the game of thrones8");
                values.put("title","权利的游戏第8季");
                values.put("year",1991);
                values.put("length",120);
                values.put("price",60);
                values.put("overseas",0);
                db.insert("Media",null,values);
                values.clear();

                values.put("mediaId","the game of thrones1");
                values.put("title","权利的游戏第1季");
                values.put("year",1880);
                values.put("length",120);
                values.put("price",60);
                values.put("overseas",0);
                db.insert("Media",null,values);
                values.clear();

                values.put("mediaId","the walking dead");
                values.put("title","行尸走肉");
                values.put("year",2005);
                values.put("length",360);
                values.put("price",100);
                values.put("overseas",0);
                db.insert("Media",null,values);

                db.setTransactionSuccessful();
                db.endTransaction();
            }
        });

db.insert(“Media”,null,values);参数说明:insert(String table, String nullColumnHack, ContentValues values) ,table表示指定插入哪个表中,nullColumnHack一般默认为null即可,values封装的数据。
另外一种插入数据的方式,如下:

private void insert() {
        SQLiteDatabase db= mMyDataBaseHelper.getWritableDatabase();
        if(db.isOpen()){
            //执行添加的操作
            db.execSQL("insert into Media (mediaId, title, year, length, price, overseas)  values(?,?,?,?,?,?)",new String[] {"the walking dead8","行尸走肉8","2011","120","115.0","0"});
            db.close();
        }
    }
执行语句添加数据。

4.删除数据

mDeleteDataBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                SQLiteDatabase db = mMyDataBaseHelper.getWritableDatabase();
                db.beginTransaction();

                db.delete("Media","mediaId = ?",new String[] {"the walking dead"});

                db.setTransactionSuccessful();
                db.endTransaction();
            }
        });

db.delete(“Media”,”mediaId = ?”,new String[] {“the walking dead”});执行删除操作,意思是:在表Media中,删除mediaId为the walking dead的那一项。
另外一种删除数据的方式,直接执行语句删除

SQLiteDatabase db= mMyDataBaseHelper.getWritableDatabase();
        if(db.isOpen()){
            //删除SQL语句
            db.execSQL("delete from Media where length  > ? " , new String[] {"119"});
            db.close();
        }

5.更新数据

mUpdataDataBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                SQLiteDatabase db = mMyDataBaseHelper.getWritableDatabase();
                db.beginTransaction();

                ContentValues values = new ContentValues();
                values.put("price",1000);
                db.update("Media",values,"length > ?",new String[]{"100"});

                db.setTransactionSuccessful();
                db.endTransaction();
            }
        });

db.update(“Media”,values,”length > ?”,new String[]{“100”})的意思是在表Media中将length > 100的那一项的数据更新,更新的内容为values中的内容,values中将price变为1000.
另外一种更新数据的操作:

SQLiteDatabase db= mMyDataBaseHelper.getWritableDatabase();
        if(db.isOpen()){
            //更新SQL语句
            db.execSQL("update Media set price = ? where length > ? " , new String[] {"1000","100"});
            db.close();
        }

6.查询数据

mQueryDataBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                SQLiteDatabase db = mMyDataBaseHelper.getWritableDatabase();

                Cursor cursor = db.query("Media",null,null,null,null,null,"year",null);

                showMediaResult(cursor);
            }
        });

db.query方法中有很多参数可选,db.query(“Media”,null,null,null,null,null,”year”,null)表示在Media表中查询所有的数据,并按照year字段排序。SQLiteDatabase的query方法很强大,里面可以传入不同的参数,返回不同的结果,例如:

//在Media表中查询所有length>100的项
Cursor cursor = db.query("Media",null,"length > ?",new String[]{"100"},null,null,null,null);
使用SQLite语句查询全部的另外一种方法:
private void queryAll() {
        SQLiteDatabase db= mMyDataBaseHelper.getWritableDatabase();
        if(db.isOpen()){
            //查询全部SQL语句
            db.execSQL("select * from Media  " , null);
            db.close();
        }
    }
这个SQLite语句中可以增加删选条件,如:
select * from person  

select * from person order by id desc  

select name from person group by name having count(*)>1 

SQLite可以解析大部分标准SQL语句,如:查询语句:select * from 表名 where 条件子句 group by 分组字句 having … order by 排序子句 (顺序一定不能错)

可以看到返回的结果都是Cursor对象,需要解析出有用信息,解析基本都是以下的逻辑:

if (cursor != null) {
            if (cursor.moveToFirst()) {
                do {
                    int id = cursor.getInt(cursor.getColumnIndex("id"));
                    String mediaId = cursor.getString(cursor.getColumnIndex("mediaId"));
                    String title = cursor.getString(cursor.getColumnIndex("title"));
                    int year = cursor.getInt(cursor.getColumnIndex("year"));
                    int length = cursor.getInt(cursor.getColumnIndex("length"));
                    float price = cursor.getFloat(cursor.getColumnIndex("price"));
                    media += (id+","+mediaId+","+title+","+year+","+length+","+price+"\n");
                } while (cursor.moveToNext());
            }
            cursor.close();
        }

以上是关于数据库的基本使用。其实在上面的增删改查四个方法中,都有用到事务,使用事务的原因是避免数据库操作到一半因为异常而终止导致数据丢失。


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值