zoukankan      html  css  js  c++  java
  • iBatis第四章:动态SQL的用法

    一、什么是动态SQL,以及使用动态SQL的好处
    所谓动态SQL,是针对静态SQL而言的,静态SQL的SQL语句是固定的,使用动态SQL是为了增强SQL的灵活性和复用性,可以用一个动态SQL达到在不同条件下执行不同的SQL语句的效果,如果不用动态SQL,我们可能需要使用几个不同的SQL语句才能达到目的,但是使用动态SQL,只需要一个SQL就可以实现。
    例如下面是一个动态SQL的例子:
    select * from t_user
    <dynamic prepend="where">
    <isNull property="id">
    id is null
    </isNull>
    <isNotNull>
    id = #id#
    </isNotNull>
    </dynamic>
    上面的SQL语句会根据调用这个SQL语句的入参来组装成不同的SQL语句,当id为null时,其语句如下:
    select * from t_user where id is null
    当id不为null时,其SQL语句如下:
    select * from t_user where id = #id#
    由此可见,我们通过一个动态SQL就达到了两个静态SQL的目的,分别处理了两种不同的情况,这就是动态SQL的好处。

    注意:在数据库中,查询值为null的情况不能用=来处理,例如select * from t_user where id is null和select * from t_user where id = ''是不同的!

    二、如何使用动态SQL
    iBatis 为我们处理动态SQL提供了一组相应的标签,我们只需要使用者一套动态标签就可以享受动态SQL带给我们的便利之处了。下面分别讨论 iBatis 的动态标签,它分为5大类:
    1、<dynamic>标签
    2、二元标签
    3、一元标签
    4、参数标签
    5、<iterate>标签
    在讨论这些动态标签之前,我们先说明一下,有一些标签的属性是共享的,例如 prepend、open、close等这几个属性。其中prepend表示添加前缀、open和close分别表示开始和结尾,后面例子详细说明。

    -----------------1、<dynamic>标签
    <dynamic>是动态标签的最顶层标签,也就是说它不能嵌套,它用来划分一个动态SQL片段。
    其属性如下:
    prepend:前缀
    open:以XX开始
    close:以XX结束

    示例:
    <select id="select_stulist" parameterClass="com.test.bean.Student" resultClass="com.test.bean.Student">
    select id,name,sex from t_stu
    <dynamic prepend="where">
    <isNotNull property="sex">
    sex = #sex#
    </isNotNull>
    </dynamic>
    </select>

    /**
    * 测试动态标签 <dynamic>
    */
    private void testDynamic(){
    SqlMapClient sqlMapClient = BaseDAO.getInstance();
    Student student = new Student();
    try {
    student.setSex("女");
    List<Student> stuList = sqlMapClient.queryForList("select_stulist", student);
    if(stuList != null && stuList.size()>0){
    for(Student stu:stuList){
    System.out.println(stu.getName()+" "+stu.getSex());
    }
    }
    } catch (SQLException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    }

    动态标签的好处就是可以根据我们的参数不同实现不同的 sql查询功能。

    -----------------2、二元标签
    二元标签的作用就是将我们的参数同另外一个值或者参数进行比较,如果结果为true,则包含二元标签内的内容,否则就不包含。
    常用的二元标签如下:
    <isEqual> 用于比较值是否相同
    <isNotEqual> 用于比较值是否不同
    <isGreaterThan> 比较值是否大于
    <isGreaterEqual> 比较值是否大于等于
    <isLessThan> 比较值是否小于
    <isLessEqual> 比较值是否小于等于

    二元标签的常用属性:
    property:指定需要比较的属性
    compareProperty:指定需要与property比较的属性
    compareValue:指定一个静态值,用于同property的属性值比较【注意compareProperty和compareValue必须指定其中一个】

    prepend:前缀作用
    open:以XX开始
    close:以XX结束

    示例:
    <typeAlias alias="student" type="com.test.bean.Student"></typeAlias>
    <!-- 测试 二元 标签 :如果入参性别为男 则查询编号大于给定值的学生信息-->
    <select id="select_stulist1" parameterClass="student" resultClass="student">
    select id,name,sex from t_stu
    <dynamic prepend="where">
    <isEqual property="sex" compareValue="男">
    id > #id#
    </isEqual>
    </dynamic>
    </select>


    private void testBinaryTag(){
    SqlMapClient sqlMapClient = BaseDAO.getInstance();
    Student student = new Student();
    try {
    student.setId(2);
    student.setSex("男");

    List<Student> stuList = sqlMapClient.queryForList("select_stulist1", student);
    if(stuList != null && stuList.size()>0){
    for(Student stu:stuList){
    System.out.println(stu.getId()+"______"+stu.getName()+" "+stu.getSex());
    }
    }
    } catch (SQLException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    }
    二元标签可以用我们的入参与给定值进行比较。满足根据是否满足一定条件来生成不同的SQL。

    -----------------3、一元标签
    一元标签用于参考入参的某个属性是否满足一定条件,如果满足,则包含标签内的内容,否则忽略标签体得内容。
    常用一元标签:
    <isNull> 确定所指定的字段是否为null
    <isNotNull> 确定所指定的字段是否不为null
    <isEmpty> 确定所指定的字段是否为null、或者" "、以及是否为空的集合
    <isNotEmpty> 确定所指定的字段是否不为null、或者不为" "、以及是否不为空的集合
    <isPropertyAvailable> 是否存在所指定的字段,对于Bean它寻找属性,对于集合它寻找键值
    <isNotPropertyAvailable> 与上面相反

    一元标签常用属性:
    property:指定需要比较的属性
    prepend:前缀作用
    open:以XX开始
    close:以XX结束

    示例:
    <typeAlias alias="student" type="com.test.bean.Student"></typeAlias>

    <!-- 测试 一元 标签 -->
    <select id="select_stulist2" parameterClass="student" resultClass="student">
    select id,name,sex from t_stu
    <dynamic prepend="where">
    <isNotNull property="sex">
    sex = #sex#
    </isNotNull>
    </dynamic>
    </select>

    private void testUnaryTag(){
    SqlMapClient sqlMapClient = BaseDAO.getInstance();
    Student student = new Student();
    try {

    //如果性别不为null,则查询指定性别的数据
    student.setSex("女");

    List<Student> stuList = sqlMapClient.queryForList("select_stulist2", student);
    if(stuList != null && stuList.size()>0){
    for(Student stu:stuList){
    System.out.println(stu.getId()+"______"+stu.getName()+" "+stu.getSex());
    }
    }
    } catch (SQLException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    }

    -----------------4、参数标签
    参数标签用于检查某个参数是否传递进来了,主要有下面两个标签:
    <isParameterPresent>和<isNotParameterPresent> ,这个不常用,了解即可。以后用到在做详细学习。

    -----------------5、<iterate>标签
    <iterate>允许一个集合或者数组作为一个属性传递到映射语句,我们通过遍历这个集合或者数组,得到一个具体的SQL。它仅有<iterate>这个个标签,主要有如下几个属性:
    property:指定需要比较的属性
    prepend:前缀作用
    open:以XX开始
    close:以XX结束
    <conjunction>: 用于连接集合或者数组产生的SQL的字符或者符号。

    示例:
    <typeAlias alias="student" type="com.test.bean.Student"></typeAlias>
    <!-- 测试 iterate标签 -->
    <select id="select_stulist3" parameterClass="student" resultClass="student">
    select id,name,sex from t_stu
    <dynamic prepend="where name in">
    <iterate property="names" open="(" close=")" conjunction=",">
    #names[]#
    </iterate>
    </dynamic>
    </select>

    private void testIterateTag(){
    SqlMapClient sqlMapClient = BaseDAO.getInstance();
    Student student = new Student();
    try {

    List<String> names = new ArrayList<String>();
    names.add("修改后的姓名");
    names.add("新增学生测试");

    student.setNames(names);

    List<Student> stuList = sqlMapClient.queryForList("select_stulist3", student);
    if(stuList != null && stuList.size()>0){
    for(Student stu:stuList){
    System.out.println(stu.getId()+"______"+stu.getName()+" "+stu.getSex());
    }
    }
    } catch (SQLException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    }

  • 相关阅读:
    win7-64系统下安装nodejs
    Vue项目使用npm run dev出现npm ERR! missing script: dev
    本地环境时覆盖Apollo配置
    金蝶K3序时簿页面增加物料即时库存显示功能
    LeetCode——开篇
    url 与 params 参数的常见操作归纳汇总(含精心准备的注释)
    如何让 arcgis require 里定义的方法可以在全局访问?
    字体图标库 iconfont、iconmoon 的维护管理与使用探索
    【转载】ES5-ES12 常用语法特性
    一次 outline 去除经验(非继承属性,看着像继承)
  • 原文地址:https://www.cnblogs.com/funnyboy0128/p/7647367.html
Copyright © 2011-2022 走看看