Android-SQLite使用笔记
SQLite在项目中的使用越来越频繁,所以有必要记下一些常用的操作。Android系统内置了丰富的API供开发人员来操作SQLite,让大家可以轻松地完成对数据的存取。
先看看下面的基本的数据库操作方法。
对于添加、更新和删除,都能使用
1 db.executeSQL(String sql); 2 db.executeSQL(String sql, Object[] bindArgs);//sql语句中使用占位符,然后第二个参数是实际的参数集
除了统一的形式,还有各自的操作方式
1 db.insert(String table, String nullColumnHack, ContentValues values); 2 db.update(String table, Contentvalues values, String whereClause, String whereArgs); 3 db.delete(String table, String whereClause, String whereArgs);
以上三个方法的第一个参数都是表示要操作的表名;insert中的第二个参数表示如果插入的数据每一列都为空的话,需要指定此行中某一列的名称,系统将此列设置为NULL,不至于出现错误;insert中的第三个参数是ContentValues类型的变量,是键值对组成的Map,key代表列名,value代表该列要插入的值;update的第二个参数也很类似,只不过它是更新该字段key为最新的value值,第三个参数whereClause表示WHERE表达式,比如“age > ? and age < ?”等,最后的whereArgs参数是占位符的实际参数值;delete方法的参数同上。
查询操作比较复杂,查询形式也很丰富
1 db.rawQuery(String sql, String[] selectionArgs); 2 db.query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy); 3 db.query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit); 4 db.query(String distinct, String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit);
上面几种都是常用的查询方法,第一种最为简单,将所有的SQL语句都组织到一个字符串中,使用占位符代替实际参数,selectionArgs就是占位符实际参数集;下面的几种参数都很类似,columns表示要查询的列所有名称集,selection表示WHERE之后的条件语句,可以使用占位符,groupBy指定分组的列名,having指定分组条件,配合groupBy使用,orderBy指定排序的列名,limit指定分页参数,distinct可以指定“true”或“false”表示要不要过滤重复值。需要注意的是,selection、groupBy、having、orderBy、limit这几个参数中不包括“WHERE”、“GROUP BY”、“HAVING”、“ORDER BY”、“LIMIT”等SQL关键字。
最后他们都会返回一个Cursor对象,代表数据集的游标。Cursor对象的常用方法有
1 c.move(int offset); //以当前位置为参考,移动到指定行 2 c.moveToFirst(); //移动到第一行 3 c.moveToLast(); //移动到最后一行 4 c.moveToPosition(int position); //移动到指定行 5 c.moveToPrevious(); //移动到前一行 6 c.moveToNext(); //移动到下一行 7 c.isFirst(); //是否指向第一条 8 c.isLast(); //是否指向最后一条 9 c.isBeforeFirst(); //是否指向第一条之前 10 c.isAfterLast(); //是否指向最后一条之后 11 c.isNull(int columnIndex); //指定列是否为空(列基数为0) 12 c.isClosed(); //游标是否已关闭 13 c.getCount(); //总数据项数 14 c.getPosition(); //返回当前游标所指向的行数 15 c.getColumnIndex(String columnName);//返回某列名对应的列索引值 16 c.getString(int columnIndex); //返回当前行指定列的值
ps:当我们完成了对数据库的操作后,记得调用SQLiteDatabase的close()方法释放数据库连接,否则容易出现SQLiteException。
以上是常用方法中的一些,更详细的还要查询SDK。
在实际的开发中,为了能够更好的管理和维护数据库,我们会封装一个继承自SQLiteOpenHelper类的数据库操作类,然后以这个类为基础,再封装我们的业务逻辑方法。
下面以我目前做的一个个人项目中的对数据库的操作作为讲解,主要为了实现多个微博账户的存储和切换,结构如下:
其中LoginSqliteHelper继承了SQLiteOpenHelper,作为维护和管理数据库的基类,TSpeakDataHelper以LoginSqliteHelper为基础,封装了常用的业务方法。LoginInfo是Login表对应的JavaBean。
先看LoginSqliteHelper
1 public class LoginSqliteHelper extends SQLiteOpenHelper { 2 3 public static final String TB_NAME = "login_account"; 4 5 public LoginSqliteHelper(Context context, String name, 6 CursorFactory factory, int version) { 7 super(context, name, factory, version); 8 // TODO Auto-generated constructor stub 9 } 10 11 String CreateTableSQL = "CREATE TABLE IF NOT EXISTS " + TB_NAME + " (" 12 + LoginInfo._ID + " integer primary key," + LoginInfo.USERID 13 + " varchar," + LoginInfo.TOKEN + " varchar," + LoginInfo.USERNAME 14 + " varchar, " + LoginInfo.ICONURL + " varchar," 15 + LoginInfo.ICONURL_LARGE + " varchar" + ")"; 16 17 @Override 18 public void onCreate(SQLiteDatabase db) { 19 // TODO Auto-generated method stub 20 db.execSQL(CreateTableSQL); 21 Log.d(TB_NAME, "onCreate"); 22 } 23 24 @Override 25 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 26 // TODO Auto-generated method stub 27 db.execSQL("DROP TABLE IF EXISTS " + TB_NAME); 28 onCreate(db); 29 Log.d(TB_NAME, "onUpgrade"); 30 } 31 32 /** 更新列 */ 33 public void updateColumn(SQLiteDatabase db, String oldColumn, 34 String newColumn, String typeColumn) { 35 try { 36 db.execSQL("ALTER TABLE " + TB_NAME + " CHANGE " + oldColumn + " " 37 + newColumn + " " + typeColumn); 38 } catch (SQLException e) { 39 // TODO Auto-generated catch block 40 e.printStackTrace(); 41 } 42 } 43 }
数据库第一次创建时onCreate方法会被调用,我们可以执行创建表的语句,当系统发现版本变化之后,会调用onUpgrade方法,我们可以执行修改表结构等语句。
Login表对应的LoginInfo类如下。
1 /** 2 * 登录帐户的信息 3 * @author zengjiyang 4 * 5 */ 6 public class LoginInfo { 7 8 public static final String _ID = "id"; 9 public static final String USERID = "userid"; 10 public static final String TOKEN = "token"; 11 public static final String USERNAME = "username"; 12 public static final String ICONURL = "iconurl"; 13 public static final String ICONURL_LARGE = "largeiconurl"; 14 15 private String ID; 16 private String UserID; 17 private String Token; 18 private String UserName; 19 private String LargeIconUrl; 20 private String IconUrl; 21 22 public String getIconUrl() { 23 return IconUrl; 24 } 25 26 public void setIconUrl(String iconUrl) { 27 IconUrl = iconUrl; 28 } 29 30 public String getID() { 31 return ID; 32 } 33 34 public void setID(String iD) { 35 ID = iD; 36 } 37 38 public String getUserID() { 39 return UserID; 40 } 41 42 public void setUserID(String userID) { 43 UserID = userID; 44 } 45 46 public String getToken() { 47 return Token; 48 } 49 50 public void setToken(String token) { 51 Token = token; 52 } 53 54 public String getUserName() { 55 return UserName; 56 } 57 58 public void setUserName(String userName) { 59 UserName = userName; 60 } 61 62 public String getLargeIconUrl() { 63 return LargeIconUrl; 64 } 65 66 public void setLargeIconUrl(String largeIconUrl) { 67 LargeIconUrl = largeIconUrl; 68 } 69 70 71 72 }
然后是封装了常用操作方法的TSpeakDataHelper类
1 public class TSpeakDataHelper { 2 3 private static final String DB_NAME = "tspeakweibo.db"; 4 private static int DB_VERSION = 1; 5 private SQLiteDatabase db; 6 private LoginSqliteHelper dbHelper; 7 8 public TSpeakDataHelper(Context context) { 9 dbHelper = new LoginSqliteHelper(context, DB_NAME, null, DB_VERSION); 10 db = dbHelper.getWritableDatabase(); 11 } 12 13 public void Close() { 14 db.close(); 15 dbHelper.close(); 16 } 17 18 /** 获取 login表中的 UserID、Access Token、Access Secret 的记录 */ 19 public List<LoginInfo> GetLoginList() { 20 List<LoginInfo> mList = new ArrayList<LoginInfo>(); 21 Cursor mCursor = db.query(LoginSqliteHelper.TB_NAME, null, null, null, 22 null, null, LoginInfo._ID + " DESC"); 23 LoginInfo loginInfo; 24 while (mCursor.moveToNext()) { 25 loginInfo = new LoginInfo(); 26 loginInfo.setID(mCursor.getString(0)); 27 loginInfo.setUserID(mCursor.getString(1)); 28 loginInfo.setToken(mCursor.getString(2)); 29 loginInfo.setUserName(mCursor.getString(3)); 30 loginInfo.setIconUrl(mCursor.getString(4)); 31 loginInfo.setLargeIconUrl(mCursor.getString(5)); 32 mList.add(loginInfo); 33 } 34 mCursor.close(); 35 return mList; 36 } 37 38 /** 判断表中是否含有某个userid的记录 */ 39 public Boolean HaveUserInfo(String UserID) { 40 Boolean result = false; 41 Cursor mCursor = db.query(LoginSqliteHelper.TB_NAME, null, 42 LoginInfo.USERID + "=" + UserID, null, null, null, null); 43 result = mCursor.moveToFirst(); 44 Log.e("HaveLoginInfo", result.toString()); 45 mCursor.close(); 46 return result; 47 } 48 49 /** 根据用户id获取登录用户记录 */ 50 public LoginInfo GetOneLoginRecord(String UserID) { 51 LoginInfo loginInfo=null; 52 Cursor mCursor = db.query(LoginSqliteHelper.TB_NAME, null, 53 LoginInfo.USERID + "=" + UserID, null, null, null, null); 54 while (mCursor.moveToNext()) { 55 loginInfo = new LoginInfo(); 56 loginInfo.setID(mCursor.getString(0)); 57 loginInfo.setUserID(mCursor.getString(1)); 58 loginInfo.setToken(mCursor.getString(2)); 59 loginInfo.setUserName(mCursor.getString(3)); 60 loginInfo.setIconUrl(mCursor.getString(4)); 61 loginInfo.setLargeIconUrl(mCursor.getString(5)); 62 } 63 mCursor.close(); 64 return loginInfo; 65 } 66 67 /** 更新login表的记录,根据userid更新用户名和头像地址 */ 68 public int UpdateLoginInfo(String userName, String iconUrl, 69 String largeIconUrl, String userId) { 70 ContentValues values = new ContentValues(); 71 values.put(LoginInfo.USERNAME, userName); 72 values.put(LoginInfo.ICONURL, iconUrl); 73 values.put(LoginInfo.ICONURL_LARGE, largeIconUrl); 74 int id = db.update(LoginSqliteHelper.TB_NAME, values, LoginInfo.USERID 75 + "=" + userId, null); 76 Log.e("UpdateLoginInfo2", "==========>" + id); 77 return id; 78 } 79 80 /** 更新login表的记录 */ 81 public int UpdateLoginInfo(LoginInfo loginInfo) { 82 ContentValues values = new ContentValues(); 83 values.put(LoginInfo.USERID, loginInfo.getUserID()); 84 values.put(LoginInfo.TOKEN, loginInfo.getToken()); 85 int id = db.update(LoginSqliteHelper.TB_NAME, values, LoginInfo.USERID 86 + "=" + loginInfo.getUserID(), null); 87 Log.e("UpdateLoginInfo", "==========>" + id); 88 return id; 89 } 90 91 /** 插入login表的记录 */ 92 public long InsertLoginInfo(LoginInfo loginInfo) { 93 ContentValues values = new ContentValues(); 94 values.put(LoginInfo.USERID, loginInfo.getUserID()); 95 values.put(LoginInfo.TOKEN, loginInfo.getToken()); 96 long id = db.insert(LoginSqliteHelper.TB_NAME, LoginInfo._ID, values); 97 Log.e("InsertLoginInfo", "==========>" + id); 98 return id; 99 } 100 101 /** 删除login表的记录 */ 102 public int DeleteLoginInfo(String userId) { 103 int id = db.delete(LoginSqliteHelper.TB_NAME, LoginInfo.USERID + "=" 104 + userId, null); 105 Log.e("DeleteLoginInfo", "==========>" + id); 106 return id; 107 } 108 }
具体的应用就是对TSpeakDataHelper封装好的公共方法的调用,简单明了。