Android中的SQLite使用学习

jopen 13年前
     <p style="margin-top:15px;margin-bottom:15px;">SQLite是非常流行的嵌入式关系型数据库,轻载,速度快,而且是开源。在Android中,runtime提供SQLite,所以我们可以使用SQLite,而且是全集的SQLite。SQLite提供 SQL接口,和一般的数据库一样。但是Android的API不采用JDBC,JDBC消耗太多的资源。</p>    <p style="margin-top:15px;margin-bottom:15px;">SQLite支持绝大部分SQL-92标准,不支持:FOREIGN KEY constraints, nested transactions, RIGHT OUTER JOIN, FULL OUTER JOIN, and some flavors of ALTER TABLE.而我们在手持终端上使用SQLite,一般并不涉及太复杂的数据库处理,除了上诉,其他的SQL,包括tirger、transaction 等都是支持,应该说SQLite提供的功能是足够。</p>    <p style="margin-top:15px;margin-bottom:15px;">和一般的SQL数据库比较,最大的差异是数据类型,例如我们定义一个表的某个column的数据类型为INTEGET,如果在插入时这个数值采用String,在SQLite中是包会产生错误,我们可以将定义表格的数据类型作为一个提示,用于说明期待的数据类型,但是并不真实起到检测作用。如果真的需要限制,要以来程序的其他部分进行判断。</p>    <p style="margin-top:15px;margin-bottom:15px;"><strong>1、建立我们的数据库</strong></p>    <p style="margin-top:15px;margin-bottom:15px;">在MySQL等数据库中,第一步是创建数据库,第二步是创建表,如需要,还加上我们的初始预制的数据。在Android的SQLite的使用是一样的。稍微特别一点是,我们需要通过继承 SQLiteOpenHelper这个类来达到目的。对于抽象类SQLiteOpenHelper的继承,需要重写:1)constructor,2)onCreate()和onUpgrade(),下面举例介绍。</p>    <p style="margin-top:15px;margin-bottom:15px;">这个例子,我们创建一个称为bebook_db的数据库,里面有一个叫mytable的表格,有三列:_id,Name,Weight。下面我们将演示如何创建数据库,如何在数据库中创建表,如何删除表,如何更新数据库。</p>    <p style="border-bottom:#ffbcbc thin dashed;border-left:#ffbcbc thin dashed;padding-bottom:5pt;line-height:130%;background-color:#ffffea;padding-left:5pt;padding-right:5pt;margin-left:10pt;font-size:9.5pt;border-top:#ffbcbc thin dashed;border-right:#ffbcbc thin dashed;padding-top:5pt;"><span style="color:#3366ff;">/* 对于抽象类SQLiteOpenHelper的继承,需要重写:1)constructor,2)onCreate()和onUpgrade()  * */</span><br /> public class Chapter22Db extends SQLiteOpenHelper{<br /> <span style="color:#999999;">    public static final String DATABASE_BAME ="bebook_db";</span><br /> <br />   <span style="color:#3366ff;">  /* step 1 :重写构造函数中,继承super的构造函数,创建database */</span><br />     public Chapter22Db(Context context){<br /> <span style="color:#3366ff;">        /* 第一个参数 为当前环境<br />          * 第二个参数 String name为数据库文件,如果数据存放在内存 ,则为null,<br />          * 第三个参数 为SQLiteDatabase.CursorFactory  factory,存放cursor,缺省设置为null<br />          * 第四个参数 为int version数据库的版本,从1开始,如果版本旧,则通过onUpgrade()进行更新,如果版本新则通过onDowngrade()进行发布。例如,我要更改mytable表格,增加一列,或者修改初始化的数据,或者程序变得复杂,我需要增加一个表,这时我需要在版本的数字增加,在加载时,才会对 SQLite中的数据库个更新,这点非常重要,同时参见onUpgrade()的说明 */</span><br />         super(context,DATABASE_BAME,null,1);<br />     }<br />     <br /> <span style="color:#3366ff;">    /*step 2 :重写onCreate(),如果Android系统中第一次创建我们的数据库时(即后面介绍调用getWritableDatabase()或者 getReadbleDatabase()时),将调用onCreate(),这这里创建数据库(虽然在构造函数中填入数据库名,但数据库的创建实在 onCreate()中自动进行。在这里一般进行创建table和写入初始数据*/</span><br />     public void onCreate(SQLiteDatabase db) {<br /> <span style="color:#3366ff;">        //创建table:SQL的语句是“CREATE TABLE constants(_id INTEGER PRIMARY KEY AUTOINCREMENT,title TEXT, value REAL);”,我们可以直接通过<span style="color:#000099;"><strong>db.execSQL(SQLCommand)来执行没有返回值的SQL语言</strong></span>,例如CREATE,DELETE,UPDATE,INSERT,DROP。</span><br />         db.execSQL("CREATE TABLE mytable(_id INTEGER PRIMARY KEY AUTOINCREMENT, Name TEXT,Weight REAL); ");<br />         <br />        <span style="color:#3366ff;"> //下面是加入三个原始数据,如果对表格进行增、删、改、查,后面会详细介绍。</span><span style="color:#666666;">下面的几个数据来自Android自带的重力表,据说是为了传感器管理用,Android已经考虑到我们在月球和火星上使用Android手机的情况^_^</span><span style="color:#999999;">,程序员有时真的很无聊……</span><br />         ContentValues cv = new ContentValues();<br />         <br />         cv.put("Name", "Gravity, Earth");<br />         cv.put("Weight", SensorManager.GRAVITY_EARTH);<br />         db.insert("mytable", "Name", cv);<br />         <br />         cv.put("Name", "Gravity, Mars");<br />         cv.put("Weight", SensorManager.GRAVITY_MARS);<br />         db.insert("mytable", "Name", cv);<br /> <br />         cv.put("Name", "Gravity, Moon");<br />         cv.put("Weight", SensorManager.GRAVITY_MOON);<br />         db.insert("mytable", "Name", cv);<br />     }<br /> <br />     <span style="color:#3366ff;">/* step 3:重写onUpgrade(),如果版本比原来的高,将调用onUpgrade(),在这个例子中,我们删除原来的表格,根据新需求创建*/</span><br />     public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {<br />        <span style="color:#3366ff;"> //这次同样<strong>通过<span style="color:#000099;">db.execSQL(SQLCommand)来执行没有返回值的SQL语言</span></strong>,将表格删除</span><br />         db.execSQL("DROP TABLE IF EXISTS mytable");<br />         onCreate(db);<br />     }<br /> <br /> }</p>    <p style="margin-top:15px;margin-bottom:15px;"><strong>2、和数据库进行关联</strong></p>    <p style="margin-top:15px;margin-bottom:15px;">就如同在MYSQL中进行来数据库的创建,表格创建和初始数据的填写,其他的操作一般在Activity中和用户互动产生。回忆一下我们在Linux环境中如何处理,首先是要创建和数据库的连接,Android也一样,另外在Activity结束时,我们需要将连接断开,以释放有关资源。</p>    <p style="border-bottom:#ffbcbc thin dashed;border-left:#ffbcbc thin dashed;padding-bottom:5pt;line-height:130%;background-color:#ffffea;padding-left:5pt;padding-right:5pt;margin-left:10pt;font-size:9.5pt;border-top:#ffbcbc thin dashed;border-right:#ffbcbc thin dashed;padding-top:5pt;">public class Chapter22Test1 extends ListActivity{<br />    <span style="color:#999999;"> private SQLiteDatabase  db = null;</span><br />     <span style="color:#c0c0c0;">private Cursor cursor = null; //在后面与ListView互动中使用</span><br /> <br />     protected void onCreate(Bundle savedInstanceState) {<br />        <span style="color:#999999;"> super.onCreate(savedInstanceState);</span><br /> <span style="color:#3366ff;">        // 获取处理SQLiteOpenHelper的子类的SQLite的实例,如果只读,可以采用getReadableDatabase(),这个例子我们奖通过SQLiteDatabase实例的操作,来进行对数据进行增删改查询,采用可写的方式。</span><br />        <strong> </strong>db= (new Chapter22Db (getApplicationContext()))<strong>.getWritableDatabase();  </strong><br />     }<br /> <br />     protected void onDestroy() {<br /> <span style="color:#999999;">        super.onDestroy();</span><br />     <span style="color:#3366ff;">   //释放和数据库的连接</span><br />         <strong>db.close();</strong><br />     }<br /> }</p>    <p style="margin-top:15px;margin-bottom:15px;"><strong>3、对表格进行操作</strong></p>    <p style="margin-top:15px;margin-bottom:15px;">对表格的操作有两种方式,一种是RAW方式,即直接给出SQL语句,另一种是采用SQLiteDatabase中给出的方法来进行,姑且称为API方式。下面就这两种方式的增、删、改、查进行实验。</p>    <p style="margin-top:15px;margin-bottom:15px;"><span style="color:#663300;">3.1增加一行数据</span></p>    <p style="margin-top:15px;margin-bottom:15px;">在设置创建表格时,使用了db.execSQL(SQLCommand)来执行没有返回值的SQL语言,这个是RAW方式。另一种方式在之前加入原始数据时给出,通过db.insert("mytable","Name",<<em>ContentValues value</em>s>);来实现。其中第二个参数比较特别。SQL是不运行加入一个空的行。如果第二个参数不设置为null,则对这种情空行情况进行处理,将对应列的值设置为“NULL”。</p>    <p style="border-bottom:#ffbcbc thin dashed;border-left:#ffbcbc thin dashed;padding-bottom:5pt;line-height:130%;background-color:#ffffea;padding-left:5pt;padding-right:5pt;margin-left:10pt;font-size:9.5pt;border-top:#ffbcbc thin dashed;border-right:#ffbcbc thin dashed;padding-top:5pt;"><span style="color:#3366ff;">//RAW方式。</span><br /> db.<strong>execSQL</strong>("INSERT INTO mytable(Name,Weight) VALUES ('Test1',1.0);");<br /> <span style="color:#3366ff;">//API方式</span><span style="color:#3366ff;">,通过db.insert("mytable","Name",<ContentValues values>);来处理,其中ContentValues是用于存储名称和数值,对应为表格的列的名词和其在行中的数据。</span><br /> <span style="color:#999999;">ContentValues values =new ContentValues(2);</span><span style="color:#66cccc;">//ContentValues有两个数值</span><br /> <span style="color:#999999;">values.put("Name", "Test2"); </span><span style="color:#66cccc;">//一个列名为Name,数据为Test2</span><br /> <span style="color:#999999;">values.put("Weight", 2.0); </span><span style="color:#66cccc;">//一个列名为Weight,数据为2.0</span><br /> db.<strong>insert</strong>("mytable","Name",values);</p>    <p style="margin-top:15px;margin-bottom:15px;"><span style="color:#663300;">3.2删除一行数据</span></p>    <p style="border-bottom:#ffbcbc thin dashed;border-left:#ffbcbc thin dashed;padding-bottom:5pt;line-height:130%;background-color:#ffffea;padding-left:5pt;padding-right:5pt;margin-left:10pt;font-size:9.5pt;border-top:#ffbcbc thin dashed;border-right:#ffbcbc thin dashed;padding-top:5pt;"><span style="color:#3366ff;">//RAW方式</span><br /> db.<strong>execSQL</strong>("DELETE FROM mytable WHERE Name='Test1';");    <br /> <span style="color:#3366ff;">//API方式,方法是:delete (String <em>table</em>, String <em>whereClause</em>, String[] <em>whereArgs</em>)</span><br /> db.<strong>delete</strong>("mytable", "Name=?", {"Test1"});</p>    <p style="margin-top:15px;margin-bottom:15px;"><span style="color:#663300;">3.3更新一行数据</span></p>    <p style="border-bottom:#ffbcbc thin dashed;border-left:#ffbcbc thin dashed;padding-bottom:5pt;line-height:130%;background-color:#ffffea;padding-left:5pt;padding-right:5pt;margin-left:10pt;font-size:9.5pt;border-top:#ffbcbc thin dashed;border-right:#ffbcbc thin dashed;padding-top:5pt;"><span style="color:#3366ff;">//RAW方式</span><br /> db.<strong>execSQL</strong>("UPDATE mytable SET Weight=5.0 WHERE Name='Test1';");<br /> <span style="color:#3366ff;">//API方式,方法是:update (String <em>table</em>, ContentValues<em>values</em>, String<em>whereClause</em>, String[]<em>whereArgs</em>)</span><br /> <span style="color:#999999;">String[] name = {"Test1"};<br /> ContentValues values =new ContentValues(2);</span><br /> <span style="color:#999999;">values.put("Name", "Test1");<br /> values.put("Weight", 5.0);</span><br /> db.<strong>update</strong>("mytable",values,"Name=?",name);</p>    <p style="margin-top:15px;margin-bottom:15px;"><span style="color:#663300;">3.4查询和游标Cursor</span></p>    <p style="margin-top:15px;margin-bottom:15px;">上面的三个操作都是无返回值的,而查询SELECT则不然,将返回游标Cursor。下面是两种方式的查询</p>    <p style="border-bottom:#ffbcbc thin dashed;border-left:#ffbcbc thin dashed;padding-bottom:5pt;line-height:130%;background-color:#ffffea;padding-left:5pt;padding-right:5pt;margin-left:10pt;font-size:9.5pt;border-top:#ffbcbc thin dashed;border-right:#ffbcbc thin dashed;padding-top:5pt;"><span style="color:#3366ff;"><span style="color:#3366ff;"><span style="color:#3366ff;">//RAW方式</span>,带返回值,采用db.rawQuery(SQL语句)方式</span><br /> <span style="color:#000000;"><strong>Cursor</strong> result1 =db.<strong>rawQuery</strong>("SELECT _id,Name,Weight from mytable ORDER BY Name", null);</span></span><br /> <span style="color:#3366ff;">/API方式,带返回值,采用public Cursor query (String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy)</span><br /> <span style="color:#999999;">String[] columns ={"Name","Weight"};<br /> String[] name ={"Name"};</span><br /> <strong>Cursor</strong> result2 = db.<strong>query</strong>("mytable", columns, "Name=?", name, null, null, null);</p>    <p style="margin-top:15px;margin-bottom:15px;">游标和Iterator接口有些相似,对于Cursor result我们可以通过下面的方式来读取数据:</p>    <p style="border-bottom:#ffbcbc thin dashed;border-left:#ffbcbc thin dashed;padding-bottom:5pt;line-height:130%;background-color:#ffffea;padding-left:5pt;padding-right:5pt;margin-left:10pt;font-size:9.5pt;border-top:#ffbcbc thin dashed;border-right:#ffbcbc thin dashed;padding-top:5pt;">result.<strong>moveToFirst</strong>();<br /> while(!result.<strong>isAfterLast</strong>()){ <br />     int id = result.getInt(0); <br />     String name = result.getString(1);<br />     double weight = result.getDouble(2);<br />    <span style="color:#999999;"> System.out.println("\t "+id + "\t["+ name + "]\t" +weight);</span><br />     result.<strong>moveToNext</strong>();<br /> }        <br /> result.<strong>close</strong>();    </p>    <p style="margin-top:15px;margin-bottom:15px;">通过Cursor我们可以读取数据库的详细信息我们可以数据用ArrayList<HashMap<>>来存放,由于real非对象,简单地用 ArrayList<HashMap<String,String>>来存储。我们已经有能力对SQLite数据进行处理,并也有能力处理ListView,这样可以编写我们的Activity。<br /> <br /> 来自:<a href="/misc/goto?guid=4959517976245086720" target="_blank">http://blog.csdn.net/flowingflying/article/details/6841070</a></p>