zoukankan      html  css  js  c++  java
  • Sqlite3 数据库

    SQLite是Android平台软件开发中会经常用到的数据库产品,作为一款轻型数据库,SQLite的设计目标就是是嵌入式的,而且目前已经在很多嵌入式产品中使用了它,它占用资源非常的低,在嵌入式设备中,可能只需要几百K的内存就够。下面我们一起来看看针对Android平台的SQlite 3的使用。

    两个重要的类:

    1. SQLiteOpenHelper     数据库、表存放的地方

    2. SQLiteDatabase        操作表的类。增删改查

    sql语句:

    建表 删表 向表中增删改查

      //只执行一次
     @Override
     public void onCreate(SQLiteDatabase db) {
       String sql = "create table user (" +
          "id integer primary key not null," +
          "name varchar2(100)," +
          “age integer" +
          ")";
       db.execSQL(sql);
     }

     //当version改变的时候调用,先删除所有表,再重新调用onCreate();重新建表,用于表中数据变化时升级数据库


     @Override
     public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        String sql = "drop table user";
        db.execSQL(sql);
        this.onCreate(db);
     }

       //增

     case R.id.btnToast:
         String sql = "insert into user values(1, 'lianghui', 26)";
         SQLiteDatabase writableDatabase = helper.getWritableDatabase();
         writableDatabase.execSQL(sql);
         writableDatabase.close();
       break;

     //查
     case R.id.btnselect:
         sql = "select * from user where id = ?";
         String[] selectionArgs = { "1" };
         SQLiteDatabase readableDatabase = helper.getReadableDatabase();
         Cursor cursor = readableDatabase.rawQuery(sql, selectionArgs);
         while (cursor.moveToNext()) {
           int id = cursor.getInt(cursor.getColumnIndex("id"));
          String name = cursor.getString(cursor.getColumnIndex("name"));
         int age = cursor.getInt(cursor.getColumnIndex("age"));

          Log.e("sqlite", "id is : " + id + " and name is : " + name
            + " and age is : " + age);
       }
         readableDatabase.close();
         cursor.close();
       break;

      //改
    case R.id.btnupdate:
         sql = "update user set age = ? where id = ?";
         String[] selectionArgs2 = { "25", "1" };
         SQLiteDatabase writableDatabase2 = helper.getWritableDatabase();
         writableDatabase2.execSQL(sql, selectionArgs2);
         writableDatabase2.close();
       break;

        //删
    ase R.id.btndelete:
         sql = "delete from user where id = ?";
         String[] selectionArgs3 = { "1" };
         SQLiteDatabase writableDatabase3 = helper.getWritableDatabase();
         writableDatabase3.execSQL(sql, selectionArgs3);
         writableDatabase3.close();
       break;

     Android提供了一个名为SQLiteDatabase的类,该类封装了一些操作数据库的API,使用该类可以完成对数据进行添加(Create)、查询(Retrieve)、更新(Update)和删除(Delete)操作(这些操作简称为CRUD)。对SQLiteDatabase的学习,我们应该重点掌握execSQL()和rawQuery()方法。 execSQL()方法可以执行insert、delete、update和CREATE TABLE之类有更改行为的SQL语句; rawQuery()方法可以执行select语句。

    execSQL()方法的使用例子:

    Java代码
    1. SQLiteDatabase db = ....;  
    2. db.execSQL("insert into person(name, age) values('安桌', 4)");  
    3. db.close();  



           执行上面SQL语句会往person表中添加进一条记录,在实际应用中, 语句中的“安桌”这些参数值会由用户输入界面提供,如果把用户输入的内容原样组拼到上面的insert语句, 当用户输入的内容含有单引号时,组拼出来的SQL语句就会存在语法错误。要解决这个问题需要对单引号进行转义,也就是把单引号转换成两个单引号。有些时候用户往往还会输入像“ & ”这些特殊SQL符号,为保证组拼好的SQL语句语法正确,必须对SQL语句中的这些特殊SQL符号都进行转义,显然,对每条SQL语句都做这样的处理工作是比较烦琐的。 SQLiteDatabase类提供了一个重载后的execSQL(String sql, Object[] bindArgs)方法,使用这个方法可以解决前面提到的问题,因为这个方法支持使用占位符参数(?)。

           使用例子如下:

    Java代码
    1. SQLiteDatabase db = ....;  
    2. db.execSQL("insert into person(name, age) values(?,?)"new Object[]{"安桌"4});   
    3. db.close();  



            execSQL(String sql, Object[] bindArgs)方法的第一个参数为SQL语句,第二个参数为SQL语句中占位符参数的值,参数值在数组中的顺序要和占位符的位置对应。

            SQLiteDatabase的rawQuery() 用于执行select语句,使用例子如下:

    java代码:

    Java代码
    1. SQLiteDatabase db = ....;  
    2. Cursor cursor = db.rawQuery(“select * from person”, null);  
    3. while (cursor.moveToNext()) {  
    4. int personid = cursor.getInt(0); //获取第一列的值,第一列的索引从0开始  
    5. String name = cursor.getString(1);//获取第二列的值  
    6. int age = cursor.getInt(2);//获取第三列的值  
    7. }  
    8. cursor.close();  
    9. db.close();  


           rawQuery()方法的第一个参数为select语句;第二个参数为select语句中占位符参数的值,如果select语句没有使用占位符,该参数可以设置为null。带占位符参数的select语句使用例子如下:

    java代码:
    JAVA代码
    1. Cursor cursor = db.rawQuery("select * from person where name like ? and age=?"new String[]{"%传智%""4"});  

            Cursor是结果集游标,用于对结果集进行随机访问,如果大家熟悉jdbc, 其实Cursor与JDBC中的ResultSet作用很相似。使用moveToNext()方法可以将游标从当前行移动到下一行,如果已经移过了结果集的最后一行,返回结果为false,否则为true。另外Cursor 还有常用的moveToPrevious()方法(用于将游标从当前行移动到上一行,如果已经移过了结果集的第一行,返回值为false,否则为true )、moveToFirst()方法(用于将游标移动到结果集的第一行,如果结果集为空,返回值为false,否则为true )和moveToLast()方法(用于将游标移动到结果集的最后一行,如果结果集为空,返回值为false,否则为true )。

    除了前面给大家介绍的execSQL()和rawQuery()方法, SQLiteDatabase还专门提供了对应于添加、删除、更新、查询的操作方法: insert()、delete()、update()和query() 。这些方法实际上是给那些不太了解SQL语法的菜鸟使用的,对于熟悉SQL语法的程序员而言,直接使用execSQL()和rawQuery()方法执行SQL语句就能完成数据的添加、删除、更新、查询操作。

           Insert()方法用于添加数据,各个字段的数据使用ContentValues进行存放。 ContentValues类似于MAP,相对于MAP,它提供了存取数据对应的put(String key, Xxx value)和getAsXxx(String key)方法,  key为字段名称,value为字段值,Xxx指的是各种常用的数据类型,如:String、Integer等。

    Java代码:
    Java代码
    1. SQLiteDatabase db = databaseHelper.getWritableDatabase();  
    2. ContentValues values = new ContentValues();  
    3. values.put("name""安桌");  
    4. values.put("age"4);  
    5. long rowid = db.insert(“person”, null, values);//返回新添记录的行号,与主键id无关  


           不管第三个参数是否包含数据,执行Insert()方法必然会添加一条记录,如果第三个参数为空,会添加一条除主键之外其他字段值为Null的记录。Insert()方法内部实际上通过构造insert语句完成数据的添加,Insert()方法的第二个参数用于指定空值字段的名称,相信大家对此参数会感到疑惑,此参数的作用是干嘛的?是这样的:如果第三个参数values 为Null或者元素个数为0, Insert()方法必然要添加一条除了主键之外其它字段为Null值的记录,为了满足这条insert语句的语法, insert语句必须给定一个字段名,如:insert into person(name) values(NULL),倘若不给定字段名 , insert语句就成了这样: insert into person() values(),显然这不满足标准SQL的语法。对于字段名,建议使用主键之外的字段,如果使用了INTEGER类型的主键字段,执行类似insert into person(personid) values(NULL)的insert语句后,该主键字段值也不会为NULL。如果第三个参数values 不为Null并且元素的个数大于0 ,可以把第二个参数设置为null。

           delete()方法的使用:

    java代码:
    Java代码
    1. SQLiteDatabase db = databaseHelper.getWritableDatabase();  
    2. db.delete("person""personid<?"new String[]{"2"});  
    3. db.close();  


            上面代码用于从person表中删除personid小于2的记录。

            update()方法的使用:

    java代码:
    Java代码
    1. SQLiteDatabase db = databaseHelper.getWritableDatabase();  
    2. ContentValues values = new ContentValues();  
    3. values.put(“name”, “安桌”);//key为字段名,value为值  
    4. db.update("person", values, "personid=?"new String[]{"1"});   
    5. db.close();  


            上面代码用于把person表中personid等于1的记录的name字段的值改为“安桌”。
            query()方法实际上是把select语句拆分成了若干个组成部分,然后作为方法的输入参数:

    java代码:
    Java代码
    1. SQLiteDatabase db = databaseHelper.getWritableDatabase();  
    2. Cursor cursor = db.query("person"new String[]{"personid,name,age"}, "name like ?"new String[]{"%传智%"}, nullnull"personid desc""1,2");  
    3. while (cursor.moveToNext()) {  
    4. int personid = cursor.getInt(0); //获取第一列的值,第一列的索引从0开始  
    5. String name = cursor.getString(1);//获取第二列的值  
    6. int age = cursor.getInt(2);//获取第三列的值  
    7. }  
    8. cursor.close();  
    9. db.close();  


           上面代码用于从person表中查找name字段含有“传智”的记录,匹配的记录按personid降序排序,对排序后的结果略过第一条记录,只获取2条记录。
            query(table, columns, selection, selectionArgs, groupBy, having, orderBy, limit)方法各参数的含义:
            table:表名。相当于select语句from关键字后面的部分。如果是多表联合查询,可以用逗号将两个表名分开。
            columns:要查询出来的列名。相当于select语句select关键字后面的部分。
            selection:查询条件子句,相当于select语句where关键字后面的部分,在条件子句允许使用占位符“?”
            selectionArgs:对应于selection语句中占位符的值,值在数组中的位置与占位符在语句中的位置必须一致,否则就会有异常。
            groupBy:相当于select语句group by关键字后面的部分
            having:相当于select语句having关键字后面的部分
            orderBy:相当于select语句order by关键字后面的部分,如:personid desc, age asc;
            limit:指定偏移量和获取的记录数,相当于select语句limit关键字后面的部分。

    第一次调用getWritableDatabase()或getReadableDatabase()方法后,SQLiteOpenHelper会缓存当前的SQLiteDatabase实例,SQLiteDatabase实例正常情况下会维持数据库的打开状态,所以在你不再需要SQLiteDatabase实例时,请及时调用close()方法释放资源。一旦SQLiteDatabase实例被缓存,多次调用getWritableDatabase()或getReadableDatabase()方法得到的都是同一实例。


     
    事务操作:
    使用SQLiteDatabasebeginTransaction()方法可以开启一个事务,程序执行到endTransaction() 方法时会检查事务的标志是否为成功,如果程序执行到endTransaction()之前调用了setTransactionSuccessful() 方法设置事务的标志为成功则提交事务,如果没有调用setTransactionSuccessful() 方法则回滚事务。使用例子如下:
     SQLiteDatabase db = ....;
    db.beginTransaction();//开始事务
    try {
        db.execSQL("insert into person(name, age) values(?,?)", new Object[]{"hello", 4});
        db.execSQL("update person set name=? where personid=?", new Object[]{"hello", 1});
        db.setTransactionSuccessful();//调用此方法会在执行到endTransaction() 时提交当前事务,如果不调用此方法会回滚事务
    } finally {
        db.endTransaction();//由事务的标志决定是提交事务,还是回滚事务
    }
    db.close();
    上面两条SQL语句在同一个事务中执行。
     
    使用事务操作,可以保证数据库的一系列操作的完整性,例如上面的两条sql语句,如果不适用事务操作的话,可能只执行了第一条语句而没有执行第二条sql语句就发生率错误,如果这样则不能保证操作的完整性。
  • 相关阅读:
    jmeter(46) redis
    jmeter(45) tcp/ip协议
    Codeforces Round #538 (Div. 2)D(区间DP,思维)
    Codeforces Global Round 1D(DP,思维)
    Educational Codeforces Round 57D(DP,思维)
    UPC11073(DP,思维)
    Yahoo Progamming Contest 2019D(DP,思维)
    Atcoder Beginner Contest 118D(DP,完全背包,贪心)
    Xuzhou Winter Camp 1C(模拟)
    Educational Codeforces Round 57 (Rated for Div. 2)D(动态规划)
  • 原文地址:https://www.cnblogs.com/lianghui66/p/2853051.html
Copyright © 2011-2022 走看看