How to Implement Attribute Dynamic Injection Elegantly

Keywords: Java Database Attribute Mybatis Mobile

Preface

This is a problem encountered in practical development projects. A collection of List < Map < String, Object > returned from a database query. And the column names returned are Chinese, and the project does not use jdbcTemplate directly used by mybatis. And the fields are super many, so when data conversion, if one by one injection will make the code stinky, so there is dynamic injection.
I posted the whole idea here.

Instance class Entry

Let's first build an entry class. Used for object storage.
I create a BaseDateBean class here

@Setter
@Getter
public class BaseDateBean {

    private String  startTime;
    private String  operator;
    private String  code;
    private String  testNumber;
    private String  iphoneCardCode;
    private String  sampleNumber;
    private String  sampleTime;
    private String  callNumber;
    private String  callStatus;
    private String  downInstantaneousSpeedCard;
    private String  upInstantaneousSpeedCard;
    private String  ssid;
    private String  bssid;
    private String  encryptType;
    private String  intranetIp;
    private String  externalIp;
    private String  rssi;
    private String  WIFIFrequency;
    private String  WIFIChannel;
    private String  baiduLongitude;
    private String  baiduLatitude;
    private String  originalLongitude;
    private String  originalLatitude;
    private String  positioningPrecision;
    private String  positioningType;
    private String  businessType;
    private String  networkType;
    private String  speedType;
    private String  tac;
    private String  eci;
    private String  mnc;
    private String  mcc;
    private String  rsrq;
    private String  earfcnDl;
    private String  earfcnUl;
    private String  frequencyDl;
    private String  band;
    private String  sinr;
    private String  cdmaRxlev;
    private String  evdoRxlev;
    private String  earfcn;
    private String  psc;
    private String  uarfcn;
    private String  rscp;
    private String  rsrp;
    private String  imsi;
    private String  imei;
    private String  lac;
    private String  ci;
    private String  signalStrength;
    private String  snr;
    private String  pci;
    private String  nid;
    private String  bid;
    private String  sid;
    private String  cdmaDbm;
    private String  cdmaEcio;
    private String  evdoDbm;
    private String  evdoEcio;
    private String  evdoSnr;
    private String  arfcn;
    private String  frequencyUl;
    private String  bsic;
    private String  rxlev;
    private String  averageSpeed;
    private String  updatedLongitude;
    private String  updatedLatitude;
    private String  averageUpstreamRate;
    private String  averageDownstreamRate;
}

As you can see, there are still many attributes in the actual project. I'm only in the first edition, so if one set injection is very low.

Create map mapping

After creating the entity class, we also need to create a static map set, which corresponds the column names of the database to the attribute names of our entity class one by one. The set of maps created here is my personal folly. It's the first thing to do without thinking of a better way.
Let's create a BaseDataMap class

public  class BaseDataMap{
    private BaseDataMap(){}
    public static final Map<String,String> cnEnMap=new HashMap<>();
    static{
        cnEnMap.put("Test start time","startTime");
        cnEnMap.put("Operator","operator");
        cnEnMap.put("number","code");
        cnEnMap.put("Test number","testNumber");
        cnEnMap.put("Mobile Card Number","iphoneCardCode");
        cnEnMap.put("Sampling number","sampleNumber");
        cnEnMap.put("Sampling time","sampleTime");
        cnEnMap.put("Call number","callNumber");
        cnEnMap.put("Call state","callStatus");
        cnEnMap.put("Downward instantaneous velocity","downInstantaneousSpeedCard");
        cnEnMap.put("Upward instantaneous velocity","upInstantaneousSpeedCard");
        cnEnMap.put("SSID","ssid");
        cnEnMap.put("BSSID","bssid");
        cnEnMap.put("Encryption type","encryptType");
        cnEnMap.put("Intranet IP","intranetIp");
        cnEnMap.put("Extranet IP","externalIp");
        cnEnMap.put("RSSI","rssi");
        cnEnMap.put("WIFI frequency","WIFIFrequency");
        cnEnMap.put("WIFI channel","WIFIChannel");
        cnEnMap.put("Baidu longitude","baiduLongitude");
        cnEnMap.put("Baidu latitude","baiduLatitude");
        cnEnMap.put("Original longitude","originalLongitude");
        cnEnMap.put("Primitive latitude","originalLatitude");
        cnEnMap.put("positioning accuracy","positioningPrecision");
        cnEnMap.put("Location type","positioningType");
        cnEnMap.put("Data Business Type","businessType");
        cnEnMap.put("Network type","networkType");
        cnEnMap.put("Speed type","speedType");
        cnEnMap.put("TAC","tac");
        cnEnMap.put("ECI","eci");
        cnEnMap.put("MNC","mnc");
        cnEnMap.put("MCC","mcc");
        cnEnMap.put("RSRQ","rsrq");
        cnEnMap.put("EARFCN DL","earfcnDl");
        cnEnMap.put("EARFCN UL","earfcnUl");
        cnEnMap.put("FREQUENCY DL","frequencyDl");
        cnEnMap.put("BAND","band");
        cnEnMap.put("SINR","sinr");
        cnEnMap.put("CDMA RXLEV","cdmaRxlev");
        cnEnMap.put("EVDO RXLEV","evdoRxlev");
        cnEnMap.put("EARFCN","earfcn");
        cnEnMap.put("PSC","psc");
        cnEnMap.put("UARFCN","uarfcn");
        cnEnMap.put("RSCP","rscp");
        cnEnMap.put("RSRP","rsrp");
        cnEnMap.put("IMSI","imsi");
        cnEnMap.put("IMEI","imei");
        cnEnMap.put("LAC","lac");
        cnEnMap.put("CI","ci");
        cnEnMap.put("signal intensity","signalStrength");
        cnEnMap.put("SNR","snr");
        cnEnMap.put("PCI","pci");
        cnEnMap.put("NID","nid");
        cnEnMap.put("BID","bid");
        cnEnMap.put("SID","sid");
        cnEnMap.put("CDMA DBM","cdmaDbm");
        cnEnMap.put("CDMA ECIO","cdmaEcio");
        cnEnMap.put("EVDO DBM","evdoDbm");
        cnEnMap.put("EVDO ECIO","evdoEcio");
        cnEnMap.put("EVDO SNR","evdoSnr");
        cnEnMap.put("ARFCN","arfcn");
        cnEnMap.put("FREQUENCY UL","frequencyUl");
        cnEnMap.put("BSIC","bsic");
        cnEnMap.put("RXLEV","rxlev");
        cnEnMap.put("rate","averageSpeed");
        cnEnMap.put("Corrected Posterior Longitude","updatedLongitude");
        cnEnMap.put("Corrected Latitude","updatedLatitude");
        cnEnMap.put("Uplink average rate","averageUpstreamRate");
        cnEnMap.put("Downlink average rate","averageDownstreamRate");
    }
}

You can see that it's a dynamic map.

Mapping class

Next is the core code. Let's create a ReflectHelper class

@Slf4j
public class ReflectHelper {

    private Class cls;
    /**
     * Pass-on object
     */
    private Object obj;
    private Hashtable<String, Method> getMethods = null;
    private Hashtable<String, Method> setMethods = null;
    public ReflectHelper(Object o) {
        obj = o;
        initMethods();
    }
    public void initMethods() {
        getMethods = new Hashtable<>();
        setMethods = new Hashtable<>();
        cls = obj.getClass();
        Method[] methods = cls.getMethods();
        // Define regular expressions and filter getter / setter functions from methods.
        String gs = "get(\\w+)";
        Pattern getM = Pattern.compile(gs);
        String ss = "set(\\w+)";
        Pattern setM = Pattern.compile(ss);
        // Remove "set" or "get" from the method, $1 matches the first
        String rapl = "$1";
        String param;
        for (int i = 0; i < methods.length; ++i) {
            Method m = methods[i];
            String methodName = m.getName();
            if (Pattern.matches(gs, methodName)) {
                param = getM.matcher(methodName).replaceAll(rapl).toLowerCase();
                getMethods.put(param, m);
            } else if (Pattern.matches(ss, methodName)) {
                param = setM.matcher(methodName).replaceAll(rapl).toLowerCase();
                setMethods.put(param, m);
            }
        }
    }
    public boolean setMethodValue(String property,Object object) {
        Method m = setMethods.get(property.toLowerCase());
        if (m != null) {
            try {
                // Calling the setter function of the target class
                m.invoke(obj, object);
                return true;
            } catch (Exception ex) {
                ex.printStackTrace();
                return false;
            }
        }
        return false;
    }
}

As you can see from the above code, there are actually two methods, setMethodValue and initMethods.
The initMethods method is executed when instantiating the ReflectHelper class. The main task is to find the get and set methods that we need to dynamically inject the instance class. The setMethodValue method assigns values to this property.
# Implementation Method
Now the preparatory work is ready, how to use it?
private List<BaseDateBean> getBaseDateBean(List<Map<String, Object>> mapList){ List<BaseDateBean> list=new ArrayList<>(); if(mapList==null||mapList.isEmpty()){ return list; } BaseDateBean baseDateBean; for(Map<String, Object> map:mapList){ baseDateBean=new BaseDateBean(); for(Map.Entry<String, Object> entry : map.entrySet()){ String mapKey = entry.getKey(); log.info(mapKey); ReflectHelper reflectHelper = new ReflectHelper(baseDateBean); log.info(BaseDataMap.cnEnMap.get(mapKey)); String value=entry.getValue()==null?ConstantPool.SEPARATORNULL:entry.getValue().toString(); log.info(value); if(entry.getValue()!=null){ reflectHelper.setMethodValue(BaseDataMap.cnEnMap.get(mapKey),String.valueOf(entry.getValue())); } } list.add(baseDateBean); } return list; }
Traversing the map in the list set, the attribute values are dynamically injected into the entity class.

In the extreme
I am here for my business development and design ideas, for your reference.

Welcome to pay attention to the personal public number "programmers love yogurt"

Share various learning materials, including java, linux, big data, etc. The information includes video documents and source code, and shares my own and high-quality technical blog posts.

If you like to remember to pay attention to and share yo

Posted by harman on Sun, 29 Sep 2019 02:44:17 -0700