MyBatis xml sql常用结构记录

MyBatis xml sql常用结构记录

sql语句语法

SQL语句中 in 和 exists 的区别

参考链接

select * from a where a.id in (select b.id from b)

select * from a where exists(select 1 from b where b.id=a.id)

sql的效率在 a,b的大小不同时会得到不同的效果。

分析过程
1.使用in关键词时是先将 b表的数据查询出来置于内存,遍历b表的数据,去查询a表。
假设B有100000条记录,A有10条记录,会交互100000次数据库;再假设B有10条记录,A有100000记录,只会发生10次交互。
2.使用exist关键词时,先将a表数据置于内存,
假设A有10000条记录,B有10条记录,数据库交互次数为10000;假设A有10条,B有10000条,数据库交互次数为10。
3.使用in关键词时,不会应用到索引使用exist进行子查询时 ,可以应用到索引

结论当主表小于子表时,使用exists,当子表小于主表时,使用in

case when else

此处含义:当AFTERSALES_ORDER_ID=0时 返回 SKU_ORDER_ID
当 AFTERSALES_ORDER_ID !=0时 返回 AFTERSALES_ORDER_ID
若以上两条都不满足 则返回零

	(CASE WHEN twt.AFTERSALES_ORDER_ID=0 THEN twt.SKU_ORDER_ID 
	WHEN twt.AFTERSALES_ORDER_ID!=0 THEN twt.AFTERSALES_ORDER_ID 
	else 0 
	end) 
	as 订单号

多表连接时需要注意

1.查询是否涉及到主表概念,如果存在应该使用left join进行表连接,且需要注意相连接的两张表的数量对应关系(一对一、一对多、多对多),因为如果不是一对一的关系会导致查询结果比主表多出数据。

Mybatis/MybatisPlus基本语法

分页查询

首先根据自己的mybatis-plus版本选择合适的分页插件 mybatis-plus是物理分页 会根据sql拼接limit字段
查询的结构如下

SELECT COUNT(1) FROM TR_WORK_TICKET 
SELECT * FROM ( SELECT TMP.*, ROWNUM ROW_ID FROM ( select * from TR_WORK_TICKET ) TMP WHERE ROWNUM <=10) WHERE ROW_ID > 0 
Page<TrWorkTicketEntity> page=new Page<>(2,10);
List<TrWorkTicketEntity> list=trWorkTicketMapper.selectMethodPage(page);

大于小于符号处理

因为xml是标签语言,当我们的 > <出现的时候可能会出现报错的情况 所以可选择红字的字符进行代替
需要注意的是,转译字符是不能直接当做sql语句去执行的,我们的sql语句还是需要改成真正的 < >符号

在这里插入图片描述

判断参数某个属性不为空

<if test="param.mainOrderId !=null and param.mainOrderId != ''">
                and tom.MAIN_ORDER_ID=#{param.mainOrderId}
</if>

在进行模糊查询时

此处使用的是 || 符号进行字符串拼接

and twt.TRICKET_CONTENT like '%'|| #{param.tricketContent} ||'%'

choose when 结构

<choose>
                    <when test="param.ticketType == 1">
                        and twt.TICKET_TYPE=1
                    </when>
                    <when test="param.ticketType == 2">
                        and twt.TICKET_TYPE=2
                    </when>
                    <otherwise>
                        and twt.TICKET_TYPE=3
                    </otherwise>
</choose>

include 标签应用

使用include标签时,在执行一个 mapper方法时 会将 <sql> 中的语句拼接到前方的sql语句中进行执行。

select twt.rowid RID
 <include refid="workTicket"></include>


<sql id="workTicket">
        from TR_WORK_TICKET twt
        left join TR_ORDER_MAIN_SKU toms
        on twt.sku_order_id = toms.sku_order_id
        left join TR_ORDER_MAIN tom
        on toms.MAIN_ORDER_ID =tom.MAIN_ORDER_ID
</sql>

开始日期、截止日期

根据前端传入的日期字符串,在后端将日期字符串按照指定格式转化成数据库的date类型进行日期的比较

			<if test="param.startTime !=null and param.startTime !='' ">
                and twt.CREATE_TIME >=to_date(#{param.startTime},'yyyy-mm-dd')
            </if>
            <if test="param.endTime!=null and param.endTime !=''">
                and twt.CREATE_TIME &lt; to_date(#{param.endTime},'yyyy-mm-dd') + 1
            </if>

MyBatis Xml文件if 判断一个值等于另一个值

于某一个值时,选择了 *.toString 进行判断和选择拼接不同的sql语句 **

<if test="param.orderType !=null">
                <if test="param.orderType != null and param.orderType == '1'.toString() ">
                    and not exists  (select * from TR_ORDER_MAIN_SKU oms join GS_GOODS_SKU_MAPPING gsm on oms.SKU_ID=gsm.SKU_ID where oms.MAIN_ORDER_ID=t.MAIN_ORDER_ID )
                </if>
                <if test="param.orderType != null and param.orderType != '1'.toString() ">
                 and t.MAIN_ORDER_ID  in  (select distinct(oms.MAIN_ORDER_ID)  from TR_ORDER_MAIN_SKU oms join GS_GOODS_SKU_MAPPING gsm on oms.SKU_ID=gsm.SKU_ID where gsm.GOODS_TYPE=#{param.orderType})
                </if>
            </if>

oracle 分页查询基础结构

        (select RID
        from (select R.RID, ROWNUM LINENUM
        from (select twt.rowid RID
        <include refid="workTicket"></include>
        ) R
        where ROWNUM <= #{param.pageSize} * #{param.pageNum})
        where LINENUM > #{param.pageSize} * (#{param.pageNum} - 1)) TAB1
public void mainReflect() {
        Object o=new TrWorkTicketEntity();
        boolean hasCreateUser = false;
        Class<?> aClass = o.getClass();
        Field[] fields = aClass.getDeclaredFields();
        for (Field field : fields) {
            if(field.getName().equals("createUser")){
                hasCreateUser=true;
                break;
            }
        }
        if(hasCreateUser){
            try {
                Method setCreateUser = aClass.getMethod("setCreateUser",String.class);
                String userName = "fengyu";
                setCreateUser.invoke(o,userName);
                System.out.println(o);
            } catch (Exception e) {
                log.info("切面出现异常");
            }
        }
    }

Mybatis 调用函数

大写处为对应的函数的名称

select F_WORK_TICKET_REST_TIME(to_char(t.expect_time,'yyyy-mm-dd hh24:mi:ss')) as rest_time from TR_WORK_TICKET t

Mybatis 调用数据库存储过程代码示例

// 传入参数是一个 map类型
Map<String, String> map = new HashMap<>();
        map.put("v_logistics_id", String.valueOf(param.getLogisticsId()));
        map.put("v_content", param.getContent());
        map.put("v_logistics_time", param.getLogisticsTime());
        trOrderMainMapper.sp_order_logistics_record_save(map);
        // 在调用完存储过程之后,可以通过map 参数得到该存储过程的调用返回结果
        if (!"success".equalsIgnoreCase(map.get("v_out_code"))) {
            throw new BusinessException(CommonResponseCode.ORDER_ERROR.getCode(), map.get("v_out_msg"));
        } else {
            trOrderLogisticsMapper.updateLogisticsStatus(param.getLogisticsId());
        }
-- 通过call关键字调用存储过程 并声明相关的参数和返回结果。
<select id="sp_order_logistics_record_save" statementType="CALLABLE" parameterType="java.util.Map">
        {
            call sp_order_logistics_record_save(
                #{map.v_logistics_id, mode=IN,jdbcType=BIGINT },
                #{map.v_content, mode=IN,jdbcType=VARCHAR },
                #{map.v_logistics_time, mode=IN,jdbcType=VARCHAR },
                #{map.v_out_code,mode=OUT,jdbcType=VARCHAR },
                #{map.v_out_msg,mode=OUT,jdbcType=VARCHAR }
            )
            }
    </select>

dual表

因为在 Oracle 中,SELECT 语句必须要有 FROM 子句,所以在某些只需要计算表达式或调用内置函数的情况下,我们需要借助 DUAL 表来保证语法的正确性。

oracle 编写函数简单示例

--  工单根据期望日期计算剩余时间
create or replace function F_WORK_TICKET_REST_TIME(expext_time_str varchar2)

  return varchar2 is
  expext_time    Date;
  restTime       varchar2(32);
  restTimeNumber number;
  restDay        number;
  restHour       number;
  restMinute     number;
  
  
begin
  -- 计算得出两日期相差的秒数
  -- 1min = 60 s
  -- 1hour = 60*60 s
  -- 1day = 24*60*60 s
  expext_time := To_date(expext_time_str, 'yyyy-mm-dd hh24-mi-ss');
  select ceil((expext_time - sysdate) * 24 * 60 * 60)
    into restTimeNumber
    from dual;
  restDay := ABS(ceil(restTimeNumber / (24 * 60 * 60)));
  
  restTimeNumber := MOD(restTimeNumber, 24 * 60 * 60);
  restHour       := ABS(ceil(restTimeNumber / (60 * 60)));
  
  restTimeNumber := MOD(restTimeNumber, 60 * 60);
  restMinute     := ABS(ceil(restTimeNumber / 60));
  
  if expext_time > sysdate then
    restTime := '剩余' || restDay || '天' || restHour || '小时' || restMinute || '分';
  elsif expext_time < sysdate then
    restTime := '超时' || restDay || '天' || restHour || '小时' || restMinute || '分';
  end if;

  

  return restTime;
  
end F_WORK_TICKET_REST_TIME;

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值