当前位置: 首页 > news >正文

JavaSSM框架-MyBatis 框架(五)

9. 动态 SQL

Mybatis框架的动态SQL技术是一种根据特定条件动态拼装SQL语句的功能,它存在的意义是为了解决拼接SQL语句字符串时的痛点问题。

9.1 if & where & trim 标签

  1. DynamicSQLMapper 接口

    public interface DynamicSQLMapper {List<Emp> getEmpByCondition(Emp emp);
    }
    
  2. DynamicSQLMapper 映射文件
    if 标签可通过test属性的表达式进行判断,若表达式的结果为true,则标签中的内容会执行;反之标签中的内容不会执行
    注意:其本质就是SQL拼接,如果if条件为true,则直接把if标签里的内容拼接在SQL语句后面

    <!--注意开启下划线映射驼峰-->
    <!--List<Emp> getEmpByCondition(@Param("emp") Emp emp);-->
    <select id="getEmpByCondition" resultType="Emp">select * from t_emp where<!--注意test里面写判断语句,即if括号中的内容,要用and连接,因为&&是特殊字符--><if test="empName != null and empName != '' ">emp_name = #{empName}</if><if test="age != null">and age = #{age}</if><if test="gender != null and gender != '' ">and gender = #{gender}</if>
    </select>
    

    注意:上述SQL语句存在的问题,当第一个if条件不成立时,而第二个成立时,SQL语句就会变成,select * from t_emp where and age = #{age}显然是错误的,当所有if都不成立时,SQL语句最后就多了个where,也是错误的,以下有三种解决方案:

    1. 解决方案一:在where后面加1=1,并且在第一个if前加and

      <select id="getEmpByCondition" resultType="Emp">select * from t_emp where 1 = 1<!--在第一个if里面加and,同时在where后面加上1=1,--><if test="empName != null and empName != '' ">and emp_name = #{empName}</if><if test="age != null">and age = #{age}</if><if test="gender != null and gender != '' ">and gender = #{gender}</if>
      </select>
      
    2. 解决方案二:使用where标签

      where和if一般结合使用:

      • where标签中有条件成立,会自动生成where关键字

      • where标签中的if条件都不满足,则where标签没有任何功能,即不会添加where关键字

      • where标签中的if条件满足,则where标签会自动添加where关键字,并将条件最前方多余的and去掉

      注意:where标签不能去掉条件最后多余的and,也不能添加and

      <select id="getEmpByCondition" resultType="Emp">select * from t_emp<where><if test="empName != null and empName != '' ">emp_name = #{empName}</if><if test="age != null">and age = #{age}</if><if test="gender != null and gender != '' ">and gender = #{gender}</if></where>
      </select>
      

      where和if配合工作流程如下:

      1. 首先是if进行判断,如果条件成立,则将其拼接,例如如果第二个if语句,即age != null成立,且第三个if也成立,那么最后where标签里就会变成如下内容,即将符合条件的语句拼接在一起

        <where>and age = #{age} and gender = #{gender}
        </where>
        
      2. 而后便是where标签执行,where标签会将标签里的内容中,前面的and去掉,并在最前面加上where,最后便会变成如下内容:

        where age = #{age} and gender = #{gender}
        
    3. 解决方案三:使用trim标签

      trim用于去掉或添加标签中的内容

      常用属性:

      • prefix:在trim标签中的内容的前面添加某些内容

      • prefixOverrides:在trim标签中的内容的前面去掉某些内容

      • suffix:在trim标签中的内容的后面添加某些内容

      • suffixOverrides:在trim标签中的内容的后面去掉某些内容

      <select id="getEmpByCondition" resultType="Emp">select * from t_emp<trim prefix="where" suffixOverrides="and"><!--注意test里面写判断语句,即if括号中的内容,要用and连接,因为&&是特殊字符--><if test="empName != null and empName != '' ">emp_name = #{empName} and</if><if test="age != null">age = #{age} and</if><if test="gender != null and gender != '' ">gender = #{gender} and</if></trim></select>
      

      注意:其原理与where标签类似,首先判断if条件否成立,然后进行拼接,最后对trim标签的内容进行相应的操作

  3. Junit 测试

    @Test
    public void testGetEmpByCondition() {SqlSession sqlSession = SqlSessionUtil.getSqlSession();DynamicSQLMapper mapper = sqlSession.getMapper(DynamicSQLMapper.class);// Emp emp = new Emp(null,"张三",19,"男");Emp emp = new Emp(null,"",19,"男");List<Emp> empList = mapper.getEmpByCondition(emp);System.out.println(empList);
    }
    

9.2 choose、when、otherwise

choose、when、 otherwise:

  • 相当于java中的if…else if…else
  • when至少设置一个,otherwise 最多设置一个
  1. DynamicSQLMapper 接口

    public interface DynamicSQLMapper {List<Emp> getEmpByChoose(Emp emp);
    }
    
  2. DynamicSQLMapper 映射文件

    <!--List<Emp> getEmpByChoose(Emp emp);-->
    <select id="getEmpByChoose" resultType="Emp">select * from t_emp<where><choose><!--其中第一个when就相当于if,后面的when相当于if else,最后的otherwise相当于else其实就是多分支结构,也类似与switch语句--><when test="empName != null and empName != ''">emp_name = #{empName}</when><when test="age != null">age = #{age}</when><when test="gender != null and gender != '' ">gender = #{gender}</when><otherwise></otherwise></choose></where>
    </select>
    
  3. Junit 测试

    @Test
    public void testGetEmpByChoose() {SqlSession sqlSession = SqlSessionUtil.getSqlSession();DynamicSQLMapper mapper = sqlSession.getMapper(DynamicSQLMapper.class);Emp emp = new Emp(null,"",19,"男");List<Emp> empList = mapper.getEmpByChoose(emp);System.out.println(empList);
    }
    

9.3 foreach 标签

foreach 标签属性如下:

  • collection:设置要循环的数组或集合
  • item:用一个字符串表示数组或集合中的每一个数据
  • separator:设置每次循环的数据之间的分隔符
  • open:循环的所有内容以什么开始
  • close:循环的所有内容以什么结束
  1. DynamicSQLMapper 接口

    public interface DynamicSQLMapper {void insertMoreEmp(@Param("emps") List<Emp> emps);void deleteMoreEmp(@Param("empIds") Integer[] empIds);
    }
    
  2. DynamicSQLMapper 映射文件

    <!--void insertMoreEmp(@Param("emps") List<Emp> emps);-->
    <insert id="insertMoreEmp">insert into t_emp values<foreach collection="emps" item="emp" separator=",">(null,#{emp.empName},#{emp.age},#{emp.gender},null)</foreach>
    </insert><!--void deleteMoreEmp(Integer[] empIds);-->
    <delete id="deleteMoreEmp"><!--第一种方式--><!--delete from t_emp where emp_id in(<foreach collection="empIds" item="empId" separator=",">#{empId}</foreach>)--><!--第二种方式:open表示以什么开始,close表示以什么结束--><!--delete from t_emp where emp_id in<foreach collection="empIds" item="empId" separator="," open="(" close=")">#{empId}</foreach>--><!--第三种方式:注意下面的separator="or",or的左右不用加空格也行,会自动在前后加空格-->delete from t_emp where<foreach collection="empIds" item="empId" separator="or">emp_id = #{empId}</foreach>
    </delete>
    
  3. Junit 测试

    @Test
    public void testInsertMoreEmp() {SqlSession sqlSession = SqlSessionUtil.getSqlSession();DynamicSQLMapper mapper = sqlSession.getMapper(DynamicSQLMapper.class);List<Emp> emps = new ArrayList<>();emps.add(new Emp(null,"小明1",19,"男"));emps.add(new Emp(null,"小明2",19,"男"));emps.add(new Emp(null,"小明3",19,"男"));mapper.insertMoreEmp(emps);
    }@Test
    public void testDeleteMoreEmp() {SqlSession sqlSession = SqlSessionUtil.getSqlSession();DynamicSQLMapper mapper = sqlSession.getMapper(DynamicSQLMapper.class);Integer[] empIds = new Integer[]{8,9,10};mapper.deleteMoreEmp(empIds);
    }
    

9.4 SQL片段

sql片段,可以记录一段公共sql片段,在使用的地方通过include标签进行引入,其include标签属性refidsql片段的id

<sql id="empColumns">emp_id,emp_name,age,gender,dept_id
</sql>
<select id="getEmpById" resultType="Emp" >select <include refid="empColumns"></include> from t_emp where emp_id = #{empId}
</select>

文章转载自:

http://yCqVXG7T.dzdtj.cn
http://YmEDQ6Dk.dzdtj.cn
http://zA6rTdab.dzdtj.cn
http://XHiDTpR1.dzdtj.cn
http://y7bYVcZ4.dzdtj.cn
http://cD5ghN4K.dzdtj.cn
http://OFyjS7u5.dzdtj.cn
http://BDG2sHUl.dzdtj.cn
http://HEJ4kf8f.dzdtj.cn
http://NIMEumbH.dzdtj.cn
http://1hkXu68g.dzdtj.cn
http://i0Dm9rje.dzdtj.cn
http://0TCxnWEQ.dzdtj.cn
http://7sdbaigK.dzdtj.cn
http://Yu29WcLL.dzdtj.cn
http://NyZQcvZS.dzdtj.cn
http://IztS1z8f.dzdtj.cn
http://o2e9MRqn.dzdtj.cn
http://U5L2qIAY.dzdtj.cn
http://aS3s1dV0.dzdtj.cn
http://qPSJBj0f.dzdtj.cn
http://WmDTt2i0.dzdtj.cn
http://Aze0dDj1.dzdtj.cn
http://jY4AajJy.dzdtj.cn
http://TyRsArET.dzdtj.cn
http://BFAxxw4a.dzdtj.cn
http://Eqbgwjn2.dzdtj.cn
http://6DovPgVh.dzdtj.cn
http://LoRVVAtc.dzdtj.cn
http://4NFaNP7h.dzdtj.cn
http://www.dtcms.com/a/377511.html

相关文章:

  • 中州养老:设备管理介绍
  • 【Day 51|52 】Linux-tomcat
  • MySQL - 如果没有事务还要锁吗?
  • “高德点评”上线,阿里再战本地生活
  • JUC的常见类、多线程环境使用集合类
  • 《C++ 108好库》之1 chrono时间库和ctime库
  • C++篇(7)string类的模拟实现
  • 弱加密危害与修复方案详解
  • 【Linux】Linux常用指令合集
  • Android- Surface, SurfaceView, TextureView, SurfaceTexture 原理图解
  • 如何设计Agent 架构
  • MySQL主从不一致?DBA急救手册:14种高频坑点+3分钟定位+无损修复!
  • 拍我AI:PixVerse国内版,爱诗科技推出的AI视频生成平台
  • 3D柱状图--自定义柱子颜色与legend一致(Vue3)
  • LeetCode热题100--199. 二叉树的右视图--中等
  • Next系统学习(三)
  • Python深度学习:NumPy数组库
  • Django时区感知
  • PostgreSQL15——Java访问PostgreSQL
  • Shell 函数详解
  • 【系统分析师】第21章-论文:系统分析师论文写作要点(核心总结)
  • Linux 命令(top/ps/netstat/vmstat/grep/sed/awk)及服务管理(systemd)
  • 【图像生成】提示词技巧
  • 揭秘Linux:开源多任务操作系统的强大基因
  • (ICLR-2025)深度压缩自动编码器用于高效高分辨率扩散模型
  • 《Why Language Models Hallucinate》论文解读
  • 【机器学习】通过tensorflow实现猫狗识别的深度学习进阶之路
  • AD5362BSTZ电子元器件 ADI 高精度数字模拟转换器DAC 集成电路IC
  • DMA-M2M存储器与存储器之间读写
  • Mistral Document AI已正式登陆Azure AI Foundry(国际版)