Mybatis association是用于一对一和多对一,而collection是用于一对多的关系
一. Association
1. 嵌套查询实现association一对一
public class Card implements Serializable{
private Integer id;
private String code;
//省略set和get方法.
}
public class Card implements Serializable{
private Integer id;
private String code;
//省略set和get方法.
}
package com.glj.mapper;
import com.glj.poji.Card;
public interface CardMapper {
Card selectCardById(Integer id);
}
package com.glj.mapper;
import com.glj.poji.Person;
public interface PersonMapper {
Person selectPersonById(Integer id);
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.glj.mapper.CardMapper">
<select id="selectCardById" parameterType="int" resultType="com.glj.poji.Card">
select * from tb_card where id = #{id}
</select>
</mapper>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.glj.mapper.PersonMapper">
<resultMap type="com.glj.poji.Person" id="personMapper">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="sex" column="sex"/>
<result property="age" column="age"/>
<association property="card" column="card_id"
select="com.glj.mapper.CardMapper.selectCardById"
javaType="com.glj.poji.Card">
</association>
</resultMap>
<select id="selectPersonById" parameterType="int" resultMap="personMapper">
select * from tb_person where id = #{id}
</select>
</mapper>
2.连接查询实现多对一
package com.glj.pojo;
import java.io.Serializable;
import java.util.List;
public class Clazz implements Serializable{
private Integer id;
private String code;
private String name;
//班级与学生是一对多的关系
private List<Student> students;
//省略set/get方法
}
package com.glj.pojo;
import java.io.Serializable;
import java.util.List;
public class Clazz implements Serializable{
private Integer id;
private String code;
private String name;
//班级与学生是一对多的关系
private List<Student> students;
//省略set/get方法
}
package com.glj.mapper;
import com.glj.pojo.Student;
public interface StudentMapper {
Student selectStudentById(Integer id);
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.glj.mapper.StudentMapper">
<select id="selectStudentById" parameterType="int" resultMap="studentResultMap">
select s.id,s.name,s.sex,s.age,c.id cid,c.code,c.name
from tb_clazz c,tb_student s where c.id = s.id and s.id = #{id}
</select>
<select id="selectStudentByClazzId" parameterType="int" resultMap="studentResultMap">
select * from tb_student where clazz_id = #{id}
</select>
<resultMap type="com.glj.pojo.Student" id="studentResultMap">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="sex" column="sex"/>
<result property="age" column="age"/>
<association property="clazz" javaType="com.glj.pojo.Clazz">
<id property="id" column="cid"/>
<result property="code" column="code"/>
<result property="name" column="name"/>
</association>
</resultMap>
</mapper>
二. Collection
1.嵌套查询实现一对多
接上边的学生班级实例
//ClazzMapper接口
package com.glj.mapper;
import com.glj.pojo.Clazz;
public interface ClazzMapper {
Clazz selectClazzById(Integer id);
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.glj.mapper.ClazzMapper">
<select id="selectClazzById" parameterType="int" resultMap="clazzResultMap">
select * from tb_clazz where id = #{id}
</select>
<resultMap type="com.glj.pojo.Clazz" id="clazzResultMap">
<id property="id" column="id"/>
<result property="code" column="code"/>
<result property="name" column="name"/>
<!-- property: 指的是集合属性的值, ofType:指的是集合中元素的类型 -->
<collection property="students" ofType="com.glj.pojo.Student"
column="id" javaType="ArrayList"
fetchType="lazy" select="com.glj.mapper.StudentMapper.selectStudentByClazzId">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="sex" column="sex"/>
<result property="age" column="age"/>
</collection>
</resultMap>
</mapper>
2.连接查询实现一对多
<!-- 获取指定用户的地址列表(user表-address表:1对多关系) collection start-->
<resultMap type="User" id="userMap">
<id property="id" column="userId"/>
//property是属性名 ofType是List《Address》的类对象
<collection property="addressList" ofType="Address">
<id property="id" column="a_id"/>
<result property="postCode" column="postCode"/>
<result property="addressContent" column="addressContent"/>
</collection>
</resultMap>
<select id="getAddressListByUserId" parameterType="User" resultMap="userMap">
select *,a.id as a_id from user u,address a where u.id=a.userId and u.id=#{id}
</select>
<!-- collection end -->
总结:
association和collection均可以使用连接查询和嵌套查询的方法实现,连接查询可以减少select查询次数,嵌套查询可以使程序结构看起来更清晰,而且子查询可以复用。
需要特别注意的是分页查询在用连接查询实现collection时,应该先查询分页条目,再进行连接查询获取关联子条目,否则分页会基于子条目进行,查询结果会出现数据条目不匹配的情况。
参考文章:
https://www.cnblogs.com/xuerong/p/5000233.html
https://blog.csdn.net/baidu_38116275/article/details/78622669