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

目录

经典面试题:

1.mybatis动态sql

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

3.查询返回结果集

   总结:


前言:在我上篇已经学习了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的信息。

mybatis – MyBatis 3 | 动态 SQLicon-default.png?t=N6B9https://mybatis.org/mybatis-3/zh/dynamic-sql.html

例如在我们的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是一种更为灵活和强大的结果映射方式,可以自定义映射规则来处理复杂的查询结果

猜你喜欢

转载自blog.csdn.net/m0_73647713/article/details/132420165