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