Mybatis的动态SQL和结果映射

以下是MyBatis框架的全面解析,涵盖基础架构、动态SQL高级用法及结果映射机制,结合实践场景与源码逻辑梳理核心要点:


一、MyBatis基础架构与核心组件

1. 框架定位与核心特性

定位:MyBatis是一款半自动ORM框架,通过XML或注解实现SQL与Java对象的映射,避免了JDBC冗余代码(如连接管理、结果集解析)。
核心功能
定制化SQL:支持动态拼接SQL语句,灵活适应复杂查询需求。
高级映射:通过ResultMap处理嵌套对象、集合等复杂结构。
事务管理:提供基础事务接口,常与Spring集成实现分布式事务。

2. 核心组件与执行流程

关键组件
SqlSessionFactory:全局单例,通过SqlSessionFactoryBuilder加载mybatis-config.xml生成,管理数据库连接池与配置。
SqlSession:线程非安全,封装CRUD操作,通过getMapper()获取Mapper接口代理对象。
MappedStatement:存储XML/注解中定义的SQL信息(参数映射、执行逻辑、结果映射)。
执行流程

  1. 配置加载:解析XML/注解,生成MappedStatement缓存(含SQL语句、参数映射规则)。
  2. 请求处理:接收Mapper接口调用,通过动态代理定位SQL。
  3. SQL解析:结合OGNL表达式动态拼接SQL,生成BoundSql对象。
  4. 执行与映射:JDBC执行后,通过ResultSetHandler将结果集映射为Java对象。

二、动态SQL高级用法详解

1. 基础动态标签

<if>:条件判断,避免空值导致的无效过滤。

<select id="searchUsers" resultType="User">
  SELECT * FROM user
  <where>
    <if test="name != null">AND name LIKE CONCAT('%', #{name}, '%')</if>
    <if test="age != null">AND age = #{age}</if>
  </where>
</select>

<choose>/<when>/<otherwise>:多条件分支逻辑,类似Java的switch-case
<foreach>:遍历集合,支持批量操作(如IN查询、批量插入):

<insert id="batchInsert">
  INSERT INTO user (name) VALUES
  <foreach item="item" collection="list" separator=",">
    (#{item.name})
  </foreach>
</insert>
2. 语法优化标签

<trim>:自定义前缀/后缀,替代<where><set>

<update id="updateUser">
  UPDATE user
  <trim prefix="SET" suffixOverrides=",">
    <if test="name != null">name = #{name},</if>
    <if test="age != null">age = #{age},</if>
  </trim>
  WHERE id = #{id}
</update>

<bind>:预处理变量,解决数据库方言兼容性问题(如模糊查询):

<select id="searchByPattern">
  <bind name="pattern" value="'%' + keyword + '%'"/>
  SELECT * FROM table WHERE column LIKE #{pattern}
</select>
3. 高级场景与优化

多数据库适配:通过databaseId按数据库类型动态切换SQL(如MySQL与Oracle分页差异)。
脚本标签:在注解中使用<script>标签嵌入动态SQL:

@Update({"<script>",
  "UPDATE user SET name = #{name}",
  "<if test='age != null'> , age = #{age}</if>",
  "WHERE id = #{id}",
"</script>"})
void updateUserDynamic(User user);

三、结果映射机制深度解析

1. 自动映射与别名机制

自动映射:默认按列名与属性名匹配(支持驼峰转换)。

<settings>
  <setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>

别名配置:简化类型全路径,提升可读性。

<typeAliases>
  <typeAlias type="com.example.User" alias="User"/>
</typeAliases>
2. 自定义ResultMap

基础映射:处理列名与属性名不一致的场景。

<resultMap id="UserMap" type="User">
  <id property="id" column="user_id"/>
  <result property="userName" column="name"/>
</resultMap>

嵌套对象<association>处理一对一关系(如用户-地址)。

<resultMap id="OrderMap" type="Order">
  <association property="user" javaType="User">
    <id property="id" column="user_id"/>
    <result property="name" column="user_name"/>
  </association>
</resultMap>

集合映射<collection>处理一对多关系(如用户-订单列表):

<resultMap id="UserWithOrdersMap" type="User">
  <collection property="orders" ofType="Order">
    <id property="orderId" column="order_id"/>
    <result property="amount" column="order_amount"/>
  </collection>
</resultMap>
3. 动态结果映射

自动映射模式:通过autoMapping属性局部控制。

<resultMap id="PartialMap" type="User" autoMapping="true">
  <id property="id" column="id"/> <!-- 显式指定主键 -->
</resultMap>

四、最佳实践与性能优化

  1. 动态SQL优化:避免多层嵌套<if>,优先使用<trim>简化结构。
  2. 结果集处理
    延迟加载:通过lazyLoadingEnabled配置关联对象的按需加载。
    二级缓存:跨会话共享数据,需注意缓存一致性(推荐Redis集成)。
  3. 异常处理:使用<selectKey>处理主键回填,避免并发问题。

通过以上技术点整合,MyBatis既能简化基础CRUD操作,又能应对复杂业务场景。更多细节可参考官方文档或技术内幕解析。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值