這是在實際開發項目中遇到的一個問題。從數據庫查詢返回的 List< Map< String, Object>> 的集合。而且返回的列名是中文的,項目也沒有使用mybatis 直接使用的jdbcTemplate. 而且字段還超級多,這樣將數據轉換的時候若是一個一個的注入就會讓代碼臭長臭長的,因此纔有了動態注入。我這裏我整個思路都貼出來。java
咱們先建一個entry類。用於對象存儲。我這裏 建立一個BaseDateBean 的類linux
@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;
}複製代碼
能夠看到在實際項目中屬性仍是不少的,我這個還只是第一版的,因此若是一個一個的set注入就很low了。git
在建立好實體類後,還得建立一個靜態的map 集合,將數據庫的列名和咱們實體類的屬性名作一個一一對應。這裏建立的這個map 集合是我我的愚見。沒有想到更好的辦法就先這樣處理的。咱們建立一個BaseDataMap類程序員
public class BaseDataMap{
private BaseDataMap(){}
public static final Map<String,String> cnEnMap=new HashMap<>();
static{
cnEnMap.put("測試開始時間","startTime");
cnEnMap.put("運營商","operator");
cnEnMap.put("編號","code");
cnEnMap.put("測試編號","testNumber");
cnEnMap.put("手機卡編號","iphoneCardCode");
cnEnMap.put("採樣編號","sampleNumber");
cnEnMap.put("採樣時間","sampleTime");
cnEnMap.put("呼叫編號","callNumber");
cnEnMap.put("呼叫狀態","callStatus");
cnEnMap.put("下行瞬時速度","downInstantaneousSpeedCard");
cnEnMap.put("上行瞬時速度","upInstantaneousSpeedCard");
cnEnMap.put("SSID","ssid");
cnEnMap.put("BSSID","bssid");
cnEnMap.put("加密類型","encryptType");
cnEnMap.put("內網IP","intranetIp");
cnEnMap.put("外網IP","externalIp");
cnEnMap.put("RSSI","rssi");
cnEnMap.put("WIFI頻率","WIFIFrequency");
cnEnMap.put("WIFI信道","WIFIChannel");
cnEnMap.put("百度經度","baiduLongitude");
cnEnMap.put("百度緯度","baiduLatitude");
cnEnMap.put("原始經度","originalLongitude");
cnEnMap.put("原始緯度","originalLatitude");
cnEnMap.put("定位精度","positioningPrecision");
cnEnMap.put("定位類型","positioningType");
cnEnMap.put("數據業務類型","businessType");
cnEnMap.put("網絡類型","networkType");
cnEnMap.put("速度類型","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("信號強度","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("速率","averageSpeed");
cnEnMap.put("更正後經度","updatedLongitude");
cnEnMap.put("更正後緯度","updatedLatitude");
cnEnMap.put("上行平均速率","averageUpstreamRate");
cnEnMap.put("下行平均速率","averageDownstreamRate");
}
}複製代碼
能夠看到就是一個動態的map。正則表達式
接下來就是核心代碼啦。咱們建立一個ReflectHelper類數據庫
@Slf4j
public class ReflectHelper {
private Class cls;
/**
* 傳過來的對象
*/
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();
// 定義正則表達式,從方法中過濾出getter / setter 函數.
String gs = "get(\\w+)";
Pattern getM = Pattern.compile(gs);
String ss = "set(\\w+)";
Pattern setM = Pattern.compile(ss);
// 把方法中的"set" 或者 "get" 去掉,$1匹配第一個
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 {
// 調用目標類的setter函數
m.invoke(obj, object);
return true;
} catch (Exception ex) {
ex.printStackTrace();
return false;
}
}
return false;
}
}複製代碼
上面代碼能夠看到其實也就兩個方法setMethodValue 和initMethods 。initMethods 方法是在實例化 ReflectHelper 這個類的時候執行的,主要的工做就是找到咱們須要動態注入實例類的get 和set 方法。而setMethodValue 方法就是給這個屬性賦值的。網絡
如今準備工做作好了,怎麼使用呢?mybatis
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;
}複製代碼
遍歷list 集合中的map,動態的將屬性值注入到實體類中。iphone
我這裏是適合我業務開發設計的思路,給你們借鑑參考。函數
歡迎你們關注我的公衆號 "程序員愛酸奶"
分享各類學習資料,包含java,linux,大數據等。資料包含視頻文檔以及源碼,同時分享本人及投遞的優質技術博文。
若是你們喜歡記得關注和分享喲❤