基于若依springboot架构实现数据多维统计

简介: 基于springboot架构实现数据多维统计,列表动态增减列,mybatis动态传入字段等内容

需求背景

项目中需要一个统计功能,同时可以根据勾选不同维度的统计字段来实现列表动态增减,实现效果如图:https://pan.baidu.com/s/1D9cBOWJ2q6rqL7BpU_wcMQ?pwd=wx6q,由于语雀编辑器暂时不支持视频上传,这里是百度网盘的免提取码链接,可直接观看

代码实现

首先需要处理的是页面动态增减列

页面代码

accountFlowInfoRecordData.html

<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<head>
  <th:block th:include="include :: header('流转记录统计列表')" />
</head>
<body class="gray-bg">
     <div class="container-div">
    <div class="row">
      <div class="col-sm-12 search-collapse">
        <form id="formId">
          <div class="select-list">
            <ul>
              <li>
                流转类型:
                <select name="channelType" th:with="type=${@dict.getType('flow_info_channel_type')}">
                  <option value="">请选择</option>
                  <option th:each="dict : ${type}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}"></option>
                </select>
              </li>
              <li>
                数据来源:
                <input type="text" name="createDeptName" id="createDeptName" readonly="readonly" onclick="ztreeShowDept();"/>
                <input type="text"  name="params[createDeptIds]" id="createDeptId" style="display: none"/>
              </li>
              <li>
                流转部门:
                <input type="text" name="flowDeptName" id="flowDeptName" readonly="readonly" onclick="ztreeShowDept2();"/>
                <input type="text"  name="params[flowDeptIds]" id="flowDeptId" style="display: none"/>
              </li>
              <li>
                考种:
                <select name="examTypeId">
                  <option value="">请选择</option>
                  <option  th:each="examType:${examTypes}" th:value="${examType.id}" th:text="${examType.examName}"></option>
                </select>
              </li>
              <li>
                班次:
                <select name="shiftId" th:with="type=${@dict.getType('intendedShift')}">
                  <option value="">请选择</option>
                  <option th:each="dict : ${type}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}"></option>
                </select>
              </li>
              <li>
                员工:
                <input type="text" name="userName" id="userName" readonly="readonly" onclick="ztreeShowUser();"/>
                <input type="text"  name="params[userIds]" id="userId" style="display: none"/>
              </li>
              <li>
                登记时间:
                <input type="text" readonly="readonly" placeholder="时间范围" name="accountTime" id="accountTime"/>
                <input type="hidden" name="params[accountStartTime]" id="accountStartTime"/>
                <input type="hidden" name="params[accountEndTime]" id="accountEndTime"/>
              </li>
              <li>
                <a class="btn btn-primary btn-rounded btn-sm" onclick="mysearch();"><i
                    class="fa fa-search"></i>&nbsp;搜索</a>
                <a class="btn btn-warning btn-rounded btn-sm" onclick="reset();"><i
                    class="fa fa-refresh"></i>&nbsp;重置</a>
              </li>
            </ul>
          </div>
        </form>
      </div>
          <div class="btn-group-sm" id="toolbar" role="group">
        <div class="row">
          <div class="select-list">
            <ul style="padding-left: 17px;">
              <li>
                维度:
                <input type="checkbox" name="selectParam" value="1"
                     style="width: 50px;height: 20px;"/>数据类型
                <input type="checkbox" name="selectParam" value="2"
                     style="width: 50px;height: 20px;"/>数据来源
                <input type="checkbox" name="selectParam" value="3"
                     style="width: 50px;height: 20px;"/>流转部门
                <input type="checkbox" name="selectParam" value="4"
                     style="width: 50px;height: 20px;"/>考种
                <input type="checkbox" name="selectParam" value="5"
                     style="width: 50px;height: 20px;"/>班次
                <input type="checkbox" name="selectParam" value="6"
                     style="width: 50px;height: 20px;"/>员工
                <input type="checkbox" name="selectParam" value="7"
                     style="width: 50px;height: 20px;"/>时间粒度
              </li>
            </ul>
          </div>
        </div>
      </div>
      <div class="col-sm-12 select-table table-striped">
        <table id="bootstrap-table" data-mobile-responsive="true"></table>
      </div>
    </div>
  </div>
    <div th:include="include :: footer"></div>
    <script th:inline="javascript">
        var prefix = ctx + "project/accountFlowInfoRecordData";
    var columus = [
      {
        field : 'allotNums',
        title : '流转数量'
      },
      {
        field : 'dailyOrderNums',
        title : '当日成单人数'
      },
      {
        field : 'totalOrderNums',
        title : '累计成单人数'
      }];
    var channeltypes = [[${@dict.getType('flow_info_channel_type')}]];
    var shiftids = [[${@dict.getType('intendedShift')}]];
    $(function() {
      // 初始化时间范围插件,传入三个id的名称
      initDaterangepickerWithoutInitTime("accountTime","accountStartTime","accountEndTime");
      var options = {
        url: prefix + "/list",
        modalName: "流转记录统计",
        showRefresh: false,
        showSearch: false,
        showColumns: false,
        showToggle: false,
        columns: columus
      };
      $.table.init(options);
    });
    function mysearch() {
      //维度 搜索
      query();
    }
    function query() {
      //点击维度加载按钮则需销毁原有表格重新加载表格
      $("#bootstrap-table").bootstrapTable('destroy');
      var options = {
        id:"bootstrap-table",
        url: prefix + "/getAccountDataGroup",
        modalName: "流转记录统计",
        showSearch: false,
        showRefresh: false,
        showToggle: false,
        showColumns: false,
        queryParams: queryParams
      };
      //增加展示列
      var columns2 = [];
      var selectParam = "";
      $("input[name='selectParam']:checked").each(function () {
        selectParam = selectParam + $(this).val() + ",";
      });
      if (selectParam != "") {
        var one = selectParam.indexOf("1");
        var two = selectParam.indexOf("2");
        var three = selectParam.indexOf("3");
        var four = selectParam.indexOf("4");
        var five = selectParam.indexOf("5");
        var six = selectParam.indexOf("6");
        var seven = selectParam.indexOf("7");
        if (one >= 0) {
          // 1
          columns2.push({
            field : 'channelType',
            title : '数据类型',
            formatter: function(value, row, index) {
              return $.table.selectDictLabel(channeltypes,value);
            }
          });
        }
        if (two >= 0) {
          // 2
          columns2.push({
            field : 'createDeptName',
            title : '数据来源',
            formatter: function(value, row, index) {
              return value.substring(0,1)+"***"+value.substring(value.length-1);
            }
          });
        }
        if (three >= 0) {
          // 3
          columns2.push({
            field : 'flowDeptName',
            title : '流转部门',
            formatter: function(value, row, index) {
              return value.substring(0,1)+"***"+value.substring(value.length-1);
            }
          });
        }
        if (four >= 0) {
          // 4
          columns2.push({
            field : 'examTypeName',
            title : '考种',
            formatter: function(value, row, index) {
              return value.substring(0,1)+"***"+value.substring(value.length-1);
            }
          });
        }
        if (five >= 0) {
          // 5
          columns2.push({
            field : 'shiftId',
            title : '班次',
            formatter: function(value, row, index) {
              return $.table.selectDictLabel(shiftids,value);
            }
          });
        }
        if (six >= 0) {
          // 6
          columns2.push({
            field : 'userName',
            title : '员工',
            formatter: function(value, row, index) {
              return value.substring(0,1)+"***"+value.substring(value.length-1);
            }
          });
        }
        if (seven >= 0) {
          // 7
          columns2.push({
            field : 'accountTime',
            title : '时间粒度',
            formatter: function(value, row, index) {
              return $.common.dateFormat(value, "yyyy-MM-dd");
            }
          });
        }
        columns2 = columns2.concat(columus);
      }else {
        columns2 = columus;
      }
      options.columns=columns2;
      $.table.init(options);
    }
    function queryParams(params) {
      //获取复选框选中的值
      var selectParam = "";
      $("input[name='selectParam']:checked").each(function () {
        selectParam = selectParam + $(this).val() + ",";
      });
      var search = $.table.queryParams(params);
      search.selectParam = selectParam.toString();
      return search;
    }
    $("input:checkbox").change(function () {
      var selectParam = "";
      $("input[name='selectParam']:checked").each(function () {
        selectParam = selectParam + $(this).val() + ",";
      });
      query();
    });
    /**
     * 选择部门树
     */
    function ztreeShowDept() {
      // url 可选参数, 其他参数 请自定扩展
      // permission 权限 0.无权限 1.按照登录人数据权限
      // checkType 选中类型 0.多选 1.单选
      // showLevel 展示层级
      var url = ctx + "sys/deptTree?checkType=1&showLevel=4";
      var options = {
        title: '选择部门',
        width: "500",
        url: url,
        callBack: function (index,layero) {
          var body = layer.getChildFrame('body', index);
          $("#createDeptId").val(body.find('#ids').val());
          $("#createDeptName").val(body.find('#names').val());
          layer.close(index);
        }
      };
      $.modal.openOptionsDeptTree(options, $("#createDeptId").val());
    }
    /**
     * 选择部门树
     */
    function ztreeShowDept2() {
      // url 可选参数, 其他参数 请自定扩展
      // permission 权限 0.无权限 1.按照登录人数据权限
      // checkType 选中类型 0.多选 1.单选
      // showLevel 展示层级
      var url = ctx + "sys/deptTree?checkType=1&showLevel=4";
      var options = {
        title: '选择部门',
        width: "500",
        url: url,
        callBack: function (index,layero) {
          var body = layer.getChildFrame('body', index);
          $("#flowDeptId").val(body.find('#ids').val());
          $("#flowDeptName").val(body.find('#names').val());
          layer.close(index);
        }
      };
      $.modal.openOptionsDeptTree(options, $("#flowDeptId").val());
    }
    /**
     * 选择用户树
     */
    function ztreeShowUser() {
      // url 可选参数, 其他参数 请自定扩展
      // permission 权限 0.无权限 1.按照登录人数据权限
      // showType 展示方式 0.人员 1.人员+工号
      // checkType 选中类型 0.多选 1.单选
      // showLevel 展示层级
      var url = ctx + "sys/userDeptTree?showType=1&showLevel=3&checkType=0";
      var options = {
        title: '选择部门',
        width: "500",
        url: url,
        callBack: function (index,layero) {
          var body = layer.getChildFrame('body', index);
          $("#userId").val(body.find('#ids').val());
          $("#userName").val(body.find('#names').val());
          layer.close(index);
        }
      };
      $.modal.openOptionsUserTree(options, $("#userId").val());
    }
    //重置
    function reset() {
      $.form.reset();
      $("#accountTime").val('');
      $("#accountStartTime").val('');
      $("#accountEndTime").val('');
    }
    </script>
</body>
</html>

页面代码解析

image.png

image.png

image.png

image.png

页面核心函数query(),页面代码就说这么多,具体的可以查看源码,下面来看一下后端java代码

java代码

controllerk类AccountFlowInfoRecordDataController.java源码

package com.dongao.project.accountflowinforecorddata.controller;
import java.util.List;
import java.util.Map;
import com.dongao.project.examtype.domain.ExamType;
import com.dongao.project.examtype.service.IExamTypeService;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;
import com.ruoyi.framework.aspectj.lang.annotation.Log;
import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
import com.dongao.project.accountflowinforecorddata.domain.AccountFlowInfoRecordData;
import com.dongao.project.accountflowinforecorddata.service.IAccountFlowInfoRecordDataService;
import com.ruoyi.framework.web.controller.BaseController;
import com.ruoyi.framework.web.page.TableDataInfo;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.common.utils.poi.ExcelUtil;
/**
 * 流转记录统计信息操作处理
 * 
 * @author dongao
 * @date 2022-07-01
 */
@Controller
@RequestMapping("/project/accountFlowInfoRecordData")
public class AccountFlowInfoRecordDataController extends BaseController
{
    private String prefix = "project/accountFlowInfoRecordData";
  @Autowired
  private IAccountFlowInfoRecordDataService accountFlowInfoRecordDataService;
  @Autowired
  private IExamTypeService examTypeService;
  @RequiresPermissions("project:accountFlowInfoRecordData:view")
  @GetMapping()
  public String accountFlowInfoRecordData(ModelMap mmap)
  {
    ExamType examType = new ExamType();
    List<ExamType> examTypes = examTypeService.selectExamTypeList(examType);
    mmap.put("examTypes",examTypes);
      return prefix + "/accountFlowInfoRecordData";
  }
  /**
   * 查询流转记录统计列表
   */
  @RequiresPermissions("project:accountFlowInfoRecordData:list")
  @PostMapping("/list")
  @ResponseBody
  public TableDataInfo list(@RequestParam Map<String,Object> params)
  {
    startPage();
        List<AccountFlowInfoRecordData> list =
        accountFlowInfoRecordDataService.selectAccountFlowInfoRecordDataListOther(params);
    return getDataTable(list);
  }
  /**
   * 分组查询流转记录统计列表
   */
  @RequiresPermissions("project:accountFlowInfoRecordData:list")
  @PostMapping("/getAccountDataGroup")
  @ResponseBody
  public TableDataInfo getAccountDataGroup(@RequestParam Map<String,Object> params)
  {
    startPage();
        List<AccountFlowInfoRecordData> list =
        accountFlowInfoRecordDataService.getAccountDataGroup(params);
    return getDataTable(list);
  }
}

后端java代码解析

image.png

image.png

业务逻辑实现类AccountFlowInfoRecordDataServiceImpl.java代码

package com.dongao.project.accountflowinforecorddata.service;
import com.dongao.project.accountflowinforecorddata.domain.AccountFlowInfoRecordData;
import com.dongao.project.accountflowinforecorddata.mapper.AccountFlowInfoRecordDataMapper;
import com.dongao.project.examtype.domain.ExamType;
import com.dongao.project.examtype.mapper.ExamTypeMapper;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.text.Convert;
import com.ruoyi.project.system.dept.domain.Dept;
import com.ruoyi.project.system.dept.mapper.DeptMapper;
import com.ruoyi.project.system.user.domain.User;
import com.ruoyi.project.system.user.mapper.UserMapper;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
import java.util.Objects;
/**
 * 流转记录统计 服务层实现
 * 
 * @author dongao
 * @date 2022-07-01
 */
@Service
public class AccountFlowInfoRecordDataServiceImpl implements IAccountFlowInfoRecordDataService 
{
  @Autowired
  private AccountFlowInfoRecordDataMapper accountFlowInfoRecordDataMapper;
  @Autowired
  private DeptMapper deptMapper;
  @Autowired
  private ExamTypeMapper examTypeMapper;
  @Autowired
  private UserMapper userMapper;
  /**
     * 查询流转记录统计列表
     * 
     * @param accountFlowInfoRecordData 流转记录统计信息
     * @return 流转记录统计集合
     */
  @Override
  public List<AccountFlowInfoRecordData> selectAccountFlowInfoRecordDataList(AccountFlowInfoRecordData accountFlowInfoRecordData)
  {
      return accountFlowInfoRecordDataMapper.selectAccountFlowInfoRecordDataList(accountFlowInfoRecordData);
  }
  /**
   * 查询数据
   * @param params
   * @return
   */
  @Override
  public List<AccountFlowInfoRecordData> selectAccountFlowInfoRecordDataListOther(Map<String,Object> params) {
    List<AccountFlowInfoRecordData> list =
        accountFlowInfoRecordDataMapper.selectAccountFlowInfoRecordDataListOther(params);
    return list;
  }
  /**
   * 分组查询流转记录统计列表
   * @param params
   * @return
   */
  @Override
  public List<AccountFlowInfoRecordData> getAccountDataGroup(Map<String,Object> params) {
    //分组参数
    String selectParam = (String) params.get("selectParam");
    if (StringUtils.isNotEmpty(selectParam)) {
      String groupby = "";
      String groupfield = "";
      if (selectParam.contains("1")) {
        groupby = groupby + "channel_type,";
        groupfield = groupfield + "channel_type channel_type,";
      }
      if (selectParam.contains("2")) {
        groupby = groupby + "create_dept_id,";
        groupfield = groupfield + "create_dept_id create_dept_id,";
      }
      if (selectParam.contains("3")) {
        groupby = groupby + "flow_dept_id,";
        groupfield = groupfield + "flow_dept_id flow_dept_id,";
      }
      if (selectParam.contains("4")) {
        groupby = groupby + "exam_type_id,";
        groupfield = groupfield + "exam_type_id exam_type_id,";
      }
      if (selectParam.contains("5")) {
        groupby = groupby + "shift_id,";
        groupfield = groupfield + "shift_id shift_id,";
      }
      if (selectParam.contains("6")) {
        groupby = groupby + "user_id,";
        groupfield = groupfield + "user_id user_id,";
      }
      if (selectParam.contains("7")) {
        groupby = groupby + "account_time";
        groupfield = groupfield + "account_time account_time,";
      }
      if (groupby.endsWith(",")) {
        groupby = groupby.substring(0, groupby.length() - 1);
      }
      params.put("groupby",groupby);
      //字段用
      groupfield = groupfield + "SUM(allot_nums) allot_nums,SUM(daily_order_nums) daily_order_nums,SUM(total_order_nums) total_order_nums ";
      params.put("groupfield",groupfield);
    }
    List<AccountFlowInfoRecordData> list = accountFlowInfoRecordDataMapper.selectAccountFlowInfoRecordDataListOther(params);
    if (CollectionUtils.isNotEmpty(list)) {
      // 1 数据类型-页面处理  3 流转部门 4 考种 5 班次--页面处理 6 员工 7 时间粒度
      for (AccountFlowInfoRecordData account : list) {
        //2 数据来源
        if (Objects.nonNull(account.getCreateDeptId())) {
          Dept dept = deptMapper.selectDeptById(account.getCreateDeptId());
          if (Objects.nonNull(dept)) {
            account.setCreateDeptName(dept.getDeptName());
          }
        }
        //3 流转部门
        if (Objects.nonNull(account.getFlowDeptId())) {
          Dept dept = deptMapper.selectDeptById(account.getFlowDeptId());
          if (Objects.nonNull(dept)) {
            account.setFlowDeptName(dept.getDeptName());
          }
        }
        //4 考种
        if (Objects.nonNull(account.getExamTypeId())) {
          ExamType examType = examTypeMapper.selectExamTypeById(account.getExamTypeId());
          if (Objects.nonNull(examType)) {
            account.setExamTypeName(examType.getExamName());
          }
        }
        //6 员工
        if (Objects.nonNull(account.getUserId())) {
          User user = userMapper.selectUserById(account.getUserId());
          if (Objects.nonNull(user)) {
            account.setUserName(user.getUserName());
          }
        }
      }
    }
    return list;
  }
}

XML代码AccountFlowInfoRecordDataMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.dongao.project.accountflowinforecorddata.mapper.AccountFlowInfoRecordDataMapper">
    <resultMap type="AccountFlowInfoRecordData" id="AccountFlowInfoRecordDataResult">
        <result property="id"    column="id"    />
        <result property="accountTime"    column="account_time"    />
        <result property="userId"    column="user_id"    />
        <result property="deptId"    column="dept_id"    />
        <result property="channelType"    column="channel_type"    />
        <result property="createDeptId"    column="create_dept_id"    />
        <result property="flowDeptId"    column="flow_dept_id"    />
        <result property="examTypeId"    column="exam_type_id"    />
        <result property="shiftId"    column="shift_id"    />
        <result property="smallestUnit"    column="smallest_unit"    />
        <result property="allotNums"    column="allot_nums"    />
        <result property="dailyOrderNums"    column="daily_order_nums"    />
        <result property="totalOrderNums"    column="total_order_nums"    />
        <result property="createTime"    column="create_time"    />
        <result property="updateTime"    column="update_time"    />
    </resultMap>
    <sql id="selectAccountFlowInfoRecordDataVo">
        select id, account_time, user_id, dept_id, channel_type, create_dept_id, flow_dept_id, exam_type_id, shift_id, smallest_unit, allot_nums, daily_order_nums, total_order_nums, create_time, update_time from crm_account_flow_info_record_data
    </sql>
    <select id="selectAccountFlowInfoRecordDataList" parameterType="AccountFlowInfoRecordData" resultMap="AccountFlowInfoRecordDataResult">
        <include refid="selectAccountFlowInfoRecordDataVo"/>
        <where>
            <if test="id != null "> and id = #{id}</if>
            <if test="accountTime != null "> and account_time = #{accountTime}</if>
            <if test="userId != null "> and user_id = #{userId}</if>
            <if test="deptId != null "> and dept_id = #{deptId}</if>
            <if test="channelType != null "> and channel_type = #{channelType}</if>
            <if test="createDeptId != null "> and create_dept_id = #{createDeptId}</if>
            <if test="flowDeptId != null "> and flow_dept_id = #{flowDeptId}</if>
            <if test="examTypeId != null "> and exam_type_id = #{examTypeId}</if>
            <if test="shiftId != null "> and shift_id = #{shiftId}</if>
            <if test="smallestUnit != null  and smallestUnit != '' "> and smallest_unit = #{smallestUnit}</if>
            <if test="allotNums != null "> and allot_nums = #{allotNums}</if>
            <if test="dailyOrderNums != null "> and daily_order_nums = #{dailyOrderNums}</if>
            <if test="totalOrderNums != null "> and total_order_nums = #{totalOrderNums}</if>
            <if test="createTime != null "> and create_time = #{createTime}</if>
            <if test="updateTime != null "> and update_time = #{updateTime}</if>
        </where>
    </select>
    <select id="selectAccountFlowInfoRecordDataListOther" parameterType="Map"
            resultMap="AccountFlowInfoRecordDataResult">
        <choose>
            <when test="params.groupby != null and params.groupby != ''">
                select ${params.groupfield} from crm_account_flow_info_record_data
            </when>
            <otherwise>
                <include refid="selectAccountFlowInfoRecordDataVo"/>
            </otherwise>
        </choose>
        <where>
            <if test="params != null">
                <if test="params.channelType != null and params.channelType != ''"> and channel_type = #{params.channelType}</if>
                <if test="params.examTypeId != null and params.examTypeId != ''"> and exam_type_id = #{params.examTypeId}</if>
                <if test="params.shiftId != null and params.shiftId != ''"> and shift_id = #{params.shiftId}</if>
                <if test="params.userIds != null and params.userIds != '' and params.userIds.size() > 0">
                    AND user_id IN
                    <foreach collection="params.userIds" item="userId" open="(" close=")" separator=",">
                        #{userId}
                    </foreach>
                </if>
                <if test="params.flowDeptIds != null and params.flowDeptIds != '' and params.flowDeptIds.size() > 0">
                    AND flow_dept_id IN
                    <foreach collection="params.flowDeptIds" item="flowDeptId" open="(" close=")" separator=",">
                        #{flowDeptId}
                    </foreach>
                </if>
                <if
                        test="params.createDeptIds != null and params.createDeptIds != '' and params.createDeptIds.size() > 0">
                    AND create_dept_id IN
                    <foreach collection="params.createDeptIds" item="createDeptId" open="(" close=")" separator=",">
                        #{createDeptId}
                    </foreach>
                </if>
                <if test="params.accountStartTime != null and params.accountStartTime != ''" >
                    AND account_time &gt;= #{params.accountStartTime}
                </if>
                <if test="params.accountEndTime != null and params.accountEndTime != '' " >
                    AND account_time &lt;= #{params.accountEndTime}
                </if>
            </if>
        </where>
        <if test="params.groupby != null and params.groupby != ''">
            group by ${params.groupby}
        </if>
    </select>
</mapper>

xml代码解析,主要关注id为selectAccountFlowInfoRecordDataListOther的sql查询,这里用到了${},那么这里也顺便说一下#{} ${}的区别

#{} ${}的区别

#{}将传入的参数当成一个字符串,会给传入的参数加一个双引号

${}将传入的参数直接显示生成在sql中,不会添加引号

#{}能够很大程度上防止sql注入,${}无法防止sql注入

通过使用${}接收业务逻辑层处理动态传入的字段名动态生成分组查询sql,同时根据页面动态展示查询数据,到这里整个业务逻辑流程也就算完成了,实现的效果就和开始看到的效果一样了。



相关文章
|
1月前
|
消息中间件 存储 缓存
十万订单每秒热点数据架构优化实践深度解析
【11月更文挑战第20天】随着互联网技术的飞速发展,电子商务平台在高峰时段需要处理海量订单,这对系统的性能、稳定性和扩展性提出了极高的要求。尤其是在“双十一”、“618”等大型促销活动中,每秒需要处理数万甚至数十万笔订单,这对系统的热点数据处理能力构成了严峻挑战。本文将深入探讨如何优化架构以应对每秒十万订单级别的热点数据处理,从历史背景、功能点、业务场景、底层原理以及使用Java模拟示例等多个维度进行剖析。
55 8
|
1月前
|
存储 分布式计算 数据挖掘
数据架构 ODPS 是什么?
数据架构 ODPS 是什么?
336 7
|
1月前
|
数据采集 搜索推荐 数据管理
数据架构 CDP 是什么?
数据架构 CDP 是什么?
57 2
|
1月前
|
数据采集 监控 前端开发
二级公立医院绩效考核系统源码,B/S架构,前后端分别基于Spring Boot和Avue框架
医院绩效管理系统通过与HIS系统的无缝对接,实现数据网络化采集、评价结果透明化管理及奖金分配自动化生成。系统涵盖科室和个人绩效考核、医疗质量考核、数据采集、绩效工资核算、收支核算、工作量统计、单项奖惩等功能,提升绩效评估的全面性、准确性和公正性。技术栈采用B/S架构,前后端分别基于Spring Boot和Avue框架。
|
2月前
|
人工智能 自然语言处理 前端开发
SpringBoot + 通义千问 + 自定义React组件:支持EventStream数据解析的技术实践
【10月更文挑战第7天】在现代Web开发中,集成多种技术栈以实现复杂的功能需求已成为常态。本文将详细介绍如何使用SpringBoot作为后端框架,结合阿里巴巴的通义千问(一个强大的自然语言处理服务),并通过自定义React组件来支持服务器发送事件(SSE, Server-Sent Events)的EventStream数据解析。这一组合不仅能够实现高效的实时通信,还能利用AI技术提升用户体验。
239 2
|
24天前
|
负载均衡 Java 开发者
深入探索Spring Cloud与Spring Boot:构建微服务架构的实践经验
深入探索Spring Cloud与Spring Boot:构建微服务架构的实践经验
78 5
|
1月前
|
SQL 前端开发 关系型数据库
SpringBoot使用mysql查询昨天、今天、过去一周、过去半年、过去一年数据
SpringBoot使用mysql查询昨天、今天、过去一周、过去半年、过去一年数据
65 9
|
1月前
|
NoSQL Java API
springboot项目Redis统计在线用户
通过本文的介绍,您可以在Spring Boot项目中使用Redis实现在线用户统计。通过合理配置Redis和实现用户登录、注销及统计逻辑,您可以高效地管理在线用户。希望本文的详细解释和代码示例能帮助您在实际项目中成功应用这一技术。
41 4
|
2月前
|
SQL JSON Java
mybatis使用三:springboot整合mybatis,使用PageHelper 进行分页操作,并整合swagger2。使用正规的开发模式:定义统一的数据返回格式和请求模块
这篇文章介绍了如何在Spring Boot项目中整合MyBatis和PageHelper进行分页操作,并且集成Swagger2来生成API文档,同时定义了统一的数据返回格式和请求模块。
78 1
mybatis使用三:springboot整合mybatis,使用PageHelper 进行分页操作,并整合swagger2。使用正规的开发模式:定义统一的数据返回格式和请求模块
|
1月前
|
存储 easyexcel Java
SpringBoot+EasyExcel轻松实现300万数据快速导出!
本文介绍了在项目开发中使用Apache POI进行数据导入导出的常见问题及解决方案。首先比较了HSSFWorkbook、XSSFWorkbook和SXSSFWorkbook三种传统POI版本的优缺点,然后根据数据量大小推荐了合适的使用场景。接着重点介绍了如何使用EasyExcel处理超百万数据的导入导出,包括分批查询、分批写入Excel、分批插入数据库等技术细节。通过测试,300万数据的导出用时约2分15秒,导入用时约91秒,展示了高效的数据处理能力。最后总结了公司现有做法的不足,并提出了改进方向。