mybatis讲解(2)之动态SQL的运用

简介: mybatis讲解(2)之动态SQL的运用

前言:在我上篇已经学习了Mybatis简介以及如何去连接数据库,具有增删改查的方法。那么我们今天来学习Mybatis的第二节关于1.mybatis动态sql,2.模糊查询(3种方式),3.查询返回结果集。希望大家学了可以对你们的学习,工作具有帮助。

经典面试题:

问题一:#{...}与${...}区别?

       1.$是占位值赋值,#是预处理SQL

       2. 参数类型为字符串,#会在前后加单引号['],$则直接插入值    

注: mybatis中使用OGNL表达式传递参数

       3.${...}方式存在SQL注入风险

       4.${...}可以做动态列,完成动态sql开发。

注意: 优先使用#{...},因为: ${...}方式存在SQL注入风险

补充:SQL注入风险:SQL注入风险是指通过植入恶意的SQL代码,攻击者可以绕过正常的安全验证机制,执行恶意的数据库操作,导致数据泄露、破坏或未授权访问。这种风险在报表中也存在。通过在报表的查询条件中注入恶意的SQL代码,攻击者可以利用这个漏洞获取敏感数据或对数据库进行破坏。此外,由于报表工具往往直接拼接用户输入的条件串作为SQL语句的一部分,如果没有对用户输入进行充分的验证和过滤,就容易受到SQL注入攻击。因此,为了防范SQL注入风险,在报表开发中需要采取相应的安全措施,如对用户输入进行严格的验证和过滤,使用参数化查询等。

举实例:我们在使用sql查询时使用的两种方式:

deptid=822520

select * from t_oa_employee where deptid = #{deptid}

select * from t_oa_employee where deptid = 822520

                                                                                                                                          select * from t_oa_employee where deptid = ${deptid}                                                 select * from t_oa_employee where deptid =822520 or 1 = 1

第二种sql会查出来所有员工信息的不安全哦        

                               

       

                                                                                                                                         问题二:在mybatis中   resultMap,resultType区别?

在MyBatis中,resultMap和resultType是用于在查询中进行结果映射的两种方式。它们的区别如下:

  1. 对象不同:resultType是直接指定返回类型,而resultMap是一个定义了结果映射规则的对象。
  2. 描述不同:resultType通过属性名来进行结果映射,只有查询出来的列名与属性名一致时才能成功映射。而resultMap可以通过配置来定义复杂的映射规则,可以自由地对查询结果进行处理和映射。
  3. 类型适用不同:resultType适用于简单的查询结果映射,当查询结果的列名和属性名一致时比较方便。而resultMap适用于复杂的查询结果映射,可以灵活地处理和映射不同的查询结果。

1.mybatis动态sql

介绍:MyBatis动态SQL是一种基于OGNL表达式的技术,可以在SQL语句中实现一些逻辑判断。总体上,MyBatis动态SQL主要包含以下几类语句:

1. if语句:用于简单的条件判断。

2. choose语句(相当于Java语言中的switch):包含when和otherwise子句,类似于JSTL中的choose语句。

3. trim语句:在包含的内容上添加前缀或后缀,可以用于动态地拼接SQL语句。

4. where语句:主要用于简化SQL语句中的where条件判断,能够智能地处理and和or,防止多余导致语法错误。

5. set语句:主要用于更新操作。

6. foreach语句:在实现MyBatis的in语句查询时特别有用。

以上是MyBatis动态SQL的几种主要用法,可以根据具体需求选择适合的方式来编写动态SQL语句。

MyBatis Dynamic SQL是一个与MyBatis配套的项目,它解决了MyBatis在动态SQL方面的一些缺点,并提供了更灵活、强大的动态SQL功能。该项目可以帮助开发人员更方便地编写复杂的SQL语句,提高开发效率。你可以在官方文档中了解更多关于MyBatis Dynamic SQL的信息。

例如在我们的Mapper文件中修改方法的if标签

 

例如在我们的自定义Mapper文件中查询的foreach标签

使用foreach去得到指定id的查询指定的值

Mapper.xml

<select id="selectBooksIn" resultType="com.lya.model.Book" parameterType="java.util.List">
    select * from t_mvc_book where bid in
    <foreach collection="bookIds" open="(" close=")" separator="," item="bid">
      #{bid}
    </foreach>
  </select>

BookMapper的接口

List<Book> selectBooksIn(@Param("bookIds") List bookIds);

IBookService接口

List<Book> selectBooksIn(@Param("bookIds") List bookIds);

BookServiceImpl

@Override
    public List<Book> selectBooksIn(List bookIds) {
        return bookMapper.selectBooksIn(bookIds);
    }

运行结果:

2.模糊查询(3种方式)

 

   2.1 参数中直接加入%%

<!--  模糊查询-->
<!--  1-->
  <select id="like1" resultType="com.lya.model.Book" parameterType="java.lang.String">
    SELECT
    <include refid="Base_Column_List" />
    from t_mvc_book
    where bname like #{bname}
  </select>
<!--2-->
  <select id="like2" resultType="com.lya.model.Book" parameterType="java.lang.String">
    SELECT
    <include refid="Base_Column_List" />
    from t_mvc_book
    where bname like ${bname};
  </select>
<!--  3-->
  <select id="like3" resultType="com.lya.model.Book" parameterType="java.lang.String">
    SELECT
    <include refid="Base_Column_List" />
    from t_mvc_book
    where bname like concat('%','圣墟','%');
  </select>

这里我们运行第二种会有个报错

解决方法:传值添加单引号

 

   2.3 SQL字符串拼接CONCAT

3.查询返回结果集

   resultMap:适合使用返回值是自定义实体类的情况

   resultType:适合使用返回值的数据类型是非自定义的,即jdk的提供的类型

   3.1 使用resultMap返回自定义类型集合

返回单表的对应的实体类,仅有一个查询结果,可以用resultType/resultMap。

使用了resultType

<select id="selectresultType" resultType="com.lya.model.Book" parameterType="java.lang.Integer">
        select
        <include refid="Base_Column_List"/>
        from t_mvc_book
        where bid = #{bid,jdbcType=INTEGER}
    </select>

编写接口实现接口

Book selectresultType(Integer bid);
    @Override
    public Book selectresultType(Integer bid) {
        return bookMapper.selectresultType(bid);
    }

测试方法

@Test
    public void selectresultType() {
        System.out.println("测试resultType查询");
        Book book = bookbiz.selectByPrimaryKey(12);
        System.out.println(book);
    }

测试结果

2.返回单表的对应的实体类,有多个查询结果,可以用resultType/resultMap。

 

1.resultType/resultMap。resultType一个或多个都用实体对象

<select id="selectresultType01" resultType="com.lya.model.Book">
        select
        <include refid="Base_Column_List"/>
        from t_mvc_book
    </select>
    <select id="selectresultMap01" resultMap="BaseResultMap">
        select
        <include refid="Base_Column_List"/>
        from t_mvc_book
    </select>

编写接口方法和实现接口

List<Book> selectresultType01();
    List<Book> selectresultMap01();
@Override
    public List<Book> selectresultType01() {
        return bookMapper.selectresultType01();
    }
    @Override
    public List<Book> selectresultMap01() {
        return bookMapper.selectresultMap01();
    }

测试方法

 

@Test
    public void selectresultType01() {
        bookbiz.selectresultType01().forEach(System.out::println);
    }
    @Test
    public void selectresultMap01() {
        bookbiz.selectresultMap01().forEach(System.out::println);
  1. 返回多表的对应的实体类,仅有一个查询结果,通常用resultType,也可以用resultMap。
  2. 返回多表的对应的实体类,有多个查询结果,通常用resultType,也可以用resultMap。
  3. 返回单个列表,仅有一个查询结果,就用resultType。
  4. 返回单个列表,有多个查询结果,就用resultType。

 

配置xml

<!--单个-->

<select id="selectByString01" resultType="java.lang.String" parameterType="java.lang.Integer">
        select bname
        from t_mvc_book
        where bid = #{bid,jdbcType=INTEGER}
    </select>

   <!--多个-->

 

<select id="selectByString02" resultType="java.lang.String" parameterType="java.lang.String">
        select bname
        from t_mvc_book
        where bname like concat('%', #{bname}, '%')
    </select>

编写接口和实现接口

 

String selectByString01(Integer bid);
    List<String> selectByString02(String bname);
  @Override
    public String selectByString01(Integer bid) {
        return bookMapper.selectByString01(bid);
    }
    @Override
    public List<String> selectByString02(String bname) {
        return bookMapper.selectByString02(bname);
    }

测试方法

@Test
    public void selectByString01() {
        System.out.println(bookbiz.selectByString01(60));
    }
    @Test
    public void selectByString02() {
        Map map = new HashMap();
        map.put("sid", "01");
        map.put("cid", "01");
        bookbiz.selectByString02("圣墟").forEach(System.out::println);

  总结:

总结来说,resultType是一种简单的结果映射方式,适用于列名和属性名一致的情况;而resultMap是一种更为灵活和强大的结果映射方式,可以自定义映射规则来处理复杂的查询结果

目录
相关文章
|
3月前
|
SQL XML Java
通过MyBatis的XML配置实现灵活的动态SQL查询
总结而言,通过MyBatis的XML配置实现灵活的动态SQL查询,可以让开发者以声明式的方式构建SQL语句,既保证了SQL操作的灵活性,又简化了代码的复杂度。这种方式可以显著提高数据库操作的效率和代码的可维护性。
261 18
|
8月前
|
SQL Java 数据库连接
【YashanDB知识库】解决mybatis的mapper文件sql语句结尾加分号";"报错
【YashanDB知识库】解决mybatis的mapper文件sql语句结尾加分号";"报错
|
7月前
|
SQL Java 数据库连接
MyBatis动态SQL字符串空值判断,这个细节99%的程序员都踩过坑!
本文深入探讨了MyBatis动态SQL中字符串参数判空的常见问题。通过具体案例分析,对比了`name != null and name != &#39;&#39;`与`name != null and name != &#39; &#39;`两种写法的差异,指出后者可能引发逻辑混乱。为避免此类问题,建议在后端对参数进行预处理(如trim去空格),简化MyBatis判断逻辑,提升代码健壮性与可维护性。细节决定成败,严谨处理参数判空是写出高质量代码的关键。
956 0
|
3月前
|
SQL Java 数据库连接
SSM相关问题-1--#{}和${}有什么区别吗?--Mybatis都有哪些动态sql?能简述一下动 态sql的执行原理吗?--Spring支持的几种bean的作用域 Scope
在MyBatis中,`#{}`是预处理占位符,可防止SQL注入,适用于大多数参数传递场景;而`${}`是直接字符串替换,不安全,仅用于动态表名、列名等特殊场景。二者在安全性、性能及使用场景上有显著区别。
78 0
|
6月前
|
SQL XML Java
菜鸟之路Day35一一Mybatis之XML映射与动态SQL
本文介绍了MyBatis框架中XML映射与动态SQL的使用方法,作者通过实例详细解析了XML映射文件的配置规范,包括namespace、id和resultType的设置。文章还对比了注解与XML映射的优缺点,强调复杂SQL更适合XML方式。在动态SQL部分,重点讲解了`&lt;if&gt;`、`&lt;where&gt;`、`&lt;set&gt;`、`&lt;foreach&gt;`等标签的应用场景,如条件查询、动态更新和批量删除,并通过代码示例展示了其灵活性与实用性。最后,通过`&lt;sql&gt;`和`&lt;include&gt;`实现代码复用,优化维护效率。
544 5
|
8月前
|
SQL Java 数据库连接
【YashanDB 知识库】解决 mybatis 的 mapper 文件 sql 语句结尾加分号";"报错
【YashanDB 知识库】解决 mybatis 的 mapper 文件 sql 语句结尾加分号";"报错
|
8月前
|
SQL 缓存 Java
框架源码私享笔记(02)Mybatis核心框架原理 | 一条SQL透析核心组件功能特性
本文详细解构了MyBatis的工作机制,包括解析配置、创建连接、执行SQL、结果封装和关闭连接等步骤。文章还介绍了MyBatis的五大核心功能特性:支持动态SQL、缓存机制(一级和二级缓存)、插件扩展、延迟加载和SQL注解,帮助读者深入了解其高效灵活的设计理念。
|
9月前
|
SQL XML Java
九、MyBatis动态SQL
九、MyBatis动态SQL
149 2
|
10月前
|
SQL Java 数据库连接
【潜意识Java】MyBatis中的动态SQL灵活、高效的数据库查询以及深度总结
本文详细介绍了MyBatis中的动态SQL功能,涵盖其背景、应用场景及实现方式。
1059 6
|
8月前
|
SQL XML Java
六、MyBatis特殊的SQL:模糊查询、动态设置表名、校验名称唯一性
六、MyBatis特殊的SQL:模糊查询、动态设置表名、校验名称唯一性
230 0