android 自做一个简单的ORM数据库框架
来源:互联网 发布:税收数据 编辑:程序博客网 时间:2024/05/15 17:22
好久没用过数据库了, 今天突然来精神,花了近四个小时,研究了一下这玩意,在此记录成果
首先创建俩个注解类,表示id和数据库忽略字段
package com.yzx.frames.tool.db.annotation;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;@Target(value = ElementType.FIELD)@Retention(value = RetentionPolicy.RUNTIME)public @interface DBIgnore {}
package com.yzx.frames.tool.db.annotation;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;@Target(value = ElementType.FIELD)@Retention(value = RetentionPolicy.RUNTIME)public @interface ID {}
然后创建实体类的帮助方法类:
package com.yzx.frames.tool.db;import java.lang.reflect.Field;import java.util.HashMap;import java.util.Map;import com.yzx.frames.tool.db.annotation.DBIgnore;import com.yzx.frames.tool.db.annotation.ID;public class ClassHelper {/** * 判断实体类的注释是否正确 * * @param clz */public static void checkAnnotation(Class<?> clz) {int idCount = 0;int ignoreCount = 0;//Field[] fs = clz.getDeclaredFields();//if (fs.length < 1)throw new IllegalArgumentException("实体类没有属性");//for (Field f : fs) {f.setAccessible(true);if (f.getAnnotation(ID.class) != null) {if (f.getType() != Integer.class && f.getType() != String.class)throw new IllegalArgumentException("id只能是int 或 String");idCount++;}if (f.getAnnotation(DBIgnore.class) != null)ignoreCount++;}//if (idCount == 0)throw new IllegalArgumentException("实体类没有id");if (idCount > 1)throw new IllegalArgumentException("实体类id只能有一个");if (fs.length - ignoreCount < 1)throw new IllegalArgumentException("实体类无可用属性");}/** * 同步遍历回调实体类的属性Field * * @param clz * @param idCallback * 是id的时候回调 * @param colCallback * 普通字段回调 */public static void callUsefullFields(Class<?> clz, FieldCallback idCallback, FieldCallback colCallback) {Field[] fs = clz.getDeclaredFields();for (Field f : fs) {f.setAccessible(true);if (f.getAnnotation(DBIgnore.class) != null)continue;if (f.getAnnotation(ID.class) != null)idCallback.call(f);elsecolCallback.call(f);}}/** * 获取对象中 属性和值的映射map * * @param obj * @param containsNull * 是否包含值为null的字段 * @return */public static Map<String, Object> getFieldValueMap(final Object obj, final boolean containsNull) {final HashMap<String, Object> map = new HashMap<String, Object>();callUsefullFields(obj.getClass(), new FieldCallback() {// idpublic void call(Field f) {try {Object value = f.get(obj);if (!containsNull) {if (value != null)map.put(f.getName(), value);} elsemap.put(f.getName(), value);} catch (Exception e) {}}}, new FieldCallback() {// 普通public void call(Field f) {try {Object value = f.get(obj);if (!containsNull) {if (value != null)map.put(f.getName(), value);} elsemap.put(f.getName(), value);} catch (Exception e) {}}});return map;}/** * 获取对象主键的值 * * @return */public static String getPrimaryKeyValue(Object obj) {Field[] fs = obj.getClass().getDeclaredFields();for (Field f : fs) {f.setAccessible(true);if (f.getAnnotation(ID.class) != null)try {return f.get(obj).toString();} catch (Exception e) {}}return null;}}
创建回调接口
package com.yzx.frames.tool.db;import java.lang.reflect.Field;public interface FieldCallback {void call(Field f);}
然后创建sql语句帮助类
package com.yzx.frames.tool.db;import java.lang.reflect.Field;import com.yzx.frames.tool.db.annotation.ID;public class SqlGetter {/** * 创建表的sql * * @param clz * @return */public static String getCreateTable(Class<?> clz) {ClassHelper.checkAnnotation(clz);//String start = "CREATE TABLE IF NOT EXISTS " + getTableName(clz);//final StringBuffer sbb = new StringBuffer();ClassHelper.callUsefullFields(clz, new FieldCallback() {// idpublic void call(Field fi) {if (fi.getType() == Integer.class)sbb.append(fi.getName() + " INTEGER PRIMARY KEY AUTOINCREMENT,");else if (fi.getType() == String.class)sbb.append(fi.getName() + " TEXT PRIMARY KEY ,");}}, new FieldCallback() {// 普通public void call(Field fi) {sbb.append(fi.getName() + " TEXT,");}});sbb.deleteCharAt(sbb.length() - 1);//String sql = new StringBuffer().append(start).append(" (").append(sbb.toString()).append(")").toString();return sql;}/** * 获取 获取全部数据的 sql * * @param clz * @return */public static String getGetSql(Class<?> clz, String where) {return "SELECT * FROM " + getTableName(clz) + " WHERE " + where;}/** * 获取表名称 * * @param clz * @return */public static String getTableName(Class<?> clz) {return clz.getName().replaceAll("\\.", "_");}/** * 获取id属性名称 * * @param clz * @return 没有返回null */public static String getPrimaryKeyName(Class<?> clz) {Field[] fs = clz.getDeclaredFields();for (Field f : fs) {f.setAccessible(true);if (f.getAnnotation(ID.class) != null)return f.getName();}return null;}}
最后是主要的方法操作类
package com.yzx.frames.tool.db;import java.io.File;import java.lang.reflect.Field;import java.util.ArrayList;import java.util.List;import java.util.Map;import android.app.Application;import android.content.ContentValues;import android.database.Cursor;import android.database.sqlite.SQLiteDatabase;public class DBManager {private DBManager() {}private SQLiteDatabase db;public boolean save(Object obj) {Map<String, Object> map = ClassHelper.getFieldValueMap(obj, false);ContentValues cv = new ContentValues();for (Map.Entry<String, Object> en : map.entrySet())cv.put(en.getKey(), en.getValue().toString());long c = db.insert(SqlGetter.getTableName(obj.getClass()), null, cv);return c > 0;}public void save(List<Object> list) {db.beginTransaction();for (Object obj : list)save(obj);db.setTransactionSuccessful();}public boolean deleteById(Class<?> clz, String id) {String table = SqlGetter.getTableName(clz);String idName = SqlGetter.getPrimaryKeyName(clz);int c = db.delete(table, idName + " = '" + id + "'", null);return c > 0;}public boolean deleteByWhere(Class<?> clz, String where) {String table = SqlGetter.getTableName(clz);int c = db.delete(table, where, null);return c > 0;}public boolean update(Object obj, String idValue) {String tableName = SqlGetter.getTableName(obj.getClass());String idName = SqlGetter.getPrimaryKeyName(obj.getClass());Map<String, Object> map = ClassHelper.getFieldValueMap(obj, false);ContentValues cv = new ContentValues();for (Map.Entry<String, Object> en : map.entrySet())cv.put(en.getKey(), en.getValue().toString());int c = db.update(tableName, cv, idName + " = '" + idValue + "'", null);return c > 0;}public List<Object> getByWhere(Class<?> clz, String where) {final Cursor cur = db.rawQuery(SqlGetter.getGetSql(clz, where), null);ArrayList<Object> list = new ArrayList<Object>(0);if (cur != null && cur.getCount() > 0)while (cur.moveToNext()) {try {final Object ins = Class.forName(clz.getName()).newInstance();ClassHelper.callUsefullFields(ins.getClass(), new FieldCallback() {// idpublic void call(Field f) {setFieldValue(f, ins, cur.getString(cur.getColumnIndex(f.getName())));}}, new FieldCallback() {// 普通public void call(Field f) {setFieldValue(f, ins, cur.getString(cur.getColumnIndex(f.getName())));}});list.add(ins);} catch (Exception e) {}}closeCursor(cur);return list;}public List<Object> getAll(Class<?> clz) {return getByWhere(clz, "1 = 1");}public void close() {if (db != null)db.close();db = null;}//// ------------------------------------- priavte ↓-----------------------------------//private void setFieldValue(Field f, Object obj, Object value) {try {f.set(obj, value);} catch (Exception e) {}}private void closeCursor(Cursor c) {if (c != null)c.close();}//// ------------------------------------- static ↓ -------------------------------------//@SuppressWarnings("unused")private static Application context;private static File dbDir;/** * 初始化 * * @param context * @param dbDir * 存储数据库的文件夹路径 */public static void init(Application context, String dbDir) {DBManager.context = context;DBManager.dbDir = new File(dbDir);DBManager.dbDir.mkdirs();}/** * 打开数据库 * * @param dbName * 数据库名称 * @param clz * 对应的实体类的class * @return * */public static DBManager open(String dbName, Class<?> clz) {DBManager dbm = new DBManager();{SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(new File(dbDir, dbName + ".db"), null);db.execSQL(SqlGetter.getCreateTable(clz));dbm.db = db;}return dbm;}}
使用示例 :
首先在Application中写上:
DBManager.init(this, getFilesDir().getAbsolutePath());//第二个参数为数据库文件存储未知路径
Activity 中:
package com.yzx.frames.main;import java.util.List;import android.app.Activity;import android.os.Bundle;import android.widget.Toast;import com.yzx.frames.R;import com.yzx.frames.tool.db.DBManager;public class MainActivity extends Activity {private DBManager db;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);db = DBManager.open("test_db", Person.class);Person p = new Person();// 一个简单的实体类p.setAge("99");p.setName("yzx");p.setNumber("001");boolean b = db.save(p);Toast.makeText(this, b + "", Toast.LENGTH_SHORT).show();// true 表示存储成功 false 表示存储失败}@Overrideprotected void onDestroy() {super.onDestroy();if (db != null)db.close();}@Overridepublic void onBackPressed() {List<Object> list = db.getAll(Person.class);if (list.size() > 0)Toast.makeText(this, ((Person) (list.get(0))).getNumber() + "", Toast.LENGTH_SHORT).show();}}
Person实体类 :
package com.yzx.frames.main;import java.io.Serializable;import com.yzx.frames.tool.db.annotation.DBIgnore;import com.yzx.frames.tool.db.annotation.ID;public class Person implements Serializable {@DBIgnoreprivate static final long serialVersionUID = 4985156148924823533L;private String name;private String age;@IDprivate String number;public String getName() {return name;}public void setName(String name) {this.name = name;}public String getAge() {return age;}public void setAge(String age) {this.age = age;}public String getNumber() {return number;}public void setNumber(String number) {this.number = number;}}
没了
0 0
- android 自做一个简单的ORM数据库框架
- 一个简单的Android SQLite ORM框架
- android ORM数据库框架ActiveAndroid的简单使用
- Android 数据库ORM框架
- Android-数据库-ORM框架
- 简单实用的Android ORM框架TigerDB
- 简单实用的Android ORM框架TigerDB
- 简单实用的Android ORM框架TigerDB
- Android 的 数据库 ORM框架 DBExecutor
- ORM数据库简单的框架和黄油刀的使用
- Android ORM数据库框架对比
- android数据库ORM框架GreenDao
- Android 数据库ORM框架(一)
- Android数据库ORM框架-greenDAO
- 这是一个简单的ORM框架思路及雏形
- 使用元类编写一个简单的ORM框架
- android ORM框架的性能简单测试(androrm vs ormlite)
- Android ORM框架之-ActiveAndroid的简单分析
- R语言如何将读写大数据(RData) Large matrix table
- Holding Bin-Laden Captive!
- Objective-C Expected a type错误
- 导出EXCEL,PDF 方法简单明了
- WCF REST 工作总结(一)
- android 自做一个简单的ORM数据库框架
- bootstrap(选项卡、提示框和弹出框)
- Java中对文件的信息的读出,输出在控制台上
- 结合java讲sql server存储过程
- 如何在SpringMVC中获取request对象
- printf()参数传递
- ajax
- 树状数组(木有看到图)
- Dungeon Game