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

测试环境的搭建:

本篇文章的测试环境搭建和上篇文章基本相似,如有需要请移至上篇文章

上篇文章所提到的多对一是多个学生对应一个老师,是在查询学生信息的同时去获取对应老师的相关信息,而本篇文章的一对多,是在在查询老师信息的同时去获取对应学生的信息

新建实体类:

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

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

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文件中进行书写,所以对于学生的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.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[一对多]
2:javaType:用来指定实体类中的属性类型      ofType:用来指定映射到List或集合中的pojo类型,也就是泛型中的约束类型
3:编写的SQL语句应保证可读性强
4:注意一对一和多对一中的属性名和字段问题
  • 5
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

从未止步..

谢谢你的打赏,我会继续努力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值