mybatis实现复杂查询

mybatis实现复杂查询

实现复杂查询的环境配置

我们需要准备的东西:

  • 两个带有相联结的数据库表格(以student和teacher为例)
  • 创建一个带有日志的使用lambok插件的优化配置后的java项目

两个数据库表格的准备

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
CREATE TABLE `teacher` (
`id` INT(10) NOT NULL,
`name` VARCHAR(30) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8

INSERT INTO teacher(`id`, `name`) VALUES (1, 秦老师);

CREATE TABLE `student` (
`id` INT(10) NOT NULL,
`name` VARCHAR(30) DEFAULT NULL,
`tid` INT(10) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `fktid` (`tid`),
CONSTRAINT `fktid` FOREIGN KEY (`tid`) REFERENCES `teacher` (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8INSERT INTO `student` (`id`, `name`, `tid`) VALUES (1, 小明, 1);
INSERT INTO `student` (`id`, `name`, `tid`) VALUES (2, 小红, 1);
INSERT INTO `student` (`id`, `name`, `tid`) VALUES (3, 小张, 1);
INSERT INTO `student` (`id`, `name`, `tid`) VALUES (4, 小李, 1);
INSERT INTO `student` (`id`, `name`, `tid`) VALUES (5, 小王, 1);

在执行sql时注意:不能直接执行玩全部的sql,因为可能在执行插入操作前,还没有将表格建好。

java项目的准备

  • 导入lambok包(直接放到父项目的xml中,这样每个子项目都能直接使用了)

    1
    2
    3
    4
    5
    <dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.22</version>
    </dependency>
  • 设置日志(在子项目的核心配置文件中设置最简单的日志)

    1
    2
    3
    4
    <!--这里设置了一个最基础的日志-->
    <settings>
    <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>
  • 编写剩余的java程序(pojo,until等)

需要注意的点在于:

  • 这一次我么使用了两个实体类,因此为了体现分离的原则,我们把Mapper.xml创建到resource文件夹下,但是要求1.mapper.xml也有相同的包结构 2.mapper.xml与其对应的抽象类同名

    文件位置关系

  • 创建好的每一个xml都需要在核心配置文件中进行配置

    1
    2
    3
    4
    <mappers>
    <mapper resource="com/dwx/mapper/TeacherMapper.xml"/>
    <mapper resource="com/dwx/mapper/StudentMapper.xml"/>
    </mappers>

解释上述为何要相同的包结构:因为在生成target文件时,由于两者有相同的包结构 就会被当成是在一个包下,这就符合了我们之前要求的xml文件与接口类在同一包下且同名的要求

target文件结构

处理多对一问题

处理多对一问题即:从多个表中查寻相关联的数据。

处理方法在MySQL中有两种:

  • 子查询
  • 联表查询

因此在java程序中也出现两种方法:

  • 按照查询嵌套处理
  • 按照结果嵌套处理

按照查询嵌套处理

按照查询嵌套处理的逻辑等同于mysql中的子查询

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!--第一种使用子查询 基本原理 在查询到tid后再查询tname-->

<select id="getStudent_Teacher" resultMap="studentTeacherMap">
select * from mybatis.student1
</select>
<resultMap id="studentTeacherMap" type="Student">
<!--对于基本属性直接进行映射即可-->
<result property="id" column="id"/>
<result property="name" column="id"/>
<!--但是对于引用参数 需要使用assocation来操作-->
<!--这里是嵌套一个方法-->
<association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/>
</resultMap>
<select id="getTeacher" resultType="Teacher">
select * from mybatis.teacher where id = #{tid}
</select>

注意点:

  • 对于<resultmap>,如果是基本类型,直接使用映射即可
  • 如果是引用类型使用<association>
  • 如果是集合类型则使用<collection>

原理就是在每一次查询到tid时到teacher表中查询teacher的名字

用SQL表现为:

1
2
SELECT student1.`id`,student1.`name` ,(SELECT teacher.`name` WHERE teacher.`id` = student1.`tid`) AS teachername
FROM student1,teacher

按照结果嵌套处理

使用这种方法进行处理相当于sql中的联表查询

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!--使用联表查询-->
<select id="getStudent_Teacher2" resultMap="studentTeachermap">
<!--下边是使用链表查询的sql-->
select s.id sid,s.name sname,t.name tname
from student1 s,teacher t
where s.tid = t.id
</select>
<!--西边是链表查询的resultmap-->
<resultMap id="studentTeachermap" type="Student">
<result column="sid" property="id"/>
<result column="sname" property="name"/>
<association property="teacher" javaType="Teacher">
<result column="tname" property="name"/>
</association>
</resultMap>

注意:

  • 这里我们使用了大量的别名 因此在映射时,数据库一边的参数用别名表示
1
2
3
SELECT s.id sid,s.name sname,t.name tname
FROM student1 s,teacher t
WHERE s.tid = t.id

处理一对多问题

环境准备:一对多,一个老师对应多个学生,因此老师的参数有一个是一个一student为类型的集合

而学生参数变为和数据库中参数一样。

student类

1
2
3
4
5
6
7
8
9
10
11
//编写Student实体类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
private int id;
private String name;
//这里是一个联表 在java代码中 直接把链表的参数放进去
private int tid;
}

teacher类

1
2
3
4
5
6
7
8
9
10
//编写Teacher的实体类
//这里直接使用注解来完成实体类的完善
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Teacher {
private String name;
private int id;
private List<Student> studentList;
}

注意:此时由于teacher类中使用了List<Student>因此在SQLresultmap中有所改变

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<mapper namespace="com.dwx.mapper.TeacherMapper">
<select id="getTeacher" resultMap="teacherMap">
select s.id sid,s.name sname,t.name tname,t.id tid
from mybatis.teacher t, mybatis.student1 s
where s.tid = t.id
</select>
<resultMap id="teacherMap" type="Teacher">
<result property="id" column="id"/>
<result property="name" column="name"/>
<collection property="studentList" ofType="Student">
<result property="id" column="sid"/>
<result property="name" column="sname"/>
<result property="tid" column="stid"/>
</collection>
</resultMap>
</mapper>

注意:使用<collection property="java中的属性" foType="list的类型"></collection>这样来给List集合做映射。

Donate
  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.

扫一扫,分享到微信

微信分享二维码
  • Copyrights © 2015-2023 dwx
  • Visitors: | Views:

请我喝杯咖啡吧~

支付宝
微信