多对一:
按照查询嵌套处理:
StudentMapper:(接口很简单需要返回一个List)
package com.Li.dao;
import com.Li.pojo.Student;
import org.apache.ibatis.annotations.Select;
import java.util.List;
public interface StudentMapper {
//查询所有学生的信息,以及对应的老师的信息.难点在于写出对的sql
public List<Student> getStudent();
}
StudentMapper.xml:(难点:嵌套查询,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.Li.dao.StudentMapper">
<!--
思路:
1.查询所有的学生信息
2.根据查询出来的学生的tid,寻找对应的老师! 子查询-->
<select id="getStudent" resultMap="StudentTeacher">
select * from mybatis.student
</select>
<resultMap id="StudentTeacher" type="Student">
<result property="id" column="id"/>
<result property="name" column="name"/>
<!-- 复杂的属性,我们需要单独处理 对象:association 集合:collection 这里javaType并不重要,主要是其余的三个 -->
<association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/>
</resultMap>
<select id="getTeacher" resultType="Teacher">
select * from mybatis.teacher where id = #{id}
</select>
</mapper>
测试类增加的内容:
@Test
public void testStudent(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
List<Student> studentList = mapper.getStudent();
for (Student student : studentList) {
System.out.println(student);
}
sqlSession.close();
}
成功!
按照结果嵌套处理:
第二种方式的接口:
public List<Student> getStudent2();
StudentMapper.xml:详解可以看里面的注释。
<!--按照结果嵌套处理-->
<select id="getStudent2" resultMap="StudentTeacher2">
select s.id sid,s.name sname,t.name tname
from mybatis.student s,mybatis.teacher t
where s.tid = t.id
</select>
<resultMap id="StudentTeacher2" type="Student">
<result property="id" column="sid"/>
<result property="name" column="sname"/>
<!--由于老师的查询不是简单的字符类型,而是一个类(从pojo的Student可以知道),所以需要association-->
<!--property是实体类的名字,也就是pojo里参数的实际名字。后面javaType就相当于返回类型,这次我们需要查的是Teacher当然返回的就是Teacher了。相当于套娃。Student里面套了一个Teacher-->
<!--Teacher中property的内容是Teacher实体类中实际的参数名字,column同意都是数据库中列的名字-->
<association property="teacher" javaType="Teacher">
<result property="name" column="tname"/>
</association>
</resultMap>
在这里做一个小小的修改就可以测试了。
成功!
个人感觉第二种方式比较易于理解,并且方便使用。
如果第一种方式要连接5个表的话,还需要多写5个select分散的语句再将他们连起来。
在做一件事的时候一定是分工明确的。sql就写sql,对应关系就搞对应关系,分工明确。实现高内聚。这样分块之后,可读性强,而且易于修改。
问题:我没有查询老师的id为什么结果会有老师的id???
这两种对应两种sql查询方式:
子查询
联表查询
一对多:
配置基础环境:很简单。
创建moudule之后,复制06的这几个内容。pom.xml只需要导入一个lombox包就OK了
修改实体类,变为一对多。以下分别是Student和Teacher
package com.Li.pojo;
import lombok.Data;
@Data
public class Student {
private int id;
private String name;
private int tid;
}
package com.Li.pojo;
import lombok.Data;
import java.util.List;
@Data
public class Teacher {
private int id;
private String name;
//一个老师拥有多个学生
private List<Student> students;
}
编写这个
这个方式是我最喜欢的处理方式。
<select id="getTeacher" resultMap="TeacherStudent">
SELECT s.id sid,s.name sname,t.name tname,t.id,tid
from student s,teacher t
where s.tid = t.id and t.id = #{tid}
</select>
<resultMap id="TeacherStudent" type="Teacher">
<result property="id" column="tid"/>
<result property="name" column="tname"/>
<!-- 复杂的属性,我们需要单独处理 对象:association 集合:collection
javaType="" 指定属性的类型!
集合中的泛型信息,我们使用ofType获取.简单来说,用collection的时候使用ofType不用javaType
-->
<collection property="students" ofType="Student">
<result property="id" column="sid"/>
<result property="name" column="sname"/>
<result property="tid" column="tid"/>
</collection>
</resultMap>
注意看注释的内容。里面有解析。
创建测试文件:
@Test
public void Test(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);
Teacher teacher = mapper.getTeacher(1);
System.out.println(teacher);
sqlSession.close();
}
测试成功!
第二种方式:(个人不推荐)
接口代码:
//子查询的方式实现
Teacher getTeacher2(@Param("tid") int id);
TeacherMapper.xml:
<select id="getTeacher2" resultMap="TeacherStudent2">
select * from mybatis.teacher where id = #{tid}
</select>
<resultMap id="TeacherStudent2" type="Teacher">
<collection property="students" javaType="ArrayList" ofType="Student" select="getStudentByTeacherId" column="id"/>
</resultMap>
<select id="getStudentByTeacherId" resultType="Student">
select * from mybatis.student where tid = #{tid}
</select>
测试代码:
@Test
public void Test2(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);
Teacher teacher = mapper.getTeacher2(1);
System.out.println(teacher);
sqlSession.close();
}
成功!
小结:
javaType:实体类中属性的类型。也就是参数的数据类型
ofType:泛型中才会出现。值为泛型中的数据类型。如List<某某某>,那么ofType的值就是某某某。
面试高频:
- Mysql引擎
- InnoDB底层原理
- 索引
- 索引优化