[MyBatis] Advanced mapping many-to-one, one-to-many and lazy loading

Database preparation:

1. Many to one:

Multiple students correspond to a class (the student table is the main table, and the class table is the sub table)

Multiple implementation methods, including three common

  1. The first way: a sql statement, cascade attribute mapping

// StudentMapper.xml
// 一条sql语句, 级联属性映射
<resultMap id="studentResultMap" type="Student">
    <id property="sid" column="sid"/>
    <result property="sname" column="sname"/>
    <result property="clazz.cid" column="cid"/>
    <result property="clazz.cname" column="cname"/>
</resultMap>

<select id="selectById" resultMap="studentResultMap">
    select
        s.sid,s.sname,c.cid,c.cname
    from
        stu s left join clazz c on s.cid = c.cid
    where
        s.sid = #{sid}
</select>

// 接口
public interface StudentMapper{
    // 根据id获取学生信息, 同时获取学生关联的班级信息
    // 返回一个学生对象, 但是学生对象当中含有班级对象
    Student selectById(Integer id);
} 

// @test
public static void main(String[] args) {
    SqlSession sqlSession = SqlSessionUtil.openSession();
    CarMapper mapper = sqlSession.getMapper(StudentMapper.class);

    Student student = mapper.selectById(6);
    System.out.println(student);
    sqlSession.close();
}
  1. The second way: a sql statement, association label

// StudentMapper.xml
// 一条sql语句, association(关联)
<resultMap id="studentResultMapAssociation" type="Student">
    <id property="sid" column="sid"/>
    <result property="sname" column="sname"/>
    
    // association翻译为关联, 一个Student对象关联一个Clazz对象
    // property: 提供要映射的POJO类的属性名
    // javaType: 用来指定要映射的java类型
    <association property="Clazz" javaType="Clazz">
        <id property="cid" column="cid"/>
        <result property="cname" column="cname"/>
    </association>
    
</resultMap>

<select id="selectByIdAssociation" resultMap="studentResultMapAssociation">
    select
        s.sid,s.sname,c.cid,c.cname
    from
        stu s left join clazz c on s.cid = c.cid
    where
        s.sid = #{sid}
</select>

// 接口
public interface StudentMapper{
    // 根据id获取学生信息, 同时获取学生关联的班级信息
    // 返回一个学生对象, 但是学生对象当中含有班级对象
    // 使用association
    Student selectByIdAssociation(Integer id);
} 

// @test
public static void main(String[] args) {
    SqlSession sqlSession = SqlSessionUtil.openSession();
    CarMapper mapper = sqlSession.getMapper(StudentMapper.class);

    Student student = mapper.selectByIdAssociation(6);
    System.out.println(student);
    sqlSession.close();
}
  1. The third method: two SQL statements, distributed query (this method is commonly used: the advantages can be reused, and lazy loading is supported)

// StudentMapper.xml
// 一条sql语句, association(关联)
<resultMap id="studentResultMapByStep" type="Student">
    <id property="sid" column="sid"/>
    <result property="sname" column="sname"/>
    
	// 会将column传给select这条sql语句
    <association property="Clazz"
                 select="ClazzMapper.selectByIdStep2"
                 column="cid"/>
</resultMap>

<select id="selectByIdStep1" resultMap="studentResultMapByStep">
    select sid,sname,cid from stu where sid = #{sid}
</select>
-------------------------------------------------------------------------------------
// ClazzMapper.xml
<select id="selectByIdStep2" resultType="Clazz">
    select cid,cname from clazz where cid = #{cid}
</select>
-------------------------------------------------------------------------------------

// 接口
public interface StudentMapper{
	// 分布查询第一步, 先根据id查询出学生信息
    Student selectByIdStep1(Integer id);
} 
public interface ClazzMapper{
	// 分布查询第二步, 根据cid获取班级信息
	Clazz selectByIdStep2(Integer cid);
}

// @test
public static void main(String[] args) {
    SqlSession sqlSession = SqlSessionUtil.openSession();
    CarMapper mapper = sqlSession.getMapper(StudentMapper.class);

    Student student = mapper.selectByIdStep1(6);
    System.out.println(student);
    sqlSession.close();
}

2. Lazy loading:

  • Benefits of distributed queries:

  • Strong reusability, can be reused, large steps are broken down into multiple small steps, and each small step is more reusable.

  • Can take full advantage of the fucking lazy loading/lazy loading mechanism

  • What is lazy loading (lazy loading), and what is it for?

  • The core principle of lazy loading is: execute the query statement when it is used, and not query it when it is not used.

  • Function: improve performance

  • How to enable lazy loading in mybatis?

  • Lazy loading is not enabled by default

  • Add fetchType="lazy" to the association tag

  • This configuration of fetchType="lazy" in the association tag is a local setting, which only works on the sql statement associated with the current association

<resultMap id="studentResultMapByStep" type="Student">
    <id property="sid" column="sid"/>
    <result property="sname" column="sname"/>
    
    <association property="Clazz"
                 // 这条sql语句用到的时候再查询
                 select="ClazzMapper.selectByIdStep2"
                 column="cid"
                 fetchType="lazy"/>
</resultMap>

// 如果只需要查看学生的名字
//		那么就不会使用到ClazzMapper.selectByIdStep2语句
// 如果想看班级的名字
//		那么就会执行ClazzMapper.selectByIdStep2语句了
    

3. One-to-many:

A class corresponds to multiple students (the class table is the main table, and the student table is the sub table)

One-to-many implementation, usually there is a List collection attribute in one party

One-to-many implementation usually includes two implementation methods:

  1. collection

// ClazzMapper.xml
<resultMap id="clazzResultMap" type="Clazz">
    <id property="cid" column="cid"/>
    <result property="cname" column="cname"/>
    
    // 一对多, 这里的collection是集合的意思
    // ofType属性用来指定集合当中的元素类型
	<collection property="stus //list集合名" ofType="Student">
    	<id property="sid" column="sid">
    	<result property="sname" column="sname">
	</collection>
    
</resultMap>
    
<select id="selectByCollection" resultMap="clazzResultMap">
    select c.cid,c.cname,s.sid,s.sname 
    	from clazz c left join stu s on c.cid = s.cid
    where c.cid = #{cid}
</select>

// 接口
public interface ClazzMapper{
	// 根据班级编号查询班级信息
	Clazz selectByCollection(Integer cid);
}

// @test
public static void main(String[] args) {
    SqlSession sqlSession = SqlSessionUtil.openSession();
    CarMapper mapper = sqlSession.getMapper(StudentMapper.class);

    Clazz clazz = mapper.selectByCollection(6);
    System.out.println(clazz);
    sqlSession.close();
}
  1. Distribution query (commonly used)

// StudentMapper.xml
<select id="selectByIdStep2" resultType="Student">
    select * from stu where cid = #{cid}
</select>
-------------------------------------------------------------------------------------
// ClazzMapper.xml
<resultMap id="clazzResultMapStep" type="Clazz">
    <id property="cid" column="cid"/>
    <result property="cname" column="cname"/>
    
	// 会将column传给select这条sql语句
    <collection property="stus"
                 select="StudentMapper.selectByCidStep2"
                 column="cid"/>
</resultMap>

<select id="selectByIdStep1" resultMap="clazzResultMapStep">
    select cid,cname from clazz where cid = #{cid}
</select>
-------------------------------------------------------------------------------------

// 接口
public interface StudentMapper{
	// 分布查询第二步, 先根据班级编号查询出学生信息
    List<Student> selectByCidStep2(Integer id);
} 
public interface ClazzMapper{
	// 分布查询第一步, 根据班级编号获取班级信息
	Clazz selectByIdStep1(Integer cid);
}

// @test
public static void main(String[] args) {
    SqlSession sqlSession = SqlSessionUtil.openSession();
    CarMapper mapper = sqlSession.getMapper(StudentMapper.class);

    Clazz clazz = mapper.selectByIdStep1(6);
    System.out.println(clazz);
    sqlSession.close();
}

Guess you like

Origin blog.csdn.net/qq_68993495/article/details/128860606