通过注解获取Ormlite数据库主键

前言

工作的时候,有线上问题反馈有很少量数据库问题,而且不好解决,后面发现是在封装数据库的时候出了问题。先解释下问题,然后再解决。

数据库封装中的问题

private int updateIfValueNotNull(T t) {
        int result = 0;
        UpdateBuilder updateBuilder = this.ormLiteDao.updateBuilder();
        Map<String, Object> map = this.getFieldsIfValueNotNull(t);
        if(map.isEmpty()) {
            LogUtil.w("all field value is null.");
            return 0;
        } else if(map.get("id") == null) {
            return 0;
        } else {
            try {
                updateBuilder.where().idEq(map.get("id"));
                Iterator var5 = map.entrySet().iterator();

                while(var5.hasNext()) {
                    Entry<String, Object> entry = (Entry)var5.next();
                    if(!((String)entry.getKey()).equals("id")) {
                        updateBuilder.updateColumnValue((String)entry.getKey(), entry.getValue());
                    }
                }

                result = updateBuilder.update();
            } catch (SQLException var7) {
                LogUtil.e(var7);
            } catch (java.sql.SQLException var8) {
                LogUtil.e(var8);
            }

            return result;
        }
    }

这里封装存在两个问题:

1、数据库bean当中,可能有些字段属性并不一定是和数据库对应。

private Map<String, Object> getFieldsIfValueNotNull(Object obj) {
        Map<String, Object> map = new HashMap<>();
        Field[] fields = obj.getClass().getDeclaredFields();
        for (Field field : fields) {
            LogUtil.d("getFieldsIfValueNotNull + " + field.getName());
            field.setAccessible(true);
            Object valueObj = null;
            try {
                valueObj = field.get(obj);
            } catch (IllegalAccessException e) {
                LogUtil.e(TAG, e);
            }
            if (valueObj != null) {
                map.put(field.getName(), valueObj);
            }
        }
        return map;
    }

使用上面的方法去全匹配字段,如果映射数据库表的Bean中包含某个字段 int age 但是 age字段并没有数据库注解,没有映射到数据表的时候,那么我们在进行更新操作的时候,会去全匹配,当匹配到age的时候就会出错。因为数据库表中并无该属性。

2、我们可以看到代码中去匹配主键时候,全部是写死的id,这样的话当某些表的主键字段并不是id的时候就会出错。

解决办法:

对于第一个问题,我们在进行更新操作的时候,并不要去全匹配,而是只匹配数据库对应的bean中加了DatabaseField注解的字段。代码如下:

public static void showAnnotationWrodOther(Object object){
        Field[] fields =  object.getClass().getDeclaredFields();
        for(Field field : fields){
            boolean fieldHasAnno = field.isAnnotationPresent(DatabaseField.class);
            //是否有DatabaseField注解
            if(fieldHasAnno) {
                DatabaseField fieldAnno = field.getAnnotation(DatabaseField.class);
                //这里可以输出注解的属性
                boolean b = fieldAnno.generatedId();
                System.out.println(field.getName() + ",isgeneratedId = " + b);
            }
        }
    }

上面的方法就可以筛选出有注解的字段,并对其进行操作。

对于第二个问题,我们就需要一个拿到主键的方法,然后再去匹配。方法如下:

//获取数据库表封装的bean的主键
    private String getDbPrimarykey(Object obj) {
        Field[] fields = obj.getClass().getDeclaredFields();
        String primaryKey = "";
        for (Field field : fields) {
            String name = field.getName();
            //1、获取属性上的指定类型的注解
            Annotation annotation = field.getAnnotation(DatabaseField.class);
            if (null != annotation) {
                DatabaseField databaseField = (DatabaseField) annotation;
                //通过注解判断是否是主键
                if (databaseField.generatedId() || databaseField.id() || !TextUtils.isEmpty(databaseField.generatedIdSequence())) {
                    primaryKey = name;
                    break;
                }
            }
        }
        return primaryKey;
    }

小节:

本文为自己工作中发现的问题,并作出些许优化,如果存在问题,欢迎大家不佞指出。谢谢,希望大家一起进步

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值