以下转自兰陵王同学的博文
mybatis中的三个巨坑
一、The content of element type “resultMap” must match “(constructor?,id*,result*,association*,collection*,discriminator?)”.
有时候,明明resultMap根本没问题,可就总是会报这个莫名其妙的错(我这里用的是ssm)
后来无意间在一篇博客上看到说只要把tab键换成空格就行
ok了
这个错我纠结了两天,想破头皮都想不出来居然是这么回事!!
但是,大多数情况下报这个错都是因为顺序不对,只要按照顺序写就没错了,我这个问题算是很奇葩的了!!!
二、同样的sql语句在mybatis中运行出来的结果集中的数据量比在数据库中运行出来的少
——以下是我遇到的问题
mapper接口
ThinkIdeaData这个类的功能是存储查询到的想法的数据
content字段就是想法的内容,其对应类ThinkIdeaContent的字段可以不用管,不是重点
这是对应的resultMap
这是前端传过来的参数:
这是对应的select语句,其功能就是根据传进来的userId查询想法,并判断是否赞或踩
这是测试controller,传过去的参数中,userId=1,isUserLogin=true,filter=1
service层略过
当请求到findThinkIdea.do时,会将获取的数据打印到控制台
可以看到,这里只有三条数据,但是如果把对应的sql语句放到数据库中运行
数据库中运行得到的结果
可以看到,这里总共有9条数据
问题就来了,这是为什么呢?!
这是因为,如果你查询的数据中没有唯一标识每行的字段的话,mybatis会过滤掉那些它觉得重复了的数据,所以如果只有isAgree和isStepon这两个字段的话,我觉得最多查询到4条数据
那要怎么解决呢?其实很简单,只需加上一个id(我取名为virtualId即虚拟id,因为这个字段没用)即可,只要能唯一标识每一行就行,(多半使用主键)
对应的mapper.xml
sql
运行结果
这样,mybatis中和数据库中的结果就是一样的了。
三.SpringBoot中mapper接口和mapper.xml无法映射的问题
我在整个SpringBoot、mybatis的时候,最初一直使用的注解方式,没有整合过xml文件映射,几天内试了试,发现了一些很坑的问题,特意记录:
我按照网上的博文:
1.首先我在application.properties中配置了(扫描*mapper.xml)
mybatis.mapper-locations=classpath:mapping/*.xml
2.其次,在入口类中配置了(扫描mapper接口):
@MapperScan("edu.olp.lsnustudyonline.dao")
但是依然报错!mapper接口和mapper.xml依然无法映射!
springBoot Property ‘mapperLocations’ was not specified or no matching …
最后在雪化山河的博文中看到了正解
原来,对于“dao层”,有的人喜欢写成“mapper层”,其实哪种写法都是没有问题的,问题是如果使用"dao"这种写法,那么dao接口以及对应的映射文件,也要用dao来命名,如果使用“mapper”这种写法,则对应的映射文件也要使用mapper来命名,即“接口和映射文件”命名要一致!
原来我的包名是dao,但是内层是mapper和mapper.xml,所以出错了!!很奇葩的问题,今天记录了下来
后面发现,其实用两个步骤,先配置application.properties和入口类MapperScann也是可以的,但是必须是classpath*,具体原因我也不知。但是算是试出来
再总结一次
# mapper 映射
# 注意SpringBoot、Mybatis的mapper和mapper.xml映射有两种方式:
# 1.直接放mapper包下,在开关类中加上MapperScan("club.mzywucai.mapper") 就可以自动映射注入了
# 注意细节:此时如果你的包名是mapper则,文件也必须:是*Mapper和*Mapper.xml
# 此时如果你的包名是dao则,文件也必须:是*Dao和*Dao.xml
# 2.(1)在注解类上加MapperScan("club.mzywucai.dao")
# (2)在application.properties中加mybatis.mapper-locations=classpath*:mapper/*.xml
# 注意细节:此时必须是classpath*,不能是classpath,因为我写classpath的时候一直报错
# classpath*就没得问题!
# 这样的好处是可以把mapper.xml和mapper接口分开,mapper.xml可以直接放resources下面
# 并且没得上面第一种方法,对包名文件名的要求!