第二章 SQL映射文件详解(2023版本IDEA)


  我们学习了MyBatis框架的基础知识,搭建基于MyBatis框架的开发环境并初步掌握了其他使用方法,同时对MyBatis框架的核心对象和核心配置文件有了一定的了解。(如果没有了解可以去我主页看看第一章 初识MyBatis框架(2023版本IEDA)来学习)。本章继续学习MyBatis框架基本要素中的SQL映射文件,实现增、删、改及更复杂的查询操作。

2.1 SQL映射文件

  在MyBatis框架中,SQL映射文件(通常是以.xml为扩展名的文件)是定义SQL语句与Java对象之间映射关系的关键部分。这些文件允许你编写SQL语句,并指定如何将结果集映射到Java对象

  • SQL映射文件中的几个顶级元素介绍如下:
    • mapper: SQL映射文件的根元素。只有一个属性namespace,用于区分不同的mapper,必须全局唯一。

    • cache: 为给定命名空间配置缓存。

    • cache-ref: 引用其他命名空间中的缓存配置。

    • resultMap: 用来描述查询结果集中的字段和Java实体类属性的对应关系。

    • sql: 定义可重用的SQL语句块,可以在其他语句映射中引用,提高编写和维护SQL语句的效率。

    • insert: 映射insert语句。

    • update: 映射update语句。

    • delete: 映射delete语句。

    • select: 映射select语句。

注意
  MyBatis框架支持面向接口的SQL映射编程,这种情况下,SQL映射文 件的开发需要注意以下规则。
(1)习惯上,SQL映射文件与该Mapper接口同名(实体类名+Mapper),并放置在同一包路径下。
(2)以要映射的Mapper接口的完全限定名(即包含包名的完整名称)作为namespace属性的值。
(3)接口中的方法名与映射文件中SQL语句映射的 ID 一 一对应。MyBatis框架通过namespace+ID确定和接口方法绑定的SQL语句。
(4)在不同的SQL映射文件中,子元素的ID可以相同。

2.2MyBatis框架的条件查询

  实际项目中的查询操作通常伴随着各种条件,那么在MyBatis框架下如何为SQL语句中的查询条件赋值呢?

2.2.1实现单一条件查询

  在MyBatis中实现单一条件查询通常涉及编写一个Mapper接口方法、对应的SQL映射文件(XML)中的<select>标签以及Java实体类。下面是一个简单的示例,说明如何实现单一条件查询

1. Java实体类(User.java)
首先,你需要一个Java实体类来映射数据库中的表。例如:对于一个用户表(user),你可能有一个User类:

package com.example.domain;  
  
public class User {
     
    private int id;  
    private String name;  
    private String email;  
    // ... getter, setter, toString等方法  
}

2. Mapper接口(UserMapper.java)
接下来,你需要创建一个Mapper接口来定义查询方法。例如,你可以创建一个UserMapper接口,并定义一个根据用户名查询用户的方法:

package com.example.mapper;  
  
import com.example.domain.User;  
  
import java.util.List;  
  
public interface UserMapper {
     
    // 根据用户名查询用户  
    User selectUserByName(String name);  
    // ... 其他方法  
}

3. SQL映射文件(UserMapper.xml)
然后,你需要创建一个与Mapper接口相对应的SQL映射文件。在这个文件中,你将编写SQL查询语句,并指定如何将查询结果映射到Java对象。例如,你可以创建一个UserMapper.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="selectUserByName" parameterType="string" resultType="com.example.domain.User">  
        SELECT * FROM users WHERE name = #{name}  
    </select>  
  
    <!-- ... 其他SQL语句 -->  
  
</mapper>

在上面的<select>标签中,id属性与Mapper接口中的方法名相对应,parameterType指定了传递给SQL语句的参数类型(这里是字符串),而resultType则指定了查询结果的映射类型(这里是User类的完全限定名)

4. 配置MyBatis
最后,你需要在MyBatis的配置文件(如mybatis-config.xml)中指定SQL映射文件的位置,或者如果你使用的是Spring框架,你可以在Spring的配置文件中进行配置。以下是在MyBatis配置文件中指定映射文件的一个示例:

<configuration>  
    <!-- ... 其他配置 ... -->  
  
    <mappers>  
        <mapper resource="com/example/mapper/UserMapper.xml"/>  
        <!-- ... 其他映射文件 ... -->  
    </mappers>  
  
    <!-- ... 其他配置 ... -->  
</configuration>

MyBatis框架内建的部分别名与Java数据类型的映射关系

别名 映射的类型 别名 映射的类型
boolean Boolean string String
byte Byte bigdecimal或decimal BigDecimal
long Long date Date
short Short map Map
int或integer Integer hashmap HashMap
double Double list List
float Float arraylist ArrayList

注意
  有关MyBatis框架内建别名的更多内容,可以参考MyBatis框架用户手册的“3.1.3 typeAliases”一节。

2.2.2实现多条件查询

  在实际应用中,数据查询经常会综合多种条件,对于多条件查询,MyBatis框架提供了多种方法实现条件赋值。它允许你直接使用 XML 文件或注解来配置和映射原生 SQL、存储过程以及高级映射。下面是如何使用 MyBatis 实现多条件查询的一个示例:
  首先,假设你有一个 User 表,并且你想根据用户名(username)、邮箱(email)和年龄(age)等字段进行查询

  1. 定义 Mapper 接口
    在你的 Mapper 接口中,你可以定义一个方法来执行多条件查询。
public interface UserMapper {
     
    List<User> selectUsersByConditions(@Param("username") String username,  
                                       @Param("email") String email,  
                                       @Param("age") Integer age);  
}

注意这里使用了 @Param 注解来指定参数名,这样你就可以在 XML 映射文件中引用这些参数了

  1. 编写 XML 映射文件
    在 MyBatis 的 XML 映射文件中,你可以使用动态 SQL(<if> 标签)来实现多条件查询
<mapper namespace="com.example.mapper.UserMapper">  
  
    <select id="selectUsersByConditions" resultType="com.example.domain.User">  
        SELECT * FROM user  
        WHERE 1 = 1  
        <if test="username != null and username != ''">  
            AND username = #{username}  
        </if>  
        <if test="email != null and email != ''">  
            AND email = #{email}  
        </if>  
        <if test="age != null">  
            AND age = #{age}  
        </if>  
    </select>  
  
</mapper>

注意这里使用了 WHERE 1 = 1 作为条件查询的起始点,这样即使所有的 <if> 条件都不满足,查询也不会因为缺少 WHERE 子句而报错

  1. 在Service 或 Controller 中调用 Mapper 方法
    现在你可以在你的 Service 或 Controller 中调用 UserMapper 的 selectUsersByConditions 方法来执行多条件查询了
@Service  
public class UserService {
     
  
    @Autowired  
    private UserMapper userMapper;  
  
    public List<User> getUsersByConditions(String username, String email, Integer age) {
     
        return userMapper.selectUsersByConditions(username, email, age);  
    }  
}

  然后你就可以在你的 Controller 或其他需要的地方调用 UserService 的 getUsersByConditions 方法了。
  这样,你就可以使用 MyBatis 实现多条件查询了。根据具体需求,你可以进一步扩展和优化这个查询

1.将查询条件封装成Java对象作为入参

  在MyBatis中,你可以将查询条件封装成一个Java对象,然后将其作为Mapper方法的参数。这样做的好处是,你可以更方便地管理多个查询条件,并且可以让代码更加清晰和易于维护
  我来举一个例子:

  1. 定义查询条件对象:
    首先,定义一个包含查询条件的Java对象(DTO,Data Transfer Object)
public class UserQueryDTO {
     
    private String username;  
    private String email;  
    private Integer age;  
  
    // Getters方法和setters方法
    public String getUsername() {
     
        return username;  
    }  
  
    public void setUsername(String username) {
     
        this.username = username;  
    }  
  
    public String getEmail() {
     
        return email;  
    }  
  
    public void setEmail(String email) {
     
        this.email = email;  
    }  
  
    public Integer getAge() {
     
        return age;  
    }  
  
    public void setAge(Integer age) {
     
        this.age = age;  
    }  
}
  1. 修改Mapper接口
    在Mapper接口中,将方法的参数更改为你的查询条件对象
public interface UserMapper {
     
    List<User> selectUsersByConditions(UserQueryDTO queryDTO);  
}
  1. 编写XML映射文件
    在MyBatis的XML映射文件中,你可以像之前一样使用动态SQL,但是这次你将从queryDTO对象中引用参数
<mapper namespace="com.example.mapper.UserMapper">  
  
    <select id="selectUsersByConditions" resultType="com.example.domain.User">  
        SELECT * FROM user  
        <where>  
            <if test="queryDTO.username != null and queryDTO.username != ''">  
                AND username = #{queryDTO.username}  
            </if>  
            <if test="queryDTO.email != null and queryDTO.email != ''">  
                AND email = #{queryDTO.email}  
            </if>  
            <if test="queryDTO.age != null">  
                AND age = #{queryDTO.age}  
            </if>  
        </where>  
    </select>  
  
</mapper>

注意这里使用了<where>元素,它可以智能地处理开头的AND或OR,使得在没有任何条件被添加时不会包含额外的WHERE子句

  1. 在Service或Controller中调用Mapper方法
    现在,你可以在你的Service或Controller中创建一个UserQueryDTO对象,设置查询条件,然后调用Mapper方法
@Service  
public class UserService {
     
  
    @Autowired  
    private UserMapper userMapper;  
  
    public List<User> getUsersByConditions(UserQueryDTO queryDTO) {
     
        return userMapper.selectUsersByConditions(queryDTO);  
    }  
}

现在,你的代码更加清晰,并且查询条件被封装在一个单独的Java对象中,这使得它们更容易被管理和使用

2.将查询条件封装成Map对象作为入参

  在MyBatis中,除了将查询条件封装成Java对象(DTO)作为入参外,你还可以选择使用Map对象来传递查询条件。这样做在某些场景下可能更加灵活,尤其是当你不需要为每一个查询条件都创建一个DTO类。

以下使用Map对象作为查询条件入参:

  1. 在Mapper接口中定义方法
    Mapper接口的方法现在将接收一个Map<String, Object>类型的参数
public interface UserMapper {
     
    List<User> selectUsersByConditions(Map<String, Object> params);  
}
  1. 编写XML映射文件
    在XML映射文件中,你可以直接通过#{paramName}的形式来引用Map中的参数。
<mapper namespace="com.example.mapper.UserMapper">  
  
    <select id="selectUsersByConditions" resultType="com.example.domain.User">  
        SELECT * FROM user  
        <where>  
            <if test="params.username != null and params.username != ''">  
                AND username = #{params.username}  
            </if>  
            <if test="params.email != null and params.email != ''">  
                AND email = #{params.email}  
            </if>  
            <if test="params.age != null">  
                AND age = #{params.age}  
            </if>  
        </where>  
    </select>  
  
</mapper>
  1. 在Service或Controller中调用Mapper方法
    现在,在你的Service或Controller中,你可以创建一个Map对象,设置查询条件,然后调用Mapper方法
@Service  
public class UserService {
     
  
    @Autowired  
    private UserMapper userMapper;  
  
    public List<User> getUsersByConditions(String username, String email, Integer age) {
     
        Map<String, Object> params = new HashMap<>();  
        params.put("username", username
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值