欢迎投稿

今日深度:

Android SQLite 使用总结,androidsqlite

Android SQLite 使用总结,androidsqlite


以下内容转载自:Android中SQLite应用详解  为了个人理解,有改动部分。

另附  Sqlite 介绍: 同样也是上面那位博主写的,很详细

通常使用方法

        //打开或创建数据库
        SQLiteDatabase db=openOrCreateDatabase("test.db", Context.MODE_PRIVATE, null);
        db.execSQL("DROP TABLE IF EXISTS person");

        //创建表
        db.execSQL(CREATE_TABLE_PERSON);

        Person person=new Person("小白",11);
        //带占位符的插入语句
        db.execSQL("insert into person values(?,?)", new Object[]{person.getName(), person.getAge()});


        person.setValue("小黑", 16);

        ContentValues cv=new ContentValues();
        cv.put("name", person.getName());
        cv.put("age", person.getAge());

        //通过ContentValues 插入数据
        db.insert("person", null, cv);

        ContentValues updateCV=new ContentValues();
        updateCV.put("age", 19);

        //通过ContentValues 修改数据
        db.update("person", updateCV, "name=?", new String[]{"小白"});

        //查询整行数据
        Cursor cursor=db.rawQuery("SELECT * FROM person",null);
        while(cursor.moveToNext()){

            //通过获取列的索引获取数据
            String name=cursor.getString(cursor.getColumnIndex("name"));
            int age=cursor.getInt(cursor.getColumnIndex("age"));
            Log.d("my","name = :"+name+" age = : "+age);
        }
        cursor.close();

        //删除
        db.delete("person", "name=?", new String[]{"小黑"});


        //如果数据库存在且已打开则将它关闭
        if(db!=null&&db.isOpen())
            db.close();

对于建立表,插入,删除,修改等可以使用通用的语法:

    db.executeSQL(String sql);  
    db.executeSQL(String sql, Object[] bindArgs);//sql语句中使用占位符,然后第二个参数是实际的参数集  

统一操作外对应的方法:

    db.insert(String table, String nullColumnHack, ContentValues values);  
    db.update(String table, Contentvalues values, String whereClause, String whereArgs);  
    db.delete(String table, String whereClause, String whereArgs);  
以上语句的第一个参数都为需要操作的表。
insert 中第二个参数 nullColumnHack 表示当行中的数据都为空时,指定该行的某一列的值为null,防止出错.
values 参数为 Contentvalues 类型 为键值对组成的 Map , key 为列名,value为要插入的值
whereClause 表示为 WHERE 表达式 ,如 "WHERE NAME = ?" , whereArgs 为实际占位符表示的值

丰富的查询方法:

    db.rawQuery(String sql, String[] selectionArgs);

    db.query(String table, String[] columns, String selection, String[] selectionArgs, 
        String groupBy, String having, String orderBy);

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

    db.query(String distinct, String table, String[] columns, String selection, String[] selectionArgs,
     String groupBy, String having, String orderBy, String limit);

第一种最简单, sql 参数为实际的整个 SELEC 语句, selectionArgs 为实际占位符表示的值


    其余参数:
        table:              表名  
        colums:             查询的列所有名称集 
        selectionArgs:      WHER 语句后面的内容,可用占位符
        groupBy:            指定分组的列名
        having:             指定分组条件
        orderBy:            指定排序列名
        limit:              指定分页参数
        distinct:           指定 true 或 false 表示要不要过滤重复值
    
    selection,groupB,having,orderBy,limit这几个参数中
        不包括 “WHERE”、“GROUP BY”、“HAVING”、“ORDER BY”、“LIMIT”等SQL关键字。

Cursor 常用方法:

Cursor 常用方法:
    c.move(int offset); //以当前位置为参考,移动到指定行  
    c.moveToFirst();    //移动到第一行  
    c.moveToLast();     //移动到最后一行  
    c.moveToPosition(int position); //移动到指定行  
    c.moveToPrevious(); //移动到前一行  
    c.moveToNext();     //移动到下一行  
    c.isFirst();        //是否指向第一条  
    c.isLast();     //是否指向最后一条  
    c.isBeforeFirst();  //是否指向第一条之前  
    c.isAfterLast();    //是否指向最后一条之后  
    c.isNull(int columnIndex);  //指定列是否为空(列基数为0)  
    c.isClosed();       //游标是否已关闭  
    c.getCount();       //总数据项数  
    c.getPosition();    //返回当前游标所指向的行数  
    c.getColumnIndex(String columnName);//返回某列名对应的列索引值  
    c.getString(int columnIndex);   //返回当前行指定列的值  
    c.getColumnName()                    //从给定的索引返回列名
    c.getColumnCount()        //返回所有列的总数

正如上面所述,数据库第一次创建时onCreate方法会被调用,我们可以执行创建表的语句,
当系统发现版本变化之后,会调用onUpgrade方法,我们可以执行修改表结构等语句。
然而每次这样使用数据库,会显得非常繁琐,所以需要把相应的方法封装起来,操作更加方便。
首先定义一个DbOpenHelper 的类方便数据库的创建,更新
public class DbHelper extends SQLiteOpenHelper {

    public  static String DATABASE_NAME="m.db3";
    private static int DATABASE_VERSION=1;

    private static String CREATE_TABLE_PERSON=
            "CREATE TABLE IF NOT EXISTS person ("
            +"_id  INTEGER PRIMARY KEY ,"
            + "name char(20) ,"
            + "age int )";

    //重新建表
    public void resetTable(){
        getWritableDatabase().execSQL("DROP TABLE IF EXISTS person");
        getWritableDatabase().execSQL(CREATE_TABLE_PERSON);
    }

    public DbHelper(Context context, int version) {
        super(context, DATABASE_NAME, null, version);
    }

    //数据库创建时会调用 onCreate
    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(CREATE_TABLE_PERSON);
    }

    //如果数据库版本不同,将会调用 onUpgrade
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            //db.execSQL("ALTER TABLE person ADD COLUMN sex char(2)");
    }
}
然后为了能够面向对象操作数据,需要把数据封装到一个 Person 类中
public class Person
{
    private String name;
    private int age;
    public Person(){
        name="小明";
        age=1;
    }
    public Person(String name,int age){
        this.name=name;
        this.age=age;
    }
    public String getName(){
        return name;
    }
    public void setName(String name){
        this.name=name;
    }
    public int getAge(){
        return age;
    }
    public void setAge(int age) {
        this.age=age;
    }
    public void setValue(String name,int age){
        this.name=name;
        this.age=age;
    }
}


接下来需要一个 DbManager 来把需要的方进行封装:

public class DbManager {

    private  DbHelper dbHelper;
    private  SQLiteDatabase db;

    public DbManager(Context context){
        dbHelper=new DbHelper(context,1);
        db=dbHelper.getWritableDatabase();

    }

    public void resetTable(){
        dbHelper.resetTable();
    }

    public void add(List<Person> lists){
        //开启一个事务
        db.beginTransaction();
        try {
            for (Person person:lists)
                db.execSQL("INSERT INTO person VALUES(?,?,?)",
                        new Object[]{null,person.getName(),person.getAge()});
            db.setTransactionSuccessful();//设置事务完成
        }
        finally {
            db.endTransaction();//事务结束
        }
    }

    public void updateAge(Person person){
        ContentValues contentValues=new ContentValues();
        contentValues.put("age",person.getAge());
        db.update("person", contentValues, "name=?", new String[]{person.getName()});
    }

    public void deletePerson(Person person){
        db.delete("person", "name=?", new String[]{person.getName()});
    }

    public ArrayList<Person>query(){
        ArrayList<Person> lists=new ArrayList<Person>();
        Cursor cursor=db.rawQuery("SELECT * FROM person",null);
        while(cursor.moveToNext()){
            Person person=new Person();
            person.setName(cursor.getString(cursor.getColumnIndex("name")));
            person.setAge(cursor.getInt(cursor.getColumnIndex("age")));
            lists.add(person);
        }
        cursor.close();
        return lists;
    }
    public Cursor queryTheCursor(){
        Cursor cursor=db.rawQuery("SELECT * FROM person",null);
        return cursor;
    }
    public void closeDatabase(){
        db.close();
    }
}

使用示范


public class MainActivity extends AppCompatActivity implements View.OnClickListener {


    TextView textView;
    EditText nameEdit,ageEdit;
    DbManager dbManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        getView();
        dbManager=new DbManager(MainActivity.this);
    }

    @Override
    public void onClick(View v) {
        String name=nameEdit.getText().toString();
        String age=ageEdit.getText().toString();
        if(age.equals(""))age="0";
        Person person=new Person(name,Integer.parseInt(age));
        switch (v.getId()){
            case R.id.createButton:
                dbManager.resetTable();
                break;
            case R.id.insertButton:
                ArrayList<Person>lists=new ArrayList<Person>();
                lists.add(person);
                dbManager.add(lists);
                break;
            case R.id.deleteButton:
                dbManager.deletePerson(person);
                break;
            case R.id.updateButton:
                dbManager.updateAge(person);
                break;
            case R.id.queryButton:
                query();

               /*显示在TextView 中
                ArrayList<Person>persons=dbManager.query();
                StringBuffer stringBuffer=new StringBuffer();
                for(int i=0;i<persons.size();i++){
                    Person per=persons.get(i);
                    stringBuffer.append(per.getName()+"\t"+per.getAge()+"\n");
                }
                textView.setText(stringBuffer);
                */
                break;
        }
    }
    //把查询结果 显示在 ListView 中
    public void query(){

        Cursor cursor= dbManager.queryTheCursor();
        
        startManagingCursor(cursor);
        //托付给activity根据自己的生命周期去管理Cursor的生命周期

        CursorWrapper cursorWrapper=new CursorWrapper(cursor){
            @Override
        public String getString(int columnIndex){
                return super.getString(columnIndex);
            }
        };

        SimpleCursorAdapter adapter=new SimpleCursorAdapter(
                this,android.R.layout.simple_list_item_2,
                cursorWrapper,new String []{"name","age"},
                new int[]{android.R.id.text1,android.R.id.text2});
        ListView listView=(ListView)findViewById(R.id.list);
        listView.setAdapter(adapter);

    }

    //获得界面中的组件
    private void getView(){

        textView=(TextView)findViewById(R.id.text);
        nameEdit=(EditText)findViewById(R.id.nameEdit);
        ageEdit=(EditText)findViewById(R.id.ageEdit);

        Button createButton=(Button)findViewById(R.id.createButton);
        Button insertButton=(Button)findViewById(R.id.insertButton);
        Button deleteButton=(Button)findViewById(R.id.deleteButton);
        Button updateButton=(Button)findViewById(R.id.updateButton);
        Button queryButton=(Button)findViewById(R.id.queryButton);

        createButton.setOnClickListener(this);
        insertButton.setOnClickListener(this);
        deleteButton.setOnClickListener(this);
        updateButton.setOnClickListener(this);
        queryButton.setOnClickListener(this);
    }

    //关闭数据库
    @Override
    public void onDestroy(){
        super.onDestroy();
        dbManager.closeDatabase();
    }
}



这里需要注意的是SimpleCursorAdapter的应用,当我们使用这个适配器时,我们必须先得到一个Cursor象,

这里面有几个问题:如何管理Cursor的生命周期,如果包装Cursor,Cursor结果集都需要注意什么。如果手动去管
理Cursor的话会非常的麻烦,还有一定的风险,处理不当的话运行期间就会出现异常,幸好Activity为我们提供
了startManagingCursor(Cursor cursor)方法,它会根据Activity的生命周期去管理当前的Cursor对象,下面是该
方法的说明:


/** 
     * This method allows the activity to take care of managing the given 
     * {@link Cursor}'s lifecycle for you based on the activity's lifecycle. 
     * That is, when the activity is stopped it will automatically call 
     * {@link Cursor#deactivate} on the given Cursor, and when it is later restarted 
     * it will call {@link Cursor#requery} for you.  When the activity is 
     * destroyed, all managed Cursors will be closed automatically. 
     *  
     * @param c The Cursor to be managed. 
     *  
     * @see #managedQuery(android.net.Uri , String[], String, String[], String) 
     * @see #stopManagingCursor 
     */  

     中提到,startManagingCursor方法会根据Activity的生命周期去管理当前的Cursor对象的生命周期,就是说当Activity停止时他会自动调用Cursor的deactivate方法,禁用游标,当Activity重新回到屏幕时它会调用Cursor的requery方法再次查询,当Activity摧毁时,被管理的Cursor都会自动关闭释放。

    如何包装Cursor:我们会使用到CursorWrapper对象去包装我们的Cursor对象,实现我们需要的数据转换工作,这个CursorWrapper实际上是实现了Cursor接口。我们查询获取到的Cursor其实是Cursor的引用,而系统实际返回给我们的必然是Cursor接口的一个实现类的对象实例,我们用CursorWrapper包装这个实例,然后再使用SimpleCursorAdapter

将结果显示到列表上。

Cursor结果集需要注意些什么:一个最需要注意的是,在我们的结果集中必须要包含一个“_id”的列,

否则SimpleCursorAdapter就会翻脸不认人,为什么一定要这样呢?因为这源于SQLite的规范,主键以“_id”为标准。
解决办法有三:
    第一,建表时根据规范去做;
    第二,查询时用别名,例如:SELECT id AS _id FROM person;
    第三,在CursorWrapper里做文章:

CursorWrapper cursorWrapper = new CursorWrapper(c) {  
    @Override  
    public int getColumnIndexOrThrow(String columnName) throws IllegalArgumentException {  
        if (columnName.equals("_id")) {  
            return super.getColumnIndex("id");  
        }  
        return super.getColumnIndexOrThrow(columnName);  
    }  
};  
如果试图从CursorWrapper里获取“_id”对应的列索引,我们就返回查询结果里“id”对应的列索引即可

www.htsjk.Com true http://www.htsjk.com/SQLite/33775.html NewsArticle Android SQLite 使用总结,androidsqlite 以下内容转载自: Android中SQLite应用详解    为了个人理解,有改动部分。 另附   Sqlite 介绍 : 同样也是上面那位博主写的,很详细 通常使用方法 /...
相关文章
    暂无相关文章
评论暂时关闭