上一篇我们讲了如何存储数据,这一篇,当然是查询数据了,这是最基本的操作了,如何将一个cursor表映射成为一个model呢,我们还是用反射来。
/**
* 获取模型
* @param cursor
* @param classZ
* @param <T>
* @return
*/
public <T> List<T> getModel(final Cursor cursor,Class<T> classZ){
int resultCounts = cursor.getCount();
if (resultCounts == 0) {
return null;
}
Class <T> c = classZ;
Field[] fields = c.getDeclaredFields();
Method[] methods = c.getDeclaredMethods();
List<T> list = new ArrayList<>();
while(cursor.moveToNext()) {
T a = getInstance(c);
for (Field f : fields) {
String fieldName = f.getName();
String typeName = f.getType().getSimpleName();
String setMethodName = "set" + fieldName;
//找到对应的set方法
Method method = getMethod(setMethodName, methods);
if(null == method) continue;
final int columnIndex = cursor.getColumnIndex(fieldName);
final Object[] ot = {new Object()};
Object oj = null;
getResult(typeName, oj, new ValueTypeInterface() {
@Override
public void getValue(Integer result) {
ot[0] = cursor.getInt(columnIndex);
}
@Override
public void getValue(Boolean result) {
int intresult = cursor.getInt(columnIndex);
if(intresult == 0)
ot[0] = false;
else
ot[0] = true;
}
@Override
public void getValue(Float result) {
ot[0] = cursor.getFloat(columnIndex);
}
@Override
public void getValue(Double result) {
ot[0] = cursor.getDouble(columnIndex);
}
@Override
public void getValue(Long result) {
ot[0] = cursor.getLong(columnIndex);
}
@Override
public void getValue(String result) {
ot[0] = cursor.getString(columnIndex);
}
@Override
public void getValue(Byte result) {
ot[0] = cursor.getBlob(columnIndex);
}
});
try {
method.invoke(a, ot);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
list.add(a);
}
return list;
}
/**
* 通过反射去实例化相应类
*
* @param <T> 返回实例的泛型类型
* @return
*/
public static <T> T getInstance(Class clazz) {
try {
return (T) clazz.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
我们传入一个cursor表和一个我们要转的model 的class实例,我们通过这个实例反射生成一个对象,然后找到每个对象的set方法,因为要通过set方法来将cursor表中的值设进model中,到了这里,我们已经能将一个cursor表所有的对象映射成为一个list对象了,我们编写我们数据库操作的查询操作DBAction的query方法实现
@Override
public <T> List<T> query(String tableNamele, String[] selection, String[] selectionArgs, String orderBy,Class<T> classZ) {
String[] columns = dbUtils.getTableFieldName(classZ);
StringBuffer sb = new StringBuffer();
if(null != selection) {
for (String s : selection) {
sb = sb.append(s);
}
}
Cursor cursor = db.query(tableNamele,columns,sb.toString(),selectionArgs,"","",orderBy);
List<T> list = dbUtils.<T>getModel(cursor,classZ);
return list;
}
我们需要传入表名,查询的条件以及model的对应的class实例,我们在这里使用泛型而不是使用Object是有好处的,因为泛型会在编译是检查类型,有什么问题我们在编译时就发现了,使用Object会不安全,并且还需要手动转换类型,很麻烦,所以要使用泛型,这样一个方法可以变得很灵活,不过也有坏处,具体好坏我就不在这里说了,然后我们UserDao的实现
@Override
public User get(String id) {
daoHelp.open();
List<User> list = daoHelp.getDao().query(USERTABLE,new String[]{"id=?"},new String[]{id},null,User.class);
daoHelp.close();
if(null != list && list.size() > 0)
return list.get(0);
else
return null;
}
我们通过id去查询数据库 并且取出数据,调用方式
findViewById(R.id.btnQuery).setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
User user = dao.get("15");
Log.i("TAG",user.toString());
}
}
);
到这里,我们的简易sqlite框架就完成了一大半,不过我们还是要自己写建表语句是不是觉得特别麻烦,为什么不能像java后台一样使用JPA直接将一个model映射成表呢?肯定可以啊,下一篇,我们加入注解,直接将model映射成一张表,先到这里了。
源码已上传github
github地址:https://github.com/jredthree/DBTest