问题背景:
springboot + mybatis + vue项目,IDEA开发。
绩效计划通过eid(员工编号)关联一个员工,有一个绩效计划表还有一个员工表。
关联方式为:嵌套查询。可以有两种实现方式:
第一种,不列举绩效计划表列和绩效计划bean属性的对应关系和数据类型(开始采取的方式):
<resultMap id="PRResultMap1" type="bshr.bean.EmpPlanResult">
<association property="emp" javaType="bshr.bean.Employee"
select="bshr.mapper.EmpMapper.getEmpByEid"
column="eid"></association>
</resultMap>
第二种,列举出绩效计划表的列和绩效计划bean属性的对应关系以及数据类型(最终采取的方式):
<resultMap id="PRResultMap2" type="bshr.bean.EmpPlanResult">
<id column="rowid" property="rowid" jdbcType="VARCHAR"/>
<result column="eid" property="eid" jdbcType="VARCHAR"/>
<result column="submitdate" property="submitdate" jdbcType="TIMESTAMP"/>
<result column="startdate" property="startdate" jdbcType="TIMESTAMP"/>
<result column="enddate" property="enddate" jdbcType="TIMESTAMP"/>
<result column="g_taskpoint" property="g_taskpoint" jdbcType="INTEGER"/>
<result column="g_appoint" property="g_appoint" jdbcType="INTEGER"/>
<result column="g_timepoint" property="g_timepoint" jdbcType="INTEGER"/>
<result column="r_taskpoint" property="r_taskpoint" jdbcType="INTEGER"/>
<result column="r_appoint" property="r_appoint" jdbcType="INTEGER"/>
<result column="state" property="state" jdbcType="INTEGER"/>
<result column="remark" property="remark" jdbcType="VARCHAR"/>
<result column="deleted" property="deleted" jdbcType="TINYINT"/>
<association property="emp" javaType="bshr.bean.Employee"
select="bshr.mapper.EmpMapper.getEmpByEid"
column="eid">
</association>
</resultMap>
当然,也可以通过嵌套resultmap的方式关联两个表,但是定义resultmap和进行查询时,相对来说都会比较繁琐,所以一开始我就没有采取这种方式。
在查询绩效计划时,想要根据员工名称进行筛选。
问题描述:
后端程序能够正常启动,但是前端进行相关查询操作时,从后端传过来的数据有问题。chrome浏览器,F12可见:
1.绩效计划对象中的eid为null,但是有根据该eid查到的emp。
2.后端传来的count(前端分页,后端传过来的数据的个数)为null,甚至根本就不显示。
后端因为有相应的try...catch...语句所以打印了调用栈,显示错误:
org.springframework.jdbc.BadSqlGrammarException:
### Error querying database. Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'from emp_pfmplanresult ep ,employee emp
where ep.eid = emp.id
' at line 2
### The error may exist in bshr/mapper/PfmMapper.xml
### The error may involve defaultParameterMap
### The error occurred while setting parameters
### SQL: select count * from emp_pfmplanresult ep ,employee emp where ep.eid = emp.id and ep.state = 0
### Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'from emp_pfmplanresult ep ,employee emp
where ep.eid = emp.id
' at line 2
; bad SQL grammar []; nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'from emp_pfmplanresult ep ,employee emp
where ep.eid = emp.id
' at line 2
at ...
(在本问题中,前端一个请求(获取满足条件的绩效计划),后端进行两次查询:
1.查询满足条件的绩效计划信息(同时要满足前端分页的约束,即页数以及每页显示的数据条数);
2.查询满足条件的绩效计划的数量(不必考虑页数和每页的数据条数)
两次查询报错相似。)
问题分析:
根据错误信息:
### The error may involve defaultParameterMap
### The error occurred while setting parameters
可知,与参数有关。
复制这两行信息,到浏览器,也有人遇到过类似的问题,有人说是因为参数类型不明确所致。
解决方案:
将问题背景中描述的关联:嵌套查询的实现改为第二种方式,问题解决。
(提示,问题虽然解决了,但未必是因为参数类型不明确,因为原本采取的嵌套查询的方式不仅没有指明参数类型,也没有指明参数,就是没有指明列和属性以及其对应关系。可以通过实验,删除上述代码中的参数类型相关的语句,看运行结果。当然也可以通过深入了解mybatis的运行机制和语法在理论上得到答案。)
启发:
熟悉mybatis的工作流程或许能更早的发现导致的问题的可能原因(参数不明)。
最终解决此问题的关键是:发现了那两行错误信息,同时在网上找到了相似问题,并发现了可能的问题原因,且尝试了第二种嵌套查询的方式。
由此可见,错误信息是首要参考,网友们的问题和回答也是非常重要的参考,必要的知识有助于我们在找到可能的原因后快速想到如何修改。
最后,大胆猜想,小心尝试。