05_MyBatis动态SQL学习笔记

05_MyBatis动态SQL学习笔记

参考学习网站

动态sql目的是为了解决查询条件不确定而存在的,条件判断使用的表达式为OGNL 表达式,常用的动态SQL有:<if> <where> <choose> <foreach>

注意

在 mapper 的动态 SQL 中若出现大于号(>)、小于号(<)、大于等于号(>=),小于等于号(<=)等符号,最好将其转换为实体符号。否则,XML 可能会出现解析出错问题。

特别是对于小于号(<),在 XML 中是绝对不能出现的。否则,一定出错。

05_MyBatis动态SQL学习笔记

<if> 标签

为了解决两个条件均未做设定的情况,在 where 后添加了一个“1=1”的条件。这样就不至于两个条件均未设定而出现只剩下一个 where,而没有任何可拼接的条件的不完整 SQL 语句。

<?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.lusifer.mybatis.dao.DynamicStudentDao">
    <!-- if -->
    <select id="selectByIf" resultType="com.lusifer.mybatis.entity.Student">
        SELECT
            id,
            name,
            age,
            score
        FROM
            student
        WHERE 1 = 1
        <if test="name != null and name != ''">
            AND name LIKE concat('%', #{name}, '%')
        </if>
        <if test="age != null and age > 0">
            AND age > #{age}
        </if>
    </select>
</mapper>

<where> 标签

<if/> 标签的中存在一个比较麻烦的地方:需要在 where 后手工添加1=1 的子句。因为,若 where 后的所有 <if/> 条件均为 false,而 where 后若又没有 1=1 子句,则 SQL 中就会只剩下一个空的 whereSQL 出错。所以,在 where 后,需要添加永为真子句 1=1,以防止这种情况的发生。但当数据量很大时,会严重影响查询效率。

where标签是为了解决前and问题.

<!-- where-->
<select id="selectByWhere" resultType="com.lusifer.mybatis.entity.Student">
    SELECT
        id,
        name,
        age,
        score
    FROM
      student
    <where>
        <if test="name != null and name != ''">
            AND name LIKE concat('%', #{name}, '%')
        </if>
        <if test="age != null and age > 0">
            AND age > #{age}
        </if>
    </where>
</select>


<choose> 标签

该标签中只可以包含 ,可以包含多个 与一个 。它们联合使用,完成 Java 中的开关语句 switch…case 功能。

本例要完成的需求是,若姓名不空,则按照姓名查询;若姓名为空,则按照年龄查询;若没有查询条件,则没有查询结果。

<!-- choose -->
<select id="selectByChoose" resultType="com.lusifer.mybatis.entity.Student">
    SELECT
        id,
        name,
        age,
        score
    FROM
      student
    <where>
        <choose>
            <when test="name != null and name != ''">
                AND name LIKE concat('%', #{name}, '%')
            </when>
            <when test="age != null and age > 0">
                AND age > #{age}
            </when>
            <otherwise>
                AND 1 != 1
            </otherwise>
        </choose>
    </where>
</select>

<foreach> 标签

  • <foreach/> 标签用于实现对于数组与集合的遍历。对其使用,需要注意:
  • collection 表示要遍历的集合类型,这里是数组,即 array。
  • opencloseseparator 为对遍历内容的 SQL 拼接。
package shop.tbzj.mapper;
import shop.tbzj.entity.Order;
import java.util.List;

public interface OrderMapper {

    public void insertOrder(Order order);

    public List<Order> findOrderByIds(List<Long> ids);

    public List<Order> findOrderByArrayIds(Long[] ids);

}

<?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="shop.tbzj.mapper.OrderMapper">
    <insert id="insertOrder" useGeneratedKeys="true" keyProperty="id">
          insert into tb_order(name,price)values(#{name},#{price});
    </insert>


    <select id="findOrderByIds" resultType="shop.tbzj.entity.Order">
        select * from tb_order
            <if test="list !=null and list.size !=0">
                WHERE id IN
                <foreach collection="list" open="(" close=")" item="id" separator=",">
                    #{id}
                </foreach>
            </if>
    </select>

    <select id="findOrderByArrayIds" parameterType="long"  resultType="shop.tbzj.entity.Order">
        select * from tb_order
        <if test="array !=null and array.length !=0">
            WHERE id IN
            <foreach collection="array" open="(" close=")" item="id" separator=",">
                #{id}
            </foreach>
        </if>
    </select>


</mapper>

注意传递的参数如果是List<Long>ids 那么collection就需要些list

如果传递的参数为Long[] ids 那么collection就需要些array

package shop.tbzj.test;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import shop.tbzj.entity.Order;
import shop.tbzj.mapper.OrderMapper;

import java.util.ArrayList;
import java.util.List;


@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:spring-context.xml")
public class TestOrder {

    @Autowired
    private OrderMapper orderMapper;

    @Test
    public void insertOrder() {
        Order order = new Order();
        order.setName("tom2");
        order.setPrice(22.3);

        orderMapper.insertOrder(order);

        System.out.println(order.toString());
    }

    @Test
    public void findOrderByIds() {
        List<Long> ids = new ArrayList<Long>();
        ids.add(4L);
        ids.add(5L);
        List<Order> orders = orderMapper.findOrderByIds(ids);
        for (Order order : orders) {
            System.out.println(order);
        }

    }

    @Test
    public void findOrderByIds2() {
        Long[] ids = {4L, 5L};
        List<Order> orders = orderMapper.findOrderByArrayIds(ids);
        for (Order order : orders) {
            System.out.println(order);
        }

    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/100790.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • java开发webservice接口_webservice接口的开发和调用

    java开发webservice接口_webservice接口的开发和调用一、WebService的开发手段使用Java开发WebService时可以使用以下两种开发手段1、使用JDK开发(1.6及以上版本)2、使用CXF框架开发(工作中)二、使用JDK开发WebService2.1、开发WebService服务器端1、定义一个interface,使用@WebService注解标注接口,使用@WebMethod注解标注接口中定义的所有方法,如下所示:1package…

    2022年7月16日
    20
  • sqlyog安装步骤_sqlyog安装教程

    sqlyog安装步骤_sqlyog安装教程百度网盘账号(QQ账号):374879539QQ密码:fjl12345进去下载SQLyog的安装包就可以了用完之后及得给我的博客点个赞和关注哦!

    2022年9月24日
    5
  • 深入理解Batchnorm

    深入理解Batchnorm这几天面试经常被问到BN层的原理,虽然回答上来了,但还是感觉答得不是很好,今天仔细研究了一下BatchNormalization的原理,以下为参考网上几篇文章总结得出。  BatchNormalization作为最近一年来DL的重要成果,已经广泛被证明其有效性和重要性。虽然有些细节处理还解释不清其理论原因,但是实践证明好用才是真的好,别忘了DL从Hinton对深层网络做Pre-Train开…

    2022年6月9日
    29
  • c++算法之最长递增子序列(LIS)

    c++算法之最长递增子序列(LIS)题目:输入一个整数n,随后输入n个整数,求这个长度为n的序列中严格递增的子序列的最长长度。例:输入:6143265输出:3解题思路:动态规划。将输入的序列存入一个数组v中,另外再定义一个数组a,用以存储以当前数字v[i]结尾时,最长递增子序列的长度是多少。定义数组时,全部初始化为1,初始状态表示的是最坏的情况,以v[i]结尾的最长递增子序列就是v[i]它本身,长度为1。接着将v[i]逐一…

    2022年6月3日
    30
  • SSR服务器端渲染(Next.js总结和豆瓣电影项目)「建议收藏」

    SSR服务器端渲染(Next.js总结和豆瓣电影项目)「建议收藏」一.前言先解释一下Nuxt.js和Next.js虽然只有一个字母之差,但它们是不同的两个服务端渲染框架.什么是Next.js?引用Next中文官网的一句话:Next.js是一个轻量级的React服务端渲染应用框架。Next.js带来了很多好的特性:默认服务端渲染模式,以文件系统为基础的客户端路由(注意:没有专门路由)代码自动分割使页面加载更快以webpack的热替换(HMR…

    2025年6月12日
    3
  • 常用的免费好用的DNS有哪些?

    常用的免费好用的DNS有哪些?阿酷TONY原创文章关键词:免费dns、百度dns、阿里dns、114dns、GoogleDNS2019-1-24DNS(DomainNameServer,域名服务器)是进行域名(domainname)和与之相对应的IP地址(IPaddress)转换的服务器。DNS中保存了一张域名(domainname)和与之相对应的IP地址(IPaddress)的表,以解析…

    2022年6月7日
    31

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号