• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

奋斗的软件工程师

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

MyBatis 动态 SQL、多表查询与注解开发详解

MyBatis 动态 SQL、多表查询与注解开发详解

1. MyBatis 动态 SQL

MyBatis 提供了强大的动态 SQL 功能,允许我们根据不同的条件拼接 SQL 语句,避免了手动拼接 SQL 的繁琐和错误。常见的动态 SQL 标签包括:

  • if:用于条件判断,根据条件是否成立来决定是否拼接 SQL 片段。
  • choose (when, otherwise):类似于 Java 中的 switch 语句,用于多选一的场景。
  • where:用于拼接 WHERE 子句,并自动去除多余的 AND 或 OR。
  • set:用于拼接 UPDATE 语句中的 SET 子句,并自动去除多余的逗号。
  • foreach:用于遍历集合或数组,常用于 IN 查询。

1.1 if 标签

if 标签用于条件判断,根据条件是否成立来决定是否拼接 SQL 片段。例如:

<select id="queryLikeUserName" resultType="user">
    select * from user where sex='男'
    <if test="userName!=null and userName.trim()!=''">
        and username like '%${userName}%'
    </if>
</select>

解释:

  • test 属性用于编写 OGNL 表达式,判断条件是否成立。
  • 如果 userName 不为空且不为空字符串,则拼接 and username like '%${userName}%' 到 SQL 语句中。

1.2 choose 标签

choose 标签类似于 Java 中的 switch 语句,用于多选一的场景。例如:

<select id="queryByUserNameOrAddress" resultType="user">
    select * from user where sex='男'
    <choose>
        <when test="userName!=null and userName.trim()!=''">
            and username like '%${userName}%'
        </when>
        <when test="address!=null and address.trim()!=''">
            and address = #{address}
        </when>
        <otherwise>
            and username='孙悟空'
        </otherwise>
    </choose>
</select>

解释:

  • choose 标签包含多个 when 子标签和一个 otherwise 子标签。
  • 每个 when 子标签都有一个 test 属性,用于判断条件是否成立。
  • 如果某个 when 子标签的条件成立,则拼接对应的 SQL 片段。
  • 如果所有 when 子标签的条件都不成立,则拼接 otherwise 子标签中的 SQL 片段。

1.3 where 标签

where 标签用于拼接 WHERE 子句,并自动去除多余的 AND 或 OR。例如:

<select id="queryByUserNameAndAge" resultType="user">
    SELECT * FROM user
    <where>
        <if test="userName != null and userName.trim()!=''">
            username = #{userName}
        </if>
        <if test="address!=null and address.trim()!=''">
            AND address = #{address}
        </if>
    </where>
</select>

解释:

  • where 标签会自动在生成的 SQL 语句中添加 WHERE 关键字。
  • 如果 where 标签内的条件都不成立,则不会添加 WHERE 关键字。
  • where 标签会自动去除多余的 AND 或 OR 关键字。

1.4 set 标签

set 标签用于拼接 UPDATE 语句中的 SET 子句,并自动去除多余的逗号。例如:

<update id="updateSelectiveUser">
    update user
    <set>
        <if test="username != null and username.trim()!=''">
            username = #{username},
        </if>
        <if test="birthday != null">
            birthday=#{birthday},
        </if>
        <if test="sex != null and sex.trim()!=''">
            sex=#{sex},
        </if>
        <if test="address != null and address.trim()!=''">
            address=#{address}
        </if>
    </set>
    where id = #{id}
</update>

解释:

  • set 标签会自动在生成的 SQL 语句中添加 SET 关键字。
  • set 标签会自动去除多余的逗号。

1.5 foreach 标签

foreach 标签用于遍历集合或数组,常用于 IN 查询。例如:

<select id="queryByIds" resultType="user">
    SELECT * FROM user WHERE id IN
    <foreach collection="arrIds" item="ID" separator="," open="(" close=")">
        #{ID}
    </foreach>
</select>

解释:

  • collection 属性指定要遍历的集合或数组。
  • item 属性指定集合或数组中的每个元素的别名。
  • separator 属性指定每个元素之间的分隔符。
  • open 属性指定遍历开始时的字符串。
  • close 属性指定遍历结束时的字符串。

2. MyBatis 多表查询

MyBatis 支持多表查询,常见的多表关系包括一对一、一对多和多对多。通过 resultMap 可以灵活地处理多表查询的结果映射。

2.1 一对一查询

一对一查询通常用于查询主表数据及其关联的从表数据。例如,查询订单信息及其对应的用户信息:

<resultMap id="orderAndUserResultRelative" type="Order" autoMapping="true">
    <id column="oid" property="id"/>
    <association property="user" javaType="User" autoMapping="true">
        <id column="uid" property="id"/>
    </association>
</resultMap>

<select id="queryOrderAndUserByOrderNumber2" resultMap="orderAndUserResultRelative">
    SELECT * FROM tb_order tbo
    INNER JOIN tb_user tbu ON tbo.user_id = tbu.id
    WHERE tbo.order_number = #{orderNumber}
</select>

解释:

  • resultMap 标签用于定义结果集的映射关系。
  • association 标签用于定义一对一关联关系。
  • id 标签用于定义主键映射关系。
  • result 标签用于定义普通字段的映射关系。

2.2 一对多查询

一对多查询通常用于查询主表数据及其关联的多个从表数据。例如,查询用户信息及其对应的多个订单信息:

<resultMap id="oneToManyResult" type="User" autoMapping="true">
    <id column="uid" property="id"/>
    <collection property="orders" javaType="List" ofType="Order" autoMapping="true">
        <id column="oid" property="id"/>
    </collection>
</resultMap>

<select id="oneToManyQuery" resultMap="oneToManyResult">
    SELECT * FROM tb_user tbu
    INNER JOIN tb_order tbo ON tbu.id = tbo.user_id
    WHERE tbu.id = #{id}
</select>

解释:

  • collection 标签用于定义一对多关联关系。
  • ofType 属性指定集合中元素的类型。

3. MyBatis 注解开发

MyBatis 提供了基于注解的开发方式,可以简化 XML 配置文件的编写。常见的注解包括:

  • @Insert:用于插入数据。
  • @Update:用于更新数据。
  • @Delete:用于删除数据。
  • @Select:用于查询数据。
  • @Options:用于配置主键回填等选项。
  • @Results:用于结果集映射。

3.1 注解实现 CRUD

通过注解可以快速实现 CRUD 操作。例如:

@Insert("INSERT INTO tb_user VALUES(NULL,#{userName},#{password},#{name},#{age},#{sex})")
@Options(useGeneratedKeys = true, keyColumn = "id", keyProperty = "id")
void saveUser(User user);

@Delete("DELETE FROM tb_user WHERE id = #{id}")
void deleteUserById(Long id);

@Update("UPDATE tb_user SET user_name=#{userName}, password=#{password}, name=#{name}, age=#{age}, sex=#{sex} WHERE id=#{id}")
void updateUser(User user);

@Select("SELECT * FROM tb_user")
List<User> queryAllUsers();

解释:

  • @Insert 注解用于插入数据。
  • @Options 注解用于配置主键回填。
  • @Delete 注解用于删除数据。
  • @Update 注解用于更新数据。
  • @Select 注解用于查询数据。

3.2 注解实现动态 SQL

MyBatis 注解开发也支持动态 SQL,可以通过 @SelectProvider 注解来实现。例如:

@SelectProvider(type = ProviderUtils.class, method = "queryUsersBySexOrUsernameSQL")
List<User> queryUsersBySexOrUsername(@Param("sex") String sex, @Param("username") String username);

动态 SQL 生成类:

public class ProviderUtils {
    public String queryUsersBySexOrUsernameSQL(@Param("sex") String sex, @Param("username") String username) {
        String sql = "SELECT * FROM tb_user WHERE sex = #{sex}";
        if (username != null && !"".equals(username)) {
            sql += " AND user_name LIKE CONCAT('%', #{username}, '%')";
        }
        return sql;
    }
}

解释:

  • @SelectProvider 注解用于指定动态 SQL 生成类和方法。
  • ProviderUtils 类中的 queryUsersBySexOrUsernameSQL 方法用于生成动态 SQL。

4. 总结

MyBatis 提供了强大的动态 SQL 功能,能够根据不同的条件灵活拼接 SQL 语句。同时,MyBatis 支持多表查询,通过 resultMap 可以轻松处理一对一、一对多等复杂关系。注解开发方式进一步简化了 MyBatis 的配置,使得开发更加高效。通过合理使用动态 SQL 和注解,可以大大提升 MyBatis 的开发效率和代码的可维护性。

posted on 2025-01-09 20:46  周政然  阅读(189)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3