Asp.Net MVC 开发微信扫码支付详细步骤与教程
765
2022-10-30
LazyDB :提供一种实现 Android ORM 框架的解决方案
LazyDB
一款简易使用的orm框架
1. 框架设计
1.1. 总体流程
对于数据库的“增删改”操作,将对象输入,通过ORM框架处理,构建SQL语句,然后写入数据库,如图1所示;
对于查询数据库的操作,输入要输出对象的Class,通过ORM框架处理,构建SQL语句,查询数据库,返回后构建成Object输出,如图2所示;
1.2. ORM内部实现流程
构建SQL语句的原理:通过Java反射机制,获取Class的字段和Object字段值,通过字符串拼接构建SQL。
1.3. Java数据类型与SQLite数据类型映射表
Java数据类型 | SQLite数据类型 |
---|---|
int、Integer、byte、Byte、short、Short、long、Long、Boolean、boolean | INTEGER |
float、Float、double、Double | REAL |
Date | DATE |
String | TEXT |
PS:这里简单起见,将所有的字符串都用TEXT;整数都用INTEGER;
2. 内部实现的几个重要实现规则
1. 对于SQLite表字段与Java对象字段映射规则:
(1)只映射非final和非static的Java字段; (2)Java的字段名即SQLite表的字段名; (3)主键取Java对象中的名字为ID(不区分大小写)或者加了@ID注解的字段,优先查找注解;
2. 保存数据类型规则:
(1)以Java基本数据类型以及其包装类为主,还有Date;对于其他类不做处理;
3. 表名称生成规则:
(1)以Java类的完全限定名来命名(.替换为_),例如:com.andy.Person的代表的表名为com_andy_Person,保证了表名的唯一性;
3. 代码实现
介绍一下几个重要的类 (1) 用于构造SQL语句的类SQLBuilder(主要用了Java反射机制) (2) 用于执行SQL语句的类SQLiteDBExecutor (3) 提供给外部使用的ORM主类LazyDB
3.1 SQLBuilder:SQL语句构建器
该Class的主要作用是,将外部传进来的Object(对象)或者Class(类),通过Java反射机制,构建成SQL语句。
这里以创建表的SQL为例
代码步骤分解: (1)取出Class中所有Field,即Field数组; (2)遍历Field数组,找出主键的Field,拼到SQL的字符串里; (3)再次遍历Field数组,过滤掉主键的Field、final、static,拼到SQL的字符串里;
具体代码如下:
// SQLBuilder类 /** * 构建创建数据库表的sql语句 * * @param clazz 类 * @return 创建表的sql语句 */ public static String buildCreateTableSql(Class> clazz) { StringBuilder sb = new StringBuilder(); Field[] fields = ReflectUtil.getDeclaredFields(clazz); if (fields == null || fields.length == 0) { throw new IllegalStateException("class'fields can not be empty"); } // 开头 sb.append("create table ") .append(TableUtil.getTableName(clazz)) // tableName .append("("); // 找到主键 Field idField = IDUtil.getIDField(fields); if (idField != null) { String idColumn = idField.getName(); ID id = idField.getAnnotation(ID.class); // 判断是有没有注解的 if (id != null && !"".equals(id.column())) { idColumn = id.column(); } DataType dataType = TableUtil.getDataType(idField.getType()); sb.append(idColumn) .append(" ") .append(dataType.toString()) .append(" primary key") .append(","); } for (Field field : fields) { if (Modifier.isStatic(field.getModifiers()) || Modifier.isFinal(field.getModifiers())) {// 移除是final和static的字段 continue; } // 让不是id的field进来 if (field != idField) { sb.append(field.getName()) .append(" ") .append(TableUtil.getDataType(field.getType())) .append(","); } } // 除去最后一个逗号 if (sb.charAt(sb.length() - 1) == ',') { sb.deleteCharAt(sb.length() - 1); } sb.append(")"); String sql = sb.toString(); // debug log DeBugLogger.d("CreateTableSql", sql); return sql; }
上面代码中用到了几个工具类: ReflectUtil:用于Java反射的工具类,将所有反射调用的方法都放到这里来,统一管理,方便优化处理; IDUtil:用于主键Field查找的工具类; TableUtil:用于数据库表字段数据与Java数据类型转换、表名生成等;
3.2 SQLiteDBExecutor:SQL语句执行器
该Class的主要作用是,用于执行SQL语句,或者通过SQLiteOpenHelper执行一些数据库操作,反正所有数据库操作都在这里面。
(1)数据库非查询操作
// SQLiteDBExecutor类 /** * 执行非查询操作事物 * * @param operation 非查询操作 */ public void executeTransaction(NoQueryOperation operation) throws Exception { SQLiteDatabase db = helper.getWritableDatabase(); try { db.beginTransaction(); DeBugLogger.d("NoQuery", "beginTransaction"); if (operation != null) { operation.onOperation(db); } db.setTransactionSuccessful(); DeBugLogger.d("NoQuery", "transactionSuccessful"); } finally { db.endTransaction(); DeBugLogger.d("NoQuery", "endTransaction"); } } public interface NoQueryOperation { void onOperation(SQLiteDatabase db) throws Exception; } /** * 执行SQL,非查询操作 * @param sql SQL语句 * @throws Exception */ public void execSQL(final String sql) throws Exception { executeTransaction(new NoQueryOperation() { @Override public void onOperation(SQLiteDatabase db) throws Exception { db.execSQL(sql); } }); }
(2)数据库查询操作
// SQLiteDBExecutor类 public Cursor rawQuery(String sql, String[] selectionArgs) { SQLiteDatabase db = helper.getReadableDatabase(); return db.rawQuery(sql, null); }
然后看一段比较好看的查询代码:
List
个人比较钟意这种构建器模式下的代码;看下查询代码,基于Builder模式的实现。
public class SelectBuilder
提供了类似写SQL查询语句的字符串构建器; 最后,执行查询;
public class SelectBuilder
PS:ObjectUtil用于通过Java反射实例化对象,然后对对象进行赋值;
3.3 LazyDB:ORM入口的主类
public final class LazyDB { /** * 阻止通过new来实例化LazyDB * 应该使用create方法来创建LazyDB */ private LazyDB() { } private SQLiteDBExecutor executor; /** * 创建默认配置的数据库 * * @param context 上下文 */ public static LazyDB create(Context context) {} ...... /** * 创建表 * * @param clazz 类 */ public void createTable(Class> clazz) throws Exception {} /** * 创建表 * * @param tableName 表名 * @param idColumn id * @param idDataType id的类型 * @param isAutoIncrement 是否自动增长 * @param columns 其他列名,不包括id */ public void createTable(String tableName, String idColumn, String idDataType, boolean isAutoIncrement, String... columns) throws Exception {} /** * 删除表 * * @param clazz 类 */ public void dropTable(final Class> clazz) throws Exception {} /** * 删除数据库中所有的表 */ public void dropAllTables() throws Exception {} /** * 查询所有表名 * * @return 所有表名的集合;若没有表,则是空集合 */ public List
4. Java反射优化方案
Java反射机制虽然好用,但是为此会牺牲性能,这里有个优化点,可以在取反射时,加一层内存缓存,先查缓存,找不到再取反射。
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~