自己动手搭建数据库框架
2018-02-08 12:31
197 查看
首先IDaoSupport接口,有查询,插入单条数据,批量插入,删除,更新
public interface IDaoSupport<T> { void init(SQLiteDatabase sqLiteDatabase, Class<T> clazz); // 插入数据 public long insert(T t); // 批量插入 检测性能 public void insert(List<T> datas); // 获取专门查询的支持类 QuerySupport<T> querySupport(); // 按照语句查询 int delete(String whereClause, String... whereArgs); int update(T obj, String whereClause, String... whereArgs); }
DaoSupportFactory:工厂模式:单列模式获得实例,并能够创建数据库或者打开数据库openOrCreateDatabase,并持有外部数据库的引用,因为是直接MainActivity去调用
public class DaoSupportFactory { private static DaoSupportFactory mFactory; //单例模式 public static DaoSupportFactory getFactory() { if (mFactory == null) { synchronized (DaoSupportFactory.class) { if (mFactory == null) { mFactory = new DaoSupportFactory(); } } } return mFactory; } // 持有外部数据库的引用 private SQLiteDatabase mSqLiteDatabase; private DaoSupportFactory() { // 把数据库放到内存卡里面 判断是否有存储卡 6.0要动态申请权限 File dbRoot = new File(Environment.getExternalStorageDirectory() .getAbsolutePath() + File.separator + "nhdz" + File.separator + "database"); if (!dbRoot.exists()) { dbRoot.mkdirs(); } File dbFile = new File(dbRoot, "nhdz.db"); // 打开或者创建一个数据库 mSqLiteDatabase = SQLiteDatabase.openOrCreateDatabase(dbFile, null); } public <T> IDaoSupport<T> getDao(Class<T> clazz) { IDaoSupport<T> daoSoupport = new DaoSupport(); daoSoupport.init(mSqLiteDatabase, clazz); return daoSoupport; } }
在使用DaoSupport之前先封装一些工具类:①获得类的名字,比如person。②数据库操作的时候根据类型进行转换。③查询数据:cursor.getInt();将int第一个字符进行转换成大写
public class DaoUtil { private DaoUtil() { throw new UnsupportedOperationException("cannot be instantiated"); } /** * 获得类名 */ public static String getTableName(Class<?> clazz) { return clazz.getSimpleName(); } /** * 数据库操作的时候根据类型进行转换 */ public static String getColumnType(String type) { String value = null; if (type.contains("String")) { value = " text"; } else if (type.contains("int")) { value = " integer"; } else if (type.contains("boolean")) { value = " boolean"; } else if (type.contains("float")) { value = " float"; } else if (type.contains("double")) { value = " double"; } else if (type.contains("char")) { value = " varchar"; } else if (type.contains("long")) { value = " long"; } return value; } /** * 查询数据:cursor.getInt();将int第一个字符进行转换成大写 */ public static String capitalize(String string) { if (!TextUtils.isEmpty(string)) { return string.substring(0, 1).toUpperCase(Locale.US) + string.substring(1); } return string == null ? null : ""; } }
DaoSupport:更新,插入,删除等操作
public class DaoSupport<T> implements IDaoSupport<T> { // SQLiteDatabase private SQLiteDatabase mSqLiteDatabase; // 泛型类 private Class<T> mClazz; private String TAG = "DaoSupport"; private static final Object[] mPutMethodArgs = new Object[2]; private static final Map<String, Method> mPutMethods = new ArrayMap<>(); public void init(SQLiteDatabase sqLiteDatabase, Class<T> clazz) { this.mSqLiteDatabase = sqLiteDatabase; this.mClazz = clazz; // 创建表 /*"create table if not exists Person (" + "id integer primary key autoincrement, " + "name text, " + "age integer, " + "flag boolean)";*/ StringBuffer sb = new StringBuffer(); sb.append("create table if not exists ") .append(DaoUtil.getTableName(mClazz)) .append("(id integer primary key autoincrement, "); Field[] fields = mClazz.getDeclaredFields(); for (Field field : fields) { field.setAccessible(true);// 设置权限 String name = field.getName(); String type = field.getType().getSimpleName();// int String boolean // type需要进行转换 int --> integer, String text; sb.append(name).append(DaoUtil.getColumnType(type)).append(", "); } sb.replace(sb.length() - 2, sb.length(), ")"); String createTableSql = sb.toString(); Log.e(TAG, "表语句--> " + createTableSql); // 创建表 mSqLiteDatabase.execSQL(createTableSql); } // 插入数据库 t 是任意对象 @Override public long insert(T obj) { /*ContentValues values = new ContentValues(); values.put("name",person.getName()); values.put("age",person.getAge()); values.put("flag",person.getFlag()); db.insert("Person",null,values);*/ // 使用的其实还是 原生的使用方式,只是我们是封装一下而已 ContentValues values = contentValuesByObj(obj); // null 速度比第三方的快一倍左右 return mSqLiteDatabase.insert(DaoUtil.getTableName(mClazz), null, values); } @Override public void insert(List<T> datas) { // 批量插入采用 事物,提高性能 mSqLiteDatabase.beginTransaction(); for (T data : datas) { // 调用单条插入 insert(data); } mSqLiteDatabase.setTransactionSuccessful(); mSqLiteDatabase.endTransaction(); } private QuerySupport<T> mQuerySupport; @Override public QuerySupport<T> querySupport() { if (mQuerySupport == null) { mQuerySupport = new QuerySupport<>(mSqLiteDatabase, mClazz); } return mQuerySupport; } // obj 转成 ContentValues private ContentValues contentValuesByObj(T obj) { // 第三方的 使用比对一下 了解一下源码 ContentValues values = new ContentValues(); // 封装values Field[] fields = mClazz.getDeclaredFields(); for (Field field : fields) { try { // 设置权限,私有和共有都可以访问 field.setAccessible(true); String key = field.getName(); // 获取value Object value = field.get(obj); // put 第二个参数是类型 把它转换 mPutMethodArgs[0] = key; mPutMethodArgs[1] = value; // 方法使用反射 , 反射在一定程度上会影响性能 //参考AppCompatViewinflater源码 String filedTypeName = field.getType().getName(); // 还是使用反射 获取方法 put 缓存方法 Method putMethod = mPutMethods.get(filedTypeName); if (putMethod == null) { putMethod = ContentValues.class.getDeclaredMethod("put", String.class, value.getClass()); mPutMethods.put(filedTypeName, putMethod); } // 通过反射执行 putMethod.invoke(values, mPutMethodArgs); } catch (Exception e) { e.printStackTrace(); } finally { mPutMethodArgs[0] = null; mPutMethodArgs[1] = null; } } return values; } /** * 删除 */ public int delete(String whereClause, String[] whereArgs) { return mSqLiteDatabase.delete(DaoUtil.getTableName(mClazz), whereClause, whereArgs); } /** * 更新 这些你需要对 最原始的写法比较明了 extends */ public int update(T obj, String whereClause, String... whereArgs) { ContentValues values = contentValuesByObj(obj); return mSqLiteDatabase.update(DaoUtil.getTableName(mClazz), values, whereClause, whereArgs); } }
QuerySupport:专门用来查询的支持类,使用链式调用
public class QuerySupport<T> { // 查询的列 private String[] mQueryColumns; // 查询的条件 private String mQuerySelection; // 查询的参数 private String[] mQuerySelectionArgs; // 查询分组 private String mQueryGroupBy; // 查询对结果集进行过滤 private String mQueryHaving; // 查询排序 private String mQueryOrderBy; // 查询可用于分页 private String mQueryLimit; private Class<T> mClass; private SQLiteDatabase mSQLiteDatabase; public QuerySupport(SQLiteDatabase sqLiteDatabase, Class<T> clazz) { this.mClass = clazz; this.mSQLiteDatabase = sqLiteDatabase; } public QuerySupport columns(String... columns) { this.mQueryColumns = columns; return this; } public QuerySupport selectionArgs(String... selectionArgs) { this.mQuerySelectionArgs = selectionArgs; return this; } public QuerySupport having(String having) { this.mQueryHaving = having; return this; } public QuerySupport orderBy(String orderBy) { this.mQueryOrderBy = orderBy; return this; } public QuerySupport limit(String limit) { this.mQueryLimit = limit; return this; } public QuerySupport groupBy(String groupBy) { this.mQueryGroupBy = groupBy; return this; } public QuerySupport selection(String selection) { this.mQuerySelection = selection; return this; } public List<T> query() { Cursor cursor = mSQLiteDatabase.query(DaoUtil.getTableName(mClass), mQueryColumns, mQuerySelection, mQuerySelectionArgs, mQueryGroupBy, mQueryHaving, mQueryOrderBy, mQueryLimit); clearQueryParams(); return cursorToList(cursor); } public List<T> queryAll() { Cursor cursor = mSQLiteDatabase.query(DaoUtil.getTableName(mClass), null, null, null, null, null, null); return cursorToList(cursor); } /** * 清空参数 */ private void clearQueryParams() { mQueryColumns = null; mQuerySelection = null; mQuerySelectionArgs = null; mQueryGroupBy = null; mQueryHaving = null; mQueryOrderBy = null; mQueryLimit = null; } /** * 通过Cursor封装成查找对象 * * @return 对象集合列表 */ private List<T> cursorToList(Cursor cursor) { List<T> list = new ArrayList<>(); if (cursor != null && cursor.moveToFirst()) { do { try { T instance = mClass.newInstance(); Field[] fields = mClass.getDeclaredFields(); for (Field field : fields) { // 遍历属性 field.setAccessible(true); String name = field.getName(); //cursor.getInt(0); // 获取角标 int index = cursor.getColumnIndex(name); if (index == -1) { continue; } // 通过反射获取 游标的方法 Method cursorMethod = cursorMethod(field.getType()); if (cursorMethod != null) { Object value = cursorMethod.invoke(cursor, index); if (value == null) { continue; } // 处理一些特殊的部分 if (field.getType() == boolean.class || field.getType() == Boolean.class) { if ("0".equals(String.valueOf(value))) { value = false; } else if ("1".equals(String.valueOf(value))) { value = true; } } else if (field.getType() == char.class || field.getType() == Character.class) { value = ((String) value).charAt(0); } else if (field.getType() == Date.class) { long date = (Long) value; if (date <= 0) { value = null; } else { value = new Date(date); } } field.set(instance, value); } } // 加入集合 list.add(instance); } catch (Exception e) { e.printStackTrace(); } } while (cursor.moveToNext()); } cursor.close(); return list; } private Method cursorMethod(Class<?> type) throws Exception { String methodName = getColumnMethodName(type); Method method = Cursor.class.getMethod(methodName, int.class); return method; } private String getColumnMethodName(Class<?> fieldType) { String typeName; if (fieldType.isPrimitive()) {//是不是基本类型 typeName = DaoUtil.capitalize(fieldType.getName());//Int } else { typeName = fieldType.getSimpleName();//Integer } String methodName = "get" + typeName; if ("getBoolean".equals(methodName)) { methodName = "getInt"; } else if ("getChar".equals(methodName) || "getCharacter".equals(methodName)) { methodName = "getString"; } else if ("getDate".equals(methodName)) { methodName = "getLong"; } else if ("getInteger".equals(methodName)) { methodName = "getInt"; } return methodName; } }
使用
IDaoSupport<Person> dao = DaoSupportFactory.getFactory().getDao(Person.class); List<Person> persons = new ArrayList<>(); for (int i = 0; i < 10; i++) { persons.add(new Person("在线", 18 + i)); } dao.insert(persons); List<Person> list = dao.querySupport().queryAll(); Toast.makeText(this, list.size() + "", Toast.LENGTH_SHORT).show();
相关文章推荐
- 自己动手写DB数据库框架(性能优化)
- 自己动手搭建一个移动端React+Redux+Webpack3项目框架
- python自己动手从零开始搭建FTP服务器2 FTP初步框架
- 深入理解strus,根据MVC自己动手搭建Struts基础框架
- 自己动手写Android数据库框架
- 自己动手搭建ava通用开发框架之二—后台页面技术选型
- 自己动手搭建ava通用开发框架之一—底层框架搭建
- 扔掉log4j、log4j2,自己动手实现一个多功能日志记录框架,包含文件,数据库日志写入,实测5W+/秒日志文件写入,2W+/秒数据库日志写入,虽然它现在还没有logback那么强大
- 自己动手写Android框架-数据库框架
- 自己动手写Android数据库框架
- 自己动手搭建ava通用开发框架之三—通用权限模型建立
- 自己动手写DB数据库框架(增)
- 自己动手搭建 SSM框架——(Spring+SpringMVC+MyBatis)问题总结
- 自己动手编写IOC框架(三)
- C++学习日志之二—贪吃蛇网游化框架搭建4数据库连接
- Hibernate框架的基本搭建(一个小的java project的测试向数据库中插入和查询数据的功能)
- 自己动手搭建MinGW
- 自己动手写 android 数据库(2)
- 自己动手搭建Git服务器-SCM-Manager
- 搭建自己的框架之2:MVP+Rxjava2,封装自己的mvp框架