🌈有幸相识 ,我是小相。有一个大厂梦,努力奔赴!加油陌生人!🌈 ??该文章是跟随B站狂神学习Mybatis时的笔记与心得,若与您有用,感谢点赞。文章不免有不足之处,请指出,我会及时改正!
该部分代码位于:mybatis-05-DynamicSQL · xcy.小相/web-Mybatis - 码云 - 开源中国 (gitee.com)
1. 环境搭建
2. 多对一查询
2.1 按照查询嵌套处理
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="top.xcyxiaoxiang.dao.StudentMapper">
<resultMap id="StudentTeacher" type="Student">
<result column="id" property="id"/>
<result column="name" property="name"/>
<association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/>
</resultMap>
<select id="getStudentList" resultMap="StudentTeacher">
select * from student;
</select>
<select id="getTeacher" resultType="Teacher">
select * from teacher where id=#{id}
</select>
</mapper>
2.2按照结果嵌套查询(重要)
<select id="getStudentList2" resultMap="StudentTeacher2" >
select s.id sid,s.name sname,t.name tname
from student s,teacher t
where t.id=s.tid;
</select>
<resultMap id="StudentTeacher2" type="Student">
<result column="sid" property="id"/>
<result column="sname" property="name"/>
<association property="teacher" javaType="Teacher">
<result property="name" column="tname"/>
</association>
</resultMap>
3. 一对多查询
List<Teacher> getStudent(int id);
<select id="getStudent" resultMap="studentTeacher">
select t.id tid, t.name tname,s.id sid, s.name sname
from student s,teacher t
where t.id=s.tid and t.id=#{id}
</select>
<resultMap id="studentTeacher" type="Teacher">
<result property="id" column="tid"/>
<result property="name" column="tname"/>
<collection property="student" ofType="Student">
<result property="id" column="sid"/>
<result property="name" column="sname"/>
<result property="tid" column="tid"/>
</collection>
</resultMap>
javaType 用于指定实体类中的属性的类型
ofType用来指定映射到list或集合中的pojo类型,泛型中的约束类型。
4. 动态SQL
4.1 定义
- 动态 SQL 是 MyBatis 的强大特性之一。
- 动态SQL就是根据不同的条件产生或执行不同的SQL语句。
- 动态SQL元素与JSTL类似,包含以下几种元素:
- if
- choose(when,otherwise)
- trim(where ,set)
- foreach
4.2 环境搭建
CREATE TABLE `blog`(
`id` VARCHAR(50) NOT NULL COMMENT '博客id',
`title` VARCHAR(100) NOT NULL COMMENT '博客标题',
`author` VARCHAR(30) NOT NULL COMMENT '博客作者',
`create_time` DATETIME NOT NULL COMMENT '创建时间',
`views` INT(30) NOT NULL COMMENT '浏览量'
)ENGINE=INNODB DEFAULT CHARSET=utf8
package top.xcyxiaoxiang.units;
import org.junit.Test;
import java.util.UUID;
public class IDUnits {
public static String getUUID(){
return UUID.randomUUID().toString().replace("-","");
}
}
- 开启驼峰命名自动映射,即从经典数据库列名 A_COLUMN 映射到经典 Java 属性名 aColumn
<settings>
<setting name="mapUnderscoreToCamelCase" value="true "/>
</settings>
<insert id="addBlog" parameterType="Blog">
insert into blog values(#{id},#{title},#{author},#{createTime},#{views})
</insert>
</mapper>
@Test
public void addBlog(){
SqlSession sqlSession = MybatisUnits.getSqlSession();
BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
Blog blog = new Blog();
blog.setId(IDUnits.getUUID());
blog.setTitle("Mybatis");
blog.setAuthor("狂神说");
blog.setCreateTime(new Date());
blog.setViews(9999);
mapper.addBlog(blog);
blog.setId(IDUnits.getUUID());
blog.setTitle("Java");
mapper.addBlog(blog);
blog.setId(IDUnits.getUUID());
blog.setTitle("Spring");
mapper.addBlog(blog);
blog.setId(IDUnits.getUUID());
blog.setTitle("微服务");
mapper.addBlog(blog);
sqlSession.commit();
sqlSession.close();
}
4.3 if元素
通过if语句来判断参数的值,从而选择性的添加语句。例如:当title为空,author不为空时,语句为select* from blog where 1=1 and author=#{autor} 。
<select id="getBlogIf" parameterType="map" resultType="Blog">
select * from blog where 1=1
<if test="title!=null">
and title=#{title}
</if>
<if test="author!=null">
and author=#{author}
</if>
</select>
4.4 choose元素
类似java中的switch语句,给定有限个数的条件来进行判断(when),并指定默认情况(otherwise)。
<select id="getBlogChoose" parameterType="map" resultType="Blog">
select * from blog
<choose>
<when test="title!=null">
where title=#{title}
</when>
<when test="author!=null">
where author=#{author}
</when>
<when test="title!=null and author!=null">
where title=#{title} and author=#{author}
</when>
<otherwise>
where 1=1
</otherwise>
</choose>
</select>
4.5 where元素
可以观察到,在if元素中我们在where后添加了1=1 ,这样做的原因是为了防止当所有条件都不满足时产生错误语句(select * from blog where )或(select * from blog where and author=#{author} )。
mybatis给我们提供了更为简便智能的方式:where元素。where 元素只会在子元素返回任何内容的情况下才插入 “WHERE” 子句。而且,若第一个 子句的开头为 “AND” 或 “OR”,where 元素也会自动将它们去除,例如:当title!=null and author=null 时sql语句为``。
<select id="getBlogWhere" parameterType="map" resultType="Blog">
select * from blog
<where>
<if test="title!=null">
and title=#{title}
</if>
<if test="author!=null">
and author=#{author}
</if>
</where>
</select>
因此,4.4中的语句可以改为:
<select id="getBlogChoose" parameterType="map" resultType="Blog">
select * from blog
<where>
<choose>
<when test="title!=null">
title=#{title}
</when>
<when test="author!=null">
author=#{author}
</when>
<when test="title!=null and author!=null">
title=#{title} and author=#{author}
</when>
</choose>
</where>
</select>
4.6 set元素
类似于where元素,对于更新时,set 元素可以用于动态包含需要更新的列,忽略其它不更新的列。set 元素会动态地在行首插入 SET 关键字,并会删掉额外的逗号。
<select id="updateBlogSet" resultType="Blog" parameterType="map">
update blog
<set>
<if test="author!=null">
author=#{author},
</if>
<if test="views!=null">
views=#{views},
</if>
</set>
where id=#{id}
</select>
4.7 trim元素
和 where 元素等价的自定义 trim 元素为:
<trim prefix="WHERE" prefixOverrides="AND |OR "></trim>
与 set 元素等价的自定义 trim 元素:
<trim prefix="SET" suffixOverrides=","></trim>
4.8 SQL片段
即将一些重复性sql语句通过SQL元素进行包装,并通过id进行唯一标识。通过<include>元素在多处进行调用,实现代码的复用。
如下方代码,
<select id="getBlogIf" parameterType="map" resultType="Blog">
select * from blog where 1=1
<if test="title!=null">
and title=#{title}
</if>
<if test="author!=null">
and author=#{author}
</if>
</select>
<select id="getBlogWhere" parameterType="map" resultType="Blog">
select * from blog
<where>
<if test="title!=null">
and title=#{title}
</if>
<if test="author!=null">
and author=#{author}
</if>
</where>
</select>
可以替换为:
<select id="getBlogIf" parameterType="map" resultType="Blog">
select * from blog where 1=1
<include refid="if"/>
</select>
<select id="getBlogWhere" parameterType="map" resultType="Blog">
select * from blog
<where>
<include refid="if"/>
</where>
</select>
<sql id="if">
<if test="title!=null">
and title=#{title}
</if>
<if test="author!=null">
and author=#{author}
</if>
</sql>
4.9 foreach
动态 SQL 的另一个常见使用场景是对集合进行遍历(尤其是在构建 IN 条件语句的时候)。通过map传入ids参数,遍历ids或多个元素。比如:
<select id="getBlogForeach" parameterType="map" resultType="Blog">
select * from blog
<where>
id in
<foreach collection="ids" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</where>
</select>
的执行语句之一为:select * from blog where id in (1,2,3)
|