【Mybatis】MyBatis 实现多表查询

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/sinat_42483341/article/details/100531875

大纲

Auto Mapping 单表实现(别名方式)
<resultMap>实现单表配置
单个对象关联查询(N+1,外连接)
集合对象关联查询
注解开发
MyBatis 运行原理


准备:创建数据库

  1. 创建表、录入测试数据
-- 教师表
create table teacher(
	id int(10) primary key auto_increment,
	name varchar(20)
);

insert into teacher values(default,'鱼老师');
insert into teacher values(default,'绿老师');
insert into teacher values(default,'酸老师');
insert into teacher values(default,'魔老师');

-- 学生表:tid含有外键约束
create table student(
	id int(10) primary key auto_increment,
	name varchar(20),
	age int(3),
	tid int(10),
	constraint fk_teacher foreign key (tid) REFERENCES teacher(id)
);

insert into student values(default,'学生1',25,1);
insert into student values(default,'学生2',28,1);
insert into student values(default,'学生3',24,3);
insert into student values(default,'学生4',24,3);
insert into student values(default,'学生5',26,2);
insert into student values(default,'学生6',25,2);
insert into student values(default,'学生7',28,4);
insert into student values(default,'学生8',21,4);
insert into student values(default,'学生9',21,1);
insert into student values(default,'学生10',22,1);
insert into student values(default,'学生11',27,1);

创建结果(学生表、教师表)
在这里插入图片描述 在这里插入图片描述
2. 模糊查询语法where 列 like '%内容%'

select * from student,teacher where student.name like '%学生%' and tid in (select id from teacher where name like '%鱼%') and tid=teacher.id;

查询结果:
在这里插入图片描述


课上笔记

使用JQuery
在这里插入图片描述

关于字符编码:tomcat默认使用iso-8859-1,网页中使用utf-8,所以会导致中文乱码。
在实际开发中,不要去修改tomcat的全局配置,会误伤到别人的项目。只能修改自己项目中的编码方式。如下:
在这里插入图片描述


一、MyBatis 实现多表查询

  1. Mybatis 实现多表查询方式
    1.1 业务装配.对两个表编写单表查询语句,在业务(Service)把查询的两个结果进行关联.
    1.2 使用Auto Mapping 特性,在实现两表联合查询时通过别名完成映射.
    1.3 使用MyBatis 的<resultMap>标签进行实现.
  2. 多表查询时,类中包含另一个类的对象的分类
    2.1 单个对象
    2.2 集合对象.

二、resultMap 标签

  1. <resultMap>标签写在mapper.xml 中,由程序员控制SQL 查询结果与实体类的映射关系.
    1.1 默认MyBatis 使用Auto Mapping 特性.
  2. 使用<resultMap>标签时,<select>标签不写 resultType 属性,而是使用 resultMap 属性引用<resultMap>标签.
  3. 使用resultMap 实现单表映射关系
    3.1 数据库设计
    在这里插入图片描述
    3.2 实体类设计
	public class Teacher{
		private int id1;
		private String name1;
	}

3.3 mapper.xml 代码

<resultMap type="teacher" id="mymap">
	<!-- 主键使用id 标签配置映射关系-->
	<id column="id" property="id1" />
	<!-- 其他列使用result 标签配置映射关系-->
	<result column="name" property="name1"/>
</resultMap>

<select id="selAll" resultMap="mymap">
	select * from teacher
</select>

4. 使用resultMap实现关联单个对象(N+1 方式)
4.1 N+1 查询方式,先查询出某个表的全部信息,根据这个表的信息查询另一个表的信息.
4.2 与业务装配的区别:
4.3.1 在 service 里面写的代码,由 mybatis 完成装配
4.3 实现步骤:
4.3.1 在 Student 实现类中包含了一个Teacher 对象

	public class Student {
		private int id;
		private String name;
		private int age;
		private int tid;
		private Teacher teacher;
		...

4.3.2 在TeacherMapper 中提供一个查询

<select id="selById" resultType="teacher" parameterType="int">
	select * from teacher where id=#{0}
</select>

4.3.3 在StudentMapper 中
4.3.3.1 <association> 装配一个对象时使用
4.3.3.2 property: 对象在类中的属性名
4.3.3.3 select:通过哪个查询查询出这个对象的信息
4.3.3.4 column: 把当前表的哪个列的值做为参数传递给另一个查询
4.3.3.5 大前提使用N+1 方式.时如果列名和属性名相同可以不配置,使用Auto mapping 特性.但是mybatis 默认只会给列
专配一次

5. 使用resultMap 实现关联单个对象(联合查询方式)
5.1 只需要编写一个SQL,在StudentMapper 中添加下面效果
5.1.1 只要专配一个对象就用这个标签
5.1.2 此时把<association/>小的<resultMap>看待
5.1.3 javaType 属性:<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.bjsxt.mapper.StudentMapper">

	<resultMap type="Student" id="stuMap">
		<result column="tid" property="tid"/>
		<!-- 如果关联一个对象 -->
		<association property="teacher" select="com.bjsxt.mapper.TeacherMapper.selById" column="tid"></association>
	</resultMap>
	
	<select id="selAll" resultMap="stuMap">
		select * from student
	</select>
	
	<resultMap type="Student" id="stuMap1">
	<!-- column是数据库查询语句起的别名,property是javabean对象属性名称.id是主键,result是普通键 -->
		<id column="sid" property="id"/>
		<result column="sname" property="name"/>
		<result column="age" property="age"/>
		<result column="tid" property="tid"/>
		<association property="teacher" javaType="Teacher" >
			<id column="tid" property="id"/>
			<result column="tname" property="name"/>
		</association>
	</resultMap>
	
	<select id="selAll1" resultMap="stuMap1">
		select s.id sid,s.name sname,age age,t.id tid,t.name tname FROM student s left outer join teacher t on s.tid=t.id
	</select>
</mapper>

test.java

package com.bjsxt.test;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import com.bjsxt.pojo.Student;


public class Test {
	public static void main(String[] args) throws IOException {	
		InputStream is = Resources.getResourceAsStream("mybatis.xml");
		SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
		SqlSession session = factory.openSession();
				
		List<Student> list = session.selectList("com.bjsxt.mapper.StudentMapper.selAll");
		System.out.println(list);
		
		List<Student> list1 = session.selectList("com.bjsxt.mapper.StudentMapper.selAll1");
		System.out.println(list1);
		
		session.close();
		System.out.println("程序执行结束");
	}
}
  1. N+1 方式和联合查询方式对比
    6.1 N+1:需求不确定时.
    6.2 联合查询:需求中确定查询时两个表一定都查询.
  2. N+1 名称由来
    7.1 举例:学生中有3 条数据
    7.2 需求:查询所有学生信息级授课老师信息
    7.3 需要执行的SQL 命令
    7.3.1 查询全部学生信息:select * from 学生
    7.3.2 执行3 遍select * from 老师where id=学生的外键
    7.4 使用多条SQl 命令查询两表数据时,如果希望把需要的数据都查询出来,需要执行N+1 条SQl 才能把所有数据库查询出来.
    7.5 缺点:
    7.5.1 效率低
    7.6 优点:
    7.6.1 如果有的时候不需要查询学生是同时查询老师.只需要执行一个select * from student;
    7.7 适用场景: 有的时候需要查询学生同时查询老师,有的时候只需要查询学生.
    7.8 如果解决N+1 查询带来的效率低的问题
    7.8.1 默认带的前提: 每次都是两个都查询.
    7.8.2 使用两表联合查询.

三.使用查询关联集合对象(N+1)

  1. 在Teacher 中添加List<Student>
public class Teacher {
	private int id;
	private String name;
	private List<Student> list;
  1. 在StudentMapper.xml 中添加通过 tid 查询
<select id="selByTid" parameterType="int" resultType="student">
	select * from student where tid=#{0}
</select>
  1. 在TeacherMapper.xml 中添加查询全部
    3.1 <collection/> 当属性是集合类型时使用的标签.
<resultMap type="teacher" id="mymap">
	<id column="id" property="id"/>
	<result column="name" property="name"/>
	<collection property="list"	select="com.bjsxt.mapper.StudentMapper.selByTid" column="id"></collection>
</resultMap>

<select id="selAll" resultMap="mymap">
	select * from teacher
</select>

猜你喜欢

转载自blog.csdn.net/sinat_42483341/article/details/100531875