springMVC下,MyBatis实现复杂查询

原创 2015年11月18日 16:34:15

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>
(3)利用association对stuCount添加查询方法getStuCount,并将参数lessId传送给该方法,该方法返回值是int类型。

<select id="getStuCount" resultType="java.lang.Integer">
    select count(1) as stuCount from user_lession where less_id=#{lessId,jdbcType=BIGINT};
</select>
通过getStuCount获取课程被选总数,又通过resultMap自动映射到Lession的属性stuCount上。

(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>
配置中,添加了user和lession的property,对这两个property,规定了它们的javaType和对应的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>
(4)做好这些准备后,我们来完成findById的实现:

<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,
		....
	}
}
小结:这么做的好处是:既能查询user_lession对应的user和lession的信息,又能根据关系表的字段来实现模糊查询。

#引申:模糊查询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>

mybatis多表复杂查询

基础部分可以查看我的另一篇博客http://haohaoxuexi.iteye.com/blog/1333271 MyBatis中在查询进行select映射的时候,返回类型可以用resultTy...

MyBatis嵌套查询解析

Mybatis表现关联关系比hibernate简单,没有分那么细致one-to-many、many-to-one、one-to-one。而是只有两种association(一)、collection(...
  • canot
  • canot
  • 2016年05月24日 00:41
  • 13613

MyBatis 多表联合查询及优化

序 这篇文章我打算来简单的谈谈 mybatis 的多表联合查询。起初是觉得挺简单的,没必要拿出来写,毕竟 mybatis 这东西现在是个开发的都会用,而且网上的文章也是一搜罗一大堆,根本就用不着我...

MyBatis-高级查询

假如我们有如下3张表 users表 +----------+-------------+------+-----+---------+----------------+ | Field | T...

mybatis ---- 级联查询 一对多 (集合映射)

关联有嵌套查询和嵌套结果两种方式,本文是按照嵌套结果这种方式来说明的 上一章介绍了多对一的关系,用到了,这是一个复杂类型的关联。我们选择一个示例来回顾下,比如:一个博客有一个用户,关联映射就工作于这种...
  • yulei_qq
  • yulei_qq
  • 2014年03月25日 20:09
  • 13147

MyBatis的动态SQL查询-让查询更灵活多变!

序言        MyBatis,大家都知道,半自动的ORM框架,原来叫ibatis,后来好像是10年apache软件基金组织把它托管给了goole code,就重新命名了MyBatis,功能相对...

mybatis学习笔记(二) 多pojo,复杂映射

现在在数据库增加两张表blog与comment ,即博客与评论表。 CREATE TABLE `blog` ( `id` int(11) NOT NULL default '0', `titl...

MyBatis SQL中如何比较大小

想在SSB(Spring+Spring MVC+MyBatis)中的Mapper.xml中配置查询语句,yin

mybatis框架的两种分页

mybatis有两种分页方法 1、内存分页,也就是假分页。本质是查出所有的数据然后根据游标的方式,截取需要的记录。如果数据量大,开销大和内存溢出。 使用方式: 利用自动生成的example类,加入my...

bootstrap table + spring + springmvc + mybatis 实现从前端到后端的表格分页

利用bootstrap table + java + spring + springmvc + mybatis 实现从前端到后端完整的分页流程  以上这些插件可以到这里下载Boots...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:springMVC下,MyBatis实现复杂查询
举报原因:
原因补充:

(最多只允许输入30个字)