编译软件: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?
👉定义
- 动态sql指的是sql语句可动态化
- 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标签运行流程详解