SQLite

 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 {
    @Override
	protected 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);
	}
	@Override
	public void onCreate(SQLiteDatabase db) {
		// TODO Auto-generated method stub
		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);
		
	}

	@Override
	public 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;
	
    @Override
	protected 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有了一个很好的理解。


你可能感兴趣的:(SQLite)