记一次性能优化(java+Mybatis+Mysql)

闲得无聊,本来是很简单的增删改查。但是,由于表设计的草蛋(所以,别问我为什么不用表连接o(╥﹏╥)o接盘的痛,又不能影响公司正在运行中的功能),以及我代码的草蛋。使得其中有一个需求——“导出excel”表,预计会由于出现几千次访问数据库而影响性能。

页面交给前端写,划水中,试试改善下性能。

考虑到:
java内存运行,速度影响不大。
mysql允许in(xx,yy)的功能,性能影响不大。
例如:

SELECT * FROM `oa_meal_offer` where (job_num, DATE_FORMAT(order_date,'%Y-%m-%d')) in (('CBR023','2020-03-30'));

性能瓶颈:java多次访问数据库Mysql

百度到:
springMVC+mybatis,如何实现批量多条件的查询?
mybatis 中 foreach 的性能问题及调优

教会了我这么干:
优化前的垃圾代码

String type=(String)params.get("type");
        PageUtils page=null;
        //type为空时,认为和"3"一个场景
        if(!StringUtils.isNotBlank(type)||type.equals("3")){

            //如果选的是全部,需要单独处理。又要分组(sql表关联自己,做成中、晚、早三张表关联),又要分页
            page=applyMealRecordService.queryAllApplyMealRecordListPage(params);
        }else {
            page = applyMealRecordService.queryApplyMealRecordListPage(params);
        }
        //得到realOrderTimeStr  //估计导excel表时会影响性能
        List<ApplyMealRecordEntity> list = (List<ApplyMealRecordEntity>) page.getList();
        for(ApplyMealRecordEntity a:list){
            String strDate=DateUtils.format(a.getInsertTime(),DateUtils.DATE_PATTERN);
            String jobNum=a.getJobNum();
            Date dateTime=applyMealRecordService.selectRealOrderTimeByJobNumAndDate(jobNum,strDate);
            a.setRealOrderTimeStr(DateUtils.format(dateTime,DateUtils.DATE_TIME_PATTERN));
        }

mybatis

<select id="selectRealOrderTimeByJobNumAndDate" parameterType="string" resultType="java.util.Date">
       select  insert_time from oa_meal_offer where job_num=#{jobNum} and DATE_FORMAT(order_date,'%Y-%m-%d') =#{strDate}  limit 1
   </select>

优化后:
java:

/**
*Controller层
*/
  /**
     * 分页查询
     * web查询 报餐记录
     */
    @GetMapping("/list")
    @RequiresPermissions("oa:applymeal:list")
    public R getApplyMealRecordList(@RequestParam Map<String, Object> params){
        String type=(String)params.get("type");
        PageUtils page=null;
        //type为空时,认为和"3"一个场景
        if(!StringUtils.isNotBlank(type)||type.equals("3")){
            //如果选的是全部,需要单独处理。又要分组(sql表关联自己,做成中、晚、早三张表关联),又要分页
            page=applyMealRecordService.queryAllApplyMealRecordListPage(params);
        }else {
            page = applyMealRecordService.queryApplyMealRecordListPage(params);
        }
        //得到realOrderTimeStr
       List<ApplyMealRecordEntity> list = (List<ApplyMealRecordEntity>) page.getList();
        //写法一
        //存在多次访问数据库。估计导excel表时,数据太多,性能8行
            /*
            for(ApplyMealRecordEntity a:list){
            String strDate=DateUtils.format(a.getInsertTime(),DateUtils.DATE_PATTERN);
            String jobNum=a.getJobNum();
            Date dateTime=applyMealRecordService.selectRealOrderTimeByJobNumAndDate(jobNum,strDate);
            a.setRealOrderTimeStr(DateUtils.format(dateTime,DateUtils.DATE_TIME_PATTERN));
           }*/

        //优化性能。写法二
        //获取工号、时间的集合 (applyMeal对象用applyMealRecord对象存其实也行吧,我只取两个属性就够了)
        List<ApplyMealEntity>  oaMealOfferList= applyMealRecordService.selectRealOrderTimeFaEr(list);
        //遍历,根据工号匹配
        for(ApplyMealRecordEntity a:list){
            for(ApplyMealEntity b:oaMealOfferList){
                if(b.getJobNum().equals(a.getJobNum())){
                    // 得到realOrderTimeStr。格式化时间,赋值给a.setRealOrderTimeStr()
                    a.setRealOrderTimeStr(DateUtils.format(b.getInsertTime(),DateUtils.DATE_TIME_PATTERN));
                }
            }
        }
        //page.setList(list);  //多余,集合、对象是引用数据类型。

        return R.ok().put("page", page);
    }
/**
*Service层
*ServiceImpl
*/
@Override
    public List<ApplyMealEntity> selectRealOrderTimeFaEr(List<ApplyMealRecordEntity> list) {
        //有两种考虑,目前认为:在java拼接,然后在mybatis用$预加载,性能会更好
        // 参数串 ('CBR023','2020-03-30'),('CBR024','2020-03-30'),('CBR025','2020-03-30')
        List<String> sbs=new ArrayList<String>();
        for(ApplyMealRecordEntity a:list){
            String jobNum=a.getJobNum();
            String strDate= DateUtils.format(a.getInsertTime(),DateUtils.DATE_PATTERN);
            StringBuffer sb=new StringBuffer();
            sb.append("(").append("'").append(jobNum).append("'").append(",").append("'").append(strDate).append("'").append(")");
            sbs.add(sb.toString());
        }
        String paramsStrs1=String.join(",", sbs);
        String paramsStrs="("+paramsStrs1+")";
        return baseMapper.selectRealOrderTimeFaEr(paramsStrs);
    }
//dao
 /**
     * 法二:
     *根据工号和时间,查询真实的下单时间
     * 性能优化
     *
     * xml用${}时需要加@Param()
     */
    List<ApplyMealEntity> selectRealOrderTimeFaEr(@Param("paramsStrs") String paramsStrs);

mybatis

 <select id="selectRealOrderTimeFaEr" parameterType="string" resultType="com.cowain.base.modules.oa.entity.ApplyMealEntity">
       SELECT * FROM `oa_meal_offer` where
       (job_num, DATE_FORMAT(order_date,'%Y-%m-%d'))
       in
        ${paramsStrs}
   </select>

// 其实此ApplyMealEntity对象里我只需 job_num,insert_time这两个数据/属性就够了

总结:
此次性能优化本质:用java内存运行的性能(内存里操作,反正很快的)换连接数据库交互(内存和硬盘,很慢)的蛋疼

在这里插入图片描述

在这里插入图片描述

20200406:我擦,我发现逼逼这么多,把offer表做主表,去left join record表就行了o(╥﹏╥)o妈的,都怪测试库数据残缺,搞得我看效果很蛋疼

补充:
20200414今天加了一个参数,又加出蛋疼来了(又自己写bug折腾自己喽):

1. ${}别写成$  {}  【navicat"美化sql"给我格式化成这个鸟样】,不识别的-_-||
2.注意,只能用${}  用#{}会报错:版本不支持in,跟字符串有关,好像会多'' (用#得在xml里搞循环,性能差一点)
AND (s.hr_id) IN ${ paramsStrs }
3. month是关键字,记得上一层@Param("cmonth") ,这里就可以是${ cmonth }了,而不会sql关键字冒橘黄了
其他照旧,比如parameterType="string",@Param("cmonth")String month
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值