在android项目开发中,我们经常会用到数据的本地存储。比如SharedPreferences存储用户的一些基本
信息,或者通过文件存储从服务器请求的接口数据。正常来说,我们肯定会优先选择SharedPreferences
存储或文件存储。这2中存储方式更简单,而且数据的读取和存储的速度都相对于数据库较快。
最近正在使用融云的ImLib做聊天,为了让用户一打开应用就能看到会话列表,再加上数据结构相对复
杂,数据量大,于是我就使用了数据库来存储这些数据。
我们的界面实现效果基本上和QQ类似,这是从我的QQ列表的截图。
界面效果:
会话Item类 ConversationItem.java:
public class ConversationItem implements Serializable {
//会话id
private String targetId;
//会话标题
private String name;
//会话内容
private String content;
//会话时间
private String time;
//是否置顶
private int istop;
public ConversationItem(String targetId, String name, String content, String time, int istop) {
this.targetId = targetId;
this.name = name;
this.content = content;
this.time = time;
this.istop = istop;
}
public String getTargetId() {
return targetId;
}
public void setTargetId(String targetId) {
this.targetId = targetId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public int getIstop() {
return istop;
}
public void setIstop(int istop) {
this.istop = istop;
}
public String getTime() {
return time;
}
public void setTime(String time) {
this.time = time;
}
}
Constant.java 定义需要用到的常量字段
public class Constant {
public static final String DATABASE_NAME = "szy_im.db";
public static final int DATABASE_VERSION = 1;
public static final String TABLE_NAME = "conversion_list";
//会话id
public static final String CID = "cid";
//用户id,当前用户的标识,用户可能会切换账号
public static final String UID = "uid";
//会话标题
public static final String TITLE = "title";
//会话内容
public static final String CONTENT = "content";
//消息时间
public static final String TIME = "time";
//会话是否置顶 0 否 1 是
public static final String ISTOP = "istop";
}
数据库的创建和表的创建 DBHelper .java:
public class DBHelper extends SQLiteOpenHelper {
public DBHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
}
public DBHelper(Context context) {
super(context, Constant.DATABASE_NAME, null, Constant.DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
String sql = "create table " + Constant.TABLE_NAME + " ( " + Constant.CID +
" text primary key," + Constant.UID + " text, " + Constant.TITLE + " text ,"
+ Constant.CONTENT + " text ,"
+ Constant.TIME + " text,"
//默认会话不置顶
+ Constant.ISTOP + " Integer default '0' )";
db.execSQL(sql);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
数据库数据操作,DBManger .java:
public class DBManger {
private static DBHelper dbHelper;
private static String uid;
public static DBHelper getInstance(Context context) {
if (dbHelper == null) {
dbHelper = new DBHelper(context);
SharedPreferences preferences = context.getSharedPreferences(Constant.SHARED_PREFERENCES, Context.MODE_PRIVATE);
uid = preferences.getString(Constant.ID_USER, "");
}
return dbHelper;
}
//把cid存入表中
public static long insert(DBHelper db, String cid) {
long ret = -1;
if (db != null && !StringUtils.isEmpty(cid)) {
boolean exist = isExist(db, cid);
if (!exist) {
SQLiteDatabase database = db.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(Constant.TID, cid);
values.put(Constant.UID, uid);
ret = database.insert(Constant.TABLE_NAME, null, values);
db.close();
}else{
SQLiteDatabase database = db.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(Constant.UID, uid);
ret = database.insert(Constant.TABLE_NAME, null, values);
db.close();
}
}
return ret;
}
//设置会话标题
public static long updateTitle(DBHelper db, String cid, String title) {
long ret = -1;
if (db != null && !StringUtils.isEmpty(title)) {
ret = update(db, cid, title, null, null, -1);
}
return ret;
}
//设置会话内容
public static long updateContent(DBHelper db, String cid, String content) {
long ret = -1;
if (db != null && !StringUtils.isEmpty(content)) {
ret = update(db, cid, null, content, null, -1);
}
return ret;
}
//设置会话时间
public static long updateTime(DBHelper db, String cid, String time) {
long ret = -1;
if (db != null && !StringUtils.isEmpty(time)) {
ret = update(db, cid, null, null, time, -1);
}
return ret;
}
//设置会话置顶
public static long updateIsTop(DBHelper db, String cid, int istop) {
long ret = -1;
if (db != null && istop >= 0) {
ret = update(db, cid, null, null, null, istop);
}
return ret;
}
//设置会话
public static long update(DBHelper db, String cid, String title, String content, String time, int istop) {
long ret = -1;
boolean isupdate = false;
if (db == null || StringUtils.isEmpty(cid)) {
return ret;
}
SQLiteDatabase database = db.getWritableDatabase();
ContentValues values = new ContentValues();
if (!StringUtils.isEmpty(title)) {
values.put(Constant.TITLE, title);
isupdate = true;
}
if (!StringUtils.isEmpty(content)) {
values.put(Constant.CONTENT, content);
isupdate = true;
}
if (!StringUtils.isEmpty(time)) {
values.put(Constant.TIME, time);
isupdate = true;
}
if (istop >= 0) {
values.put(Constant.ISTOP, istop);
isupdate = true;
}
if (isupdate) {
ret = database.update(Constant.TABLE_NAME, values, Constant.CID + "= ?", new String[]{cid});
database.close();
}
return ret;
}
//删除表中所有数据
public static long deleteAll(DBHelper db) {
long ret = -1;
if (db != null) {
SQLiteDatabase database = db.getWritableDatabase();
database.delete(Constant.TABLE_NAME, null, null);
database.close();
}
return ret;
}
//根据会话ID删除数据
public static long deleteItem(DBHelper db, String cid) {
long ret = -1;
if (db != null) {
SQLiteDatabase database = db.getWritableDatabase();
ret = database.delete(Constant.TABLE_NAME, Constant.CID + " = ?", new String[]{cid});
database.close();
}
return ret;
}
//根据uid查询表中的所有数据,并根据时间和是否置顶进行降序排列
public static List<ConversationItem> selectAll(DBHelper db) {
List<ConversationItem> list = new ArrayList<>();
if (db == null) {
return list;
}
SQLiteDatabase database = db.getReadableDatabase();
String sql = "select * from " + Constant.TABLE_NAME + " where " + Constant.UID + "= ? order by "
+ Constant.TIME + " DESC," + Constant.ISTOP + " DESC";
Cursor cursor = database.rawQuery(sql, new String[]{uid});
if (cursor.moveToFirst()) {
do {
String cid = cursor.getString(cursor.getColumnIndex(Constant.CID));
String title = cursor.getString(cursor.getColumnIndex(Constant.TITLE));
String content = cursor.getString(cursor.getColumnIndex(Constant.CONTENT));
String time = cursor.getString(cursor.getColumnIndex(Constant.TIME));
int istop = cursor.getInt(cursor.getColumnIndex(Constant.ISTOP));
ConversationItem item = new ConversationItem(tid, title, content, time, istop);
list.add(item);
} while (cursor.moveToNext());
}
cursor.close();
database.close();
return list;
}
//查询cid是否存在
public static boolean isExist(DBHelper db, String cid) {
boolean ret = true;
if (db == null) {
return ret;
}
SQLiteDatabase database = db.getReadableDatabase();
String sql = "select * from " + Constant.TABLE_NAME + " where " + Constant.TID + " = ?";
Cursor cursor = database.rawQuery(sql, new String[]{cid});
if (cursor.getCount() < 1) {
ret = false;
}
return ret;
}
}
目前数据库没有什么太大的问题,但还是有一个小问题,我把会话id设置为主键,当切换账号的时候,若
新账号也有相同的会话,则新账号在本地数据库取不到该会话数据,暂时还没想到怎么解决。
界面显示的时候是先从本地数据库中去会话数据,然后开启一个线程去取融云存储的聊天会话,虽然我的
数据库存储有点问题,但还是可以正确显示的。
还有一个问题需要大家注意,就是数据库的数据的维护,最好是接收消息然后存到数据库,这样的话,可
以有效的减少对数据库的操作,从而也提高了效率。可能我比较笨吧,后来才想到这样做,哈哈!
我是一个小菜鸟,不足之处请大神们进行批评和指正。