https://blog.youkuaiyun.com/e_anjing/article/details/49908459
springMVC下,MyBatis实现复杂查询
springMVC和MyBatis基础环境配置这里不表。
一、情况如下:(实体类的其他参数此处不写)
-
用户表user: id,user_name,nick_name,...
-
用户类User: id,userName,nickName,...
-
-
课程表lession: id,less_name,speeker,...
-
课程类Lession: id,leeName,speeker,...
-
-
关系表user_lession: id,user_id,less_id
-
关系类UserLession: id,userId,lessId
二、需要实现的查询情况:
1、对课程表查询时,查询出选课人数;
2、对关系表查询时,查询出对应的user和lession,并封装成User和Lession。
三、实现过程
1、对课程表查询时,查询出选课人数
(1)首先在Lession类中添加int stuCount(选课学生总数)字段,并set/get;(2)在lessionMapper.xml中配置resultMap(映射关系)
-
<resultMap id="BaseResultMap" type="cn.xxx.domain.Lession" > <!--对象所在包名自取-->
-
<id column="id" property="id" jdbcType="BIGINT" />
-
<result column="less_name" property="lessName" jdbcType="VARCHAR" />
-
<result column="speeker" property="speeker" jdbcType="VARCHAR" />
-
<association property="stuCount" select="getStuCount" column="{lessId=id}" javaType="java.lang.Integer"/>
-
</resultMap>
-
<select id="getStuCount" resultType="java.lang.Integer">
-
select count(1) as stuCount from user_lession where less_id=#{lessId,jdbcType=BIGINT};
-
</select>
(4)以下是MyBatis中findById方法获取Lession的sql配置:
-
<select id="findById" resultMap="WithConditionResult" parameterType="java.lang.Long" >
-
select *
-
from lession
-
where id = #{id,jdbcType=BIGINT}
-
</select>
小结:这种方法类似于一个sql语句:
-
select l.*,( select count( 1) from user_lession ul where ul.less_id=?) as stuCount
-
from lession l where l.id=?
2、对关系表查询时,查询出对应的user和lession,并封装成User和Lession
(1)在UserLession类中,添加User user和Lession lession属性,并set/get(2)配置UserLessionMapper.xml中的resultMap(映射关系)
-
<resultMap id="BaseResultMap" type="cn.xxx.domain.UserLession" >
-
<id column="id" property="id" jdbcType="BIGINT" />
-
<result column="user_id" property="userId" jdbcType="VARCHAR" />
-
<result column="less_id" property="lessId" jdbcType="VARCHAR" />
-
<association property="user" resultMap="UserResultMap" javaType="cn.xxx.domain.User"/>
-
<association property="lession" resultMap="LessionResultMap" javaType="cn.xxx.domain.Lession"/>
-
</resultMap>
(3)则需要再配置相应的UserResultMap和LessionResultMap:
-
<resultMap id="UserResultMap" type="cn.xxx.domain.User" >
-
<id column="id" property="id" jdbcType="VARCHAR" />
-
<result column="user_name" property="userName" jdbcType="VARCHAR" />
-
<result column="nick_name" property="nickName" jdbcType="VARCHAR" />
-
</resultMap>
-
<resultMap id="LessionResultMap" type="cn.xxx.domain.Lession" >
-
<id column="id" property="id" jdbcType="BIGINT" />
-
<result column="less_name" property="lessName" jdbcType="VARCHAR" />
-
<result column="speeker" property="speeker" jdbcType="VARCHAR" />
-
</resultMap>
-
< select id= "findById" resultMap= "BaseResultMap" parameterType= "java.lang.Long" >
-
select ul.*,u.*,l.*
-
from user_lession ul
-
left join user u on ul.user_id=u.id
-
left join lession l on ul.less_id=l.id
-
where ul.id = #{ id,jdbcType= BIGINT}
-
</ select>
于是,findById就能讲u.*和l.*通过映射关系,封装成User和Lession,而通过BaseResultMap添加到UserLession中。
查询出来的结果结构如下:
-
UserLession:
-
{
-
userId:xxx,
-
lessId:xxx,
-
user:{
-
id:xxx,
-
....
-
},
-
lession:{
-
id:xxx,
-
....
-
}
-
}
#引申:模糊查询findList(分页这里就不写了)
-
<select id="findList" resultMap="BaseResultMap">
-
select ul.*,u.*,l.*
-
from user_lession ul
-
left join user u on ul.user_id=u.id
-
left join lession l on ul.less_id=l.id
-
<include refid="baseCondition"/>
-
order by ul.create_time DESC
-
</select>
-
<sql id="baseCondition">
-
<where>
-
1=1
-
<if test="userId != null" >
-
and ul.user_id = #{userId,jdbcType=VARCHAR}
-
</if>
-
<if test="lessId != null" >
-
and ul.less_id = #{lessId,jdbcType=VARCHAR}
-
</if>
-
<if test="keyword != null" >
-
and CONCAT(
-
IFNULL(u.user_name,''),IFNULL(u.nick_name,''),
-
IFNULL(l.less_name,''),IFNULL(l.speeker,'')
-
) like CONCAT('%',#{keyword,jdbcType=VARCHAR},'%')
-
</if>
-
</where>
-
</sql>