详解Mybatis之动态sql问题(上)

简介: 详解Mybatis之动态sql问题(上)

编译软件:IntelliJ IDEA 2019.2.4 x64

操作系统:win10 x64 位 家庭版

Maven版本:apache-maven-3.6.3

Mybatis版本:3.5.6


一. 在sql映射文件中如何写注释?

关于XXXMapper接口对应的映射文件里SQL中的注释

👉语法

①方式一

//mysql的注释  
-- 1=1

②方式二

//xml的注释
<!-- 1=1  -->

使用这两种注释方式各有什么不同呢?

👉请看如下测试

代码示例如下:

①使用第一种注释

<!--  根据查询条件查找对应的员工信息(条件不确定) 即采用动态的sql去查询  -->
    <select id="selectEmpByopr" resultType="employee">
        SELECT
            `id`,
            `last_name`,
            `email`,
            `salary`,
            `dept_id`
        FROM
            `tbl_employee`
        WHERE
            -- 1=1
            <if test="id !=null">
               and id=#{id}
            </if>
            <if test="lastName != null">
               and last_name=#{lastName}
            </if>
            <if test="email != null">
                and email=#{email}
            </if>
            <if test="salary != null">
                and last_name=#{salary}
            </if>
    </select>

②使用第二种注释

<!--  根据查询条件查找对应的员工信息(条件不确定) 即采用动态的sql去查询  -->
    <select id="selectEmpByopr" resultType="employee">
        SELECT
            `id`,
            `last_name`,
            `email`,
            `salary`,
            `dept_id`
        FROM
            `tbl_employee`
        WHERE
<!--             1=1-->
            <if test="id !=null">
               and id=#{id}
            </if>
            <if test="lastName != null">
               and last_name=#{lastName}
            </if>
            <if test="email != null">
                and email=#{email}
            </if>
            <if test="salary != null">
                and last_name=#{salary}
            </if>
    </select>

💡结论

通过以上二者运行测试结果对比,所以在需要使用注释时,推荐使用第二种注释方式


二. 什么是动态sql?

👉定义

  1. 动态sql指的是sql语句可动态化
  2. Mybatis的动态sql中支持OGNL表达式语言,OGNL(Object Graph Navigation
    Language)是对象图导航语言

❗注意

👉用法案例

不指定查询条件,查询对应员工信息,即当你传入id,程序就根据id去查,传入什么条件,就去根据此条件去查(多个条件不确定)

代码示例如下

①在EmployeeMapper接口下书写相应的方法

//动态的sql方式,即不指定查询条件,查询对应员工信息
public List<Employee> selectEmpByopr(Employee employee);

②在EmployeeMapper接口相应的sql

<!--  根据查询条件查找对应的员工信息(条件不确定) 即采用动态的sql去查询  -->
    <select id="selectEmpByopr" resultType="employee">
        SELECT
            `id`,
            `last_name`,
            `email`,
            `salary`,
            `dept_id`
        FROM
            `tbl_employee`
        WHERE
            <if test="id !=null">
               and id=#{id}
            </if>
            <if test="lastName != null">
               and last_name=#{lastName}
            </if>
            <if test="email != null">
                and email=#{email}
            </if>
            <if test="salary != null">
                and last_name=#{salary}
            </if>
    </select>

③测试

@Test
public void test01(){
    try {
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //通过SqlSessionFactory对象调用openSession();
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //获取EmployeeMapper的代理对象
        EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);
        //动态参数(无参会报错,没有第一个参数也会报错)
        Employee employee=new Employee();
        List<Employee> employees = employeeMapper.selectEmpByopr(employee);
        //遍历集合employees
        for (Employee employee1 : employees) {
            System.out.println(employee1);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

❓但是这样会出现一个问题,即不传参会报错,没有第一个参数也会报错

💡原因分析

不传参时,mybatis解析sql的过程中走到where的部分,无参,会进入where里,但不会执行里面的任意if判断,where后没有任何赋值表达式,此sql为非法sql,故报错。没有第一个参数时也会报类似的问题。

👉解决方案

①在第二步中的where里加上 1=1,作为条件恒等式(老版本的解决措施)

②使用where标签

代码示例如下:

<!--  根据查询条件查找对应的员工信息(条件不确定) 即采用动态的sql去查询  -->
    <select id="selectEmpByopr" resultType="employee">
        SELECT
            `id`,
            `last_name`,
            `email`,
            `salary`,
            `dept_id`
        FROM
            `tbl_employee`
         <where>
            <if test="id !=null">
               and id=#{id}
            </if>
            <if test="lastName != null">
               and last_name=#{lastName}
            </if>
            <if test="email != null">
                and email=#{email}
            </if>
            <if test="salary != null">
                and last_name=#{salary}
            </if>
         </where>
    </select>


三. 动态sql常用标签有哪些?

3.1 if标签

👉功能

用于完成简单的判断

示例代码如下:

//如果属性id不为空,就将传入的参数id赋值给sql中的字段id
 <if test="id !=null">
      id=#{id}
 </if>

3.2 where标签

👉功能:

用于解决where关键字及where后第一个and或or的问题

示例代码如下:

<where>
   <if test="id !=null">
      and id=#{id}
   </if>
   <if test="lastName != null">
      and last_name=#{lastName}
   </if>
   <if test="email != null">
       and email=#{email}
   </if>
   <if test="salary != null">
       and last_name=#{salary}
   </if>
</where>

3.3 trim标签

👉功能

可以在条件判断完的SQL语句前后添加或者去掉指定的字符

👉属性

  • prefix添加前缀
  • prefixOverrides去掉前缀
  • suffix添加后缀
  • suffixOverrides去掉后缀

👉用法案例

不指定查询条件,查询对应员工信息(trim标签优化版)

代码示例如下:

①在EmployeeMapper接口定义相应的方法

//不指定查询条件,查询对应员工信息
public List<Employee> selectEmpByEmpTrim(Employee employee);

②在EmployeeMapper接口对应的映射文件中定义相应的sql

<!--  根据查询条件查找对应的员工信息(条件不确定) 动态的sql(trim标签优化版)  -->
<select id="selectEmpByEmpTrim" resultType="employee">
    SELECT
        `id`,
        `last_name`,
        `email`,
        `salary`,
        `dept_id`
    FROM
        `tbl_employee`
    <!--  给下面的sql语句加上前缀 where,去掉后缀and      -->
    <trim prefix="where" suffixOverrides="and">
        <if test="id !=null">
            id=#{id} and
        </if>
        <if test="lastName != null">
           last_name=#{lastName}  and
        </if>
        <if test="email != null">
            email=#{email}  and
        </if>
        <if test="salary != null">
            salary=#{salary}   and
        </if>
    </trim>
</select>

③测试

@Test
    public void test02(){
        try {
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            //通过SqlSessionFactory对象调用openSession();
            SqlSession sqlSession = sqlSessionFactory.openSession();
            //获取EmployeeMapper的代理对象
            EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);
            //动态参数
            Employee employee=new Employee();
          /*  employee.setLastName("jack");
            employee.setSalary(5600.0);
*/
            List<Employee> employees = employeeMapper.selectEmpByEmpTrim(employee);
            //遍历集合employees
            for (Employee employee1 : employees) {
                System.out.println(employee1);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

trim标签运行流程详解

相关文章
|
4月前
|
SQL Java 测试技术
3、Mybatis-Plus 自定义sql语句
这篇文章介绍了如何在Mybatis-Plus框架中使用自定义SQL语句进行数据库操作。内容包括文档结构、编写mapper文件、mapper.xml文件的解释说明、在mapper接口中定义方法、在mapper.xml文件中实现接口方法的SQL语句,以及如何在单元测试中测试自定义的SQL语句,并展示了测试结果。
3、Mybatis-Plus 自定义sql语句
|
5天前
|
SQL XML Java
mybatis实现动态sql
MyBatis的动态SQL功能为开发人员提供了强大的工具来应对复杂的查询需求。通过使用 `<if>`、`<choose>`、`<foreach>`等标签,可以根据不同的条件动态生成SQL语句,从而提高代码的灵活性和可维护性。本文详细介绍了动态SQL的基本用法和实际应用示例,希望对您在实际项目中使用MyBatis有所帮助。
27 11
|
1月前
|
SQL 缓存 Java
【详细实用のMyBatis教程】获取参数值和结果的各种情况、自定义映射、动态SQL、多级缓存、逆向工程、分页插件
本文详细介绍了MyBatis的各种常见用法MyBatis多级缓存、逆向工程、分页插件 包括获取参数值和结果的各种情况、自定义映射resultMap、动态SQL
【详细实用のMyBatis教程】获取参数值和结果的各种情况、自定义映射、动态SQL、多级缓存、逆向工程、分页插件
|
27天前
|
SQL Java 数据库连接
canal-starter 监听解析 storeValue 不一样,同样的sql 一个在mybatis执行 一个在数据库操作,导致解析不出正确对象
canal-starter 监听解析 storeValue 不一样,同样的sql 一个在mybatis执行 一个在数据库操作,导致解析不出正确对象
|
2月前
|
SQL Java 数据库连接
mybatis使用四:dao接口参数与mapper 接口中SQL的对应和对应方式的总结,MyBatis的parameterType传入参数类型
这篇文章是关于MyBatis中DAO接口参数与Mapper接口中SQL的对应关系,以及如何使用parameterType传入参数类型的详细总结。
54 10
|
3月前
|
SQL XML Java
mybatis复习03,动态SQL,if,choose,where,set,trim标签及foreach标签的用法
文章介绍了MyBatis中动态SQL的用法,包括if、choose、where、set和trim标签,以及foreach标签的详细使用。通过实际代码示例,展示了如何根据条件动态构建查询、更新和批量插入操作的SQL语句。
mybatis复习03,动态SQL,if,choose,where,set,trim标签及foreach标签的用法
|
4月前
|
SQL Java 数据库连接
Mybatis系列之 Error parsing SQL Mapper Configuration. Could not find resource com/zyz/mybatis/mapper/
文章讲述了在使用Mybatis时遇到的资源文件找不到的问题,并提供了通过修改Maven配置来解决资源文件编译到target目录下的方法。
Mybatis系列之 Error parsing SQL Mapper Configuration. Could not find resource com/zyz/mybatis/mapper/
|
3月前
|
SQL XML Java
mybatis :sqlmapconfig.xml配置 ++++Mapper XML 文件(sql/insert/delete/update/select)(增删改查)用法
当然,这些仅是MyBatis功能的初步介绍。MyBatis还提供了高级特性,如动态SQL、类型处理器、插件等,可以进一步提供对数据库交互的强大支持和灵活性。希望上述内容对您理解MyBatis的基本操作有所帮助。在实际使用中,您可能还需要根据具体的业务要求调整和优化SQL语句和配置。
67 1
|
4月前
|
SQL Java 数据库连接
Mybatis系列之 动态SQL
文章详细介绍了Mybatis中的动态SQL用法,包括`<if>`、`<choose>`、`<when>`、`<otherwise>`、`<trim>`和`<foreach>`等元素的应用,并通过实际代码示例展示了如何根据不同条件动态生成SQL语句。
|
4月前
|
SQL 关系型数据库 MySQL
解决:Mybatis-plus向数据库插入数据的时候 报You have an error in your SQL syntax
该博客文章讨论了在使用Mybatis-Plus向数据库插入数据时遇到的一个常见问题:SQL语法错误。作者发现错误是由于数据库字段中使用了MySQL的关键字,导致SQL语句执行失败。解决方法是将这些关键字替换为其他字段名称,以避免语法错误。文章通过截图展示了具体的操作步骤。