Android中SQLite数据库知识点总结
SQLite数据库简介
SQLite是一个轻量级数据库,它是D.RichardHipp建立的公有领域项目,在2000年发布了第一个版本。它的设计目标是嵌入式的,而且占用资源非常低,在内存中只需要占用几百kB的存储空间,这也是Android移动设备采用SQLite数据库的重要原因之一。
SQLite是遵守ACID的关系型数据库管理系统。这里的ACID是指数据库事务正确执行的4个基本要素,即原子性(Atomicity)、致性(Consistency)、隔离性(lolation).持久性(Durabilily)。它能够支持Windows/Linux/UNIX等主流的操作系统,能够跟很多程序语言,例如Tcl、C#、PHP、Java等相结合。比起Mysql、PostgreSQL这两款开源数据库管理系统来讲,SQLite的处理速度更快。
SQLite没有服务器进程,它通过文件保存数据,该文件是跨平台的,可以放在其他平台中使用。并且在保存数据时,支持null(零)、integer(整数)、real(浮点数字)、text(字符串文本)和blob(二进制对象)5种数据类型。但实际上SQLite也接收varchar(n)、char(n)、decimal(p,s)等数据类型,只不过在运算或保存时会转换成对应的5种数据类型。因此,可以将各种类型的数据保存到任何字段中,而不用关心字段声明的数据类型。
SQLite数据库创建
在Android系统中,创建SQLite数据库是非常简单的。Android系统推荐使用SQLiteOpenHelper的子类创建数据库,因此需要创建一个继承自SQLiteOpenHelper,并重写该类中的onCreate()方法和onUpgrade()方法即可。
为什么要使用SQLiteOpenHelper的子类呢,因为SQLiteOpenHelper为抽象类(abstract),必须使用其子类进行继承,同时还需要重写父类的抽象方法,onCreate()方法和onUpgrade()方法都是其父类中的抽象方法。
publicclassMyHelperextendsSQLiteOpenHelper{ @Override privatestaticStringDATABASE_NAME="alan.db"; privatestaticintDATABASE_VERSION=2; publicMyHelper(Contextcontext){ super(context,DATABASE_NAME,null,DATABASE_VERSION);//调用父类的构造方法 } //数据库第一次被创建时调用该方法 publicvoidonCreate(SQLiteDatabasedb){ //初始化数据库的表结构,执行一条建表的SQL语句 db.execSQL("CREATETABLEIFNOTEXISTSperson(_idINTEGERPRIMARYKEYAUTOINCREMENT,nameVARCHAR(20),priceINTEGER); } //当数据库版本增加时调用 publicvoidonUpgrade(SQLiteDatabasedb,intoldVersion,intnewVersion){ } }
//SQLiteOpenHelper类的构造函数有四个参数 //context代表上下文,name是数据库名字,factory是游标工厂,一般情况下为null值,version是数据库版本,软件在今后的升级中会用到。 publicSQLiteOpenHelper(Contextcontext,Stringname,CursorFactoryfactory,intversion){ this(context,name,factory,version,null); }
SQLite数据库使用
前面介绍了SQLite数据库及如何创建数据库,接下来将针对SQLite数据库的增、删、改、查操作进行详细讲解。
一、SQLite基本操作方法一
1.增加一条数据
下面以alan.db数据库中的person表为例,介绍如何使用SQLiteDatabase对象的insert()方法向表中插入一条数据,示例代码如下。
publicvoidinsert(Stringname,Stringprice){ SQLiteDatabasedb=myHelper.getWritableDatabase();//获取可写入的SQLiteDatabase对象 ContentValuesvalues=newContentValues();//创建ContentValues对象 values.put("name",name);//将数据添加到ContentValues对象 values.put("price",price); longid=db.insert("person",null,values);//插入一条数据到person表 db.close();//关闭数据库 }
在上述代码中,通过getWritableDatabase()方法得到SQLiteDatabase对象,然后获得ContentValues对象并将数据添加到ContentValues对象中,最后调用inser()方法将数据插入到person表中。
insert()方法接收3个参数,第一个参数是数据表的名称,第二个参数表示如果发现将要插入的行为空行时,会将这个列名的值设为null,第三个参数为ContentValues对象。ContentValues类类似于Map类,通过键值对的形式存入数据,这里的key表示插入数据的列名,value表示要插入的数据。
需要注意的是,使用完SQLiteDatabase对象后定要调用close()方法关闭,否则数据库连接会一直存在,不断消耗内存,当系统内存不足时将获取不到SQLiteDatabase对象,并且会报出数据库未关闭异常。
2.修改一条数据
下面介绍如何使用SQLiteDatabase的update()方法修改person表中的数据,示例代码如下。
publicintupdate(Stringname,stringprice){ SQLiteDatabasedb=myHelper.getwritableDatabasel; ContentValuesvalues=newContentValues(); values.put("price",price); intnumber=db.update("person",values,"name=?",newString[]{name}); db.close(); returnnumber; }
在上述代码中,通过SQLiteDatebase对象db调用update()方法用来修改数据库中的数据,update()方法接收4个参数,第一个参数表示表名,第二个参数接收一个ContentValues对象,第三个参数可选择where语句,第四个参数表示whereClause语句中的占位参数列表,这些字符串会替换掉where条件中的"?"。
3.删除一条数据
下面介绍如何使用SQLiteDatabase的delete()方法修改person表中的数据,示例代码如下。
publicintdelete(longid){ SQLiteDatabasedb=myHelper.getwritableDatabasel; intnumber=db.delete("person",_id=?,"name=?",newString[]{id}); db.close(); returnnumber; }
从上述代码中可以看出,删除数据不同于增加和修改数据,因为删除数据不需要ContentValues来添加数据。
4.查询一条数据
在进行数据查询时使用的是SQLiteDatabase的query0方法,该方法返回的是一个行数集合Cursor。Cursor是一个游标接口,提供了遍历查询结果的方法,如移动指针方法move(),获得列值方法getString()等,通过这些方法可以获取集合中的属性值以及序号等。
需要注意的是,在使用完Cursor对象后,一定要及时关闭,否则会造成内存泄露。下面介绍如何使用SQLiteDatabase的query()方法查询数据,示例代码如下。
publicbooleanfind(longid){ SQLiteDatabasedb=helper.getReadableDatabase();//获取可读取的SQLiteDatabase对象 Cursorcursor=db.query("person",null,“_id=?",newString[]{id}),null,null,null);booleanresult=cursor.moveToNext();cursor.close();//关闭游标db.close();returnresult;}
//Cursor中的的重要方法: c.move(intoffset);//以当前位置为参考,移动到指定行 c.moveToFirst();//移动到第一行 c.moveToLast();//移动到最后一行 c.moveToPosition(intposition);//移动到指定行 c.moveToPrevious();//移动到前一行 c.moveToNext();//移动到下一行 c.isFirst();//是否指向第一条 c.isLast();//是否指向最后一条 c.isBeforeFirst();//是否指向第一条之前 c.isAfterLast();//是否指向最后一条之后 c.isNull(intcolumnIndex);//指定列是否为空(列基数为0) c.isClosed();//游标是否已关闭 c.getCount();//总数据项数 c.getPosition();//返回当前游标所指向的行数 c.getColumnIndex(StringcolumnName);//返回某列名对应的列索引值,如果不存在返回-1 c.getString(intcolumnIndex);//返回当前行指定列的值 c·getColumnIndexOrThrow(StringcolumnName)//从零开始返回指定列名称,如果不存在将抛出IllegalArgumentException异常。 c.close()//关闭游标,释放资源
在上述代码中,介绍了使用query()方法查询person表中的数据,query()方法接收7个参数,第一个参数表示表名称,第二个参数表示查询的列名,第三个参数接收查询条件子句,第四个参数接收查询子句对应的条件值,第五个参数表示分组方式,第六个参数接收having条件,即定义组的过滤器,第七个参数表示排序方式。
二、SQLite基本操作方法二
这种操作方法类似于执行SQL语句(语法和SQLserver类似)。
1.增加一条数据
db.execSQL("insertintoperosn(name,price)values(?,?)",newString[]{name,price})
2.修改一条数据
db.execSQL("updatepersonsetprice=?wherename=?",newString[]{price,name});
3.删除一条数据
db.execSQL("deletefrompersonwhere_id=?",newString[]{id});
4.查询一条数据
Cursorcursor=db.rawQuery("select_id,name,pricefrompersonwhereid=?",newString[]{id});
从上述代码可以看出,查询操作与增、删、改操作有所不同,前面三个操作都是通过execSQL()方法执行SQL语句,而查询操作使用的是rawQuery()方法。这是因为查询数据库会返回一个结果集Cursor,而execSQL()方法则没有返回值。