今天在写多表查询时发现之前对mapper.xml的理解有误
情形:
有三张表(评论表、视频表、用户表),视频表中有个主键vid,用户表主键为uid,而评论表中有复合主键vid+uid+commenttime(其中uid是用户表的外键,而vid则是上面视频表的外键)。现在要通过vid查询出某个视频的所有评论信息。
最开始的解决方法和出现的问题:
mapper.xml写法:
<resultMap id="BaseResultMap" type="com.liaojiexin.videoweb.entity.Comments" >
<id column="commenttime" property="commenttime" jdbcType="TIMESTAMP" />
-----------↓↓↓下面两行不能省略-------------------
<!-- <id column="uid" property="uid" jdbcType="INTEGER" />-->
<!-- <id column="vid" property="vid" jdbcType="INTEGER" />-->
<result column="comment" property="comment" jdbcType="VARCHAR" />
<!-- 多对一的关系 多条评论对应一个评论人-->
<!-- column:指的是数据库队列名,property: 指的是属性名称, javaType:指的是属性的类型 -->
<association property="user" javaType="com.liaojiexin.videoweb.entity.User">
<id column="uid" property="uid" jdbcType="INTEGER" />
<result column="username" property="username" jdbcType="VARCHAR" />
<result column="password" property="password" jdbcType="VARCHAR" />
<result column="email" property="email" jdbcType="VARCHAR" />
<result column="birthday" property="birthday" jdbcType="DATE" />
</association>
<!-- 多对一的关系 多条评论对应一个视频-->
<!-- column:指的是数据库队列名,property: 指的是属性名称, javaType:指的是属性的类型 -->
<association property="video" javaType="com.liaojiexin.videoweb.entity.Video">
<id column="vid" property="vid" jdbcType="INTEGER" />
<result column="vname" property="vname" jdbcType="VARCHAR" />
<result column="vtag" property="vtag" jdbcType="CHAR" />
<result column="date" property="date" jdbcType="TIMESTAMP" />
<result column="uid" property="uid" jdbcType="INTEGER" />
<result column="introduce" property="introduce" jdbcType="VARCHAR" />
<result column="url" property="url" jdbcType="VARCHAR" />
<result column="imageurl" property="imageurl" jdbcType="VARCHAR" />
<result column="state" property="state" jdbcType="TINYINT" />
<result column="special" property="special" jdbcType="VARCHAR" />
<result column="countcomments" property="countcomments" jdbcType="INTEGER" />
<result column="countlikes" property="countlikes" jdbcType="INTEGER" />
<result column="countlooks" property="countlooks" jdbcType="INTEGER" />
</association>
</resultMap>
<!-- 查询视频全部评论 -->
<select id="selectcomments" resultMap="BaseResultMap">
select comments.*,username
from comments,user
where comments.uid=user.uid and comments.vid=#{vid,jdbcType=INTEGER}
</select>
如上所视,我一开始以为uid和vid作为外键,可以省略(因为我看好多教程这种多对一的关系时,是把外键给省略的),而且数据库表中也有定义这三个为外键所有应该没有什么问题。但是实际上如果不写在property="commenttime"的模块里面的话,就会出现把commenttime属性作为主键,而不是vid+uid+commenttime
下面贴上dubug的图和数据库的图,就可以看出错误了:全部5条数据,但是只查出3条,而且comment=156的值的uid应该为1,但是debug的结果却是23,这正是重复了id,所以就会出现这种情况
解决方法: 正确的写法就是把uid和vid补充上去,今后如果多对一关系中,多的一方的某个属性为id或复合id时,mapper中就不能省略,当然最保险的方法就是实体类中有的属性,mapper就写上。
正确写法:
<resultMap id="BaseResultMap" type="com.liaojiexin.videoweb.entity.Comments" >
<id column="commenttime" property="commenttime" jdbcType="TIMESTAMP" />
<id column="uid" property="uid" jdbcType="INTEGER" />
<id column="vid" property="vid" jdbcType="INTEGER" />
<result column="comment" property="comment" jdbcType="VARCHAR" />
代码省略(剩下的代码和上面的写法一样).....
</resultMap>