文章目录
一、对应关系
1、 一对一
MyBatis中使用association标签来解决一对一的关联查询,javaType属性是指关联元素的对象类型。
老师和学生。
从学生角度看:学生和老师是一对一的关系。
需求:如果有学生表和老师表,查询所有学生对应老师的名字
student
表
teacher
表
实体类
Student实体类:
Teacher实体类:
如果单单写sql语句:
SELECT s.id, s.username, t.tname
FROM student s, teacher t
WHERE s.tid=t.id
StudentMapper.xml
但那样是不行的。需要在xml中映射,要用resultMap和association,如下:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lu.mapper.StudentMapper">
<resultMap id="studentTeacher" type="com.lu.pojo.Student">
<result property="id" column="id"/>
<result property="username" column="username"/>
<association property="teacher" javaType="com.lu.pojo.Teacher">
<result property="tname" column="tname"/>
</association>
</resultMap>
<select id="findAllStudent" resultMap="studentTeacher">
SELECT s.id, s.username, t.tname
FROM student s, teacher t
WHERE s.tid=t.id
</select>
</mapper>
测试就调用方法就可以了。
2、 一对多
MyBatis中使用collection标签来解决一对多的关联查询,ofType属性指定集合中元素的对象类型。
还是 老师和学生。
这次,从老师角度看:就是一个老师对多个学生,一对多。
需求:如果有学生表和老师表,查询id为1的老师对应的所有学生。
学生表和老师表和一对一的一样。
实体类
Student实体类:
Teacher实体类:
如果单单写sql
SELECT s.id sid, s.username sname, t.tname tname, t.id tid
FROM student s, teacher t
WHERE s.tid=t.id and t.id =1
TeacherMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lu.mapper.TeacherMapper">
<resultMap id="teacherStudent" type="com.lu.pojo.Teacher">
<result property="id" column="id"/>
<result property="tname" column="tname"/>
<collection property="studentList" ofType="com.lu.pojo.Student">
<result property="id" column="tid"/>
<result property="username" column="sname"/>
</collection>
</resultMap>
<select id="teacherList" resultMap="teacherStudent">
SELECT s.id sid, s.username sname, t.tname tname, t.id tid
FROM student s, teacher t
WHERE s.tid=t.id and t.id = #{id}
</select>
</mapper>
3、 多对多
待补充
二、动态sql
动态 SQL 是 MyBatis 的强大特性之一。例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL,可以彻底摆脱这种痛苦。
mybatis动态sql语句是基于OGNL表达式的,主要有:
- if 语句 (简单的条件判断)
- choose (when,otherwize) ,相当于java 语言中的 switch
- where (主要是用来简化sql语句中where条件判断的,能智能的处理 and or ,不必担心多余导致语法错误)、
- set (主要用于更新时)
- trim (对包含的内容加上 prefix,或者 suffix 等,前缀,后缀)
- foreach (在实现 mybatis in 语句查询时特别有用)
1、if 标签
if标签根据判断条件进行sql拼接。如下,如果参数不为空,就会拼接
<select id="findActiveBlogWithTitleLike" resultType="Blog">
SELECT * FROM BLOG
WHERE state = ‘ACTIVE’
<if test="title != null">
AND title like #{title}
</if>
</select>
如上:如果title为空,所有处于 “ACTIVE” 状态的 BLOG都会返回;
如果title不为空,所有处于 “ACTIVE” 状态和title对应的BLOG会返回。
2、choose (when,otherwize)标签
有时候,我们不想使用所有的条件,而只是想从多个条件中选择一个使用。针对这种情况,MyBatis 提供了 choose 元素。
<select id="findActiveBlogLike" resultType="Blog">
SELECT * FROM BLOG WHERE state = ‘ACTIVE’
<choose>
<when test="title != null">
AND title like #{title}
</when>
<when test="author != null and author.name != null">
AND author_name like #{author.name}
</when>
<otherwise>
AND featured = 1
</otherwise>
</choose>
</select>
如上:如果传了title,就根据title查找;如果传入了author,就根据author查询;如果都没传入,就返回 <otherwise>
标签里面的查询。
3、where 标签
如下:将 “state = ‘ACTIVE’” 设置成动态条件,如果两个if条件都不成立,或者只有第二的if条件成立,那sql语句的格式是有问题,导致错误。
<select id="findActiveBlogLike" resultType="Blog">
SELECT * FROM BLOG
WHERE
<if test="state != null">
state = #{state}
</if>
<if test="title != null">
AND title like #{title}
</if>
</select>
简单改动一下就可以了把where换成标签,如下:
<select id="findActiveBlogLike"
resultType="Blog">
SELECT * FROM BLOG
<where>
<if test="state != null">
state = #{state}
</if>
<if test="title != null">
AND title like #{title}
</if>
</where>
</select>
where 元素只会在子元素返回任何内容的情况下才插入 “WHERE” 子句。而且,若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除。
4、set 标签
set 元素可以用于动态包含需要更新的列,忽略其它不更新的列。
比如:
<update id="updateAuthorIfNecessary">
update Author
<set>
<if test="username != null">username=#{username},</if>
<if test="password != null">password=#{password},</if>
<if test="email != null">email=#{email},</if>
<if test="bio != null">bio=#{bio}</if>
</set>
where id=#{id}
</update>
set元素会动态地在行首插入 SET 关键字,并会删掉额外的逗号。
5、trim
trim 是 set和 where 元素等价的自定义元素。
就是说用trim自定义可以实现set和where元素的效果
比如,和 where 元素等价的自定义 trim 元素为:
<!-- 移除首部所有指定在 prefixOverrides 属性中的内容,
并且插入 prefix 属性中指定的内容-->
<trim prefix="WHERE" prefixOverrides="AND |OR ">
...
</trim>
与 set 元素等价的自定义 trim 元素:
<!-- 移除尾部所有指定在 suffixOverrides 属性中的内容,
并且插入 prefix 属性中指定的内容-->
<trim prefix="SET" suffixOverrides=",">
...
</trim>
6、foreach
foreach 是用来对集合进行遍历(尤其是在构建 IN 条件语句的时候)
foreach标签有以下几个属性collection, item,index,open,separator,close。
-
collection表示需要遍历的集合
-
item 表示每次遍历时生成的对象名
-
index表示在迭代过程中,每次迭代到的位置
-
open表示开始遍历时要拼接的字符串,代表开始
-
separator表示在每次遍历时两个对象直接的连接字符串,代表遇到这个要分割
-
close表示结束遍历时要拼接的字符串,代表结束
当使用 Map 对象时,index 是键,item 是值。
在使用foreach的时候针对不同的参数类型, collection属性值要分为以下3种情况:
1.如果传入的是单参数且参数类型是一个List的时候,collection属性值为list
2.如果传入的是单参数且参数类型是一个array数组的时候,collection的属性值为array
3.如果传入的参数是多个的时候,我们就需要把它们封装成一个Map或者Object。
<select id="selectPostIn" resultType="domain.blog.Post">
SELECT *
FROM POST P
WHERE ID in
<foreach item="item" index="index" collection="list"
open="(" separator="," close=")">
#{item}
</foreach>
</select>
参考官网:动态sql
<!-- 只有一个List参数时它的参数名为list,即collection="list" ; 如果参数类型时数组object[],则 collection="array" -->
<select id="foreachTest" resultType="com.sl.po.Product">
select * from products
<where>
<if test="list!=null">
<foreach item="id" index="index" collection="list" open="id
in(" separator="," close=")">
#{id}
</foreach>
</if>
</where>
</select>
三、sql片段
在代码中,我们可以将常用的代码封装成一个类或者方法,重复使用。
sql元素就可以提取重复的sql,使用时用 include 引用就行了。
提取
<sql id="userColumns">
...
</sql>
使用
把 include 引用放到要使用的地方
<include refid="userColumns"/>