关联查询与动态SQL - MyBatis 面试题及答案
2025/12/19大约 4 分钟
返回MyBatis 面试题索引 第 3/5 章
9.Mybatis能执行一对一、一对多的关联查询吗?
当然可以,不止支持一对一、一对多的关联查询,还支持多对多、多对一的关联查询。

一对一
<association>比如订单和支付是一对一的关系,这种关联的实现:
- 实体类:
public class Order { private Integer orderId; private String orderDesc; /** * 支付对象 */ private Pay pay; //…… }- 结果映射
<!-- 订单resultMap --> <resultMap id="peopleResultMap" type="cn.fighter3.entity.Order"> <id property="orderId" column="order_id" /> <result property="orderDesc" column="order_desc"/> <!--一对一结果映射--> <association property="pay" javaType="cn.fighter3.entity.Pay"> <id column="payId" property="pay_id"/> <result column="account" property="account"/> </association> </resultMap>
* 查询就是普通的关联查 ```xml <select id="getTeacher" resultMap="getTeacherMap" parameterType="int"> select * from order o left join pay p on o.order_id=p.order_id where o.order_id=#{orderId} </select> ```一对多
<collection>比如商品分类和商品,是一对多的关系。
实体类
public class Category { private int categoryId; private String categoryName; /** * 商品列表 **/ List<Product> products; //…… }结果映射
<resultMap type="Category" id="categoryBean"> <id column="categoryId" property="category_id" /> <result column="categoryName" property="category_name" /> <!-- 一对多的关系 --> <!-- property: 指的是集合属性的值, ofType:指的是集合中元素的类型 --> <collection property="products" ofType="Product"> <id column="product_id" property="productId" /> <result column="productName" property="productName" /> <result column="price" property="price" /> </collection> </resultMap> ``` * 查询 查询就是一个普通的关联查询 ```xml <!-- 关联查询分类和产品表 --> <select id="listCategory" resultMap="categoryBean"> select c.*, p.* from category_ c left join product_ p on c.id = p.cid </select> ```
那么多对一、多对多怎么实现呢?还是利用<association>和<collection>,篇幅所限,这里就不展开了。
10.Mybatis是否支持延迟加载?原理?
- Mybatis支持association关联对象和collection关联集合对象的延迟加载,association指的就是一对一,collection指的就是一对多查询。在Mybatis配置文件中,可以配置是否启用延迟加载lazyLoadingEnabled=true|false。
- 它的原理是,使用CGLIB创建目标对象的代理对象,当调用目标方法时,进入拦截器方法,比如调用a.getB().getName(),拦截器invoke()方法发现a.getB()是null值,那么就会单独发送事先保存好的查询关联B对象的sql,把B查询上来,然后调用a.setB(b),于是a的对象b属性就有值了,接着完成a.getB().getName()方法的调用。这就是延迟加载的基本原理。
- 当然了,不光是Mybatis,几乎所有的包括Hibernate,支持延迟加载的原理都是一样的。
11.如何获取生成的主键?
新增标签中添加:keyProperty=" ID " 即可
<insert id="insert" useGeneratedKeys="true" keyProperty="userId" > insert into user( user_name, user_password, create_time) values(#{userName}, #{userPassword} , #{createTime, jdbcType= TIMESTAMP}) </insert>这时候就可以完成回填主键
mapper.insert(user); user.getId;
12.MyBatis支持动态SQL吗?
MyBatis中有一些支持动态SQL的标签,它们的原理是使用OGNL从SQL参数对象中计算表达式的值,根据表达式的值动态拼接SQL,以此来完成动态SQL的功能。

扫描下方微信,备注:网站+所在城市,即可拉你进工作内推群。
