如何使用mybatis处理数据库关系中的一对多关系呢?

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

测试环境的搭建

本篇文章的测试环境搭建和上篇文章基本相似这里在上篇文章传送门测试环境的基础上进行对比和修改

上篇文章所提到的多对一是多个学生对应一个老师是在学生的角度去获取老师的信息而本篇文章的一对多是在老师的角度去获取对应学生的信息

新建实体类

在实体类上与上篇文章中的多对一不同的地方在于

多对一老师作为学生的一个属性
而这里的一对多学生作为老师的一个属性

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&amp;useUnicode=true&amp;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[一对多]
2javaType:用来指定实体类中的属性类型      ofType用来指定映射到List或集合中的pojo类型也就是泛型中的约束类型
3编写的SQL语句应保证可读性强
4注意一对一和多对一中的属性名和字段问题
阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: 数据库