You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot中MySQL语法错误如何修复?附报错与代码示例

问题分析与修复方案

错误原因

你开启了nativeQuery = true执行原生MySQL SQL,但同时在SQL中使用了HQL特有的NEW com.emp.employeeMangement.api.DTO.ResponseDTO(...)语法——MySQL原生SQL无法识别Java类的实例化逻辑,因此在该位置抛出SQL语法错误。

修复方案

方案一:改用HQL语法(关闭原生查询)

将nativeQuery = true改为nativeQuery = false,使用HQL查询以支持NEW DTO实例化语法,但需注意HQL不支持MySQL用户变量(如@per_day),需调整计算逻辑:

@Query(value = "select NEW com.emp.employeeMangement.api.DTO.ResponseDTO(" +
        "emp.empName, " +
        "emp.gender, " +
        "emp.email, " +
        "emp.empCode, " +
        "att.noOfAbsent, " +
        "att.noOfPresent, " +
        "att.month, " +
        "att.noOfDaysInMonth, " +
        "sal.salAmount, " +
        "round(sal.salAmount / att.noOfDaysInMonth), " +
        "round(att.noOfPresent * (sal.salAmount / att.noOfDaysInMonth)) " +
        ") " +
        "from Employee emp " +
        "join Attendence att on emp.emp_id = att.cp_fk " +
        "left join Salary sal on sal.emp_id_fk = emp.emp_id")
List<ResponseDTO> getInfoInExcel();

若不想重复计算sal.salAmount/att.noOfDaysInMonth,可在ResponseDTO中新增构造函数,传入基础字段后在DTO内部计算派生值:

// ResponseDTO新增构造函数
public ResponseDTO(String empName, String gender, String email, String empCode,
                   Integer noOfAbsent, Integer noOfPresent, String month, Integer noOfDaysInMonth,
                   BigDecimal salAmount) {
    this.empName = empName;
    this.gender = gender;
    this.email = email;
    this.empCode = empCode;
    this.noOfAbsent = noOfAbsent;
    this.noOfPresent = noOfPresent;
    this.month = month;
    this.noOfDaysInMonth = noOfDaysInMonth;
    this.salAmount = salAmount;
    this.salperday = salAmount.divide(new BigDecimal(noOfDaysInMonth), RoundingMode.HALF_UP);
    this.Salarycurrentmonth = salperday.multiply(new BigDecimal(noOfPresent));
}

对应简化后的HQL:

@Query(value = "select NEW com.emp.employeeMangement.api.DTO.ResponseDTO(" +
        "emp.empName, " +
        "emp.gender, " +
        "emp.email, " +
        "emp.empCode, " +
        "att.noOfAbsent, " +
        "att.noOfPresent, " +
        "att.month, " +
        "att.noOfDaysInMonth, " +
        "sal.salAmount " +
        ") " +
        "from Employee emp " +
        "join Attendence att on emp.emp_id = att.cp_fk " +
        "left join Salary sal on sal.emp_id_fk = emp.emp_id")
List<ResponseDTO> getInfoInExcel();

方案二:保留原生SQL,手动转换DTO

维持nativeQuery = true,仅查询原始字段,在Service层将Object[]类型的查询结果手动转换为ResponseDTO对象:

Repository代码修改:

@Query(value = "select " +
        "emp.empName, " +
        "emp.gender, " +
        "emp.email, " +
        "emp.empCode, " +
        "att.noOfAbsent, " +
        "att.noOfPresent, " +
        "att.month, " +
        "att.noOfDaysInMonth, " +
        "sal.salAmount, " +
        "round(sal.salAmount/att.noOfDaysInMonth) as salperday, " +
        "round(att.noOfPresent*(sal.salAmount/att.noOfDaysInMonth)) as Salarycurrentmonth " +
        "from Employee as emp " +
        "join Attendence as att " +
        "on emp.emp_id=att.cp_fk " +
        "left join Salary as sal " +
        "on sal.emp_id_fk=emp.emp_id", nativeQuery = true)
List<Object[]> getInfoInExcel();

Service层转换逻辑:

public List<ResponseDTO> getExcelInfo() {
    List<Object[]> rawData = employeeRepository.getInfoInExcel();
    List<ResponseDTO> dtoList = new ArrayList<>(rawData.size());
    for (Object[] row : rawData) {
        ResponseDTO dto = new ResponseDTO(
                (String) row[0],
                (String) row[1],
                (String) row[2],
                (String) row[3],
                (Integer) row[4],
                (Integer) row[5],
                (String) row[6],
                (Integer) row[7],
                (BigDecimal) row[8],
                (BigDecimal) row[9],
                (BigDecimal) row[10]
        );
        dtoList.add(dto);
    }
    return dtoList;
}

注意:需保证ResponseDTO存在与参数数量、类型匹配的构造函数,否则转换时会抛出异常。

内容的提问来源于stack exchange,提问作者kavitha G

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 04:50:24