介绍
这篇主要是数据库增,删的实现。其原理还是利用注解拿到变量名,然后确定对应的列名。拼装参数集合;之后用android提供的sqlite操作方法执行sql语句实现数据库的增删改查操作。
代码部分
1. 增
Activity层调用,插入5条数据。
//增 public void insert(View v) { for (int i = 0; i < 5; i++) { User user = new User(); user.name = "alex" + i; user.password = "123" + i; userDao.insert(user); } Toast.makeText(this, "insert finished", Toast.LENGTH_SHORT).show(); }
insert(User user)方法的实现。
@Override public Long insert(T entity) { Map<String, String> map = getValues(entity); ContentValues values = getContentValues(map); Long result = database.insert(tableName, null, values); return result; } private Map<String, String> getValues(T entity) { HashMap<String, String> result = new HashMap<>(); //准备遍历类的对象中的成员 Iterator<Field> fieldIterator = cacheMap.values().iterator(); while (fieldIterator.hasNext()) { //拿到类对象中的成员 Field columnToField = fieldIterator.next(); String cacheKey = null;//列名 String cacheValue = null;//变量的值 if (columnToField.getAnnotation(DbFlied.class).value() != null) { cacheKey = columnToField.getAnnotation(DbFlied.class).value(); } else { cacheKey = columnToField.getName(); } try { if (null == columnToField.get(entity)) { continue; } cacheValue = columnToField.get(entity).toString(); } catch (IllegalAccessException e) { e.printStackTrace(); } //将列名和变量的值存起来。 result.put(cacheKey, cacheValue); } return result;//返回key-value集合 } //构造ContentValues参数 private ContentValues getContentValues(Map<String, String> map) { ContentValues contentValues = new ContentValues(); Set<String> keys = map.keySet(); Iterator<String> iterator = keys.iterator(); while (iterator.hasNext()) { String key = iterator.next(); String value = map.get(key); if (value != null) { contentValues.put(key, value); } } return contentValues; }
- 这样就完成了数据的插入。
删
- Activity层调用,删除name为alex0的条目。
public void delete(View v) {
User user = new User();
user.name = "alex0";
userDao.delete(user);
Toast.makeText(this, "delete finished", Toast.LENGTH_SHORT).show();
}
- delete(user)方法的实现
@Override
public int delete(T entity) {
Map<String, String> map = getValues(entity);
Condition condition = new Condition(map);
int delete = database.delete(tableName,
condition.getWhereClause(), condition.getWhereArgs());
return delete;
}
- 其中getValues(entity)复用的是insert中的getValues,是完全相同的。而Conditions中包含了删除的参数,功能主要是根据class 来拼接语句。其代码如下:
/**
* 封装语句
*/
class Condition {
/**
* 查询条件
* name=? && password =?
*/
private String whereClause;
private String[] whereArgs;
public Condition(Map<String, String> whereClause) {
ArrayList<String> list = new ArrayList<>();
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("1 = 1");
Set<String> keys = whereClause.keySet();
Iterator<String> iteratorKey = keys.iterator();
while (iteratorKey.hasNext()) {
String key = iteratorKey.next();
String value = whereClause.get(key);
if (value != null) {
//拼装String
stringBuilder.append(" and " + key + " =?");
list.add(value);
}
}
this.whereClause = stringBuilder.toString();
this.whereArgs = list.toArray(new String[list.size()]);
}
public String getWhereClause() {
return whereClause;
}
public String[] getWhereArgs() {
return whereArgs;
}
}
改
- Activity层调用,将alex1的密码改为xxxx;
public void update(View v) {
User where = new User();
where.name = "alex1";
User entity = new User();
entity.password = "xxxx";
userDao.update(where, entity);
Toast.makeText(this, "update finished", Toast.LENGTH_SHORT).show();
}
- update(where, entity) 的实现如下:
@Override
public int update(T where, T entity) {
Map<String, String> map = getValues(where);
Condition condition = new Condition(map);
ContentValues contentValues = getContentValues(getValues(entity));
int update = database.update(tableName,
contentValues, condition.getWhereClause(),
condition.getWhereArgs());
return update;
}
- 其中 getValues ,Condition,和getContentValues的实现已经在增和删的时候已经实现了。
查
- Activity层调用,将查询到的结果用log打印出来
public void query(View v) {
User where = new User();
where.name = "alex2";
List<User> query = userDao.query(where);
Toast.makeText(this, "query finished ,
Number : " + query.size(), Toast.LENGTH_SHORT).show();
for (User user : query) {
Log.e(TAG, query.toString());
}
}
- quey(where)方法的实现如下:
@Override
public List<T> query(T where) {
return query(where, null, null, null);
}
@Override
public List<T> query(T where, String orderBy, String startIndex, Integer limit) {
Map<String, String> map = getValues(where);
String limitString = null;
if (startIndex != null && limit != null) {
limitString = startIndex + " , " + limit;
}
Condition condition = new Condition(map);
Cursor cursor = database.query(tableName, null,
condition.getWhereClause(), condition.getWhereArgs(),
null, null, orderBy, limitString);
List<T> result = getResult(cursor,where);
cursor.close();
return result;
}
- 查找这里,与之前的增删改有差异的地方在于我们要将查找出来的数据,创建成集合返回到调用层,向心你也看到的,这个过程应该在getResult(cursor,where);里面,具体的请看下面这段代码。
private List<T> getResult(Cursor cursor, T where) {
ArrayList<T> result = new ArrayList<>();
T item = null;
while (cursor.moveToNext()){
try {
item = (T) where.getClass().newInstance();
//使用缓存的map key-value集合
Iterator<Map.Entry<String, Field>> iterator = cacheMap.entrySet().iterator();
while (iterator.hasNext()){
Map.Entry<String, Field> next = iterator.next();
String columunName = next.getKey();
int columnIndex = cursor.getColumnIndex(columunName);
Field field = next.getValue();
Class<?> type = field.getType();
if (columnIndex != -1){
//逐个判断类型,然后进行赋值。
if (type == String.class){
field.set(item,cursor.getString(columnIndex));
}else if (type == Double.class){
field.set(item,cursor.getDouble(columnIndex));
}else if (type == Integer.class){
field.set(item,cursor.getInt(columnIndex));
}else if (type == Long.class){
field.set(item,cursor.getLong(columnIndex));
}else if (type == byte[].class){
field.set(item,cursor.getBlob(columnIndex));
}else{
continue;
}
}
}
result.add(item);
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
return result;
}
小结
到这里,增删改查的操作已经完了。相信你也可以看到,在MainActivity层,不再需要关心具体的sql语句的拼写,全部交给框架来实现。这样在开发起来会很方便。
如果你想了解数据库升级的相关黑科技,后续也会有更新。