MyBatis动态语句且如何实现模糊查询及resultType与resultMap的区别---详细介绍

简介: MyBatis动态语句且如何实现模糊查询及resultType与resultMap的区别---详细介绍

前言

前面我们学习了如何使用Mybatis实现简单的增删改查。今天我们来学习如何使用动态语句来根据不同的条件生成不同的SQL语句。这在实际开发中非常有用,因为通常查询条件是多样化的,需要根据实际情况来拼接SQL语句,那什么是MyBatis动态语句呢,看下面详细简介

一,什么是MyBatis动态语句?

MyBatis动态语句是指在编写SQL语句时,使用MyBatis提供的动态标签和表达式,根据不同的条件生成不同的SQL语句片段。通过使用动态语句,我们可以根据不同的条件动态地拼接SQL语句,使其更灵活和可复用。

1.1 MyBatis常用的动态标签和表达式

if 标签

    用于根据条件判断是否包含某个SQL语句片段。当条件成立时,会将<if>标签内部的SQL语句包含到最终生成的SQL语句中

示例代码:

<select id="getUser" parameterType="int" resultType="User">
    SELECT * FROM user WHERE 1=1
    <if test="id != null">
        AND id = #{id}
    </if>
    <if test="username != null">
        AND username = #{username}
    </if>
</select>

上面属性解释,具体定义一个查询语句的标签,id属性指定了查询语句的唯一标识,parameterType属性指定了输入参数的类型,resultType属性指定了返回结果的类型

<if test="id != null">:动态语句的起始标签,用于判断条件是否成立

 

AND id = #{id}:            :SQL语句片段 将id!=null 成立sql条件包含到最终生成的SQL语句中

 

AND username = #{username}:SQL语句片段,当条件username != null成立时,将被包含到最终生成的SQL语句中

其中的 test属性用于指定一个表达式,用来判断条件是否成立。表达式可以是任意的合法表达式,通常使用参数的属性进行判断#{}是MyBatis中的占位符,可以获取参数的值。

Choose 标签

   使用<choose>标签和<when><otherwise>标签来实现多条件选择,根据条件选择对应的SQL语句片段

示例代码:

<select id="getUser" parameterType="int" resultType="User">
    SELECT * FROM user WHERE 1=1
    <choose>
        <when test="id != null">
            AND id = #{id}
        </when>
        <when test="username != null">
            AND username = #{username}
        </when>
        <otherwise>
            AND age > #{age}
        </otherwise>
    </choose>
</select>

在上面的代码<otherwise>标签用于指定条件都不成立时执行的SQL语句片段。

 

Where 标签

使用<where>标签将条件拼接到WHERE子句中,如果条件不成立则不会生成WHERE关键字

示例代码:

<select id="getUser" parameterType="int" resultType="User">
    SELECT * FROM user
    <where>
        <if test="id != null">
            AND id = #{id}
        </if>
        <if test="username != null">
            AND username = #{username}
        </if>
    </where>
</select>

Set 标签

 使用<set>标签将更新的字段拼接到SET子句中,如果条件不成立则不会生成SET关键字

示例代码:

<update id="updateUser" parameterType="User">
    UPDATE user
    <set>
        <if test="username != null">
            username = #{username},
        </if>
        <if test="password != null">
            password = #{password},
        </if>
    </set>
    WHERE id = #{id}
</update>

二,MaBatis模糊查询

  2.1 #$的区别

   #(井号)

     用于预编译阶段,也称为安全的参数替换。当我们使用#来表示一个参数时,MyBatis会自动将传入的参数进行预编译处理,并且会对参数进行类型安全检查,然后将其转义后嵌入到SQL语句中。这样可以防止SQL注入攻击。因此,#通常在我们需要传递动态参数时使用。在SQL语句中使用#表示参数的位置

例如:

SELECT * FROM user WHERE id = #{userId}

   $(美元符号)

(美元符号)则是直接拼接参数值。当我们使用来表示一个参数时,MyBatis会把参数原封不动地拼接到SQL语句中,而不会进行任何转义或预编译处理。这样的参数替换是不安全的容易受到SQL注入攻击。因此,通常在我们确保参数安全或需要传递动态的表名、列名等情况下使用。在SQL语句中使用表示参数的内容

例如:

SELECT * FROM ${tableName}

注意:使用$进行参数替换时,我们需要自己确保参数的值正确并且安全,以避免潜在的安全风险。而使用#进行参数替换时,MyBatis会帮助我们处理参数的类型安全和转义等问题更加安全可靠。

 

 

实操案例:

为了更加#与$的区别,我们配置三种的方式来测试,#与$及concat

 

在我们前面一篇的Mybatis讲解中,生成增删改查的类中配置刚所写的xml中的模糊查询方法

package com.Bing.mapper;
import com.Bing.model.Book;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface BookMapper {
    int deleteByPrimaryKey(Integer bid);
    int insert(Book record);
    int insertSelective(Book record);
    Book selectByPrimaryKey(Integer bid);
    int updateByPrimaryKeySelective(Book record);
    int updatByPrimaryKey(Book record);
    List<Book> selectByBids(@Param("bids") List bids);
    List<Book> mhcx1(@Param("bname") String bname);
    List<Book> mhcx2(@Param("bname") String bname);
    List<Book> mhcx3(@Param("bname") String bname);
}

在前端和后端进行相对应的dao方法

定义一个接口并实现

接口方法:

List<Book> mhcx1(@Param("bname") String bname);
    List<Book> mhcx2(@Param("bname") String bname);
    List<Book> mhcx3(@Param("bname") String bname);

实现类:

package com.Bing.biz.impl;
import com.Bing.biz.BookBiz;
import com.Bing.mapper.BookMapper;
import com.Bing.model.Book;
import java.util.List;
/**
 * @Name BingBing
 * @company zking cy
 * @create 2023-08-21-11:30
 */
public class BookBizImpl implements BookBiz {
    private BookMapper bookMapper;
    public BookBizImpl() {
    }
    public BookMapper getBookMapper() {
        return bookMapper;
    }
    public void setBookMapper(BookMapper bookMapper) {
        this.bookMapper = bookMapper;
    }
    @Override
    public int deleteByPrimaryKey(Integer bid) {
       return  bookMapper.deleteByPrimaryKey(bid);
    }
    @Override
    public int insert(Book record) {
        return bookMapper.insert(record);
    }
    @Override
    public int insertSelective(Book record) {
        return bookMapper.insertSelective(record);
    }
    @Override
    public Book selectByPrimaryKey(Integer bid) {
        return bookMapper.selectByPrimaryKey(bid);
    }
    @Override
    public int updateByPrimaryKeySelective(Book record) {
        return bookMapper.updateByPrimaryKeySelective(record);
    }
    @Override
    public int updatByPrimaryKey(Book record) {
        return bookMapper.updatByPrimaryKey(record);
    }
    @Override
    public List<Book> selectByBids(List bids) {
         return bookMapper.selectByBids(bids);
    }
    @Override
    public List<Book> mhcx1(String bname) {
        return bookMapper.mhcx1(bname);
    }
    @Override
    public List<Book> mhcx2(String bname) {
        return bookMapper.mhcx2(bname);
    }
    @Override
    public List<Book> mhcx3(String bname) {
        return bookMapper.mhcx3(bname);
    }
}

接下来就是测试类了,测试#号

测试类 调用#号方法:

@Test
    public void mhcx1() {
        bookBiz.mhcx1("%圣墟%").forEach(System.out::println);
    }

运行结果:

 

等到的结果: #{bname}会将传入的bname值进行预编译转义处理,然后再拼接到SQL语句中

测试$号

@Test
    public void mhcx2() {
        bookBiz.mhcx2("%圣墟%").forEach(System.out::println);
    }

运行会报错

 

要在我们的xml文件中$bname加上引号' '

 

加好之后,再来测试类运行一遍

 

等到的结果:${bname}会将传入的bname值直接拼接到SQL语句中

 

三,MyBatis结果映射

resultType

   是在 SQL 映射文件中指定查询结果的数据类型。它可以直接指定一个基本数据类型(如 String、Integer 等)或一个实体类的全限定名。当查询结果只包含单个简单数据类型时,通常使用 resultType

例如:

<select id="getUserAge" resultType="Integer">
    SELECT age FROM user WHERE id = #{userId}
</select>

resultMap

   则是用于处理复杂的查询结果映射关系。它定义了数据库列和 Java 对象属性之间的映射规则。通过使用 resultMap,我们可以将查询结果映射到一个复杂的对象结构中,可以包含嵌套查询结果、联合查询等复杂情况。通常,在查询结果需要转换成复杂对象或者集合时使用 resultMap

<resultMap id="userMap" type="User">
    <id column="id" property="id"/>
    <result column="name" property="name"/>
    <result column="age" property="age"/>
    <!-- 其他属性映射 -->
</resultMap>
<select id="getUsers" resultMap="userMap">
    SELECT * FROM user
</select>

其中 <resultMap> 标签定义了 User 类中各个属性与数据库表的列之间的映射规则,并设置了唯一标识符 userMap。在 <select> 标签中使用 resultMap 属性指定查询结果的映射关系。

 

总结来说,resultType 适用于简单的查询结果映射,而 resultMap 适用于复杂的查询结果映射。根据实际情况选择合适的方式可以提高 MyBatis 查询结果的灵活性和可读性。

 

 

目录
相关文章
|
SQL XML Java
七、MyBatis自定义映射resultMap
七、MyBatis自定义映射resultMap
408 6
|
SQL XML Java
六、MyBatis特殊的SQL:模糊查询、动态设置表名、校验名称唯一性
六、MyBatis特殊的SQL:模糊查询、动态设置表名、校验名称唯一性
462 0
mybatis复习02,简单的增删改查,@Param注解多个参数,resultType与resultMap的区别,#{}预编译参数
文章介绍了MyBatis的简单增删改查操作,包括创建数据表、实体类、配置文件、Mapper接口及其XML文件,并解释了`#{}`预编译参数和`@Param`注解的使用。同时,还涵盖了resultType与resultMap的区别,并提供了完整的代码实例和测试用例。
mybatis复习02,简单的增删改查,@Param注解多个参数,resultType与resultMap的区别,#{}预编译参数
|
SQL 安全 Java
MyBatis(6)#{}和${}的区别
在MyBatis中,`#{}`和`${}`是用于在SQL语句中嵌入参数的两种方式。`#{}`用于预处理参数,可以防止SQL注入;而`${}`进行直接字符串替换,适用于动态插入表名或列名,但存在SQL注入风险。建议优先使用`#{}`,并在必要时谨慎使用`${}`。
528 3
|
SQL Java 数据库连接
MyBatis 和 Hibernate 有什么区别?
【8月更文挑战第21天】
550 0
|
SQL Java 数据库连接
在mybatis中#{}和${}的区别
在MyBatis中,使用#{}可以防止SQL注入,它通过预处理语句来安全地设置参数值,而${}会将传入的数据直接插入SQL语句中,不安全,通常用于传入数据库对象或在确保数据安全的情况下使用。
|
10月前
|
Java 数据库连接 数据库
Spring boot 使用mybatis generator 自动生成代码插件
本文介绍了在Spring Boot项目中使用MyBatis Generator插件自动生成代码的详细步骤。首先创建一个新的Spring Boot项目,接着引入MyBatis Generator插件并配置`pom.xml`文件。然后删除默认的`application.properties`文件,创建`application.yml`进行相关配置,如设置Mapper路径和实体类包名。重点在于配置`generatorConfig.xml`文件,包括数据库驱动、连接信息、生成模型、映射文件及DAO的包名和位置。最后通过IDE配置运行插件生成代码,并在主类添加`@MapperScan`注解完成整合
1578 1
Spring boot 使用mybatis generator 自动生成代码插件
|
XML Java 数据库连接
微服务——SpringBoot使用归纳——Spring Boot集成MyBatis——基于注解的整合
本文介绍了Spring Boot集成MyBatis的两种方式:基于XML和注解的形式。重点讲解了注解方式,包括@Select、@Insert、@Update、@Delete等常用注解的使用方法,以及多参数时@Param注解的应用。同时,针对字段映射不一致的问题,提供了@Results和@ResultMap的解决方案。文章还提到实际项目中常结合XML与注解的优点,灵活使用两者以提高开发效率,并附带课程源码供下载学习。
1037 0
|
前端开发 Java 数据库连接
Java后端开发-使用springboot进行Mybatis连接数据库步骤
本文介绍了使用Java和IDEA进行数据库操作的详细步骤,涵盖从数据库准备到测试类编写及运行的全过程。主要内容包括: 1. **数据库准备**:创建数据库和表。 2. **查询数据库**:验证数据库是否可用。 3. **IDEA代码配置**:构建实体类并配置数据库连接。 4. **测试类编写**:编写并运行测试类以确保一切正常。
751 2
|
Java 数据库连接 Maven
mybatis使用一:springboot整合mybatis、mybatis generator,使用逆向工程生成java代码。
这篇文章介绍了如何在Spring Boot项目中整合MyBatis和MyBatis Generator,使用逆向工程来自动生成Java代码,包括实体类、Mapper文件和Example文件,以提高开发效率。
780 2
mybatis使用一:springboot整合mybatis、mybatis generator,使用逆向工程生成java代码。