Android中的SQLite的高级使用

SQLite在android实际开发中是基本上避免不了的,很多时候我们都会使用到他作为数据存储的一种手段。

比如,我们现在,一般打开app,不用有网络的一些操作,我们就可以给用户显示上次退出之前的最新的前二十条或者多少条数据,一些评论等等。我们就是可以使用SQLite来实现。思想是:每一次用户有刷新成功的操作,我们就保存本次刷新得到的前二十条(根据实际情况)数据,然后把相关数据保存本地,通过数据库去维护并且获取,这样子的用户体验就很好,因为不用打开APP需要有网络请求的数据成功之后才有东西显示出来。

我们本次聊聊的就是如何使用SQLite去保存数据。

首先需要了解一些关于SQLite的相关的东西,比如语法,它允许的字段类型等等(虽然SQlite是基本上可以说没有类型之分,但是还是需要了解的)

请看连接:http://blog.csdn.net/liweijie_chengxuyuan/article/details/47031163

其中最基本的增删吃、改差我这里就不提及了,跟大家分享一些比较高级一点的东西,比如拿出来的数据如何排序,怎么从一个地方拿从一个位置到另外一个位置的数据等等。这些我们都是可以使用得上的,比如,我们把某一类型的数据本地化了,使用SQLite保存,然后我们显示的时候,不可能一次性从本地获取完毕的是吧,所以呢,我们就是当用户下拉加载的时候,我们就去根据当前显示的list的数据的大小作为我们从数据库再拿数据的开始,然后一次再拿十五条数据(自己定),然后拿出来的数据需要按照一定的格式排好顺序这样。

下面是实例:

首先是建表,我这里建两个表,一个是Book,一个是Person,其中,Book的主键只有一个,使用自动生成的id作为主键,Person表的的主键是age+id(主要是为了测试)。

他的的创建表语句的使用时这样的:

数据库帮助类:,一般的数据库需要使用单利模式,因为很多时候数据库会有并发问题出现

package com.example.sqlite_demo.helper;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

public class MySqliteHelper extends SQLiteOpenHelper
{
	private static final String DB_NAME = "mydb";
	private static final int VERSION = 1;
	private static final String DROP = "DROP TABLE IF EXISTS ";
	public static final String BOOK_TABLE = "book";
	public static final String BOOK_PERSON = "person";

	private MySqliteHelper(Context context)
	{
		super(context, DB_NAME, null, VERSION);
		// TODO Auto-generated constructor stub
	}

	@Override
	public void onCreate(SQLiteDatabase db)
	{
		// TODO Auto-generated method stub
		db.execSQL(DROP + BOOK_TABLE);
		String CREATE_BOOK = "CREATE TABLE " + BOOK_TABLE + "( "
		    + "_id INTEGER PRIMARY KEY AUTOINCREMENT ,name TEXT, price INTEGER" + ")";
		db.execSQL(CREATE_BOOK);

		db.execSQL(DROP + BOOK_PERSON);
		String CREATE_PERSON = "CREATE TABLE " + BOOK_PERSON + " ("
		    + "name TEXT,age INTEGER,birthDay DATE,salary INTEGER,id INTEGER,PRIMARY KEY(age,id)" + ")";
		db.execSQL(CREATE_PERSON);
		Log.i("MySqliteHelper","创建表完成");
	}

	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
	{
		// TODO Auto-generated method stub
		db.execSQL(DROP + BOOK_TABLE);
		db.execSQL(DROP + BOOK_PERSON);
		onCreate(db);
	}

	private static MySqliteHelper helper;

	/**
	 * 使用单例模式
	 *
	 * @param context
	 * @return
	 */
	public static MySqliteHelper getInstance(Context context)
	{
		if (null == helper)
		{
			synchronized (MySqliteHelper.class)
			{
				if (null == helper)
				{
					helper = new MySqliteHelper(context);
				}
			}
		}

		return helper;
	}

}

添加数据:

	// 增加
	public void addperson(Person per)
	{
		// 写入的时候需要确保是可以写进去的
		SQLiteDatabase db = mHelper.getWritableDatabase();
		db.execSQL("INSERT INTO " + MySqliteHelper.BOOK_PERSON + " values(?,?,?,?,?)", new Object[]
		{ per.getName(), per.getAge(), per.getBirthDay(), per.getSalary(), per.getId() });
	}

	// 增加
	public void addBook(Book b)
	{
		// 写入的时候需要确保是可以写进去的
		SQLiteDatabase db = mHelper.getWritableDatabase();
		db.execSQL("INSERT INTO " + MySqliteHelper.BOOK_TABLE +  "(name,price) values(?,?)", new Object[]
		{ b.getName(), b.getPrice() });
	}

这是TestSqlite,继承了AndroidTestCase的测试类中添加数据,注意,日期格式的那一栏的必须是像我那样,不能是“2015-1-1”之类的,然后,大家注意一下主键的问题,在Person表中,age+id在插入数据的时候是没有一个相同的,但是在Book表中,就可以有相同的数据,这就是主键的不同作用。

public void testAddDb() throws Exception
	{
		MySQLiteService service = new MySQLiteService(getContext());
		Person per = new Person("A", 22, "1993-04-20", 10, 1);
		Person per1 = new Person("B", 22, "1990-04-20", 109, 2);
		Person per2 = new Person("C", 22, "1996-04-20", 108, 3);
		Person per3 = new Person("D", 22, "1998-04-10", 107, 4);
		Person per4 = new Person("E", 22, "2000-04-20", 107, 5);
		Person per5 = new Person("F", 23, "2015-04-20", 104, 1);
		Person per6 = new Person("G", 24, "2014-04-20", 101, 1);
		Person per7 = new Person("H", 25, "2005-04-20", 100, 1);
		service.addperson(per);
		service.addperson(per1);
		service.addperson(per2);
		service.addperson(per3);
		service.addperson(per4);
		service.addperson(per5);
		service.addperson(per6);
		service.addperson(per7);

		Book b = new Book("1", 1);
		Book b1 = new Book("1", 1);
		Book b2 = new Book("2", 3);
		Book b3 = new Book("4", 1);
		Book b4 = new Book("5", 1);
		service.addBook(b);
		service.addBook(b);
		service.addBook(b1);
		service.addBook(b2);
		service.addBook(b3);
		service.addBook(b4);

	}

截图结果,对应两个表

关于删除更新那些操作大家可以看看我之前的blog,这里要介绍是高级一点的SQLite技能

按照我们需要的一些东西排序之后得到查找结果:比如,我需要按照生日的顺序,由小到大排序,就可以这样

	// 获取person,然后按出生日期排序
	public List<Person> getListPerson()
	{
		List<Person> mList = new ArrayList<Person>();
		SQLiteDatabase db = mHelper.getWritableDatabase();
		Cursor cursor = db.rawQuery("select * from " + MySqliteHelper.BOOK_PERSON + " ORDER BY "
		    + "birthDay" + " DESC", null);
		if (cursor.moveToFirst())
		{
			do
			{
				Person per = new Person();
				per.setAge(cursor.getInt(cursor.getColumnIndex("age")));
				per.setBirthDay(cursor.getString(cursor.getColumnIndex("birthDay")));
				per.setId(cursor.getInt(cursor.getColumnIndex("id")));
				per.setName(cursor.getString(cursor.getColumnIndex("name")));
				per.setSalary(cursor.getInt(cursor.getColumnIndex("salary")));
				mList.add(per);
			} while (cursor.moveToNext());
		}
		cursor.close();
		return mList;
	}

测试代码:

public void testOrderBy() throws Exception
	{
		MySQLiteService service = new MySQLiteService(getContext());
		List<Person> listPerson = service.getListPerson();
		for (Person per : listPerson)
		{
			Log.i(TAG, per.toString());
		}
	}

结果截图:

其中DESC是从大到小(日期的话是从进到远,向这里)ASC则是与DESC相反,这里不写实例

第二种需求:我们需要从我们的数据库查询数据,而不是全部查询,比如我一次需要查询二十条,假如数据库没有辣么多数据的时候,则是查找全部

首先,我们需要知道数据的、库有多少条数据

	//query count
	public int getPersonCount()
	{
		int count = 0;
		SQLiteDatabase db = mHelper.getWritableDatabase();
		Cursor cursor = db.rawQuery("select * from " + MySqliteHelper.BOOK_PERSON, null);
		count = cursor.getCount();
		cursor.close();
		return count;
	}

这样就可以获得了

现在,我们往数据库插入100条新数据

测试代码,需要保证的是age+id唯一:

	public void testAddDb() throws Exception
	{
		MySQLiteService service = new MySQLiteService(getContext());
		for (int i = 0; i < 100; i++)
		{
			Person per = new Person(i + "名字", i, "2015-08-30", i * 100, i);
			service.addperson(per);
		}
	}

然后,这时候我们去获取数据,获取的数据的原则是,从哪一个位置开始,到哪一个位置结束

代码:

public List<Person> getListPersonByLimit(int start, int length)
	{
		List<Person> list = new ArrayList<Person>();
		SQLiteDatabase db = mHelper.getWritableDatabase();
		Cursor cursor = db.rawQuery(
		    "select * from " + MySqliteHelper.BOOK_PERSON + " limit " + String.valueOf(start) + ","
		        + String.valueOf(length), null);
		if (cursor.moveToFirst())
		{
			do
			{
				Person per = new Person();
				per.setAge(cursor.getInt(cursor.getColumnIndex("age")));
				per.setBirthDay(cursor.getString(cursor.getColumnIndex("birthDay")));
				per.setId(cursor.getInt(cursor.getColumnIndex("id")));
				per.setName(cursor.getString(cursor.getColumnIndex("name")));
				per.setSalary(cursor.getInt(cursor.getColumnIndex("salary")));
				list.add(per);
			} while (cursor.moveToNext());
		}
		cursor.close();
		return list;
	}

测试代码:

public void testLimit() throws Exception
	{
		MySQLiteService service = new MySQLiteService(getContext());
		Log.i(TAG, "数据库目前的长度大小" + service.getPersonCount());
		List<Person> listPerson = service.getListPersonByLimit(10, 19);
		Log.i(TAG, "获取的list的的长度大小" + listPerson.size());
		for (Person per : listPerson)
		{
			Log.i(TAG, per.toString());
		}
	}

截图结果:结果的意思就是从数据库的第十个开始去,去19条数据出来,假如没有19条数据,则取完

好了,终极的问题来了,就是假如,我需要查询从某一个位置开始的数据,差取20条,然后需要按照什么鬼排序,而且我查询的是条件是什么等等。

我们首先为了测试方便,就添加一些新的数据

public void testAddDb() throws Exception
	{
		MySQLiteService service = new MySQLiteService(getContext());
		for (int i = 0; i < 31; i++)
		{
			Person per;
			//保证日期格式正确
			if (i < 10)
			{
				per = new Person("liweijie", i, "2015-08-0" + i, i * 100, i + 300);
			} else
			{
				per = new Person("liweijie", i, "2015-08-" + i, i * 100, i + 300);
			}
			service.addperson(per);
		}
	}

现在,我们要获取二十条 名字叫liweijie的 ,id>300的,按照日期从近到远排列的一个list

代码实现:

	/**
	 * @param start
	 *          开始位置
	 * @param length
	 *          获取长度
	 * @param name
	 *          查询条件
	 * @param id
	 *          查询条件
	 * @param birthday
	 *          排序方式
	 * @return
	 */
	public List<Person> getPerson(int start, int length, String name, int id)
	{
		List<Person> list = new ArrayList<Person>();
		SQLiteDatabase db = mHelper.getWritableDatabase();
		Cursor cursor = db.rawQuery("select * from " + MySqliteHelper.BOOK_PERSON
		    + " where name = ? and id >=? ORDER BY birthDay DESC limit " + String.valueOf(start) + ","
		    + String.valueOf(length), new String[]
		{ name, String.valueOf(id) });
		if (cursor.moveToFirst())
		{
			do
			{
				Person per = new Person();
				per.setAge(cursor.getInt(cursor.getColumnIndex("age")));
				per.setBirthDay(cursor.getString(cursor.getColumnIndex("birthDay")));
				per.setId(cursor.getInt(cursor.getColumnIndex("id")));
				per.setName(cursor.getString(cursor.getColumnIndex("name")));
				per.setSalary(cursor.getInt(cursor.getColumnIndex("salary")));
				list.add(per);
			} while (cursor.moveToNext());
		}
		cursor.close();
		return list;
	}

测试daim:

public void testGetPerson() throws Exception
	{
		MySQLiteService service = new MySQLiteService(getContext());
		Log.i(TAG, "数据库目前的长度大小" + service.getPersonCount());
		List<Person> listPerson = service.getPerson(0, 20, "liweijie", 300);
		Log.i(TAG, "获取的list的的长度大小" + listPerson.size());
		for (Person per : listPerson)
		{
			Log.i(TAG, per.toString());
		}
	}

好了,写了一个下午,之后会在、继续跟大家分享

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-29 06:45:24

Android中的SQLite的高级使用的相关文章

Android中使用Sqlite数据库 (一) 建表

一.实现一个类,继承SQLiteOpenHelper类,并实现构造函数,onCreate()  onUpgrade() import android.content.Context; import android.database.DatabaseErrorHandler; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase.CursorFactory; impo

Android中使用Sqlite数据库 (二) 增删改查

定义接口 package com.example.android_db.service; import java.util.List; import java.util.Map; public interface PersonService { public boolean addPerson(Object[] params); public boolean deletePerson(Object[] params); public boolean updatePerson(Object[] p

在Android中利用SQLite实现对数据的增删查改

停更了一天,I'm back again~~当我们需要操作大量的数据时,我们首先想到的当然是数据库,因为可以通过简单的语句实现数据的增删改查,在Android中,我们不使用SQL或者ORACLE,我们使用SQLite,因为它占用资源更少,而语句格式与SQL语句一样. 首先,我们来在Android中实现数据库的创建与增删改查,引用数据库的类时,不再继承常用的Activity类,而是继承Android中的SQLiteOpenHelper,创建一个构造方法,四个参数分别是(Context contex

在android中使用SQLite数据库

SQLite数据库以其轻量.体积小等特点,使其在开发中运用的非常广泛,在前面的博客中我也介绍过在Cocos2d-x中使用SQLite数据库,这篇博客是介绍在Android中使用SQLite数据库,Android中直接集成了SQLite数据库,使用起来非常方便,不需要向Cocos2d-x中那样添加外部文件 我将使用SQLite数据库实现一个下图所示的效果,打开app后会弹出下图所示的界面 单击createDatabase按钮后,在logcat中可以看到打印了一条提示信息,表示数据库创建成功,当再次

详解Android中的SQLite数据库存储

前言 在Android中存储数据的方式有很多种,其中使用SQLite数据库是存储结构化数据的最佳选择.幸运的是,Android中默认提供了对SQLite的支持,这就使得在Android中使用SQLite数据库变得格外方便. 支持的数据类型 SQLite是一款轻量级的数据库,其支持的数据类型也很简单,主要有以下几种: text:字符类型 real:浮点类型 integer:整数类型 blob:二进制数据类型 创建数据库 SQLite数据库的使用始于SQLiteOpenHelper这个抽象类.我们需

Android中数据库Sqlite的性能优化

1.索引简单的说,索引就像书本的目录,目录可以快速找到所在页数,数据库中索引可以帮助快速找到数据,而不用全表扫描,合适的索引可以大大提高数据库查询的效率.(1). 优点大大加快了数据库检索的速度,包括对单表查询.连表查询.分组查询.排序查询.经常是一到两个数量级的性能提升,且随着数据数量级增长. (2). 缺点索引的创建和维护存在消耗,索引会占用物理空间,且随着数据量的增加而增加.在对数据库进行增删改时需要维护索引,所以会对增删改的性能存在影响. (3). 分类a. 直接创建索引和间接创建索引直

如何调试Android中的Sqlite数据

第一步:root你的手机,使用360手机助手的root工具最快: 第二步:在手机上安装RE文件管理器(英文全名root explorer,手机需授予root权限),然后根据这篇文章的内容将自己的app应用目录权限赋值为777 http://blog.csdn.net/libaineu2004/article/details/25247711 注意,你的app目录一般是/data/data/com.your.app.dir 第三步:在ADT中使用file explorer视图找到你的app目录,导

Android中使用SQLite

Android系统内置了对SQLite数据库的支持,并提供了帮助类SQLiteOpenHelper.我们在开发时需要新建一个类继承SQLiteOpenHelper,并重写onCreate和onUpdate方法.onCreate方法仅在第一次新建数据库时调用,主要做创建表的操作.onUpdate方法在数据库版本更新时调用,根据业务需要做一些表的创建.删除.表结构改变等操作.同时需要实现一个构造函数,向父类的构造函数传入上下文对象.数据库名称.游标工厂和版本号.以下是一个简单的示例: 1 publi

在Android 中调用sqlite数据库

1在Android studio 工程中gradle文件夹右击新建assets文件夹.将建好的sqlite数据库导入其中. 2在主activity中判断app是否是第一次启动调用如下方法: /**检查APP是否为第一次启动*/private int CheckFirstActivate(){ /*设定数据库转移状态*/ int SetSQLiteDatabase_state = 0; /*检查APP是否为第一次启动&转移数据库*/ SharedPreferences sharedPreferen