Mysql+Java+Echarts 通过用户身份证获取性别、年龄段统计

昨天,接受一个新需求,将我们通过认证用户身份证分析出用户的年龄、性别并作出统计。通过思考查阅资料最终我选择了Mysql+java+Echarts 实现这个小需求。思路如下:

1、通过Mysql 语句查我们的用户表中身份证号。不仅仅是查。通过稍微有逻辑的语句直接获取到年龄段以及该年龄段个数。语句如下:

select 
        case 
              when TIMESTAMPDIFF(YEAR,STR_TO_DATE(substr(id_card_no,7,8),'%Y%m%d'),sysdate())>=17 and TIMESTAMPDIFF(YEAR,STR_TO_DATE(substr(id_card_no,7,8),'%Y%m%d'),sysdate())<=23
                  then '17~23' 
              when TIMESTAMPDIFF(YEAR,STR_TO_DATE(substr(id_card_no,7,8),'%Y%m%d'),sysdate())>=24 and TIMESTAMPDIFF(YEAR,STR_TO_DATE(substr(id_card_no,7,8),'%Y%m%d'),sysdate())<=28
                  then '24~28'
              when TIMESTAMPDIFF(YEAR,STR_TO_DATE(substr(id_card_no,7,8),'%Y%m%d'),sysdate())>=29 and TIMESTAMPDIFF(YEAR,STR_TO_DATE(substr(id_card_no,7,8),'%Y%m%d'),sysdate())<=33
                  then '29~33'
              when TIMESTAMPDIFF(YEAR,STR_TO_DATE(substr(id_card_no,7,8),'%Y%m%d'),sysdate())>=34 and TIMESTAMPDIFF(YEAR,STR_TO_DATE(substr(id_card_no,7,8),'%Y%m%d'),sysdate())<=38
                  then '34~38'
              when TIMESTAMPDIFF(YEAR,STR_TO_DATE(substr(id_card_no,7,8),'%Y%m%d'),sysdate())>=39 and TIMESTAMPDIFF(YEAR,STR_TO_DATE(substr(id_card_no,7,8),'%Y%m%d'),sysdate())<=43
                  then '39~43'
             when TIMESTAMPDIFF(YEAR,STR_TO_DATE(substr(id_card_no,7,8),'%Y%m%d'),sysdate())>=44 and TIMESTAMPDIFF(YEAR,STR_TO_DATE(substr(id_card_no,7,8),'%Y%m%d'),sysdate())<=48
                  then '44~48'
             when TIMESTAMPDIFF(YEAR,STR_TO_DATE(substr(id_card_no,7,8),'%Y%m%d'),sysdate())>=49 and TIMESTAMPDIFF(YEAR,STR_TO_DATE(substr(id_card_no,7,8),'%Y%m%d'),sysdate())<=53
                  then '49~53'
             when TIMESTAMPDIFF(YEAR,STR_TO_DATE(substr(id_card_no,7,8),'%Y%m%d'),sysdate())>=49 and TIMESTAMPDIFF(YEAR,STR_TO_DATE(substr(id_card_no,7,8),'%Y%m%d'),sysdate())<=59
                  then '54~59'
             when TIMESTAMPDIFF(YEAR,STR_TO_DATE(substr(id_card_no,7,8),'%Y%m%d'),sysdate())>=60
                  then '60+' END age,count(*) count                                                                                                                                                                                             
             from tb_users
            where substr(id_card_no,-2,1)%2 = 1 group by age

解释:通过substr()获取身份证号出生年月例如19940627 ,str_to_date()方法将字符串,转化成我时间格式例如str_to_date('19940627','%Y%m%d') 结果是1994-06-27。

    TIMESTAMPDIFF 这个类似Oracle 的month_between.这个方法可以计算出两个时间差。第一个参数是差值精确到年、月、日等等。我这里是算年龄,所以是Year。这个计算出当前与身份证出生时间的差值,也就是年龄。

    然后case when then 语法做类似if else 操作 这个应该好理解。

最后通过传参数来实现查找男的还是女。思路就是通过substr()获取身份证号倒数第二位,和2取余。奇数男的,偶数女的。这个就是身份证规则。然后group by age 也就是年龄段分组。


2、java 集合转换Json数据

    CardUtil工具类

package com.dairuijie.manage.utils;

import java.util.Calendar;

/**
 * 
* @Title: CardUtil.java 
* @Package com.qzbl.demo01 
* @author Drj  
* @date 2018年5月3日 上午10:36:58 
* @version V1.0
 */
public class CardUtil {
    public static String ONE_STAGE = "17~23";
    public static String TWO_STAGE = "24~28";
    public static String THREE_STAGE = "29~33";
    public static String FOUR_STAGE = "34~38";
    public static String FIVE_STAGE = "39~43";
    public static String SIX_STAGE = "44~48";
    public static String SERVEN_STAGE = "49~53";
    public static String EIGHT_STAGE = "54~59";
    public static String NINE_STAGE = "60+";
    /**
     * 通过身份证号获取年龄
     * @param idCard
     * @return
     */
    public static int getAgeByIdCard(String idCard) {
        int iAge = 0;
        Calendar cal = Calendar.getInstance();
        String year = idCard.substring(6, 10);
        int iCurrYear = cal.get(Calendar.YEAR);
        iAge = iCurrYear - Integer.valueOf(year);
        return iAge;
    }
    /**
     * 通过身份证号获取性别
     * @param idCard
     * @return
     */
    public static boolean getGenderByIdCard(String idCard) {
        boolean sGender = true;
        String sCardNum = idCard.substring(16, 17);
        if (Integer.parseInt(sCardNum) % 2 != 0) {
            sGender = true;//男
        } else {
            sGender = false;//女
        }
        return sGender;
    }
    /**
     * 身份证号15位转换18位
     * @param IdCardNO
     * @return
     */
    public static String transIDCard15to18(String IdCardNO){
        String cardNo=null;
        if(null!=IdCardNO&&IdCardNO.trim().length()==15){
            IdCardNO=IdCardNO.trim();
            StringBuffer sb=new StringBuffer(IdCardNO);
            sb.insert(6, "19");
            sb.append(transCardLastNo(sb.toString()));
            cardNo=sb.toString();
        }
        return cardNo;
    }
    /**
     * 转换身份证号最后一位
     * @param newCardId
     * @return
     */
    private static String transCardLastNo(String newCardId){
        char[] ch=newCardId.toCharArray();
        int m=0;
        int [] co={7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2};
        char [] verCode=new char[]{'1','0','X','9','8','7','6','5','4','3','2'};
        for (int i = 0; i < newCardId.length(); i++) {
            m+=(ch[i]-'0')*co[i];
        }
        int residue=m%11;
        return String.valueOf(verCode[residue]);
         
    }
}

封装到集合

 /**
     * 封装男女不同年龄段的集合
     * @param allList
     * @param countMap
     * @return
     */
    public List<Integer> getUserCountByStage(List<String> allList,List<Map<String,Object>> countMap){
        List<Integer> count = new ArrayList<Integer>();
        for(int i=0; i< allList.size(); i++) {
            for(Map<String, Object> male : countMap) {
                if(male.get("age").toString().equals(allList.get(i).toString())){
                    count.add(Integer.valueOf((male.get("count").toString())));
                }
            }
            if(count.size() < i+1) {
                count.add(0);
            }
        }
        return count;
    }

配置注解以及ObjectJson

    @RequestMapping("/echarts")
    @ResponseBody
    public String echarts(HttpServletResponse response){
        JSONObject result = new JSONObject();
        List<String> allList = new ArrayList<String>();
        allList.add(CardUtil.ONE_STAGE);
        allList.add(CardUtil.TWO_STAGE);
        allList.add(CardUtil.THREE_STAGE);
        allList.add(CardUtil.FOUR_STAGE);
        allList.add(CardUtil.FIVE_STAGE);
        allList.add(CardUtil.SIX_STAGE);
        allList.add(CardUtil.SERVEN_STAGE);
        allList.add(CardUtil.EIGHT_STAGE);
        allList.add(CardUtil.NINE_STAGE);
        List<Map<String,Object>> maleList = mRealCertifyService.selectCountInfo(1);
        List<Map<String,Object>> femaleList = mRealCertifyService.selectCountInfo(0);
        result.put("maleList", getUserCountByStage(allList,maleList));
        result.put("femaleList", getUserCountByStage(allList,femaleList));
        return result.toString();
    }

3、Echarts实现图形化

 $(function(){
        $.ajax({
            url : "userCreditInfo/echarts.html",
            dataType : "json",
            cache : false,
            success : function(json) {
                Myecharts(json);
            },
            errr:function(){
                layer.alert("error");
            }
        }) 
    })
function Myecharts(obj) {
        var myChart = echarts.init(document.getElementById('main'));
        // 指定图表的配置项和数据
        var option = {
            title : {
                text : '用户统计图'
            },
            tooltip : {},
            legend : {
                data : [ '女', '男' ]
            },
            xAxis : {
                data : [ "17~23", "24~28", "29~33", "34~38", "39~43", "44~48",
                        "49~53", "54~59", "60+" ],
                name : '岁'
            },
            yAxis : {
                name : '人'
            },
            series : [ {
                name : '女',
                type : 'bar',
                data : obj.femaleList
            }, {
                name : '男',
                type : 'bar',
                data : obj.maleList
            } ]
        };
        myChart.setOption(option);
    }

模拟数据如图上

总结:这样可以帮助我们更好分析用户使用我们的产品一个年龄段,为我们做计划,是一个很好的参考。

猜你喜欢

转载自blog.csdn.net/qq_29897369/article/details/80186751