Mybatis的OneToMany,ManyToOne和解决N+1查询问题

OneToMany

1.在”one”的实体类总添加many的一对多关系:

private List studentList;//(get和set方法略)

2.在”many”的配置文件中添加查询的方法:

  
    <select id="selectStudentByTeacherId" parameterType="java.lang.Integer" resultMap="BaseResultMap">
        select * from student where teacher_id=#{teacherId,jdbcType=INTEGER}
    select>

3.在”one”的配置文件的resultMap中添加一个集合:

 
      <collection property="studentList" column="teacher_id" ofType="com.shinowit.entity.Student" select="com.shinowit.dao.mapper.StudentMapper.selectStudentByTeacherId">
      collection>

4.编写单元测试

    @Resource
    private Teacher1Mapper teacher1DAO;
    protected final Logger logger = Logger.getLogger(getClass());
    @Test
    public void test1() {
        Teacher1 teacher11=teacher1DAO.selectByPrimaryKey(1);
        for(Student stu:teacher11.getStudentList()){
            logger.debug(stu.getName());
        }
     }

ManyToOne

1.在”many”的实体类总添加one的多对一关系:

  private Teacher1 tea;//(get和set方法略)

2.在many的配置文件中添加映射的关联(association):
(因为查many的数据本质是从xml文件查的,所以要在xml文件中把刚才的tea字段添加到映射result中)

 
<association property="tea" column="teacher_id" javaType="com.shinowit.entity.Teacher1"         select="com.shinowit.dao.mapper.Teacher1Mapper.selectByPrimaryKey"/>

3.编写单元测试

    @Resource
    private StudentMapper studentDAO;
    protected final Logger logger = Logger.getLogger(getClass());
    @Test
    public void test1() {
        Student stu=studentDAO.selectByPrimaryKey(2);//ManyToOne查学生信息,会把老师信息一同查出
        logger.debug(stu.getTea().getName());
          }

解决N+1查询问题

方法一:

  • 在one的标签下添加一个标签

方法二:
1. 在many的实体类中添加要附带查出来的字段,如:

 private String teacherName;//(get和set方法略)

2.在many的Mapper中添加一个接口,如:

List selectStudentWithTeacherNameByPrimaryKey(Integer student_id);

3.在many的xml文件最下面新添加一个和一个,如:


<resultMap id="resultMapWithTeacherName" type="com.shinowit.entity.Student" extends="BaseResultMap">
        <result column="teacher_name" property="teacherName" jdbcType="VARCHAR"/>
resultMap>             
    


    <select id="selectStudentWithTeacherNameByPrimaryKey" parameterType="java.lang.Integer" resultMap="resultMapWithTeacherName">
        select a.*,b.name as teacher_name from student a inner join teacher1 b on a.teacher_id=b.teacher_id where student_id=#{student_id,jdbcType=INTEGER}
    select>               

4.编写单元测试

    @Resource
    private StudentMapper studentDAO;
    protected final Logger logger = Logger.getLogger(getClass());
    @Test
List studentList=studentDAO.selectStudentWithTeacherNameByPrimaryKey(1);
    //用自己写sql语句的方法解决N+1查询问题                  logger.debug(studentList.get(0).getTeacherName());
                    }

注:尽量少用collection 和association 标签,因是他是N+1查询,而hibernate就是N+1查询

方法二扩展:

1.在many的实体类中添加要附带查出来的字段,如:

private String teacherName;//(get和set方法略)

2.在many的Mapper中添加一个接口,如:

List<Student> selectStudentWithTeacherNameByPrimaryKey(StudentExample example);

3.在many的xml文件最下面新添加一个和一个,如:


    <resultMap id="resultMapWithTeacherName" type="com.shinowit.entity.Student" extends="BaseResultMap">
        <result column="teacher_name" property="teacherName" jdbcType="VARCHAR"/>
    resultMap>

    <select id="selectStudentWithTeacherNameByPrimaryKey" parameterType="com.shinowit.entity.StudentExample" resultMap="resultMapWithTeacherName">
        select *,(select name from teacher1 where teacher1.teacher_id=student.teacher_id) as teacher_name from student
        <if test="_parameter != null">
            <include refid="Example_Where_Clause"/>
        if>
        <if test="orderByClause != null">
            order by ${orderByClause}
        if>
    select>

4.编写单元测试

    @Resource
    private Teacher1Mapper teacher1DAO;
    protected final Logger logger = Logger.getLogger(getClass());
    @Test
    public void test1() {
      StudentExample ex=new StudentExample();//比较复杂的用StudentExample作参数的方法解决N+1问题
        ex.createCriteria().andTeacherIdEqualTo(1);
        List studentList=studentDAO.selectStudentWithTeacherNameByPrimaryKey(ex);
        for(Student student:studentList){
            logger.debug(student.getTeacherName());
        }}

你可能感兴趣的:(mybatis)