当前位置: 代码迷 >> SQL >> SQLite小结数据的增删查修
  详细解决方案

SQLite小结数据的增删查修

热度:82   发布时间:2016-05-05 09:44:34.0
SQLite总结数据的增删查修
1 SQLite简介


SQLite 轻量级数据库,对多数用户仅仅表现为数据库文件而已
占用资源非常低,占用的内存空间可能只需要几百KB,多用于嵌入式产品
执行效率高
SQLite数据库相当于是每个应用的私有数据,应用程序卸载,对应的SQLite文件也被删除


SQLite是无类型的:即在创建数据库表时可用不用指定字段(列)的数据类型
任意数据类型的数据都可以保存到任意的字段(列)中,但仍然强烈推荐开发人员在创建数据表时指定数据类型,并合理的填充数据
以便于开发人员之间的交流,及可能存在的数据库引擎更换


2 创建数据库和数据表


创建数据库的方式有:
(1)调用openOrCreateDatabase()方法;(不常用)
(2)扩展SQLiteOpenHelper类




方法一openOrCreateDatabase()


·调用ContextWrapper类定义的openOrCreateDatabase()方法即可打开
或创建数据库,即:


 如果指定的数据库不存在,则先创建它,然后再打开;
 如果指定的数据已经存在,则直接打开它


该方法的签名如下:


public SQLiteDatabase openOrCreateDatabase(String name,int mode,CursorFactory factory)


参数 1数据库文件名xxx.db,
参数2 文件的操作类型
参数3游标工厂,暂时不需要传入null就行


SQLiteDatabase类
·SQLiteDatabase类是在Android系统中用于执行各种相关操作的类
例如创建数据表,对数据进行增删改查,执行事务等。


·调用该类的execSQL()方法执行无需返回结果的SQL指令,该方法签名,
如下:
public void execSQL(String sql) throws SQLException


创建数据表:


·使用一般的创建数据表的SQL语法即可创建数据表,如果表名,字段名可
能与关键字冲突,可使用方括号:


CREATE TABLE [students](
 [_id] INTEGER PRIMARY KEY AUTOINCREMENT,
 [_name]VARCHAR(50) UNIQUE NOT NULL,
[_age] INT NOT NULL DEFAUL 15
)


方法二 扩展SQLiteOpenHelper类(抽象类)


·使用SQLiteOpenHelper类的相关方法也可以获取SQLiteDatabase类的对象,以实现数据表,数据的相关操作;


·SQLiteOpenHelper可更方便的实现数据库的初始化,版本更新等问题。


·SQLiteOpenHelper类是抽象类,并且没有无参的构造方法,因此,开发人员定义其子类时,需要在子类的构造方法中显示的调用给构造方法;


·构造方法签名:
public SQLiteOpenHelper(Context context,String name,CursorFactory factory,int version)
1,上下文对象
2,数据库文件名
3 游标
4 版本(应该一次比一次大,新版本要比老版本数值要大)


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


   ·public synchronized SQLiteDatabase getReadableDatabase()
   ·public synchronized SQLiteDatebase getWritableDatabase()


子类继承扩展SQLiteOpenHelper类,子类的对象只有调用上面这两个方法中的任意一个
之后才有可能执行子类中的构造方法和重写的方法


(注意区别:getReadableDatabase()扔尝试获取一个可执行写操作的数据库访问对象
(等效于getWritableDatabase()方法)),仅当出现意外时,例如磁盘空间已满,
则获取只读的数据库访问对象。


·当第一次调用以上方法时,onCreate(),onUpgrade()方法可能被调用,
而这两个方法可能耗时比较长的执行时间,因此并不推荐在主线程中调用
以上方法






往数据库表中添加数据:


execSQL()方法
·使用execSQL(String sql,Object[] bindArgs)方法可以执行存在变量的SQL指令
该方法并不推荐用于执行增删改查






SQLiteDatabase中定义了Insert()方法用于增加数据记录
long insert(String table, String nullColumnHack, ContentValues values)


参数1 数据表名
参数2 nullColumnHack 参数
  【
  · Insert()方法本质是根据方法的第一个,第三个参数拼接处SQL语句
如果第三个参数无效(为null或没有值),则可能导致:
insert into table_name() values ()
  · 第二个参数仅当第三个参数无效时被使用,如果第二个参数被指定为"username"且第三个参数
无效时:
insert into table_name (username) values(null)
   ·即第二个参数是为了保证SQL指令不出现语法错误而存在的,当第三个参数无误时,第二个参数没有意义
   
   】


ContentValues类:


ContentValue类以键值对去(K-V)的形式封装了SQL语句中的字段名与值对象,
其中K应为字段名,V应为对应的值,ContentValues本质是使用HashMap存储数据;




例如:
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);
如果返回-1则表示插入失败,插入成功会返回执行成功的记录的id编号






数据查询:




query()方法
参数说明:
 1.String table:表名
 2.String[] columns:被检索的字段列表;
 3.String selection:SQL语句中的where子句的值
 4.String[] selectionArgs:SQL语句中的group by子句的值
 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)等根据字段索引获取值


  .boolean moveToFirst()等 :移动游标
  .boolean isFirst()等 :判断游标位置.


谨记!!!:


Cursor接口


.在第一次使用Cursor时,应该调用moveToXXX()系列方法确定游标的位置,然后再进行相关操作。
.常见的遍历游标的方式


//遍历Cursor方式之一
if(cursor.moveToFirst){
  do{
   //获取数据
   }while(cursor.moveToNext());


}
//遍历Cursor方式之2


for(cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()){
//获取数据
 }


·Cursor接口中定义了close()方法,开发人员在使用完Cursor后应该及
时调用该方法,以释放资源
例如
查询所有数据


public void queryAll(View v){
/*
* 查询数据库表中的所有数据

* */
long id;
String name;
int age;
Cursor cursor =db.query("students", new String[]{"_id","_name","_age"}, null, null, null, null, "_id desc");
/*该方法的返回值是一个游标,
* 最后一个参数是按照_id降序排列

* */

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"));
Log.d("", "_id="+id+"_name="+name+"_age="+age);
}
cursor.close();
}






例如:根据姓名查询数据:
public void queryByName(View v){
/*
* 根据姓名查询数据
* */
String name = nameEditText.getText().toString();
Cursor cursor = db.query("students", null, "_name=?", new String[]{name}, null, null, null);
if(cursor.moveToFirst()){


/*
* 在设计表时指定name唯一所以要么找不到匹配数据,要么只有唯一的一条数据
* */
long _id;
String _name;
int _age;
_id = cursor.getLong(cursor.getColumnIndex("_id"));
_name = cursor.getString(cursor.getColumnIndex("_name"));
_age = cursor.getInt(cursor.getColumnIndex("_age"));
Toast.makeText(this, "_id="+_id+"_name="+_name+"_age="+_age, 1).show();
Log.d("", "_id="+_id+"_name="+_name+"_age="+_age);
}else {
Toast.makeText(this, "没有匹配的数据", 1).show();
}


cursor.close();


}




更新和删除数据表中的数据


update()//用于修改数据表中的数据


public void update(){
ContentValues values = new ContentValues();
values.put("_age", 26);//把数据表students中名字为xiangwang的年龄更新为26
db.update("students", values, "_name=?",new String[]{"xiaowang"} );
}

delete()//删除数据



案例:

第一步:

写一个DBOpenHelper类

package com.example.sqlite_test;import android.content.Context;import android.database.sqlite.SQLiteDatabase;import android.database.sqlite.SQLiteDatabase.CursorFactory;import android.database.sqlite.SQLiteOpenHelper;public class DBOpenHelper extends SQLiteOpenHelper{	/*	 * 重写构造方法 	 * */	public DBOpenHelper(Context context) {		super(context, "tarena4.db", null, 1);		// TODO Auto-generated constructor stub	}	@Override	public void onCreate(SQLiteDatabase db) {		// TODO Auto-generated method stub		//创建数据库表students表		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	}}

第二步在MainActivity的xml布局:


<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:paddingBottom="@dimen/activity_vertical_margin"    android:paddingLeft="@dimen/activity_horizontal_margin"    android:paddingRight="@dimen/activity_horizontal_margin"    android:paddingTop="@dimen/activity_vertical_margin"    tools:context=".MainActivity" >    <Button        android:id="@+id/button1"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_alignParentLeft="true"        android:layout_alignParentTop="true"        android:onClick="queryAll"        android:text="查询所有数据" />    <EditText        android:id="@+id/et_student_name"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_alignParentLeft="true"        android:layout_below="@+id/button1"        android:ems="10"        android:hint="姓名" >        <requestFocus />    </EditText>    <Button        android:id="@+id/button2"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_below="@id/button1"        android:layout_toRightOf="@id/et_student_name"        android:onClick="queryByName"        android:text="查询" /></RelativeLayout>

第三步:

MainActivity中

package com.example.sqlite_test;import android.os.Bundle;import android.app.Activity;import android.content.ContentValues;import android.database.Cursor;import android.database.sqlite.SQLiteDatabase;import android.util.Log;import android.view.Menu;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 nameEditText;	@Override	protected void onCreate(Bundle savedInstanceState) {		super.onCreate(savedInstanceState);		setContentView(R.layout.activity_main);		helper = new DBOpenHelper(this);		db = helper.getReadableDatabase();		nameEditText =(EditText) findViewById(R.id.et_student_name);		//doinsert2();		//update();		delete();		/*		 * 数据库操作不推荐在主线程中执行,这里为了方便讲解铤而走险了		 * 下面注释部分是使用第一种方法,不常用		 * 因为使用这一种方法 创建数据库和数据表,如果下面的语句执行两次的话就会报错,同一个名字的数据库表(表名相同)不能多次创建会冲突	                    所以一般使用第二种方法创建数据库和数据库表		 * */		//创建数据库  		//		SQLiteDatabase db;		//		db = openOrCreateDatabase("tarena.db", MODE_PRIVATE,null);		//				//				//创建数据库表students表		//				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);	}	public void queryAll(View v){		/*		 * 查询数据库表中的所有数据		 * 		 * */		long id;		String name;		int age;		Cursor cursor =	db.query("students", new String[]{"_id","_name","_age"}, null, null, null, null, "_id desc");		/*该方法的返回值是一个游标,		 * 最后一个参数是按照_id降序排列		 * 		 * */				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"));			Log.d("", "_id="+id+"_name="+name+"_age="+age);		}		cursor.close();	}	public void queryByName(View v){		/*		 * 根据姓名查询数据		 * */		String name = nameEditText.getText().toString();		Cursor cursor = db.query("students", null, "_name=?", new String[]{name}, null, null, null);		if(cursor.moveToFirst()){			/*			 * 在设计表时指定name唯一所以要么找不到匹配数据,要么只有唯一的一条数据			 * */			long _id;			String _name;			int _age;			_id = cursor.getLong(cursor.getColumnIndex("_id"));			_name = cursor.getString(cursor.getColumnIndex("_name"));			_age = cursor.getInt(cursor.getColumnIndex("_age"));			Toast.makeText(this, "_id="+_id+"_name="+_name+"_age="+_age, 1).show();			Log.d("", "_id="+_id+"_name="+_name+"_age="+_age);		}else {			Toast.makeText(this, "没有匹配的数据", 1).show();		}		cursor.close();	}	public void doinsert2(){		String table = "students";		String nullColumnHack = null;		ContentValues values = new ContentValues();		values.put("_name", "Mike");		values.put("_age", 28);		db.insert(table, nullColumnHack, values);		values.put("_name", "xiaomiang");		values.put("_age", 21);		db.insert(table, nullColumnHack, values);		values.put("_name", "xiaowang");		values.put("_age", 20);		long id = db.insert(table, nullColumnHack, values);		if(id == -1){			Toast.makeText(this, "插入失败", 1).show();		}else {			Toast.makeText(this, "插入成功", 1).show();		}	}	public void doinsert(){		/*不推荐的插入数据方式		 * */		/*		 * 		String sql ="INSERT INTO students (_name, _age) VALUES (?, ?)";//第一个是字段列表,第二个是值列表		//问号对应的值:		Object[] bindArgs = new Object[]{"Jack", 25};		db.execSQL(sql, bindArgs);		 */	}	public void update(){		ContentValues values = new ContentValues();		values.put("_age", 26);//把数据表students中名字为xiangwang的年龄更新为26		db.update("students", values, "_name=?",new String[]{"xiaowang"} );	}	public void delete(){		//删除数据库表students中_id为3的记录		db.delete("students", "_id=?", new String[]{3+""});	}}

























  相关解决方案