Android数据存储
一、文件存储
1、将文件存储到文件中
Context类中提供了一个openFileOutput(String name, ContextM> ode model)
的方法,可以用于将文件存储到指定的文件中。
参数说明:
name:文件名(不可以包含路径),文件默认存储到data/data/<packname>/files/m目录下;
model:主要有两种模式,MODE_PRIVATE(同名文件覆盖)、MODE_APPEND(同名文件追加)
- 代码示例
FileOutputStream out = null;
BufferedWriter writer = null;
try {
out = openFileOutput("data", Context.MODE_PRIVATE);
writer = new BufferedWriter(new OutputStreamWriter(out));
writer.write(inputText);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (writer != null) {
writer.close();
}
}catch (IOException e){
e.printStackTrace();
}
}
2、从文件中读取数据
Context类中提供了一个“openFileInput(“data”)”方法,用于从文件中读取数据。
- 代码示例
FileInputStream in = null;
BufferedReader reader = null;
StringBuilder content = new StringBuilder();
try {
in = openFileInput("data");
reader = new BufferedReader(new InputStreamReader(in));
String line = " ";
while ((line = reader.readLine()) != null) {
content.append(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
二、SharedPreference存储
SharedPreferences是Android提供的一种存储数据的机制,用于存储少量数据,数据类型包括(boolean、int、long、float、string),主要由于存储应用的配置信息,例如:用户名、密码、是否开启震动、音乐等。
SharedPreferences实际是以键值对的形式存在,存储位置:data/data/程序报名/shared_prefs/目录下的。
1、将数据存储到SharedPreferences中
要想使用SharedPreferences来存储数据,首先需要获取到SharePreferences对象。Android中获取对象的方法有三种。
1)、Context类中的getSharedPreferences()方法
2)、Activity类中的getPreferences()方法
3)、PreferenceManager类中的getDefaultSharedPreference()方法。
这是一个静态的方法,它接收一个Context参数,并自动使用当前应用程序的包名作为前缀来命名SharedPreferences文件。得到了SharedPreferences对象之后,就可以向SharedPreferences文件中存储数据了。主要实现有3步:
- (1)、调用SharedPreferences.Editor对象的edit()方法来获取一个SharedPreferences.Editor对象;
- (2)、向SharedPreferences对象中添加数据,方法:putBoolean()、putInt()、putString();
- (3)、调用apply()方法将添加的数据提交。
实例代码:
SharedPreferences.Editer editer = getSharedPreferences("data", MODE_PRIVATE).edit();
editor.putString("name", "Tom");
editor.putInt("age", 28);
editor.putBoolean("married", false);
editor.apply();
2、从SharedPreferences中读取数据
SharedPreferences对象中提供了一系列的get方法用于读取存储数据。如:getString()、getInt()、getBoolean()
实例代码:
SharedPreference pref = getSharedPreferences("data", MODE_PRIVATE);
String name = pref.getString("name", " ");
int age = pref.getInt("age", 0);
boolean married = pref.getBoolean("married", false);
三、SQLite数据库存储
1、创建数据库
Android为我们提供了一个SQLiteOpenHelper
帮助类来创建和升级数据库SQLiteOpenHelper
是一个抽象类,在创建数据库时我们需要创建一个自己的类来继承它,然后在类中重写onCreate()
和onUpgrade()
方法实现创建、升级数据库的逻辑。
SQLiteOpenHelper
中还有两个非常重要的方法:getReadableDatabase()
和
getWriteableDatabase()
方法。这两个方法都可以创建或打开一个数据库并返回一个可以对数据路进行读写操作的对象。不同的是,当数据库不可以写入时(如磁盘空间已满),这时getReadableDatabase()
将返回一个只有读的方式打开数据库的对象,而getWriteableDatabase()
则会返回异常。
我们要创建一个自己的数据库的类,就要有构造函数,幸运的是SQLiteOpenHelper
中就有两个构造方法,我们在使用时只使用参数少的那一个。这个构造方法接收4个参数:
- Context:活动的上下文。
- 数据库名:创建数据库时使用的名字
- 允许我们在查询数据时返回一个自定义的Cursor,一般传入null
- 数据库的版本号
构建出SQLiteOpenHelper
的实例后,再调用getReadableDatabase()
或
getWriteableDatabase()
方法就可以创建数据库了。
1)、新建MyDatabaseHelper
类继承自SQLiteOpenHelper
public class MyDatabaseHelper extends SQLiter {
//Book表的建表语句,然后赋值给CREAT_BOOK
public static final String CREAT_BOOK = "create table Book ("
+ "id integer primary key autoincrement, "
+ "author text"
+ "price real"
+ "pages integer"
+ "name text)";
private Context mcontext;
public MyDatabaseHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
mcontext = context;
}
@Override
public void onCreate(SQLiteDatabase db) {
//execSQL()方法可以执行建表语句
db.execSQL(CREATE_BOOK);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){
}
}
2)、MainActivity
public class MainActivity extends AppCompatActivity {
private MyDatabaseHelper dbHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
dbHelper = new MyDatabaseHelper(this, "BookStore.db", null, 1);
Button updateData = (Button) findViewById(R.id.update_data);
updateData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dbHelper.getWriterableDatabase();
}
});
}
}
2、升级数据库
public class MyDatabaseHelper extends SQLiter {
//Book表的建表语句,然后赋值给CREAT_BOOK
public static final String CREAT_BOOK = "create table Book ("
+ "id integer primary key autoincrement, "
+ "author text"
+ "price real"
+ "pages integer"
+ "name text)";
public static final String CREATE_CATEGORY = "create table Category ("
+ "id integer primary key autoincrement, "
+ "category_name text, "
+ "category_code integer)";
private Context mcontext;
public MyDatabaseHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
mcontext = context;
}
@Override
public void onCreate(SQLiteDatabase db) {
//execSQL()方法可以执行建表语句
db.execSQL(CREATE_BOOK);
db.execSQL(CREATE_CATEGORY);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){
db.execSQL("drop table if exists Book");
db.execSQL("drop table if exists Category");
onCreate(db);
}
}
在这里我们又添加了一张表Category,在onCreate() 方法中执行建表语句,但是因为我们之前已经执行了onCreate()方法了,所以现在不会再次执行onCreate()方法了。这是如果想添加这个表,我们可以使用数据库的升级功能。
在onUpgrade()方法中执行
db.execSQL("drop table if exists Book");
db.execSQL("drop table if exists Category");
如果发现Book或Category存在,就将表删除掉,然后调用onCreate()方法重新创建。
那么,我们怎么让onUpgrade()方法执行呢?很简单,我们只需要在活动中执行
dbHelper = new MyDatabaseHelper(this, "BookStore.db", null, 2);
这个语句就可以了,注意,这里我们是将传入的版本号增加了,升级BookStore.db的版本来间接促使执行onUpgrade()方法的。
3、添加数据
我们会调用SQLiteOpenHelper的getReadableDatabase()或getWriteableDatabase()方法获得一个对象,借助这个对象对数据进行增删改查。
SQLiteDatabase中提供了insert()方法添加数据,他接受三个参数
- 表名
- 在未指定添加数据的情况下给某些可为空的记录自动赋值NULL,一般我们不会用到这个功能,直接传入null
- ContentValues对象,对象里有要添加的数据,通过ContentValues的put()添加的。
Button addData = (Button) findViewById(R.id.add_data);
addData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
//创建ContentValues对象,添加数据
ContentValues values = new ContentValues();
// 开始组装第一条数据
values.put("name", "The Da Vinci Code");
values.put("author", "Dan Brown");
values.put("pages", 454);
values.put("price", 16.96);
db.insert("Book", null, values); // 插入第一条数据
values.clear(); //清空values里的数据
// 开始组装第二条数据
values.put("name", "The Lost Symbol");
values.put("author", "Dan Brown");
values.put("pages", 510);
values.put("price", 19.95);
db.insert("Book", null, values); // 插入第二条数据
}
});
4、更新数据
利用SQLiteDatabase提供的updata()方法可以更新数据,它接受4个参数:
- 表名
- ContentValues对象
- 第三、四个参数约束更新某一行或某几行的数据,不指定默认更新所有行。
Button updateData = (Button) findViewById(R.id.update_data);
updateData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("price", 10.99);
db.update("Book", values, "name = ?", new String[] { "The Da Vinci Code" });
}
});
5、删除数据
利用SQLiteDatabase提供的delete()方法可以删除数据,它接收3个参数:
- 表名
- 第二、三个参数约束删除某一行或某几行的数据,不指定默认删除所有行。
Button deleteButton = (Button) findViewById(R.id.delete_data);
deleteButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
db.delete("Book", "pages > ?", new String[] { "500" });
}
});
6、查询数据
SQLiteDatabase提供了query()方法查询数据,这个方法最短接收7个参数:
- 表名
- 指定查询哪几个字段,不指定默认查询所有字段
- 第三、四个参数用于约束查询某一行或某几行的数据,不指定默认查询所有行。
- 第五个参数用于指定需要去group by的列,不指定则表示不对查询就过进行group by操作。
- 第六个参数用于指定对group by之后的数据进行进一步的过滤,不指定则表示不过滤
- 第七个参数用于指定查询结果的排序方式,不指定则表示默认排序方式
调用query()方法后会返回一个Cursor对象,查询的所有数据将从这个对象中取出。
Button queryButton = (Button) findViewById(R.id.query_data);
queryButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
// 查询Book表中所有的数据
Cursor cursor = db.query("Book", null, null, null, null, null, null);
if (cursor.moveToFirst()) {
do {
// 遍历Cursor对象,取出数据并打印
String name = cursor.getString(cursor.getColumnIndex("name"));
String author = cursor.getString(cursor.getColumnIndex("author"));
int pages = cursor.getInt(cursor.getColumnIndex("pages"));
double price = cursor.getDouble(cursor.getColumnIndex("price"));
Log.d("MainActivity", "book name is " + name);
Log.d("MainActivity", "book author is " + author);
Log.d("MainActivity", "book pages is " + pages);
Log.d("MainActivity", "book price is " + price);
} while (cursor.moveToNext());
}
cursor.close();
}
});
程序查询完之后会得到一个Cursor对象,接着我们调用他的moveToFirst()方法将数据的指针移动到第一行的位置,然后进入一个循环中去遍历每一个数据。在循环中通过Cursor的getColumnIndex()方法获取到某一列在表中对应的位置索引,然后将这个索引传入到相应的取值方法中,就可以得到从数据库中读取的数据了。