1. 程式人生 > >jdbc如何優雅的解決字典表數據轉化

jdbc如何優雅的解決字典表數據轉化

rest 裏的 用戶 參數 osc prope iter restrict 入參

我們在做數據庫設計的時候肯定會用字典表或者說枚舉表等固化數據,那麽當查詢數據的時候用到了這些字典值的時候我們會怎麽做呢。以下舉個栗子吧,不對應該是好幾個栗子

字典表(PUB_RESTRICTION)
SERIAL_NO DESC_ID DESC_CHINA KEYWORD
67550001 1 城區 AREA_TYPE
67550002 2 郊區 AREA_TYPE
67550003 3 縣城 AREA_TYPE
67550004 4 鄉鎮 AREA_TYPE
用戶表(MANA_USER)
USER_ID USER_NAME USER_SEX AREA_TYPE USER_STATE
1 張三 67550001 正常
2 李四 67550002 正常
3 王五 未知 67550001 凍結
4 黃六 67550004 未審核

剛畢業的Egan接到老大的需求,把用戶數據展示在頁面上,‘AREA_TYPE’字段從字典表裏面取出. Egan說到:這個簡單,兩張表關聯查詢一下。

然後Egan就吧啦吧啦的寫起了代碼….

SELECT
  mu.USER_ID,
  mu.USER_NAME,
  mu.USER_SEX,
  pr.DESC_CHINA AREA_TYPE,
  mu.USER_STATE
FROM MANA_USER mu LEFT JOIN PUB_RESTRICTION pr ON mu.AREA_TYPE = pr.SERIAL_NO
WHERE pr.KEYWORD=‘AREA_TYPE‘

就這樣超快速的寫完了,真的好簡單啊,有什麽難的,去老大那邊炫耀一下我的效率:老大寫完了,這樣是不是你要的效果

USER_ID USER_NAME USER_SEX AREA_TYPE USER_STATE
1 張三 城區 正常
2 李四 郊區 正常
3 王五 未知 城區 凍結
4 黃六 鄉鎮 未審核

“嗯嗯,小夥子不錯不錯”。老大回答到。“等等,你看性別還有狀態直接放字符串不好吧,也改成字典數據吧”。

Egan答到:“這樣也不難,我在關聯下就好了”,然後Egan又開始嗒嗒嗒的開始了。

字典表增加性別還有狀態的字典數據

SERIAL_NO DESC_ID DESC_CHINA KEYWORD
67550001 1 城區 AREA_TYPE
67550002 2 郊區 AREA_TYPE
67550003 3 縣城 AREA_TYPE
67550004 4 鄉鎮 AREA_TYPE
67510001 1 USER_SEX
67510002 2 USER_SEX
67510003 3 未知 USER_SEX
67520001 1 正常 USER_STATE
67520002 2 凍結 USER_STATE
67520003 3 未審核 USER_STATE
用戶表修改數據
USER_ID USER_NAME USER_AGE AREA_TYPE USER_STATE
1 張三 67510001 67550001 67520001
2 李四 67510002 67550002 67520001
3 王五 67510003 67550001 67520002
4 黃六 67510001 67550004 67520003
修改sql
SELECT
  mu.USER_ID,
  mu.USER_NAME,
  pr2.DESC_CHINA USER_SEX,
  pr.DESC_CHINA  AREA_TYPE,
  pr2.DESC_CHINA USER_STATE
FROM MANA_USER mu LEFT JOIN PUB_RESTRICTION pr ON mu.AREA_TYPE = pr.SERIAL_NO
  LEFT JOIN PUB_RESTRICTION pr1 ON mu.USER_SEX = pr1.SERIAL_NO
  LEFT JOIN PUB_RESTRICTION pr2 ON mu.USER_STATE = pr2.SERIAL_NO
WHERE pr.KEYWORD = ‘AREA_TYPE‘ AND pr1.KEYWORD = ‘USER_SEX‘ AND pr2.KEYWORD = ‘USER_STATE‘

就這樣寫好了,Egan看著自己寫的代碼有點煩的說到,這樣子有點難看。咚咚咚的跑去問老大:“老大,這樣寫表關聯太多了,重復的關聯那張表,好臃腫的樣子,有沒有什麽比較好的方式” “是有點,有點臃腫,讓我想想”,一會兒老大答到:“你用函數吧,寫一個函數通過字典值去取”.

然後Egan就回去寫寫起了函數

CREATE FUNCTION "GET_DESC_CHINA"(IN_SERIAL_NO NUMBER, IN_KEYWORD VARCHAR(32))
  RETURN VARCHAR
IS
  OUT_DESC_CHINA VARCHAR(40);
  BEGIN
    IF IN_SERIAL_NO IS NOT NULL
    THEN
      SELECT DESC_CHINA
      INTO OUT_DESC_CHINA
      FROM PUB_RESTRICTION
      WHERE SERIAL_NO = IN_SERIAL_NO AND KEYWORD = IN_KEYWORD;
      RETURN OUT_DESC_CHINA;
    ELSE
      RETURN ‘‘;
    END IF;
  END;

修改sql

SELECT
  mu.USER_ID,
  mu.USER_NAME,
  GET_DESC_CHINA(mu.USER_SEX,‘USER_SEX‘) USER_SEX,
  GET_DESC_CHINA(mu.AREA_TYPE,‘AREA_TYPE‘) AREA_TYPE,
  GET_DESC_CHINA(mu.USER_STATE,‘USER_STATE‘) USER_STATE
FROM MANA_USER mu

噎,看起來舒服多了。


日積月累之後,數據量增長上去,某一天Egan接到一個奇葩的需求:需要根據查詢條件導出對應的用戶數據。由於導出的數據量有點大效率有點慢下來了.

Egan有點摸不著頭腦了,找到老大說:“這樣用函數的形式數據量一大起來發現比我不轉化直接導出id來說慢了好多好多。函數這樣寫,每一行都會去字典表查詢一遍,好慢好慢,慢到要哭了(┬_┬)”

老大說到字典的數據量不大也比較固化,要不你把字典數據放到內存裏面吧。然後在程序裏面匹配吧。

Egan咚咚咚的回去,優雅的定義了一個字典對象

/**
 * 公共資源處理
 * Created by egan on 2018/11/19.
 */
@Component("pr")
public class PubRestrictUtils {

    public static final String USER_SEX = "USER_SEX";
    public static final String AREA_TYPE = "AREA_TYPE";
    public static final String USER_STATE = "USER_STATE";
    /**
     *  字典表: Map<關鍵詞, Map<SERIAL_NO, 中文名>>
     */
    private Map<String, Map<BigDecimal, Object>> propertys = new HashMap<String, Map<BigDecimal, Object>>();

    @Autowired
    private PubRestrictDao pubRestrictDao;

    @PostConstruct
    public void init(){
        loadRestrict(USER_SEX);
        loadRestrict(AREA_TYPE);
        loadRestrict(USER_STATE);
    }

    public void loadRestrict(String keyWord){
        List<Map<String, Object>> list = pubRestrictDao.getPubRestrictByKeyWord(keyWord);
        if (list.isEmpty()){
            return;
        }
         Map<BigDecimal, Object>  propertys = new HashMap<BigDecimal, Object>(list.size());
        for (Map<String, Object> map : list){
            propertys.put((BigDecimal) MapUtils.getObject(map,"SERIAL_NO"), MapUtils.getString(map,"DESC_CHINA") );
        }
        this.propertys.put(keyWord, propertys);
    }

    public String getUserSex(BigDecimal code){
        return get(USER_SEX, code);
    }

    public String getAreaType(BigDecimal code){
        return get(AREA_TYPE, code);
    }

    public String getUserState(BigDecimal code){
        return get(USER_STATE, code);
    }

    public String get(String keyWord, BigDecimal code){
        Map<BigDecimal, Object> propertys = getProperty( keyWord);
        if (MapUtils.isEmpty(propertys)){
            return code.toString();
        }
        String property = MapUtils.getString(propertys, code, code.toString());
        return property;

    }

    public Map<BigDecimal, Object> getProperty(String keyWord){
        return propertys.get(keyWord);

    }

    public Map<String, Map<BigDecimal, Object>> getPropertys() {
        return propertys;
    }
}

修改sql

SELECT
  mu.USER_ID,
  mu.USER_NAME,
  mu.USER_SEX,
  mu.AREA_TYPE,
  mu.USER_STATE
FROM MANA_USER mu

寫完字典工具類之後,把數據庫查詢出來的結果集遍歷一遍,把對應的字段取出來匹配。大概是以下這樣的

@Autowired
PubRestrictUtils pubRestrict
... 此處省略好多飯

List<Map<String, Object>> dataList = ...
for(Map<String, Object> data : dataList){
    data.put(PubRestrictUtils.USER_SEX, pubRestrict.getUserSex(data.get(PubRestrictUtils.USER_SEX)));
    data.put(PubRestrictUtils.AREA_TYPE, pubRestrict.getAreaType(data.get(PubRestrictUtils.AREA_TYPE)));
    data.put(PubRestrictUtils.USER_STATE, pubRestrict.getUserState(data.get(PubRestrictUtils.USER_STATE)));
}
... 此處省略好多飯

剛把用戶功能改完,Egan發現還有訂單,賬戶…………,好多好多,忍不住流下酸痛的淚(┬_┬)。

Egan又只好咚咚咚跑去老大那裏訴苦了:“老大,這樣我要改哭啊,而且感覺都是重復的代碼(┬_┬)”

老大連忙安慰到:“不哭不哭,你看,數據庫操作使用jdbc是吧,那在查詢的時候返回來結果是ResultSet,遍歷ResultSet之後才是你的dataList數據是吧,那你直接在統一處理吧,去判斷哪些是需要轉換的,這樣子業務層你就不用任何改動了。”

“噎,好像很有道理哦,那我怎麽知道哪些是需要轉換的呢?” Egan傻傻的回到。

老大: “你通過ResultSetMetaData.getColumnName去跟字典表的KeyWord進行匹配就好了,匹配上去了就轉換”

Egan:“不是所有ColumnName的名字都跟字典表KeyWord一樣的呢”

老大:“你試試別名上面下手腳,比如:吧啦吧啦……”

講完了,Egan好像聽懂了,就噠啦嗒啦的開始寫了


/**
 *
 *  通過別名表達式處理處理結果集方案
 *
 * 註意 <b>因別名不能超過30個字符,所以在處理的時候盡量是簡短</b>
 *
 *  使用的方式 主要分為四種
 * 方式一: bean名稱#方法名$數據庫字段名別名,這裏數據庫字段名別名用於最後展示使用
 * 這裏通過bean名稱去匹配對應的處理對象
 *  <p>
 *      select mu.AREA_TYPE \"pr#getAreaType$AREA_TYPE\" FROM MANA_USER mu
 *  </p>
 * 方式二: 方法名$數據庫字段名別名,這裏數據庫字段名別名用於最後展示使用
 *  PubRestrict pubRestrict
 * 這裏通過 new HeartAliasColumnMapRowMapper(pubRestrict) 的形式進行 pubRestrict是對象實例,然後規則內的方法名就是屬於本實例的方法名
 *  <p>
 *      select mu.AREA_TYPE \"getAreaType$AREA_TYPE\" FROM MANA_USER mu
 *  </p>
 * 方式三:集合key名稱$數據庫字段名別名,這裏數據庫字段名別名用於最後展示使用
 *  這裏的集合屬於字典表: Map<集合key名稱, Map<記錄數據, 需要轉換的值>> 這樣類型的一個集合,主要用於對結果整體的處理
 *   Map<String, Map<String, String>> propertys = new HashMap<String, Map<String, String>>();
 * 這裏通過 new HeartAliasColumnMapRowMapper(propertys) 的形式進行, propertys是所有結果列裏面存儲的信息
 *  <p>
 *      select mu.AREA_TYPE AREA_TYPE$AREA_TYPE FROM MANA_USER mu
 *  </p>
 * 方式四:k$數據庫字段名別名,這裏數據庫字段名別名用於最後展示使用
 *  這裏的集合屬於字典表:  Map<記錄數據, 需要轉換的值> 這樣類型的一個集合,主要用於對結果整體的處理
 *   Map<String, String> propertys = new HashMap<String,  String>();
 * 這裏通過 new HeartAliasColumnMapRowMapper(propertys) 的形式進行, propertys是所有結果列裏面存儲的信息
 *  <p>
 *        select mu.AREA_TYPE k$AREA_TYPE FROM MANA_USER mu
 *  </p>
 * 方式五:(數據庫字段名別名=集合key名稱)$,這裏數據庫字段名別名用於最後展示使用
 *  這裏的集合屬於字典表: Map<集合key名稱, Map<記錄數據, 需要轉換的值>> 這樣類型的一個集合,主要用於對結果整體的處理
 *   Map<String, Map<String, String>> propertys = new HashMap<String, Map<String, String>>();
 * 這裏通過 new HeartAliasColumnMapRowMapper(propertys) 的形式進行, propertys是所有結果列裏面存儲的信息
 *  <p>
 *      select mu.AREA_TYPE AREA_TYPE$ FROM MANA_USER mu
 *  </p>
 *
 * 使用方式
 *  JdbcTemplate.query(sql, new AliasElColumnMapRowMapper(propertys)
 * <p>
 * 註意: 方案五是方案三的簡化版;方案二,方案三(方案五),方案四是互斥的,在場景中只能使用一種,方案一的話是通用型的
 * </p>
 *
 * Created by egan on 2018/11/19.
 * <br/>
 * email: [email protected]
 */
public class AliasElColumnMapRowMapper extends ColumnMapRowMapper {
    private static final Logger LOGGER = LoggerFactory.getLogger(AliasElColumnMapRowMapper.class);
    private static final Map<String, Method> METHOD_MAP = new HashMap<String, Method>();
    WebApplicationContext wac = ContextLoader.getCurrentWebApplicationContext();

    /**
     * 轉換bean實例,用於方案一,二的處理
     */
    private Object bean;
    /**
     * 方案四:k$數據庫字段名別名
     */
    private Map<Object, Object> property;
    /**
     *  方案三,方案五:集合key名稱$數據庫字段名別名
     */
    private Map<String, Map<Object, Object>> propertys;

    public AliasElColumnMapRowMapper() {
    }
    /**
     * 初始化,bean或者MAP入參
     * 方式二: 方法名$數據庫字段名別名,這裏數據庫字段名別名用於最後展示使用
     *  PubRestrict pubRestrict
     * 這裏通過 new HeartAliasColumnMapRowMapper(pubRestrict) 的形式進行 pubRestrict是對象實例,然後規則內的方法名就是屬於本實例的方法名
     *  <p>
     *      select mu.AREA_TYPE \"getAreaType$AREA_TYPE\" FROM MANA_USER mu
     *  </p>
     * 方式三:集合key名稱$數據庫字段名別名,這裏數據庫字段名別名用於最後展示使用
     *  這裏的集合屬於字典表: Map<集合key名稱, Map<記錄數據, 需要轉換的值>> 這樣類型的一個集合,主要用於對結果整體的處理
     *   Map<String, Map<String, String>> propertys = new HashMap<String, Map<String, String>>();
     * 這裏通過 new HeartAliasColumnMapRowMapper(propertys) 的形式進行, propertys是所有結果列裏面存儲的信息
     *  <p>
     *      select mu.AREA_TYPE AREA_TYPE$AREA_TYPE FROM MANA_USER mu
     *  </p>
     * 方式四:k$數據庫字段名別名,這裏數據庫字段名別名用於最後展示使用
     *  這裏的集合屬於字典表:  Map<記錄數據, 需要轉換的值> 這樣類型的一個集合,主要用於對結果整體的處理
     *   Map<String, String> propertys = new HashMap<String,  String>();
     * 這裏通過 new HeartAliasColumnMapRowMapper(propertys) 的形式進行, propertys是所有結果列裏面存儲的信息
     *  <p>
     *        select mu.AREA_TYPE k$AREA_TYPE FROM MANA_USER mu
     *  </p>
     * 方式五:(數據庫字段名別名=集合key名稱)$,這裏數據庫字段名別名用於最後展示使用
     *  這裏的集合屬於字典表: Map<集合key名稱, Map<記錄數據, 需要轉換的值>> 這樣類型的一個集合,主要用於對結果整體的處理
     *   Map<String, Map<String, String>> propertys = new HashMap<String, Map<String, String>>();
     * 這裏通過 new HeartAliasColumnMapRowMapper(propertys) 的形式進行, propertys是所有結果列裏面存儲的信息
     *  <p>
     *      select mu.AREA_TYPE AREA_TYPE$ FROM MANA_USER mu
     *  </p>
     *
     * 使用方式
     *  JdbcTemplate.query(sql, new AliasElColumnMapRowMapper(propertys)
     * <p>
     */
    public AliasElColumnMapRowMapper(Object handlerObj) {
        if (null == handlerObj){
            return;
        }
        if (!(handlerObj instanceof Map)){
            this.bean = handlerObj;
            return;
        }
        Map<Object, Object> property = (Map<Object, Object>)handlerObj;
        if ( property.isEmpty()) {
            return;
        }
        if ( property.entrySet().iterator().next().getValue() instanceof Map){
            this.propertys = ( Map<String, Map<Object, Object>>) handlerObj;
            return;
        }
        this.property = property;
    }

    @Override
    public Map<String, Object> mapRow(ResultSet rs, int rowNum) throws SQLException {
        ResultSetMetaData rsmd = rs.getMetaData();
        int columnCount = rsmd.getColumnCount();
        Map<String, Object> mapOfColValues = createColumnMap(columnCount);
        for (int i = 1; i <= columnCount; i++) {
            String key = getColumnKey(JdbcUtils.lookupColumnName(rsmd, i));

            Object[] elInfo = getElInfo(key);
            Object obj = getColumnValue(rs, i);
            if (null == elInfo || null == obj){
                mapOfColValues.put(key, obj);
                continue;
            }
           Object value = ((ElHandler)elInfo[1]).handler(obj, elInfo);
            if (obj == value){
                mapOfColValues.put(key, obj);
            }else {
                mapOfColValues.put((String) elInfo[0], value);
            }
        }
        return mapOfColValues;
    }

    /**
     * 根據字段別名獲取表達式
     * @param key 字段別名
     * @return 返回格式 {別名,處理方案, (處理方法|集合key名稱)?, 處理對象}
     */
    private Object[] getElInfo(String key){
        int end = key.lastIndexOf("$");
        if (end < 1){
            return null;
        }
        if (end + 1 == key.length()){
            String alias = key.substring(0, end);
            return new Object[]{alias, ElHandler.MAP_K, alias, propertys};
        }
        String alias = key.substring(end + 1);
        String el = key.substring(0, end);
        if (ElHandler.K.name().equals(el.toUpperCase())){
          if (null == property){
              return null;
          }
            return new Object[]{alias, ElHandler.K, property};
        }
        end = el.indexOf("#");
        if (end > 1){
            return new Object[]{alias, ElHandler.BEAN, el.substring(end + 1), wac.getBean(el.substring(0, end))};
        }
        if (null != bean){
            return new Object[]{alias, ElHandler.BEAN, el, bean};
        }
        if (null != propertys){
            return new Object[]{alias, ElHandler.MAP_K, el, propertys};
        }
        return null;
    }

    enum ElHandler{
        /**
         * 方式一,方式二使用
         */
        BEAN {
            /**
             * value處理器
             *
             * @param value      數據庫查詢結果
             * @param el         表達式集
             * @return 處理後的結果
             */
            @Override
            public Object handler(Object value, Object[] el) {
                Object handlerObj = el[3];
                Class<?>  handlerClass = handlerObj.getClass();
                String methodName = (String) el[2];
                String key = handlerClass.getName() + "#" + methodName;
                Method method = METHOD_MAP.get(key);
                if (null == method){
                    method = BeanUtils.findMethod(handlerClass, methodName, value.getClass());
                    if (null == method){
                        return value;
                    }
                    METHOD_MAP.put(key, method);
                }
                try {
                    return method.invoke(handlerObj, value);
                } catch (IllegalAccessException e) {
                    AliasElColumnMapRowMapper.LOGGER.error("handlerObj 方法調用異常", e);
                } catch (InvocationTargetException e) {
                    AliasElColumnMapRowMapper.LOGGER.error("handlerObj 方法調用異常", e);
                }
                return value;
            }
        },
        /**
         * 方式三,方式五
         */
        MAP_K {
            /**
             * value處理器
             *
             * @param value      數據庫查詢結果
             * @param el         表達式集
             * @return 處理後的結果
             */
            @Override
            public Object handler(Object value, Object[] el) {

                if (null ==  el[3]){
                    return value;
                }
                Map<String, Map<Object, Object>> handlerObj = (Map<String, Map<Object, Object>>)el[3];
                if ( handlerObj.isEmpty()){
                    return value;
                }
                Map<Object, Object> property = handlerObj.get(el[2]);
                if (null == property || property.isEmpty()){
                    return value;
                }
                Object o = property.get(value);
                if (o != null){
                    return o;
                }
                return value;
            }
        },
        /**
         * 方式四
         */
        K {
            /**
             * value處理器
             *
             * @param value 數據庫查詢結果
             * @param el    表達式集
             * @return 處理後的結果
             */
            @Override
            public Object handler(Object value, Object[] el) {
                if (null ==  el[2]){
                    return value;
                }
                Map<Object, Object> handlerObj = ( Map<Object, Object>)el[2];
                if (handlerObj.isEmpty() ){
                    return value;
                }
                Object o = handlerObj.get(value);
                if (o != null){
                    return o;
                }

                return value;
            }
        };

        /**
         *  value處理器
         * @param value 數據庫查詢結果
         * @param el 表達式集 {別名,處理方案, (處理方法|集合key名稱)?, 處理對象}
         * @return 處理後的結果
         */
        public abstract Object handler(Object value,  Object[] el);
    }

修改sql

SELECT
  mu.USER_ID,
  mu.USER_NAME,
  mu.USER_SEX$,
  mu.AREA_TYPE$,
  mu.USER_STATE$
FROM MANA_USER mu

Dao部分調用代碼, JdbcTemplate 調用的時候加入第二個參數;

@Autowired
PubRestrictUtils pubRestrict
@Autowired
JdbcTemplate jdbcTemplate;
...此處省略好多好多
String sql = "SELECT  mu.USER_ID,  mu.USER_NAME,  mu.USER_SEX USER_SEX$,  mu.AREA_TYPE AREA_TYPE$,  mu.USER_STATE USER_STATE$ FROM MANA_USER mu";
List<Map<String, Object>> dataList =jdbcTemplate.query(sql, new AliasElColumnMapRowMapper(pubRestrict.getPropertys()));

...此處省略好多好多

就這樣寫好了。老大還誇獎了下Egan,Egan都樂了好幾天。


好了,進入正題,講解下AliasElColumnMapRowMapper的使用吧,雖然在這個類的說明裏面也講了很細了。

使用的時候再重申一遍

註意:

  1. 方案五是方案三的簡化版;方案二,方案三(方案五),方案四是互斥的,在場景中只能使用一種,方案一的話是通用型的
  2. 因別名不能超過30個字符,所以在處理的時候盡量是簡短

以下還是根據以上Egan所遇的問題去舉例每種方案吧。

  1. 方案一 這裏別名你不一定要跟字段表的關鍵詞KeyWord一樣,只需要你調用的方法正確即可,比如 mu.USER_SEX pr#getUserSex$SEX,別名部分pr#getUserSex$SEX的"pr"部分是bean在spring容器中的名字這裏可以倒回去看字典對象類上面的標識@Component("pr"),然後"getUserSex" 是對應pr對象的對應方法

@Autowired
PubRestrictUtils pubRestrict
@Autowired
JdbcTemplate jdbcTemplate;

String sql = "SELECT  mu.USER_ID,  mu.USER_NAME,  mu.USER_SEX \"pr#getUserSex$SEX\",  mu.AREA_TYPE \"pr#getAreaType$AREA_TYPE\",  mu.USER_STATE \"pr#getUserState$USER_STATE\" FROM MANA_USER mu";
List<Map<String, Object>> dataList =jdbcTemplate.query(sql, new AliasElColumnMapRowMapper());

查詢結果List&lt;Map&lt;String, Object&gt;&gt;對應的值:[{USER_ID=1,USER_NAME=張三,SEX=男,AREA_TYPE=城區,USER_STATE=正常},...]

  1. 方案二 這裏別名你不一定要跟字段表的關鍵詞KeyWord一樣,只需要你調用的方法正確即可,比如 mu.USER_SEX getUserSex$SEX,別名部分getUserSex$SEX的"getUserSex"是對應傳進去pubRestrict的方法
    
    @Autowired
    PubRestrictUtils pubRestrict
    @Autowired
    JdbcTemplate jdbcTemplate;

String sql = "SELECT mu.USER_ID, mu.USER_NAME, mu.USER_SEX \"getUserSex$SEX\", mu.AREA_TYPE \"getAreaType$AREA_TYPE\", mu.USER_STATE \"getUserState$USER_STATE\" FROM MANA_USER mu";
List<Map<String, Object>> dataList =jdbcTemplate.query(sql, new AliasElColumnMapRowMapper(pubRestrict));

查詢結果`List<Map<String, Object>>`對應的值:[{USER_ID=1,USER_NAME=張三,SEX=男,AREA_TYPE=城區,USER_STATE=正常},...]

3. 方案三  **這裏別名你不一定要跟字段表的關鍵詞KeyWord一樣,只需要你調用的方法正確即可,比如 mu.USER_SEX USER_SEX$SEX**,別名部分**USER_SEX$SEX**的"USER_SEX"是外層MAP的key然後SEX是前端展示的名字

@Autowired
PubRestrictUtils pubRestrictbr/>@Autowired

String sql = "SELECT mu.USER_ID, mu.USER_NAME, mu.USER_SEX USER_SEX$SEX, mu.AREA_TYPE AREA_TYPE$AREA_TYPE, mu.USER_STATE USER_STATE$USER_STATE FROM MANA_USER mu";
List<Map<String, Object>> dataList =jdbcTemplate.query(sql, new AliasElColumnMapRowMapper(pubRestrict.getPropertys()));

查詢結果`List<Map<String, Object>>`對應的值:[{USER_ID=1,USER_NAME=張三,SEX=男,AREA_TYPE=城區,USER_STATE=正常},...]

4. 方案五,這裏就不講方案五了,Egan同學的例子就是方案五了。

5. 方案四。這裏需要對字典對象做一些改動

字典對象,這裏把屬性對象做成了單層的MAP

/**

  • 公共資源處理
  • Created by egan on 2018/11/19.br/>*/
    @Component("pr")

    /**

    • 字典表: Map<SERIAL_NO, 中文名>
      */
      private Map<BigDecimal, Object> propertys = null;

    @Autowired
    private PubRestrictDao pubRestrictDao;

    @PostConstruct
    public void loadRestrict(){
    List<Map<String, Object>> list = pubRestrictDao.getPubRestrictAll();
    if (list.isEmpty()){
    return;
    }
    this.propertys = new HashMap<BigDecimal, Object>(list.size());
    for (Map<String, Object> map : list){
    this.propertys.put((BigDecimal) MapUtils.getObject(map,"SERIAL_NO"), MapUtils.getString(map,"DESC_CHINA") );
    }
    }

    public Map<BigDecimal, Object> getPropertys() {
    return propertys;
    }
    }

    對象使用, 別名展示同理 mu.USER_SEX k$SEX ,別名“k$SEX”中的“k”是固定值,“SEX”是需要展示的值

    @Autowired
    PubRestrictUtils pubRestrictbr/>@Autowired

String sql = "SELECT mu.USER_ID, mu.USER_NAME, mu.USER_SEX k$SEX, mu.AREA_TYPE k$AREA_TYPE, mu.USER_STATE k$USER_STATE FROM MANA_USER mu";
List<Map<String, Object>> dataList =jdbcTemplate.query(sql, new AliasElColumnMapRowMapper(pubRestrict.getPropertys()));


查詢結果`List<Map<String, Object>>`對應的值:[{USER_ID=1,USER_NAME=張三,SEX=男,AREA_TYPE=城區,USER_STATE=正常},...]

.

最後,安利一個全能支付Java開發工具包.優雅的輕量級支付模塊集成支付對接支付整合(微信支付,支付寶,銀聯,友店,富友,跨境支付paypal,payoneer(P卡派安盈)易極付)app,掃碼,即時到帳刷卡付條碼付刷臉付轉賬服務商模式、支持多種支付類型多支付賬戶,支付與業務完全剝離,簡單幾行代碼即可實現支付,簡單快速完成支付模塊的開發,可輕松嵌入到任何系統裏 目前僅是一個開發工具包(即SDK),只提供簡單Web實現,建議使用maven或gradle引用本項目即可使用本SDK提供的各種支付相關的功能 
 https://www.oschina.net/p/pay-java-parent

jdbc如何優雅的解決字典表數據轉化