当前位置:首页 > 技术 > 正文内容

MyBatis高级特性详解

访客 技术 2026年8月31日 1

MyBatis会话管理工具

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;

public class DatabaseConnectionManager {
    
    private static SqlSessionFactory sqlSessionFactory;
    
    static {
        try {
            SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
            sqlSessionFactory = builder.build(Resources.getResourceAsStream("mybatis-config.xml"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    public static SqlSession openSession() {
        return sqlSessionFactory.openSession(true);
    }
    
    public static SqlSession openSession(boolean autoCommit) {
        return sqlSessionFactory.openSession(autoCommit);
    }
    
    public static void commitAndClose(SqlSession session) {
        if (session != null) {
            session.commit();
            session.close();
        }
    }
    
    public static void rollbackAndClose(SqlSession session) {
        if (session != null) {
            session.rollback();
            session.close();
        }
    }
}

参数传递机制

输入参数类型 输出参数类型
HashMap HashMap
String、Integer String、Integer
POJO POJO

单参数传递

// 接口方法定义
User findUserById(Integer userId);
<select id="findUserById" resultType="user">
    SELECT * FROM user WHERE id = #{userId}
</select>

多参数传递

方式一:使用@Param注解(推荐)

User findByUsernameAndGender(@Param("username") String username, 
                              @Param("gender") String gender);
<select id="findByUsernameAndGender" resultType="user">
    SELECT * FROM user WHERE user_name = #{username} AND sex = #{gender}
</select>

方式二:使用POJO对象

void insertUser(User user);
<insert id="insertUser">
    INSERT INTO user VALUES (null, #{username}, #{birthday}, #{sex}, #{address})
</insert>

方式三:使用Map集合

List<User> findByConditions(Map<String, String> conditions);
<select id="findByConditions" resultType="user">
    SELECT * FROM user WHERE sex = #{sex} AND address = #{address}
</select>

主键自动生成

使用insert标签的属性获取自动生成的主键值:

属性 说明
useGeneratedKeys 设置为true以获取自动生成的主键
keyColumn 数据库表中主键列名
keyProperty 实体类中主键属性名
<insert id="addUser" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
    INSERT INTO user VALUES (null, #{username}, #{birthday}, #{sex}, #{address})
</insert>

参数绑定方式比较

#{}与${}的区别:

  1. #{}采用预编译方式,可以防止SQL注入
  2. ${}直接拼接SQL语句,存在SQL注入风险
  3. ${}通常用于动态表名、列名等场景

结果映射

MyBatis提供两种结果映射方式:

resultType

  • 适用于简单类型(int、String等)
  • 适用于POJO对象
  • 适用于List集合
  • 适用于Map对象

resultMap

解决数据库字段与实体类属性不一致问题,支持复杂映射:

<resultMap id="userResultMap" type="user">
    <id column="id" property="id"/>
    <result column="user_name" property="username"/>
</resultMap>

<select id="getUserById" resultMap="userResultMap">
    SELECT * FROM user WHERE id = #{id}
</select>

动态SQL

if标签

List<User> findMaleUsers(@Param("username") String username);
<select id="findMaleUsers" resultType="user">
    SELECT * FROM user WHERE sex = '男'
    <if test="username != null and username.trim() != ''">
        AND user_name LIKE CONCAT('%', #{username}, '%')
    </if>
</select>

choose、when、otherwise标签

List<User> searchUsers(@Param("username") String username, 
                         @Param("address") String address);
<select id="searchUsers" resultType="user">
    SELECT * FROM user WHERE sex = '男'
    <choose>
        <when test="username != null and username.trim() != ''">
            AND user_name LIKE CONCAT('%', #{username}, '%')
        </when>
        <when test="address != null and address.trim() != ''">
            AND address = #{address}
        </when>
        <otherwise>
            AND user_name = '孙悟空'
        </otherwise>
    </choose>
</select>

where标签

List<User> queryByConditions(@Param("username") String username, 
                              @Param("address") String address);
<select id="queryByConditions" resultType="user">
    SELECT * FROM user
    <where>
        <if test="username != null and username.trim() != ''">
            user_name LIKE CONCAT('%', #{username}, '%')
        </if>
        <if test="address != null and address.trim() != ''">
            AND address = #{address}
        </if>
    </where>
</select>

set标签

void updateUser(User user);
<update id="updateUser">
    UPDATE user
    <set>
        <if test="username != null">
            user_name = #{username},
        </if>
        <if test="birthday != null">
            birthday = #{birthday},
        </if>
        <if test="sex != null">
            sex = #{sex},
        </if>
        <if test="address != null">
            address = #{address},
        </if>
    </set>
    WHERE id = #{id}
</update>

foreach标签

List<User> findByIds(@Param("ids") List<Integer> ids);
<select id="findByIds" resultType="user">
    SELECT * FROM user WHERE id IN
    <foreach collection="ids" item="id" separator="," open="(" close=")">
        #{id}
    </foreach>
</select>

多表查询

一对一查询

Order findOrderByNumber(@Param("orderNumber") String orderNumber);
<resultMap id="orderWithUserResultMap" type="Order" autoMapping="true">
    <id column="id" property="id"/>
    <result column="order_number" property="orderNumber"/>
    <association property="user" javaType="User" autoMapping="true">
        <id column="user_id" property="id"/>
        <result column="user_name" property="username"/>
    </association>
</resultMap>

<select id="findOrderByNumber" resultMap="orderWithUserResultMap">
    SELECT o.*, u.id AS user_id, u.user_name
    FROM tb_order o
    INNER JOIN tb_user u ON o.user_id = u.id
    WHERE o.order_number = #{orderNumber}
</select>

一对多查询

User findUserWithOrders(@Param("id") Integer id);
<resultMap id="userWithOrdersResultMap" type="User" autoMapping="true">
    <id column="id" property="id"/>
    <collection property="orders" javaType="List" ofType="Order" autoMapping="true">
        <id column="order_id" property="id"/>
        <result column="order_number" property="orderNumber"/>
    </collection>
</resultMap>

<select id="findUserWithOrders" resultMap="userWithOrdersResultMap">
    SELECT u.*, o.id AS order_id, o.order_number
    FROM tb_user u
    LEFT JOIN tb_order o ON u.id = o.user_id
    WHERE u.id = #{id}
</select>

注解开发

MyBatis支持使用注解简化配置:

@Insert("INSERT INTO tb_user VALUES (null, #{username}, #{password}, #{name}, #{age}, #{sex})")
@Options(useGeneratedKeys = true, keyProperty = "id")
void addUser(User user);

@Select("SELECT * FROM tb_user WHERE id = #{id}")
User getUserById(Integer id);

@Update("UPDATE tb_user SET username = #{username} WHERE id = #{id}")
void updateUser(User user);

@Delete("DELETE FROM tb_user WHERE id = #{id}")
void deleteUser(Integer id);
标签: MyBatis
返回列表

上一篇:MySQL 常用运算符详解与实践

没有最新的文章了...

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。