说到Android中的数据存储方式,听人说有5种 其实具体有几种寡人不甚清楚,无所谓,爱有几种要几种
让我来缕一缕到底有几种方式吧 shit
回顾一下android中数据存储的方式有很多种:
(1) SharePreferences 通过api进行get、put操作 ----进程内部使用,可以实现资源共享,局限性比较大
可以参考:SharedPreference 实现不同进程间的数据共享
(2) 通过file进行一些输入输出流控制 ----能实现进程间的共享,但是使用比较麻烦,个人不太喜欢用
(3) 通过SQLite进行数据库的读写 ----进程内部使用,可以实现资源共享,局限性比较大
(4) ContentProvider 进行数据的存储 ----可以实现进程间的共享,可以和SQLite配合使用(当然也可以用其他几个存储方式,稍后补充上实例),一般实现的是大型数据操作
(5) 网络存储数据 ----比较麻烦,有局限性
(6) system.prop 也可以进行简单的数据存储 ----有局限性,有default值,可以临时修改,重启后就会恢复默认值或重新设置 //这个是网上荡来的,我并不清楚,也没有用过,,有时间百度一下
使用ContentProvider共享数据的好处是统一了数据访问方式,可以存储 一些图片等的数据。而这些其他是有局限性的。
本篇文章讲述如何利用Android内置数据库sqlite进行数据的存储
说到数据库就要说到SQLiteOpenHelper这个类了,在Android开发中利用SQLiteOpenHelper实现数据库的增删改查操作
让我们看看如何实例化这个类
/** * * Created by xuenan on 2016/3/17. */
public class PersonDbOpenHelper extends SQLiteOpenHelper{
private static final String DATABASE_NAME = "mysql.db";
private static final String TABLE_NAME = "person";
private static final int DATABASE_VERSION = 1;
private SQLiteDatabase mDb;
public PersonDbOpenHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
mDb = getWritableDatabase();
}
// 当数据库第一创建的时候调用
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE " + TABLE_NAME + " (_id INTEGER PRIMARY KEY, name TEXT, age INTEGER, height REAL)");
}
// 当数据库版本更新的时候调用
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("ALTER TABLE person ADD COLUMN sex TEXT");
}
/** * 插入一条数据 * @param person * @return */
public long insert(Person person) {
ContentValues values = new ContentValues();
values.put("name", person.getName());
values.put("age", person.getAge());
values.put("height", person.getHeight());
//public long insert (String table, String nullColumnHack, ContentValues values)
//table:表名;
//nullColumnHack:设置为null;
//valuse:你要插入的值,类型为ContentValues。
return mDb.insert(TABLE_NAME, null, values);
}
/** * 查询所有 * @return */
public List<Map<String, Object>> queryAll() {
// public Cursor query (String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit)
//table:数据库表的名称
//columns:数据库列名称数组 写入后最后返回的Cursor中只能查到这里的列的内容
//selection:查询条件
//selectionArgs:查询结果
//groupBy:分组列
//having:分组条件
//orderBy:排序列
//limit:分页查询限制 第八个参数,在方法中没有体现
Cursor cursor = mDb.query(TABLE_NAME, null, null, null, null, null, null);
List<Map<String, Object>> list = new ArrayList<>();
while (cursor.moveToNext()) {
Map<String, Object> map = new HashMap<>();
for (int i = 0; i < cursor.getColumnCount(); i++) {
int type = cursor.getType(i);
switch(type) {
case Cursor.FIELD_TYPE_FLOAT:
map.put(cursor.getColumnName(i), cursor.getFloat(i));
break;
case Cursor.FIELD_TYPE_INTEGER:
map.put(cursor.getColumnName(i), cursor.getInt(i));
break;
case Cursor.FIELD_TYPE_NULL:
map.put(cursor.getColumnName(i), null);
break;
case Cursor.FIELD_TYPE_STRING:
map.put(cursor.getColumnName(i), cursor.getString(i));
break;
}
}
list.add(map);
}
cursor.close();
return list;
}
/** * 删除所有 */
public void deleteAll() {
mDb.delete(TABLE_NAME, null, null);
}
/** * 根据id删除 * @param id */
public void deleteById(int id) {
//public int delete (String table, String whereClause, String[] whereArgs)
//table:表名;
//whereClause:删除的条件,用法和update里的一样。如果为null,则删除全部行。
//whereArgs:用法和update里的一样。
mDb.delete(TABLE_NAME, "_id=?", new String[] {String.valueOf(id)});
}
/** * 根据id查询 * @param id * @return */
public Person queryById(int id) {
Cursor cursor = mDb.query(TABLE_NAME, null, "_id=?", new String[] {String.valueOf(id)}, null, null, null);
if (cursor.moveToFirst()) {
Person p = new Person();
p.setAge(cursor.getInt(cursor.getColumnIndex("age")));
p.setHeight(cursor.getFloat(cursor.getColumnIndex("height")));
p.setId(id);
p.setName(cursor.getString(cursor.getColumnIndex("name")));
return p;
}
cursor.close();
return null;
}
/** * 根据id更新 * @param person * @return */
public int updateById(Person person) {
ContentValues values = new ContentValues();
values.put("_id", person.getId());
values.put("name", person.getName());
values.put("age", person.getAge());
values.put("height", person.getHeight());
//public int update (String table, ContentValues values, String whereClause, String[] whereArgs)
//table:表名;
//values:你需要更新个数据组成的一个map,由列的名字和列的新值构成,null是合法的值,会被转化为NULL;
//whereClause:更新的条件,为一个字符串。如果为null,则所有行都将更新;
//whereArgs:字符串数组,和whereClause配合使用。有两种用法,
// 如果whereClause的条件已经直接给出,如“class = “ + num,num是传入的参数,则whereArgs可设为null。
// 如果是”class = ?“,则?会被whereArgs这个数组中对应的值替换,whereArgs给出?代表的值,有多个?的,字符串数组里的值依次填入。
return mDb.update(TABLE_NAME, values, "_id=?", new String[] {String.valueOf(person.getId())});
}
}
主要的方法就是增删改查,当然还有一个创建一个数据库和表
类创建完之后就是使用了,上边看到了,为了方便,我们使用了一个person类
public class Person {
private int id;
private String name;
private int age;
private float height;
public Person() {
}
public Person(int id, String name, int age, float height) {
super();
this.id = id;
this.name = name;
this.age = age;
this.height = height;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public float getHeight() {
return height;
}
public void setHeight(float height) {
this.height = height;
}
@Override
public String toString() {
return "id="+id+"--"+"name="+name+"--"+"age="+age+"--"+"height="+height;
}
}
方法在Activity中的使用
public class MainActivity extends AppCompatActivity {
private EditText nameBox, ageBox, heightBox, idBox;
private TextView showText;
private PersonDbOpenHelper dbHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 初始化控件
nameBox = (EditText) findViewById(R.id.editText_name);
ageBox = (EditText) findViewById(R.id.editText_age);
heightBox = (EditText) findViewById(R.id.editText_height);
idBox = (EditText) findViewById(R.id.editText_id);
showText = (TextView) findViewById(R.id.textView_show);
// 生成Helper对象
dbHelper = new PersonDbOpenHelper(this);
}
/* * 注意:因没有进行容错处理,需要正确输入数据,否则会报异常 */
public void buttonClick(View v) {
Person p;
switch(v.getId()) {
//插入一条数据
case R.id.button_addData:
String age = ageBox.getText().toString().trim();
String height = heightBox.getText().toString().trim();
String name = nameBox.getText().toString().trim();
p = new Person();
if((StringUtils.isEmpty(age))||(StringUtils.isEmpty(height))||(StringUtils.isEmpty(name))){
Toast.makeText(MainActivity.this,"请输入完整",Toast.LENGTH_SHORT).show();
return;
}
if(!StringUtils.isUsualCharacter(name)){
Toast.makeText(MainActivity.this,"请输入平常字符",Toast.LENGTH_SHORT).show();
return;
}
if(!StringUtils.isNumeric(age)){
Toast.makeText(MainActivity.this,"请输入整数",Toast.LENGTH_SHORT).show();
return;
}
p.setAge(Integer.parseInt(age));
p.setHeight(Float.parseFloat(height));
p.setName(name);
dbHelper.insert(p);
break;
//查询所有
case R.id.button_showAll:
List<Map<String, Object>> list = dbHelper.queryAll();
showText.setText(list.toString());
break;
//清楚显示数据
case R.id.button_clear:
showText.setText(null);
break;
//删除所有数据
case R.id.button_deleteAll:
dbHelper.deleteAll();
break;
//根据id进行查找
case R.id.button_queryById:
String id = idBox.getText().toString().trim();
if(!StringUtils.isNumeric(id)){
Toast.makeText(MainActivity.this,"请输入数字",Toast.LENGTH_SHORT).show();
return;
}
p = dbHelper.queryById(Integer.parseInt(id));
showText.setText(p.toString());
break;
//根据id进行更新
case R.id.button_updateById:
String age_update = ageBox.getText().toString().trim();
String height_update = heightBox.getText().toString().trim();
String name_update = nameBox.getText().toString().trim();
String id_update = idBox.getText().toString().trim();
p = new Person();
if((StringUtils.isEmpty(age_update))||(StringUtils.isEmpty(height_update))||(StringUtils.isEmpty(name_update))){
Toast.makeText(MainActivity.this,"请输入完整",Toast.LENGTH_SHORT).show();
return;
}
if(!StringUtils.isNumeric(id_update)){
Toast.makeText(MainActivity.this,"请输入数字",Toast.LENGTH_SHORT).show();
return;
}
if(!StringUtils.isUsualCharacter(name_update)){
Toast.makeText(MainActivity.this,"请输入平常字符",Toast.LENGTH_SHORT).show();
return;
}
if(!StringUtils.isNumeric(age_update)){
Toast.makeText(MainActivity.this,"请输入整数",Toast.LENGTH_SHORT).show();
return;
}
p.setAge(Integer.parseInt(age_update));
p.setHeight(Float.parseFloat(height_update));
p.setName(name_update);
p.setId(Integer.parseInt(id_update));
dbHelper.updateById(p);
break;
//根据id进行删除
case R.id.button_deleteById:
String id_delete = idBox.getText().toString().trim();
if(!StringUtils.isNumeric(id_delete)){
Toast.makeText(MainActivity.this,"请输入数字",Toast.LENGTH_SHORT).show();
return;
}
dbHelper.deleteById(Integer.parseInt(id_delete));
break;
}
}
}
//为了防止插入数据报错,进行了容错处理