测试环境的搭建:
本篇文章的测试环境搭建和上篇文章基本相似,这里在上篇文章传送门测试环境的基础上进行对比和修改!
上篇文章所提到的多对一是多个学生对应一个老师,是在学生的角度去获取老师的信息,而本篇文章的一对多,是在老师的角度去获取对应学生的信息
新建实体类:
在实体类上,与上篇文章中的多对一不同的地方在于:
多对一:老师作为学生的一个属性
而这里的一对多:学生作为老师的一个属性
Student类:
package pojo;
import lombok.Data;
@Data
public class Student {
private int id;
private String name;
private int tid;
}
teacher类:
package pojo;
import lombok.Data;
import java.util.List;
@Data
public class Teacher {
private int id;
private String name;
//一个老师拥有多个学生
private List<Student> students;
}
注:数据库中表的创建和数据的插入步骤,与上篇文章的多对一完全相同,这里不再进行展示
新建Mapper接口:
student_Mapper接口:
package dao;
public interface student_Mapper {
}
teacher_Mapper接口:
package dao;
import pojo.Teacher;
import java.util.List;
public interface teacher_Mapper {
//获取老师
List<Teacher> getTeacher();
}
建立Mapper.xml文件:
student_Mapper.xml文件:
由于一对多是多个学生作为老师的属性,SQL语句自然是在teacher_Mapper.xml文件中进行书写,所以这里只需要绑定对应的接口,无需再进行其他操作
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="dao.student_Mapper">
</mapper>
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="dao.teacher_Mapper">
<select id="getTeacher" resultType="Teacher">
select * from teacher;
</select>
</mapper>
在核心配置文件[mybatis-config.xml]中绑定注册我们的Mapper接口或者文件:
由于是查询老师的有关信息,因此,这里绑定的为老师的接口teacher_Mapper
代码如下:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<typeAliases>
<package name="pojo"/>
</typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=false&useUnicode=true&characterEncoding=utf-8"/>
<property name="username" value="root"/>
<property name="password" value="xxx"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper class="dao.teacher_Mapper"/>
</mappers>
</configuration>
通过查询数据测试环境是否搭建成功:
package dao.user;
import dao.teacher_Mapper;
import pojo.Teacher;
import utils.mybatis_utils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.List;
public class test{
@Test
public void getUserByLimit(){
SqlSession sqlSession= mybatis_utils.getSqlSession();
teacher_Mapper teacher_mapper=sqlSession.getMapper(teacher_Mapper.class);
List<Teacher> teacherList=teacher_mapper.getTeacher();
System.out.println(teacherList);
sqlSession.close();
}
}
关于测试环境还有所需的三个文件,分别是:两个pom.xml文件,以及mybatis_utils类,在这篇文章有相应的代码,这里就不过多赘述了
输出部分结果如下:
测试成功!
但通过输出结果,我们不难发现,这里搭建的测试环境的输出结果,和多对一的关系一样,同样出现了students为null的现象,原因嘛,和上篇文章是相似的,不懂得小伙伴移步上篇文章,这里我们只给出具体的解决办法
一对多处理:
获取指定老师下的所有学生及老师的信息
按照查询嵌套处理:
方法如下:
基本与多对一的方法相似,唯一让人迷惑的就是这里为什么既有javaType还有ofType呢?
javaType用来指定对象所属的java数据类型,在多对一的关系中,多个学生对应一个老师,因此javaType的类型为Teacher,而在这里一个老师对应多个学生,那么javaType的类型可不是Student而是List,因为在实体类Teacher中students的类型就是ArrayList
ofType指定的是映射到list集合属性中泛型的类型,在一对多的关系中,学生[Student类]作为list集合的类型,因此ofType的值为Student
代码如下:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="dao.teacher_Mapper">
<select id="getTeacher2" resultMap="TeacherStudent">
select * from teacher where id=#{tid};
</select>
<resultMap id="TeacherStudent" type="Teacher">
<collection property="students" column="id" javaType="ArrayList" ofType="Student" select="getStudent"/>
</resultMap>
<select id="getStudent" resultType="Student">
select * from student where tid=#{tid};
</select>
</mapper>
按照结果嵌套处理:
在teacher_Mapper接口中编写方法:
package dao;
import org.apache.ibatis.annotations.Param;
import pojo.Teacher;
public interface teacher_Mapper {
//获取指定老师下的所有学生及老师的信息
Teacher getTeacher2(@Param("tid") int id);
}
在teacher_Mapper.xml文件中编写对应的SQL语句:
与多对一不同的是,这里我们对于复杂属性的处理是通过collection,而不是association,原因是多对一中,老师对于学生来说是一个对象,而这里的学生对于老师来说,是一个集合,association后面对应的是JavaType,而collection对应的是ofType,虽然它们的名称不同,但都指的是java类
代码如下:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="dao.teacher_Mapper">
<select id="getTeacher2" 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"/>
<collection property="students" ofType="Student">
<result property="id" column="sid"/>
<result property="name" column="sname"/>
<result property="tid" column="tid"/>
</collection>
</resultMap>
</mapper>
测试类代码如下:
package dao.user;
import dao.teacher_Mapper;
import pojo.Teacher;
import utils.mybatis_utils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
public class test{
@Test
public void getUserByLimit(){
SqlSession sqlSession= mybatis_utils.getSqlSession();
teacher_Mapper teacher_mapper=sqlSession.getMapper(teacher_Mapper.class);
Teacher teacherList=teacher_mapper.getTeacher2(1);
System.out.println(teacherList);
sqlSession.close();
}
}
部分输出结果如下:
无论上按照查询嵌套处理还是结果嵌套处理,都能够查询到正确的结果,大家可以根据自身情况,选择最适合自己的方法
最后提醒一些注意点:
1:关联----association[多对一] 集合----collection[一对多]
2:javaType:用来指定实体类中的属性类型 ofType:用来指定映射到List或集合中的pojo类型,也就是泛型中的约束类型
3:编写的SQL语句应保证可读性强
4:注意一对一和多对一中的属性名和字段问题