zoukankan      html  css  js  c++  java
  • mybatis_动态SQL

     动态SQL

    在实际的开发过程中,再查询的过程中有时可能会有多个条件,有时查询的条件个数可能时一个,用户再添加查询信息时,查询条件的个数是不一定的,所以可以利用动态SQL来解决该问题,动态SQL会根据传入的条件动态拼接SQL语句

    if 标签

    用该标签来判断用户是否输入某个条件,或用户输入是否符合查询条件

    1:再StudentMapper.xml文件中编写以下内容

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper
            PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.doaoao.dao.StudentDao">
    
        <select id="selectIf" resultType="student">
            SELECT id,name,age,score
            FROM t_student
            WHERE 1 = 1
            <if test="name != null and name != ''">
                AND name like '%' #{name} '%'
            </if>
            <if test="age > 0">
                AND age > #{age}
            </if>
        </select>
    </mapper>

    # 注:上方添加 where 1 = 1 的目的是,当用户未输入name和age两个条件是,不至于让where的条件为空,为空的话SQL语句就不正确

    2:在StudentDao中添加接口(接口名称与select中的属性id名称相同)

    package com.doaoao.dao;
    
    import com.doaoao.bean.Student;
    
    import java.util.List;
    
    public interface StudentDao {
        List<Student> selectIf(Student student);
    }

    3:在测试类中进行测试

    package com.doaoao.test;
    
    import com.doaoao.bean.Student;
    import com.doaoao.dao.StudentDao;
    import com.doaoao.util.MyBatisUtil;
    import org.apache.ibatis.session.SqlSession;
    import org.junit.After;
    import org.junit.Before;
    import org.junit.Test;
    
    import java.util.List;
    
    public class StudentTest01 {
        private StudentDao studentDao;
        private SqlSession sqlSession;
        // 执行测试方法之前会执行该方法
        @Before
        public void init(){
            sqlSession = MyBatisUtil.getSqlSession();
            studentDao = sqlSession.getMapper(StudentDao.class);
        }
    
        // 方法执行完成后需要关闭sqlSession
        @After
        public void closeSession(){
            if(sqlSession != null){
                sqlSession.close();
            }
        }
    
        @Test
        public void selectIf(){
            Student student = new Student("liu",0,0);
            List<Student> students = studentDao.selectIf(student);
            System.out.println(students);
        }
    }

    where 标签

    where标签的作用与上方 " where 1 = 1 " 具有相同的作用

    1:编写StudentMapper.xml中的内容

        <select id="selectWhere" resultType="student">
            SELECT id,name,age,score
            FROM t_student
            <where>
                <if test="name != null and name != ''">
                    AND name like '%' #{name} '%'
                </if>
                <if test="age > 0">
                    AND age > #{age}
                </if>
            </where>
    
        </select>

    2:添加接口

        List<Student> selectWhere(Student student);

    3:添加测试类

        @Test
        public void selectWhere(){
            Student student = new Student("liu",0,0);
            List<Student> students = studentDao.selectIf(student);
            System.out.println(students);
        }

    choose 标签

    该标签的作用就是,若 name 不为空,就利用name进行查询,若name为空,则利用 age 进行查询;若age也为空可利用默认的进行查询

    1:编写StudentMapper.xml中的内容

        <select id="selectChoose" resultType="student">
            SELECT id,name,age,score
            FROM t_student
            <where>
                <choose>
                    <when test="name != null and name != ''">
                        name like '%' #{name} '%'
                    </when>
                    <when test="age >= 0">
                        age > #{sge}
                    </when>
                </choose>
            </where>
        </select>

     2:添加接口

        List<Student> selectChoose(Student student);

    3:编写测试类

        @Test
        public void selectChoose(){
            Student student = new Student("liu",0,0);
            List<Student> students = studentDao.selectIf(student);
            System.out.println(students);
        }

     foreach标签

    当用户想要查询 1,3,5,7,9这几条数据时,在sql语句中我们可以用以下方式实现

    select id,name,age from t_student where id in(1,3,5,7,9)

    在mybatis中我们可以使用foreact来实现

    1:修改StudentMapper.xml中的内容

       <!-- 遍历数组 --> 
      <select id="selectForeachArray" resultType="student">
            SELECT id,name,age,score
            FROM t_student
            <if test="array != null and array.length > 0">
                WHERE id in 
                <foreach collection="array" open="(" close=")" item="id" separator=",">
                    #{id}
                </foreach>
            </if>
        </select>
    <!-- 遍历集合 --
    >   <select id="selectForeachList" resultType="student"> SELECT id,name,age,score FROM t_student <if test="list != null and list.length > 0"> WHERE id in <foreach collection="list" open="(" close=")" item="id" separator=","> #{id} </foreach> </if> </select

    2:添加接口

    // 遍历数组接口
    List<Student> selectForeachArray(Object[] ids);
    
    // 遍历集合接口
    List<Student> selectForeachList(Object[] ids);

    3:编写测试类

    // 数组测试类
    @Test
    public void selectForeachArray(){
        Object[] ids = new Object[]{1,3,5,7,9};
    
        List<Student> students = studentDao.selectForeachArray(ids);
         System.out.print(students)
    }
    
    // 集合测试类 @Test public void selectForeachList(){ List<Integer> list = new ArrayList<>(); list.add(5); list.add(6); list.add(10); list.add(15); List<Student> students = studentDao.selectForeachList(list); System.out.print(students) }

    sql 标签 

    该标签用来定义一个可被复用的sql片段

    1:在mapper中配置并使用该标签

        <!-- 定义该标签 -->
      <sql id="selectSql"> SELECT id,name,age,score FROM t_student </sql>
       <select id="selectForeach" resultType="student">
        <!-- 使用该标签 -->
        <include refid="selectSql">   <if test="array != null and array.length > 0">   WHERE id in   <foreach collection="array" open="(" close=")" item="id" separator=",">   #{id}   </foreach>   </if> </select>

    ...

    动态SQL使用注意事项

    例如:

    <!-- 不报错 -->
    <when test="age >= 0">
           age > #{sge}
    </when>
    
    <!-- 报错 -->
    <when test="age >= 0">
           age < #{sge}      “<”   会被误认为是尖括号的开头,所有报错
    </when>

    解决的第一种方式:实体符号代替的使用

    原符号      实体符号
      <         &lt;
      <=        &lt;=
      >         &gt;
      >=        &gt;=
      &         &amp;
      "         &quot;
      '         &apos;

    解决的第二种方式: CDATA

    可以将特殊的符号放在 < ! [ CDATA[ ] ]>中

        <if test="age>=0">
            AND age <![CDATA[ <  ]]> #{age}
        </if>

     ...

     本笔记参考自:小猴子老师教程 http://www.monkey1024.com

  • 相关阅读:
    行高 | line-height (Animations & Transitions)
    色域 | @media.color-gamut (Media Queries)
    自动换行 | word-wrap (Text)
    漫谈死锁
    《金融时间序列分析》第3版-蔡瑞胸
    《广告点击延时反馈建模》
    《Google软件测试之道》
    《持续集成:软件质量改进和风险降低之道》
    《DevOps实践:驭DevOps之力强化技术栈并优化IT运行》
    《架构真经:互联网技术架构的设计原则》
  • 原文地址:https://www.cnblogs.com/Doaoao/p/10705268.html
Copyright © 2011-2022 走看看