SQLite

来源:互联网 发布:在手机淘宝怎么卖东西 编辑:程序博客网 时间:2024/06/05 10:57
 SQLite是一个轻量级数据库,不同于MYSQL或MS-SQL等数据库服务系统,对于大多数用户而言,
       SQLite具体的表现仅仅只是一个数据库文件而已。
       SQLite占用资源非常低,占用的内存空间可能只需要几百kb,多用于嵌入式产品;
       SQLite可支持Windows/Linux/Unix等主流操作系统,且支持主流的程序开发语言,例如
       JAVA、C#、PHP等。
       Android系统在其核心库已经实现了SQLite数据库引擎,开发人员只需要创建
       应用程序所需要的数据库文件、构建数据表,即可实现数据库的增删改查操作;
       SQLite数据库文件的权限依赖于操作系统,因此它没有用户账户的概念,各应用程序
       独占自身所有的SQLite数据库文件。
       SQLite数据库文件的扩展名应为.db,但由于它对于扩展名没有依赖性,因此,开发人员
       可以不指定SQLite数据库文件的扩展名。
       各应用程序的SQLite数据库文件保存在/data/data/应用程序包名/database/文件夹下。
       与常用的数据库软件一样,SQLite中依然存在数据库 (表现为独立的文件)、数据表、
       数据字段等概念,且支持绝大多数SQL92标准语法,以实现对数据表、数据的管理;
       SQLite支持事务管理,但不支持完整的触发器、可写视图。
       SQLite小特性:无需安装或配置,开源,支持数据库最大2TB,比一般的数据库的
       执行效率更高。
       SQLite是无类型的,即在创建数据表时可以不用指定字段(列)的数据类型,任意数据类型
       的数据都可以保存在任意的字段中(列),但是建议在创建数据表时指定数据类型,
       并合理的填充数据,以便于与别人之间的交流。
     创建数据库与数据表
         在Android系统中,创建数据库的方式有:
     调用openOrCreateDatabase()方法
     扩展SQLite类
   调用ContextWrapper类定义的openOrCreateDatabase()方法即可打开或创建数据库,
   即:
          如果指定的数据库不存在,则先创建他,然后再打开;
  如果指定的数据库已经存在,则直接打开它。
方法签名:
    public SQLiteDatabase openOrCreateDatabase(String name,int mode,CursorFactory factory)
 
 SQLiteDatabase类是在Android系统中用于执行各种相关操作的类,例如创建数据表、对数据进行
 增删改查、执行事务等。
 调用该类的exeSQL()方法可执行无需返回结果的SQL指令,该方法签名:
         public void exeSQL(String sql) throws SQLException
使用一般创建数据表的SQL语法即可创建数据库,如果表名、字段名可能与
关键字冲突,可使用方括号:
        CREATE TABLE [students](
  [_id] INTEGER PRIMARY KEY AUTOINCREMENT,
  [_name] VAECHAR(50) UNIQUE NOT NULL,
  [_age] INT NOT NULL DEFAULT 15
)


新建一个数据库表的方法:

       主界面不需要改变,MainActivity:

 package com.example.lianxi;import android.app.Activity;import android.content.SharedPreferences;import android.content.SharedPreferences.Editor;import android.database.sqlite.SQLiteDatabase;import android.os.Bundle;import android.view.View;import android.widget.EditText;import android.widget.Toast;public class MainActivity extends Activity {    @Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);SQLiteDatabase db;db = openOrCreateDatabase("number.db", MODE_PRIVATE, null);        String sql = "CREATE TABLE [students] (" +"[_id] INTEGER PRIMARY KEY AUTOINCREMENT,"+"[_name] VARCHAR(50) UNIQUE NOT NULL,"+"[_age] INT NOT NULL DEFAULT 16"+")";db.execSQL(sql);    }     }



    使用SQLiteOpenHelper类的相关方法也可以获取SQLiteDatabase类的对象,
    以实现数据表、数据的相关操作;
    SQLiteOpenHelper可更方便的实现数据库的初始化、版本更新等问题。
    SQLiteOpenHelper类是抽象类,且没有无参数的构造方法,因此,开发人员定义其子类时,需要在子类的构造方法中显式
    的调用该构造方法;
    方法签名:

 public SQLiteOpenHelper(Context context,String name,CursorFactory factory,int version)

SQLiteOpenHelper类中的2个抽象方法约定了如何实现数据库的初始化与版本更新。
   抽象方法签名:

public void onCreate(SQLiteDatabase db)  public void onUpgrade(SQLiteDatabase db,int oldVersion ,int newVersion)

DBOpenHelper:

 package com.example.lianxi;import android.content.Context;import android.database.sqlite.SQLiteDatabase;import android.database.sqlite.SQLiteOpenHelper;public class DBOpenHelper extends SQLiteOpenHelper{ public DBOpenHelper(Context context){super(context,"number2.db",null,1);}@Overridepublic void onCreate(SQLiteDatabase db) {// TODO Auto-generated method stubString sql = "CREATE TABLE [students] (" +"[_id] INTEGER PRIMARY KEY AUTOINCREMENT,"+"[_name] VARCHAR(50) UNIQUE NOT NULL,"+"[_age] INT NOT NULL DEFAULT 16"+")";db.execSQL(sql);}@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {// TODO Auto-generated method stub}}

在Activity中调用:

 DBOpenHelper helper = new DBOpenHelper(this);//使用这种方法可以反复执行        helper.getReadableDatabase();

调用 SQLiteOpenHelper类的如下方法可获取SQLiteDatabase对象:

 public synchronized SQLiteDatabase getReadableDatabase()    public synchronized SQLiteDatabase getWritableDatabase()

 需要注意的是:getReadableDatabase()仍尝试获取一个可执行操作的数据库访问对象
 (等效于getWritableDatabase()方法),仅当出现意外时,例如磁盘空间已满,则获取只读的数据库访问对象。
 当第一次调用以上方法时,onCreate()、onUpgrade()方法可能被调用,而这2个方法可能消耗较长的执行时间,
 因此建议不在主线程中调用以上方法。


 向数据表中插入数据
         使用execSQL(String sql,Object[] bindArgs)方法可以执行存在变量的SQL指令,
      该方法签名如下:

public void execsQL(String sql,Object[] bindArgs) throws SQLException

在上边写出的一个类的基础上,在主Activity中加入以下语句即可实现数据的添加:
              这种插入数据的方法不推荐,

 DBOpenHelper helper = new DBOpenHelper(this);//使用这种方法可以反复执行        SQLiteDatabase db = helper.getReadableDatabase();        String sql = "INSERT INTO students (name,age) VALUES(?,?)";        Object[] bindArgs = new Object[] {"Jaskdk",34};        db.execSQL(sql, bindArgs);

 另外一种插入数据的方法:
      同样,在上面所提供的DBOpenHelper的前提下,在MainActivity中进行如下的修改:

 DBOpenHelper helper = new DBOpenHelper(this);//使用这种方法可以反复执行        SQLiteDatabase db = helper.getReadableDatabase();        String table = "students";                String nullColumnHack = null;        ContentValues values = new ContentValues();        values.put("_name", "Mike");        values.put("_age", 28);        long id = db.insert(table, nullColumnHack , values);if(id == -1){Toast.makeText(this, "错误", Toast.LENGTH_LONG).show();}else{Toast.makeText(this, "插入记录成功", Toast.LENGTH_LONG).show();}

 如果显示插入成功,则说明成功插入了数据
  ContentValues类以键值对(K-V)的形式封装了SQL语句中的字段名与值的对象,其中
  K应为字段名,V应为对应的值,ContentValues本质是使用HashMap存储数据;
  insert()方法的本质是根据方法的第1个、第3个参数拼接出SQL语句,如果第3个
  参数无效(为null或没有值),则可能导致:
           insert into table_name () values ()
第2个参数nullColumnHack仅当第3个参数无效时被使用,如果第2个参数被指定为
“username”且第3个参数无效时:
           insert into table_name (username) values (null)
    即第2个参数是为了保证SQL指令不出现语法错误而存在的,当
    第3个参数无误时,第二个参数没有意义。
  查询数据:
           query()方法:参数说明:
        1、 String table: 表名:
2、 String[] columns: 被检索的字段列表;
3、String selection: SQL语句中的where子句
4、String[] selectionArgs:SQL语句中的where子句的值
5、String groupBy:SQL语句中的group by子句
6、String having:SQL语句中的having子句
7、String orderBy: SQL语句中的order by子句
   返回值说明:
       返回Cursor对象,内部封装了查询到的数据。
    Cursor接口:以类似JDBC中的ResultSet接口的方式存在的、定义了如何保存从数据库中读取的结果的接口;
    常用的方法有:
          int getColumnIndex(String columnName):根据字段名获取该字段的索引号;
 int getInt(Int columnIndex)/float getFloat(int columnIndex)/String getString(int columnIndex)等;
 根据字段索引获取值;
 boolean moveToFirst() /boolean moveToLast() / boolean moveToPosition(int position)等:移动游标;
 boolean isFirst() / boolean isLast() / boolean isBeforeFirst() / boolean isAfterLast():判断游标的位置;
 在第1次使用Cursor时,应调用moveToXXX()系列方法确定游标的位置,然后再进行相关的操作。
Cursor接口中定义了close()方法,开发人员在使用完Cursor后应该及时调用该方法,以释放资源。

下面是一个在数据库中查找数据的例子:

MainActivity:

package com.example.lianxi;import android.app.Activity;import android.content.ContentValues;import android.content.SharedPreferences;import android.content.SharedPreferences.Editor;import android.database.Cursor;import android.database.sqlite.SQLiteDatabase;import android.os.Bundle;import android.view.View;import android.widget.EditText;import android.widget.Toast;public class MainActivity extends Activity {private DBOpenHelper helper;private SQLiteDatabase db;private EditText name;    @Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);helper = new DBOpenHelper(this);db = helper.getReadableDatabase();name = (EditText) findViewById(R.id.name);    }    public void find_All(View view){    Cursor cursor = db.query("students", new String[]{"_id","_name","_age"}, null, null, null, null, "_id desc");        long id;        String name;        int age;            for(cursor.moveToFirst(); !cursor.isAfterLast();cursor.moveToNext()){        id = cursor.getLong(cursor.getColumnIndex("_id"));        name = cursor.getString(cursor.getColumnIndex("_name"));        age = cursor.getInt(cursor.getColumnIndex("_age"));    System.out.println("id = " + id + " ," + "name = " +name +" ," + "age = " + age);           }    cursor.close();    }    public void findName(View view){    String findName = name.getText().toString();    Cursor cursor = db.query("students", null, "_name=?", new String[]{findName}, null, null, null);       if(cursor.moveToFirst()){       long id1;           String name1;           int age1;           id1 = cursor.getLong(cursor.getColumnIndex("_id"));       name1 = cursor.getString(cursor.getColumnIndex("_name"));       age1 = cursor.getInt(cursor.getColumnIndex("_age"));       Toast.makeText(this, "学生记录为id = " + id1 + " ," + "name = " +name1 + " ," + "age = " + age1, Toast.LENGTH_LONG).show();              }else{       Toast.makeText(this, "没有匹配的记录!", Toast.LENGTH_LONG).show();              }    }   }

DBOpenHelper:同上,

整体布局:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="fill_parent"    android:layout_height="fill_parent"    android:orientation="vertical" >    <Button        android:id="@+id/find_all"        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:layout_marginTop="30dp"        android:onClick="find_All"        android:text="查询所有数据" />    <LinearLayout        android:layout_width="fill_parent"        android:layout_height="fill_parent"        android:layout_marginTop="30dp"        android:orientation="horizontal" >    <EditText        android:id="@+id/name"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:ems="10" >    </EditText>    <Button        android:id="@+id/find"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_marginLeft="20dp"        android:onClick="findName"        android:text="查询" />  </LinearLayout></LinearLayout>

通过这次的学习,让我对SQLite有了一个很好的理解。


0 0