加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

Sqlite 反射机制封装数据库

发布时间:2020-12-12 19:59:36 所属栏目:百科 来源:网络整理
导读:public class SqliteDAO{ static final String tag="DAO"; /** * 访问的数据库 */ private SQLiteDatabase db; /** * 数据库打开辅助类 */ private static PADoctorSQLiteHelper paDoctorSQLiteHelper; private static long curUserId; /** * 数据插入冲突处
public class SqliteDAO{
    static final String tag="DAO";

    /**
     * 访问的数据库
     */
    private SQLiteDatabase db;

    /**
     * 数据库打开辅助类
     */
    private static PADoctorSQLiteHelper paDoctorSQLiteHelper;
    private static long curUserId;

    /**
     * 数据插入冲突处理方式:
     * 0-忽略
     * 1-抛出异常
     * 2-替换数据
     */
    private int conflictType = 2;

    public SqliteDAO(Context c,long userId){
        if (paDoctorSQLiteHelper == null || userId != curUserId) {
            curUserId = userId;
            String prefix = "";
            try {
                prefix = c.getExternalFilesDir(null).getAbsolutePath() + "/";
            } catch (Exception e) {
                prefix = "";
            }
            paDoctorSQLiteHelper = new PADoctorSQLiteHelper(c,prefix+"u"+curUserId+".msg",null,1);
        }
        db = paDoctorSQLiteHelper.getWritableDatabase();
    }

    public void close() {
        //db.close();
    }

    public SQLiteDatabase getSQLiteDatabase(){
        return db;
    }

    /**
     * 插入对象到数据库,存储对象的所有字段到数据库的对应字段,包括NULL字段.
     * @param entity  待插入的对象
     * @return 如果插入数据库成功则返回该对象,否则返回NULL
     */
    public <T> T insert(T entity){
        return insert(entity,false);
    }

    /**
     * 插入对象到数据库,仅存储对象的非空字段到数据库,对象的NULL字段将被忽略.
     * @param entity 待插入的对象
     * @return 如果插入数据库成功则返回该对象,否则返回NULL
     */
    public <T> T insertSelective(T entity){
        return insert(entity,true);
    }

    private <T> T insert(T entity,boolean selective){
        ContentValues values=getContentValues(entity,selective);

//        T exist_obj=this.loadByPrimaryKey(entity);
//        if(exist_obj!=null){
//            return exist_obj;
//        }

        long r;
        if(conflictType == 2){
            r = db.replace(getTableName(entity),values);
        }else{
            r = db.insert(getTableName(entity),values);
        }

        if(r >= 0){
            return entity;
        }

        return null;
    }

    /**
     * 根据主键删除数据
     * @param entity 待删除的对象,主键只必须设置.
     * @return
     */
    public <T> int delete(T entity){
        Object[] args=getPrimarySelectionAndArgs(entity);
        return db.delete(getTableName(entity),(String)args[0],(String[])args[1]);
    }

    /**
     *
     * @param entity
     * @param whereClause
     * @param whereArgs
     * @return the number of rows affected if a whereClause is passed in,0 otherwise.
     * To remove all rows and get a count pass "1" as the whereClause.
     */
    public <T> int deleteByWhereClause(T entity,String whereClause,String[] whereArgs) {
        return db.delete(getTableName(entity),whereClause,whereArgs);
    }

    /**
     * 根据主键从数据库载入一条记录到对象
     * @param entity 数据实体(必须初始化主键字段)
     * @return 成功则返回的该数据库实体,失败则返回NULL
     */
    public <T> T loadByPrimaryKey(T entity){
        Object[] args=getPrimarySelectionAndArgs(entity);
        Cursor cursor=db.query(getTableName(entity),(String[])args[1],null);
        try{
            if(cursor.moveToNext()){
                T db_entity=getEntity(cursor,entity);
                return db_entity;
            }else{
                return null;
            }
        }finally{
            cursor.close();
        }
    }

    @SuppressWarnings("unchecked")
    public <T> List<T> query(T entity,String[] columns,String selection,String[] selectionArgs,String groupBy,String having,String orderBy,String limit){
        List<T> entities = new ArrayList<T>();
        Cursor cursor = db.query(getTableName(entity),columns,selection,selectionArgs,groupBy,having,orderBy,limit);
        try{
            if(cursor!=null && cursor.moveToFirst()){
                T obj=(T)entity.getClass().newInstance();
                getEntity(cursor,obj);
                entities.add(obj);
                while(cursor.moveToNext()) {
                    obj=(T)entity.getClass().newInstance();
                    getEntity(cursor,obj);
                    entities.add(obj);
                }
            }
            return entities;
        }catch(Exception e){
            Log.e(tag,""+e,e);
            return entities;
        }finally{
            cursor.close();
        }
    }

    @SuppressWarnings("unchecked")
     public <T> List<T> loadAll(T entity,String limit){
        List<T> entities=new ArrayList<T>();

        Cursor cursor=db.query(getTableName(entity),e);
            return entities;
        }finally{
            cursor.close();
        }
    }

    /**
     * 更新数据库实体,更新对象的所有字段到数据库的对应字段,包括NULL字段.
     * @param entity 待更新的对象(必须包含主键)
     * @return 成功更新的记录数
     */
    public int updateByPrimaryKey(Object entity){
        return updateByPrimaryKey(entity,false);
    }

    /**
     * 更新数据库实体,仅更新对象的非空字段到数据库的对应字段,对象的NULL字段将被忽略.
     * @param entity 待更新的对象(必须包含主键)
     * @return 成功更新的记录数
     */
    public int updateByPrimaryKeySelective(Object entity){
        return updateByPrimaryKey(entity,true);
    }

    private int updateByPrimaryKey(Object entity,selective);
        Object[] args=getPrimarySelectionAndArgs(entity);

        int r=db.update(getTableName(entity),values,(String[])args[1]);

        return r;
    }

    /**
     * 从对象中解析出主键字段,以及主键字段对应的值
     * @param entity
     * @return
     */
    private Object[] getPrimarySelectionAndArgs(Object entity){
        Object[] ret=new Object[2];
        String selection=null;
        List<String> args=new ArrayList<String>();
        try{
            Class<?> entity_class=entity.getClass();
            Field[] fs=entity_class.getDeclaredFields();
            for(Field f:fs){
                if(isPrimaryKey(f)){
                    Method get=getGetMethod(entity_class,f);
                    if(get!=null){
                        Object o=get.invoke(entity);
                        String value=null;
                        if(o!=null){
                            value=o.toString();
                            if(selection==null){
                                selection=f.getName()+"=?";
                            }else{
                                selection+=" AND "+f.getName()+"=?";
                            }

                            args.add(value);

                        }else{
                            throw new RuntimeException("Primary key: "+f.getName()+" must not be null");
                        }
                    }
                }
            }
            if(selection==null){
                throw new RuntimeException("Primary key not found!");
            }

            ret[0]=selection;
            ret[1]=args.toArray(new String[args.size()]);
            return ret;
        }catch(Exception e){
            throw new RuntimeException(e.getMessage(),e);
        }
    }

    /**
     * 将对象转换为ContentValues
     * @param entity
     * @param selective
     * @return
     */
    private ContentValues getContentValues(Object entity,boolean selective){
        ContentValues values=new ContentValues();
        try{
            Class<?> entity_class=entity.getClass();
            Field[] fs=entity_class.getDeclaredFields();
            for(Field f:fs){
                if(isTransient(f)==false){
                    Method get=getGetMethod(entity_class,f);
                    if(get!=null){
                        Object o=get.invoke(entity);
                        if(!selective || (selective && o!=null)){
                            String name=f.getName();
                            Class<?> type=f.getType();
                            if(type==String.class){
                                values.put(name,(String)o);
                            }else if(type==int.class || type==Integer.class){
                                values.put(name,(Integer)o);
                            }else if(type==float.class || type==Float.class){
                                values.put(name,(Float)o);
                            }else if(type==long.class || type==Long.class){
                                values.put(name,(Long)o);
                            }else if(type==Date.class){
                                values.put(name,datetimeToString((Date)o));
                            }else{
                                values.put(name,o.toString());
                            }
                        }
                    }
                }
            }
            return values;
        }catch(Exception e){
            throw new RuntimeException(e.getMessage(),e);
        }
    }

    /**
     * 将数据库记录转换为对象
     *
     * @param cursor
     * @param entity
     * @return
     */
    private <T> T getEntity(Cursor cursor,T entity){
        try{
            Class<?> entity_class=entity.getClass();

            Field[] fs=entity_class.getDeclaredFields();
            for(Field f:fs){
                int index=cursor.getColumnIndex(f.getName());
                if(index>=0){
                    Method set=getSetMethod(entity_class,f);
                    if(set!=null){
                        String value=cursor.getString(index);
                        if(cursor.isNull(index)){
                            value=null;
                        }
                        Class<?> type=f.getType();
                        if(type==String.class){
                            set.invoke(entity,value);
                        }else if(type==int.class || type==Integer.class){
                            set.invoke(entity,value==null?(Integer)null:Integer.parseInt(value));
                        }else if(type==float.class || type==Float.class){
                            set.invoke(entity,value==null?(Float)null:Float.parseFloat(value));
                        }else if(type==long.class || type==Long.class){
                            set.invoke(entity,value==null?(Long)null:Long.parseLong(value));
                        }else if(type==Date.class){
                            set.invoke(entity,value==null?(Date)null:stringToDateTime(value));
                        }else{
                            set.invoke(entity,value);
                        }
                    }
                }
            }
            return entity;
        }catch(Exception e){
            throw new RuntimeException(e.getMessage(),e);
        }
    }

    private String datetimeToString(Date d){
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        if(d!=null){
            return sdf.format(d);
        }
        return null;
    }

    private Date stringToDateTime(String s){
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        if(s!=null){
            try {
                return sdf.parse(s);
            } catch (ParseException e) {
                Log.e(tag,"解析时间错误: "+s,e);
            }
        }
        return null;
    }

    private Method getGetMethod(Class<?> entity_class,Field f){
        String fn=f.getName();
        String mn="get"+fn.substring(0,1).toUpperCase()+fn.substring(1);
        try{
            return entity_class.getDeclaredMethod(mn);
        }catch(NoSuchMethodException e){
            Log.w(tag,"Method: "+mn+" not found.");

            return null;
        }
    }

    private Method getSetMethod(Class<?> entity_class,Field f){
        String fn=f.getName();
        String mn="set"+fn.substring(0,1).toUpperCase()+fn.substring(1);
        try{
            return entity_class.getDeclaredMethod(mn,f.getType());
        }catch(NoSuchMethodException e){
            Log.w(tag,"Method: "+mn+" not found.");

            return null;
        }
    }

    /**
     * 检查是否为主键字段
     */
    private boolean isPrimaryKey(Field f){
        Annotation an=f.getAnnotation(Id.class);
        if(an!=null){
            return true;
        }
        return false;
    }

    private boolean isTransient(Field f){
        Annotation an=f.getAnnotation(Transient.class);
        if(an!=null){
            return true;
        }
        return false;
    }

    private String getTableName(Object entity){
        Table table=entity.getClass().getAnnotation(Table.class);
        String name= table.name();
        return name;
    }

    public int getConflictType() {
        return conflictType;
    }

    public void setConflictType(int conflictType) {
        this.conflictType = conflictType;
    }

}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读