【Mybatis】(2)

【Mybatis】(2),第1张

文章目录
  • assciation和collection
  • 多对一
      • 子查询
      • 联表查询
  • 一对多
  • 动态SQL
      • if语句
      • switch语句
      • where标签
      • set标签
      • trim标签
      • sql片段(封装)
      • foreach标签

assciation和collection

association用来表示对象,collection用来表示集合

多对一 子查询


数据库的表如图所示,需求是查询学生和他们对应的老师信息。
实体类对象(pojo)如下:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
    private int id;
    private String name;
    //private int tid;
    private Teacher teacher;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Teacher {
    private int id;
    private String name;
}

学生的属性除了自己的id和姓名,还嵌套了一个老师类。
将查询的mapper这么写

<select id="getStudentList" resultType="Student" resultMap="map01">
    select * from student;
select>
<resultMap id="map01" type="Student">
    <result property="id" column="id"/>
    <result property="name" column="name"/>
    <association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/>
resultMap>
<select id="getTeacher" resultType="Teacher">
    select * from teacher where id=#{tid};
select>

结果是

理解一下mapper的做法:

  1. 先查询了所有学生的信息
  2. 由于teacher字段在db里映射不到,所以想到利用结果集映射,将某个结果映射给teacher字段
  3. association用于映射引用类型的字段,这个参数在java里叫teacherproperty,在db里叫tidcolumn(对于Student对象来说)
  4. 这个参数的类型是TeacherjavaType,用getTeacher这个select语句可以得到这个类型的结果集select
  5. 写getTeacher这个方法,这里取值取的 tid,就是在调用这个查询的里面的tid字段
联表查询

还是一样的表,一样的需求,mapper里换个方式查询

<select id="getStudentList2" resultMap="map02">
    select s.id sid,s.name sname,s.tid ,t.name tname
    from student s,teacher t
    where s.tid=t.id;
select>
<resultMap id="map02" type="Student">
    <result property="id" column="sid"/>
    <result property="name" column="sname"/>
    <association property="teacher" javaType="Teacher" >
        <result property="id" column="tid"/>
        <result property="name" column="tname"/>
    association>
resultMap>

理解一下mapper的做法:

  1. sql语句利用外键联表查询4个字段
  2. 结果集映射,将Student类的 id 和 name 分别对应查出来重命名的 sid 和 sname
  3. 关联剩下的两个结果,Student类的teacher参数所对应的类是Teacher,将查出来的 tid 和 tname 分别映射到teacher中的 id 和 name 上。

一对多

需求是查询每个老师对应的学生
老师类:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Teacher {
    private int id;
    private String name;
    private List<Student> student;
}

学生类:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
    private int id;
    private String name;
}

mapper内的语句:

<select id="getTeacherList" resultType="Teacher" resultMap="map01">
    select s.id sid,s.name sname,tid,t.name tname
    from mybatis.student s,mybatis.teacher t
    where s.tid=t.id;
select>
<resultMap id="map01" 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"/>
    collection>
resultMap>

collection 对应的是 List,而 ofType 用来指定泛型的类型。

动态SQL if语句

当没提供 title 时,所有的博客全部查出来,提供了 title 时,查指定的博客

<select id="queryByTitle" parameterType="map" resultType="blog">
	select * from blog where 1=1
	<if test="title != null">
		and  title=#{title}
	if>
select>
switch语句

mybatis里用的是choose-when-other,相当于Java里的switch-case-default,举个例子,需求还是当没提供 title 时,所有的博客全部查出来,提供了 title 时,查指定的博客

<select id="queryByTitle" parameterType="map" resultType="blog">
	select * from blog where 1=1
	<when test="title != null">
		and  title=#{title}
	when>
	<otherwise>
		and 2=2
	otherwise>
select>
where标签
<select id="queryByTitle" parameterType="map" resultType="blog">
	select * from blog 
	<where>
		<if test="title != null">
			and  title=#{title}
		if>
	where>
select>

当where标签里,有一个子句被调用,查询语句就会加上where关键字。
如果子句里有AND或者OR,并且作为where标签下第一个满足条件的子句,那么mybatis会帮助我们去掉这个ANDOR

set标签

类似于where标签,用于update标签,举个例子:
更新用户表的id和name
普通的sql语句:

update user set name="张三" where id=1

mybatis中使用set标签,变成动态修改后

<update id="updateUser" parameterType="map">
	update user
	<set>
		<if test="name != null">
			name=#{name},
		if>
	set>
	where id=#{id};
update>

set标签会去掉多余的,(逗号)

trim标签

是 where 和 set 的父类,不常用

<trim prefix="where" prefixOverrides="AND | OR">
	···
trim>
<trim prefix="set" suffixOverrides=",">
	···
trim>
sql片段(封装)

将一些sql 的公共部分抽取出来,方便复用,建议基于单表使用(少用)

<sql id="自定义sql片段id">
	···
sql>

<select···>
	···
		<include refid="自定义sql片段id" />
	···
select>

标签装需复用sql语句,加上id以便调用。在sql体内使用标签引用

foreach标签

用于在集合遍历,collection表示遍历的集合item,表示遍历出来的每个元素,index表示,open表示集合以什么开头,separator表示分隔符,close表示集合以什么结束

<select id="queryBlogForeach" parameterType="map" resultType="blog">
	select * from mybatis.blog
	<where>
		<foreach item="id" collection="ids" open="(" separator="," close=")">
			id=#{id}
		foreach>
	where>
select>

所以遍历的集合类似于:(id1,id2,id3)
这个查询语句本质就是在mybatis.blog里,如果ids里面有元素就根据这些id分别查询行,没有的话就全部查询(不加where语句)

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/795120.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-06
下一篇 2022-05-06

发表评论

登录后才能评论

评论列表(0条)

保存