分页查询和多表联合查询
1.分页查询
普通查询
select * from user
分页查询基础:使用sql的limit关键字进行分页查询
缺陷:并不是所有数据库都使用limit进行分页查询的,因此这条语句不通用
SELECT * FROM table LIMIT [offset,] rows---->从第offset开始查询出rows条数据
select * from user LIMIT [offset,] rows
利用RowBounds实现通用分页
//在普通查询的基础上,改变java中的语句(调用Mapper部分做一些修改)
RowBounds rowBounds=new RowBounds(offset,rows);
User user = session.selectList("com.whether.mapper.UserMapper.findAll",null,rowBounds);
使用分页插件pageHelper(不推荐)
2.多表联合查询
多对一、一对多(不需要中间表)
一.创建表
//创建Teacher表
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
DROP TABLE IF EXISTS `teacher`;
CREATE TABLE `teacher` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
INSERT INTO `teacher` VALUES (1, '赵老师');
INSERT INTO `teacher` VALUES (2, '刘老师');
SET FOREIGN_KEY_CHECKS = 1;
//创建Student表
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`tid` int(10) NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE,
INDEX `tid`(`tid`) USING BTREE,
CONSTRAINT `student_ibfk_1` FOREIGN KEY (`tid`) REFERENCES `teacher` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
INSERT INTO `student` VALUES (1, '小明', 1);
INSERT INTO `student` VALUES (2, '小红', 1);
INSERT INTO `student` VALUES (3, '小王', 1);
INSERT INTO `student` VALUES (4, '小张', 2);
INSERT INTO `student` VALUES (5, '小李', 2);
INSERT INTO `student` VALUES (6, '小秦', 1);
SET FOREIGN_KEY_CHECKS = 1;
二.创建实体类Student/Teacher---每一个学生都有一个老师,这里关注学生
@Getter
@Setter
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class Student {
private int id;
private String name;
//学生需要关联一个老师
private Teacher teacher;
}
@Getter
@Setter
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class Teacher {
private int id;
private String name;
}
三.编写Mapper
多对一(多个学生对应一个老师,查询结果与一对一相似)
public interface StudentMapper {
//查询所有学生信息,以及对应的老师信息---联表查询
List finAllStudent();
//查询所有学生信息,以及对应的老师信息---嵌套查询(子查询)
List finAllStudent2();
}
嵌套查询(子查询---推荐使用)
实际上这是两个查询,在第一个查询的基础上,再进行一次查询,将第二次查询的结果注入到某一部分比如下面的案例,先查询所有的学生,然后根据查询到的tid列,再次进行教师信息查询,将这两部分查询到的信息映射到Student,其实就是在第一个查询的基础上,再进行第二个查询,将第二个查询的结果插入到某一个字段中进行输出
select * from student
select * from teacher WHERE id=#{id}
联表查询
select s.id sid,s.name sname,s.tid tid,t.name tname
from student s left join teacher t on s.tid=t.id
一对多(一个老师对应多个学生,这里关注老师)
实体类修改
public class Teacher {
private int id;
private String name;
//一个老师对应多个学生
private List students;
}
public class Student {
private int id;
private String name;
private int tid;
}
public interface TeacherMapper {
Teacher findTeacherById(@Param("tid") int id);
Teacher findTeacherById2(@Param("tid") int id);
}
/p>
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
select s.id sid,s.name sname,t.id tid,t.name tname
from student s,teacher t
WHERE s.tid=t.id and t.id=#{tid}
select * from teacher WHERE id=#{tid}
select * from student where tid=#{id}
多对多(需要中间表)
下面是一个博客查询的案例,每一篇文章有一个或者多个标签,同时一个标签有一篇或者多篇文章
文章表content中包含了文章id、文章内容......,中间表content_meta包含了文章id,对应的标签id,标签表metas包含了标签id、标签名
查询过程:先查找所有的文章,然后根据查询出来的文章id,去中间表查询出标签的id,再根据标签的id找出对应标签名
select m.name from content_meta cm,metas m WHERE cm.mid=m.mid AND m.type='tag' AND cm.cid=#{cid}
SELECT * FROM content