现在开始就涉及到对大量数据的操作了。
我发现这是一个循序渐进的过程,先是学存储在xml文件里的小数据,然后是存储在小型数据库的多条数据,想必以后会有大型的,云端的等等。
安卓本身支持一种数据库,就是sqlite3。SQLite,是一款轻型的数据库,它的设计目标是嵌入式的,而且目前已经在很多嵌入式设备中使用了它,它占用资源非常的低,在嵌入式设备中,可能只需要几百K的内存就够了。
1. 数据库的创建也是非常简单,用到了一个类SQLiteOpenHelper,通过继承并重写它的onCreat方法来实现数据库的创建以及数据库表的创建。
所以我们需要创建一个类,用来创建数据库,继承自SQLiteOpenHelper类。需要重写onCreate和onUpgrade两个方法。onUpgrade不太理解,字面意思是升级时触发的方法,onCreate则是在创建对象(也就是创建数据库)时触发的方法。为了方便,我们可以直接在这个方法里直接把表也建好。onCreate需要传递一个类型为SQLiteDatabase的参数,用脚趾头想也知道它肯定就是那个被创建的数据库了。执行sql语句的方法是execSQL()。另外,在创建这个类的实例的时候,我们应该是已经把数据库创建好了的,否则不能在数据库里建表。所以需要重写构造方法,调用父类的构造方法,传递四个参数:上下文,数据库名称,指定创建的结果集,版本号从一开始。对于后两个参数实在没有太深的理解。
public class PersonSQLiteOpenHelper extends SQLiteOpenHelper{
/**
* 数据库构造方法
* @param context
*/
public PersonSQLiteOpenHelper(Context context) {
//用来创建数据库 名称 结果集 版本
super(context, "person.db", null, 1);
}
/**
* 数据库第一次被创建的时候调用的方法
* @param db 被创建的数据库
*/
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("create table person (id integer primary key autoincrement, name varchar(20), number varchar(20))");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
}
}
2. 第二步就是在具体类里面实现对数据库的增删改查。
首先就是创建一个之前写的创建数据库的类的实例。
接着就是创建各种执行sql语句的方法,有两种方法。一种是执行自己写的sql语句,另外一种是调用写好的方法,传递参数,然后方法自己生成sql语句。
在每创建一种执行sql语句的方法时都需要先用getWritableDatabase()或getReadableDatabase()方法获取一下。返回的是相对应的可写的或可读的数据库SQLiteDatabase类。比如insert语句,就需要获取可写的,而select语句,就需要使用可读的。
下面开始说两种执行sql语句的方法:
新增1>
db.execSQL("insert into person (name,number) values (?,?)", new Object[]{name,number});
第一个参数字符串里面的两个问号表示未知个的占位符,而第二个参数正是需要传递的参数数组。
新增2>
//传递参数集合
ContentValues values = new ContentValues();
values.put("name", name);
values.put("number", number);
//三个参数分别代表:表名/?/参数集合
long id = db.insert("person", null, values);
db.close();
return id;
首先创建一个ContentValues类的对象用来存放参数列表,跟map的用法一样。然后就可以调用数据库的insert方法执行sql语句了。其中的三个参数:第一个是表名,第三个是参数集合,第二个跟null什么的相关吧,我也不太了解。
查询1>
Cursor cursor = db.rawQuery("select * from person where name=?", new String[]{name});
查询2>
//参数们分别表示表名/要返回的列,如果null则表示所有列/where后面要加的条件/传递的参数/groupBy/having/orderBy
Cursor cursor = db.query("person", null, "name=?", new String[]{name}, null, null, null);
boolean result = cursor.moveToNext();
cursor.close();
db.close();
return result;
可以注意到,两种方法都返回了一个Cursor类型的值,这个其实也是一种数据集合。是每行的集合。关于这个类找到的资源
看这里看这里
然后我们可以看到,执行select语句的方法并不是select而是query。为什么?因为没有select方法啊。这里面的参数看得我也是醉了,不过每个参数都还是很好理解的。
更新1>
db.execSQL("update person set number=? where name=?", new Object[]{name,number});
更新2>
ContentValues values = new ContentValues();
values.put("number", number);
int i = db.update("person", values, "name=?", new String[]{name});
db.close();
return i;
和插入一条记录差不多,需要注意的是update方法里,第二个参数用来表示要修改的值,第四个参数表示第三个参数条件里需要的值。更新的时候,返回的是影响行数。
删除1>
db.execSQL("delete from person where name=?", new Object[]{name});
删除2>
int i = db.delete("person", "name=?", new String[]{name});
db.close();
return i;
删除的时候,返回的是影响行数。
以上就是数据增删改查的基本操作。
但是,查的时候肯定不仅仅需要返回一个查询到的行数就够了,返回数据集合首先想到的就是list,那么如何从Cursor实例中获取呢?显然是循环。Cursor类有一个moveToNext()方法帮助我们实现了对Cursor类实例的循环操作。而要想获取某一行指定列的数据结果,则需要用到相对应的数据类型的Cursor实例.get数据类型()方法,然后传递的就是列标,获取列标也有方法getColumnIndex()。
Cursor cursor = db.query("person", new String[]{"name", "number", "id"}, null, null, null, null, null);
List<Person> list=new ArrayList<Person>();
while(cursor.moveToNext()){
Person p = new Person(cursor.getInt(cursor.getColumnIndex("id")), cursor.getString(cursor.getColumnIndex("name")), cursor.getString(cursor.getColumnIndex("number")));
list.add(p);
}
cursor.close();
db.close();
return list;
细心的我注意到了一点,那就是所有方法都在用完SQLiteDatabase对象后又调用了close()方法。而用到Cursor实例的同样把它关闭了。没错,这是必须的,谨记。