首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >MyBatis详解

MyBatis详解

原创
作者头像
Eulogy
发布2025-08-01 18:36:09
发布2025-08-01 18:36:09
1090
举报
文章被收录于专栏:笔记本笔记本

MyBatis

MyBatis是持久层框架(持久层: 和数据库进行交互的代码;框架: 半成品软件模型)。简化了JDBC开发(使用Java提供的标准Api来操作和访问数据库)。

JDBC缺点

JDBC开发的流程:

  1. 注册驱动(Class.forName("com.mysql.jdbc.Driver"))
  2. 建立连接
  3. 编写sql
  4. 执行sql,获取数据
  5. 解析数据,封装对象

对应下面的代码:

代码语言:java
复制
// 1. 注册数据库驱动
Class.forName("com.mysql.jdbc.Driver");

// 2. 建立Connection连接
String url = "jdbc:mysql://db1?useSSL=false";
String uname = "root";
String pwd = "1234";
Connection conn = DriverManager.getConnection(url, uname, pwd);

// 3. 设置性别参数为男
String gender = "男";

// 4. 定义SQL查询语句
String sql = "select * from tb_user where gender = ?";

// 5. 创建预处理语句对象
PreparedStatement pstmt = conn.prepareStatement(sql);

// 6. 设置参数值
pstmt.setString(1, gender);

// 7. 执行SQL查询
ResultSet rs = pstmt.executeQuery();

// 8. 创建用户对象和用户列表
User user = null;
ArrayList<User> users = new ArrayList<>();

// 9. 遍历结果集
while (rs.next()) {
    // 从结果集中获取数据
    int id = rs.getInt("id");
    String username = rs.getString("username");
    String password = rs.getString("password");
    
    // 创建User对象并设置属性
    user = new User();
    user.setId(id);
    user.setUsername(username);
    user.setPassword(password);
    user.setGender(gender);
    
    // 将用户对象添加到列表中
    users.add(user);
}

硬编码: 配置信息和sql语句写到了代码里,之后如果改动需要改动代码。

操作繁琐: 手动设置sql语句的参数、手动解析结果并封装到对象中。

MyBatis如何简化?

xml配置文件: 对于硬编码问题,MyBatis使用将配置信息和sql语句都写到xml配置文件中来简化的。

配置信息:

代码语言:xml
复制
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>
    <environments default="dev">
        <environment id="dev">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/test"/>
                <property name="username" value="root"/>
                <property name="password" value="password"/>
            </dataSource>
        </environment>
    </environments>

    <mappers>
        <mapper resource="mapper/UserMapper.xml"/>
    </mappers>
</configuration>

sql语句:

代码语言:xml
复制
<?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.example.mapper.UserMapper">

    <select id="findUserById" parameterType="int" resultType="com.example.model.User">
        SELECT id, name, age FROM user WHERE id = #{id}
    </select>

</mapper>

对于操作繁琐问题,mybatis只需要一行代码就能把参数设置和封装结果解决完,让这两个操作实现了自动完成。

代码语言:sql
复制
// 1. 加载MyBatis配置文件,获取SqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

// 2. 获取SqlSession对象,用它来执行sql
SqlSession sqlSession = sqlSessionFactory.openSession();

// 3. 执行sql
List<User> users = sqlSession.selectList(statement: "test.selectAll");
System.out.println(users);

// 4. 释放资源
sqlSession.close();

SqlSession

MyBatis中的SqlSession类似于JDBC中的Connection,但是提供了更高级别的抽象和封装。

通过xml配置文件获取SqlSessionFactory,然后获取SqlSession,也就类似于JDBC中的Connection

Mapper代理开发

上文使用SqlSession来执行sql,还是会存在硬编码的问题,就是我们要知道sql配置文件中对应的sql语句的id叫什么。写起来还是不太方便。所以还可以使用Mapper代理开发,更加方便。

具体细节就不赘述。简单讲一讲实现。

创建一个mapper接口,用来配合mapper.xml文件,这个接口和mapper.xml要放在同一个路径下(spring可以通过更改扫描路径)。mapper.xml中的namespace要是接口的全限定名,并且mapper接口要有一个与mapper.xml对应sql的id相同名的方法,返回值也要和mapper.xml中对应sql的返回值相同。

然后通过SqlSession获取mapper接口的代理对象,使用代理对象直接调用接口的方法就能直接执行sql语句并且获取到对应的返回值了。

数据库表列名和实体属性名不一致

起别名: sql语句查询的时候可以通过as给不一致的列表起与实体属性名一致的别名。

resultMap: 定义<resultMap>完成不一致的属性名和列名的映射,然后使用resultMap替换 <select>标签中的resultType。

#{}和${}的区别和使用

mapper接口中带参数的方法需要在sql的select语句中搭配一个占位符,而占位符有两种,分别是${}和#{},他们两个是不同的。

${}: 会把参数替换占位符,拼接上原来的sql语句,然后组成一个完整的sql语句去进行sql查询,类似jdbc的Statement做的一样,不会预编译。

#{}: 会进行sql语句的预编译,然后会把参数替换掉预编译的占位符上,可以有效防止sql注入的问题。类似PreparedStatement。

常见标签

1. <select>

用于定义查询语句,执行数据库的SELECT操作,返回结果集。

常用于查询数据,支持动态SQL和映射。


2. @Param

这是MyBatis的注解,用于给Mapper接口方法的参数命名。

当接口方法有多个参数时,使用@Param("name")可以在SQL中通过#{name}引用对应参数。


3. <set>

用于UPDATE语句中,动态拼接SET子句。

会自动处理多余的逗号,避免SQL语法错误。

示例:

代码语言:java
复制
xml复制编辑<set>
  <if test="name != null">name = #{name},</if>
  <if test="age != null">age = #{age},</if>
</set>

4. <foreach>

用于遍历集合(List、数组、Map等),动态生成SQL片段,常用于批量操作和IN条件。

示例:

代码语言:Java
复制
xml复制编辑WHERE id IN
<foreach item="id" collection="idList" open="(" separator="," close=")">
  #{id}
</foreach>

5. <where>

用于动态生成WHERE子句,会智能处理多余的ANDOR

如果内部没有条件,则不会生成WHERE关键字。


6. <insert>

定义插入语句,对应数据库的INSERT操作。

可以支持动态字段插入。


7. <delete>

定义删除语句,对应数据库的DELETE操作。

用于删除符合条件的数据。


8. <update>

定义更新语句,对应数据库的UPDATE操作。

常配合<set>标签使用,动态更新字段。


9. <choose>

类似Java中的switch-case,用于多个条件分支中选择一个执行。

包含<when><otherwise>子标签。

示例:

代码语言:java
复制
xml复制编辑<choose>
  <when test="type == 'A'">...</when>
  <when test="type == 'B'">...</when>
  <otherwise>...</otherwise>
</choose>

参数传递

Mapper接口的方法中可以接收各种参数,可以接收

单个参数:

  1. POJO类型

属性名和参数占位符名称一致。

  1. Map集合

Map集合键名要和参数占位符一致。

  1. Collection

封装为map集合,map.put("collection",Collection集合),map.put("arg0",Collection集合)

  1. List

封装为map集合,map.put("arg0",List集合),map.put("collection",List集合),map.put("list",List集合)

  1. Array

封装为map集合,map.put("arg0",Array数组), map.put("array", Array数组)

  1. 其它类型

多个参数:

使用多个参数的时候,要使用@Param注解来定义参数的名称,这个名称要和sql语句的参数占位符一致,才能将这个参数替换到占位符上去。

ParamNameResolver封装参数: mapper接口方法如果有多个参数,那么这些参数就会被封装到一个Map集合中,key就是使用@Param定义的名称(没有@Param注解的话,默认就是arg0、arg1...和param0、param1...作为键值,使用@Param注解的话,替换的键名是argx的,paramx还存在),然后值就是参数传递过来的。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • MyBatis
    • JDBC缺点
    • MyBatis如何简化?
    • SqlSession
    • Mapper代理开发
    • 数据库表列名和实体属性名不一致
    • #{}和${}的区别和使用
    • 常见标签
      • 1. <select>
      • 2. @Param
      • 3. <set>
      • 4. <foreach>
      • 5. <where>
      • 6. <insert>
      • 7. <delete>
      • 8. <update>
      • 9. <choose>
    • 参数传递
      • 单个参数:
      • 多个参数:
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档