动态sql
mybatis支持动态生成sql语言,以便于我们根据具体数据来动态生成SQL语句,动态sql的标签十分类似于前端的c标签。
if标签
if标签和我们平常的判断条件一样,格式为<if test=“筛选条件”>sql语句</if>
例如:我们查询学生的身高数据,输出高于这个年龄段的平均身高的学生,但是男女平均身高数据是不一样的,所以我们要拿性别做一个判断:
<select id="getAverageHeight" resultMap="Student">
select * from student where
<!--如果是男性则要求身高大于170cm,sex是接口(实现类)传过来的参数-->
<if test="sex==1">
height>1.70
</if>
</select>
别问为什么不能where sex==1 and height>1.70,我就是举个栗子!
where
那if标签来看,我动态生成sql筛选部分条件,那能不能只写查询语句,把所有的条件都交给动态生成,答案是可以的。
<select id="getStudentById" resultType="Student">
select * from STUDENT
<where>
<if test="studentId!=null">
<!--test里面的逻辑连接符不能写为&& 或者 || 而是写为单词的and和or-->
STUDENTID = #{studentId}
</if>
</where>
</select>
如上所示,所有的where语句都可以在下面动态生成,这里有个问题注意的是,多个条件时,第一个if标签下的sql不需要写where,但是从第二个开始必须写明and或者or,原因是mybatis不能知道这里到底是或还是且的关系,不要担心上个一个条件不生效会形成and and或者and or这种条件缺失的问题,mybatis会自动清除多余的关系符号。
choose
我们都熟悉了有if就应该有else,但是不好意思,这个真没有,当然所谓的没有就是你看不到这个字眼而已,当我们有已知的条件的时候我们自然可以用if标签一一列出,但是所有已知条件结束后其他情况做默认处理时,又没有else标签,这个时候就用choose标签了。
例如我们查看一个年级的班级学生,如果传过来了班级号码(唯一性,一年级一班为1001),我们就查询本班级信息,如果没有就查询所在的年级信息。
<choose>
<when test="classId!=null and classId!='nan'">
classid=#{classId}
</when>
<otherwise>
and gradeId=#{gradeId}
</otherwise>
</choose>
set
我们在新增或者更改数据表中的信息时,前端或者说客户端反馈给我们的不一定满足于表格数据的要求,例如非空约束,例如数据类型不一致。
举个例子,性别在我表格里是0,1标识,但是前台为男,女,假使我注入实体类是就是使用了男女,那么我要新增或者更改数据库的时候就得做出判断,把男女换成对应的0或1:
<insert id="addNewUser" parameterType="com.elvis.pojo.User">
insert into MYBATIS_DATA_TEST(userid,
name,
sex,
age,
content,
height,
weight,
hobbies) values(
#{userid},
#{name},
<set>
<!--多余的逗号会自动清除,不怕你写,就怕你不写-->
<if test="sex=='男'">'1',</if>
<if test="sex=='女'">'0',</if>
</set>
#{age},
#{content},
#{height},
#{weight},
#{hobbies})
</insert>
update同样如此。
foreach
顾名思义就是循环的标签,例如我们要取这个几个学生的数学平均分,我把他们的学号放在一个List<String> 中,参数名为:studentIds,也就是下面collection属性值。
<select id="getAverageByClass" resultType="Student">
select avg(score) from grade_sheet
<where>
studentid in
<!--colllecttion 集合;item 单一个体别名,与#{}中一致
open 开始字符,比如上面的"studentid in "我也可以把它放进open里面,
close 结束字符,separator 分隔符-->
<foreach collection="studentIds" item="studentId" open="(" close=")" separator=",">
#{studentId}
</foreach>
</where>
</select>
这样,mybatis就为我们自动生成了in条件sql。
如果list里面是实体类的话,则需要注意@Param 与 paramType不可以重复,在#{}调用属性值用item.xx来自动调取getIter获取。
<select id="getPermissionUrl" resultType="com.msun.oa.web.model.PermissionUrl">
select distinct ID as "id",MENU_URL as "menuUrl",RESOURCE_URL as "resourceUrl" from OADB.OA_MENU
<where>
MENU_URL in
<foreach collection="menus" item="menu" open="(" close=")" separator=",">
#{menu.menuUrl, jdbcType=VARCHAR}
</foreach>
</where>
</select>
声明jadcType是必不可少滴