Spring Boot Mybatis使用详解含示例(值得珍藏)

2023-12-27 06:36:42

1. Mybatis介绍

MyBatis 是一个优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs (Plain Old Java Objects, 普通的 Java 对象)映射成数据库中的记录。

以下是 MyBatis 的主要特点:

  1. 简单易学:MyBatis 框架结构简单,学习门槛相对较低,易于上手。
  2. 灵活性强:MyBatis 允许自定义 SQL、存储过程以及高级映射,以满足复杂的业务需求。
  3. 降低耦合度:MyBatis 使得应用程序与数据库实现了解耦,便于代码的模块化管理和维护。
  4. 简化数据库操作:MyBatis 简化了 JDBC 代码的编写,减少了手动设置参数和获取结果集的工作量。
  5. 支持事务管理:MyBatis 可以与 Spring 框架集成,利用 Spring 的事务管理功能,确保数据的完整性和一致性。
  6. 缓存机制:MyBatis 内置了二级缓存机制,可以在一定程度上提高查询效率。
  7. 插件化支持:MyBatis 支持自定义插件,可以对框架进行扩展,满足特定的业务需求。
  8. 支持多数据库操作:MyBatis 可以通过配置文件或注解的方式适配不同的数据库方言,实现对多种数据库的操作。
  9. 良好的社区支持:MyBatis 拥有庞大的用户群体和活跃的社区,可以提供丰富的参考资料和解决方案。
  10. 支持 ActiveMQ 等异步消息队列:通过与异步消息队列集成,MyBatis 可以实现异步数据操作,提高系统的响应速度。

2. Mybatis使用

以下是如何在 Spring Boot 项目中使用 MyBatis 的详细步骤和示例

2.1 添加依赖

首先,你需要在你的 pom.xml 文件中添加 MyBatis 和 MyBatis-Spring 的依赖。

<dependencies>  
    <!-- other dependencies -->  
  
    <!-- MyBatis -->  
    <dependency>  
        <groupId>org.mybatis.spring.boot</groupId>  
        <artifactId>mybatis-spring-boot-starter</artifactId>  
        <version>2.2.0</version>  
    </dependency>  
</dependencies>

2.2 配置数据源

application.propertiesapplication.yml 中配置数据源信息。

# application.properties  
spring.datasource.url=jdbc:mysql://localhost:3306/test  
spring.datasource.username=root  
spring.datasource.password=rootpassword  
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

2.3 创建实体类

创建一个实体类来表示数据库中的表。例如,一个用户实体类 User

public class User {  
    private Long id;  
    private String name;  
    private String email;  
    // getters and setters ...  
}

2.4 创建 Mapper 接口

创建一个接口来定义对数据库的操作。使用 MyBatis 的注解来定义 SQL 语句。例如,一个 UserMapper

import org.apache.ibatis.annotations.*;  
import java.util.List;  
import static org.apache.ibatis.annotations.Select.*;  
  
public interface UserMapper {  
    @Select("SELECT * FROM users WHERE id = #{id}")  
    User getUserById(Long id);  
  
    @Select("SELECT * FROM users")  
    List<User> getAllUsers();  
}

2.5 在 Service 或 Controller 中使用 Mapper

你可以在你的 Service 或 Controller 中注入 UserMapper 并使用它。例如,在一个简单的 UserService:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

import static org.springframework.transaction.annotation.Transactional;
import static org.springframework.transaction.annotation.Propagation.*;

@Service("userService")
@Transactional(propagation = REQUIRED)
public class UserService {
    @Autowired
    private UserMapper userMapper;

    public User getUserById(Long id) {
        return userMapper.getUserById(id);
    }

    public List<User> getAllUsers() {
        return userMapper.getAllUsers();
    }
}

3. Mybatis语法

3.1 增删改查

MyBatis 在 XML 文件中定义 SQL 语句时,主要使用以下元素:

  1. <mapper>:映射器,通常作为根元素使用,它允许你为 SQL 语句定义一个命名空间。
  2. <select>:查询语句,用于从数据库中检索数据。
  3. <insert>:插入语句,用于向数据库中插入数据。
  4. <update>:更新语句,用于更新数据库中的数据。
  5. <delete>:删除语句,用于从数据库中删除数据。

下面是一个详细的示例,展示如何在 MyBatis 的 XML 文件中定义 SQL 语句:

<!-- 定义一个名为 "userMapper" 的映射器 -->  
<mapper namespace="com.example.UserMapper">  
  
    <!-- 查询用户信息 -->  
    <select id="getUserById" parameterType="Long" resultType="User">  
        SELECT * FROM users WHERE id = #{id}  
    </select>  
  
    <!-- 查询所有用户信息 -->  
    <select id="getAllUsers" resultType="User">  
        SELECT * FROM users  
    </select>  
  
    <!-- 插入用户信息 -->  
    <insert id="insertUser" parameterType="User">  
        INSERT INTO users (name, email) VALUES (#{name}, #{email})  
    </insert>  
  
    <!-- 更新用户信息 -->  
    <update id="updateUser" parameterType="User">  
        UPDATE users SET name = #{name}, email = #{email} WHERE id = #{id}  
    </update>  
  
    <!-- 删除用户信息 -->  
    <delete id="deleteUser" parameterType="Long">  
        DELETE FROM users WHERE id = #{id}  
    </delete>  
  
</mapper>

在上述示例中,我们定义了一个名为 “userMapper” 的映射器,并在其中定义了多个 SQL 语句。每个 SQL 语句都有一个唯一的标识符(如 “getUserById”、“getAllUsers” 等),以及参数类型和结果类型。这些 SQL 语句可以在 Java 代码中被调用,以执行相应的数据库操作。

3.2 动态SQL

MyBatis 的动态 SQL 语法允许你在 XML 映射文件中根据参数条件动态地构建 SQL 查询。它通过使用 <if><choose><when><otherwise> 等元素来构建可变的 SQL 查询。

  1. <if> 元素:用于条件判断,只有当指定的条件为真时,其内部的 SQL 片段才会被包含在最终的 SQL 语句中。

示例:

<select id="findUsers" resultType="User">  
  SELECT * FROM users  
  WHERE 1 = 1  
  <if test="name != null">  
    AND name = #{name}  
  </if>  
  <if test="email != null">  
    AND email = #{email}  
  </if>  
</select>

在上面的示例中,如果 nameemail 参数不为 null,它们会被包含在最终的 SQL 语句中。

  1. <choose>、<when>、<otherwise> 元素:这些元素可以组合使用,类似于 Java 中的 switch-case-default 结构。

示例:

<select id="findUsersByCriteria" resultType="User">  
  SELECT * FROM users  
  WHERE 1 = 1  
  <choose>  
    <when test="name != null">  
      AND name = #{name}  
    </when>  
    <when test="email != null">  
      AND email = #{email}  
    </when>  
    <otherwise>  
      AND status = 'ACTIVE'  
    </otherwise>  
  </choose>  
</select>

在上面的示例中,根据参数的条件,选择相应的查询条件。如果 name 不为 null,则包含 name 查询条件;如果 email 不为 null,则包含 email 查询条件;否则,包含默认的查询条件。

  1. 使用 <trim> 和 <where> 元素:这些元素可以用来处理 SQL 的 WHERE 子句,避免多余的 ANDOR 关键字。

示例:

<select id="findUsers" resultType="User">  
  SELECT * FROM users  
  <trim prefix="WHERE" prefixOverrides="AND | OR ">  
    <if test="name != null">AND name = #{name}</if>  
    <if test="email != null">AND email = #{email}</if>  
  </trim>  
</select>

在上面的示例中,如果 nameemail 都为 null,则最终的 SQL 将不包含 WHERE 子句;如果任一参数不为 null,则相应的查询条件将被添加到 WHERE 子句中。使用 <trim><where> 可以避免多余的 ANDOR 关键字。

  1. 使用 <set> 元素:该元素用于构建更新(UPDATE)语句中的 SET 子句。它支持多个 <if> 元素和 <trim> 元素,以根据提供的参数动态地构建 SET 子句。
<!-- 使用 <set> 元素构建动态 SET 子句 -->  
<update id="updateUsers" parameterType="map">  
  UPDATE users  
  <set>  
    <if test="name != null">name = #{name},</if>  
    <if test="email != null">email = #{email},</if>  
    <if test="phone != null">phone = #{phone},</if>  
  </set>  
  WHERE id = #{id}  
</update>  

在上面的示例中,<set> 元素用于构建动态的 SET 子句。根据提供的参数(nameemailphone),只有非 null 的参数才会被包含在 SET 子句中。注意,我们在每个条件后面添加了一个逗号(,),以确保生成的 SQL 是正确的。

  1. 使用 <foreach> 元素:该元素用于在 SQL 中迭代集合或数组。它可以与 <select><insert><update> 元素一起使用,以处理集合或数组参数。
<!-- 使用 <foreach> 元素迭代集合 -->  
<insert id="insertUsers" parameterType="list">  
  INSERT INTO users (id, name, email, phone)  
  VALUES  
  <foreach collection="list" item="user" separator=",">  
    (#{user.id}, #{user.name}, #{user.email}, #{user.phone})  
  </foreach>  
</insert>

<!-- 定义结果集映射 -->  
<resultMap id="userResultMap" type="User">  
  <id property="id" column="id" />  
  <result property="name" column="name" />  
  <result property="email" column="email" />  
  <result property="phone" column="phone" />  
</resultMap>  
  
<!-- 使用 <foreach> 元素迭代集合进行查询 -->  
<select id="getUsersByList" resultMap="userResultMap">  
  SELECT * FROM users  
  WHERE id IN  
  <foreach collection="list" item="userId" open="(" separator="," close=")">  
    #{userId}  
  </foreach>  
</select>

在上面的<foreach>示例中,<foreach> 元素用于迭代集合。在 <foreach> 元素中,我们指定了集合的名称(list)、每个元素的别名(user)和元素之间的分隔符(,)。然后,我们使用 #{user.id}#{user.name} 等语法来引用每个元素的属性。最后,我们将每个插入语句以逗号分隔的形式列出。

在上面的<select>示例中:

  • 我们首先定义了一个结果集映射 userResultMap,用于将查询结果映射到 User 类型的 Java 对象。
  • 然后,在 <select> 元素中,我们使用 <foreach> 元素来迭代传入的集合参数 list<foreach> 元素的属性指定了集合的名称(list)、每个元素的别名(userId)和元素之间的分隔符(,)。在 <foreach> 元素内部,我们使用 #{userId} 来引用每个元素的属性。
  • 最后,查询语句中的 IN 子句使用了 <foreach> 元素生成的子查询,以匹配传入的集合中的用户ID。
  1. 结果映射:当数据库中的列名与 Java 对象的属性名不匹配时,或者当查询返回多个结果集时,你需要定义结果映射。这可以通过使用 <resultMap> 元素来完成。
<!-- 定义结果集映射 -->  
<resultMap id="userResultMap" type="User">  
  <id property="id" column="id" />  
  <result property="name" column="name" />  
  <result property="email" column="email" />  
  <result property="phone" column="phone" />  
</resultMap>  
  
<!-- 使用结果集映射进行查询 -->  
<select id="getUserById" resultMap="userResultMap">  
  SELECT id, name, email, phone FROM users WHERE id = #{id}  
</select>

在上面的示例中:

  • 首先,我们定义了一个名为 userResultMap 的结果集映射。该映射指定了 Java 对象的属性与数据库表的列之间的对应关系。通过 <id> 元素指定主键列,并通过 <result> 元素指定其他列。
  • 然后,在 <select> 元素中,我们使用 resultMap 属性引用了之前定义的结果集映射 userResultMap。这样,查询结果将根据该映射进行映射,并将查询结果转换为 User 类型的 Java 对象。

3.3 其他

  1. 多表联接查询:如果你需要执行涉及多个表的复杂查询,可以使用 <join> 元素来定义多表联接查询。
  2. 别名:为了简化 SQL 语句,可以使用别名来引用表或列。例如,<table alias="user"> 可以使你使用 user.column_name 来引用列。
  3. 使用注解:虽然 MyBatis 的 XML 配置提供了很大的灵活性,但你也可以在接口方法上使用注解来简化 SQL 语句的定义。例如,@Select@Insert@Update@Delete 注解可以直接在接口方法上定义 SQL 语句。
  4. 存储过程和函数:除了标准的 CRUD 操作,MyBatis 也支持存储过程和函数的映射。
  5. 使用表达式语言 (EL):MyBatis 支持使用表达式语言 (EL) 来简化 SQL 语句的编写,例如 ${} 可以用于直接插入变量值。但是要注意,为了防止 SQL 注入攻击,建议仅在已知安全的上下文中使用 ${}。通常,建议使用 #{} 来传递参数。
  6. 类型处理器 (Type Handlers):MyBatis 支持自定义类型处理器,用于处理数据库中的特殊类型和 Java 中的特殊类型之间的转换。
  7. 事务管理:虽然 MyBatis 本身不负责事务管理,但它与 Spring 等框架集成时可以很好地支持事务管理。
  8. 插件 (Plugins):MyBatis 支持插件,允许你拦截和修改 MyBatis 的行为,例如在执行 SQL 之前或之后执行某些操作。
  9. 命名空间和别名:在大型项目中,为了避免 XML 文件之间的命名冲突,可以使用命名空间和别名来组织映射器。
  10. 分页插件:对于分页功能,MyBatis 有一些流行的分页插件,如 PageHelperMyBatis-Plus,它们提供了方便的分页功能。
  11. 日志和监控:MyBatis 支持各种日志实现,如 SLF4J、Log4j 等,这有助于监控和调试 SQL 语句的执行。
  12. XML 配置文件的位置:通常,MyBatis 的 XML 配置文件位于 src/main/resources/mybatis/mapper 目录下,与对应的接口位于同一包中。
  13. 高级特性:MyBatis 还支持高级特性,如缓存、延迟加载等。这些通常需要根据具体需求进行配置。

文章来源:https://blog.csdn.net/a342874650/article/details/135234112
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。