Mybatis使用实战

本文介绍了MyBatis框架中的高级用法,包括基础标签使用、内部类映射、批量更新与case when结合使用等技巧,并提供了MySQL解析JSON字符串自定义函数及数据分组的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、基础标签使用

       在XML中,需要转义的字符有: 
  (1) &   &
  (2) <    &lt; 
  (3)            &gt; 
  (4)   &quot; 
  (5)   &apos; 

(1)if 标签

<if test="stuName !=null and stuName != ''">
    and stu_name like '%' ||#{stuName}||'%'
</if>
<if test="stuBirthdate != null">
    //<![CDATA[...]]>这个标记所包含的内容将表示为纯文本,内部的所有内容都会被解析器忽略
    <![CDATA[and stu_birthdate>#{stuBirthdate}]]>
</if>

2、choose标签

choose元素相当于java语句的if … else if …else语句

<choose>
    <when test="type==1">
        and stu_name=#{stuName}
    </when>
    <when test="type==2">
        and stu_birthdate=#{stuBirthdate}
    </when>
    <otherwise>
        and stu_phone=#{stuPhone}
    </otherwise>
</choose>

3、where标签

使用where元素会自动根据条件的个数增删where语句and运算符

<where>
    <if test="stuName != null and stuName != ''">
        and stu_name=#{stuName}
    </if>
    <if test="stuBirthdate != null">
        and stu_birthdate=#{stuBirthdate}
    </if>
</where>

4、trim 标签

 

二、mybatis内部类映射写法

(1)java实体类创建

/**
 * 具体消息返回封装
 * @author YJX
 *
 */
public class MessageCenterVo extends MessageCenter implements Serializable{
	private static final long serialVersionUID = 1L;
	private String activeTime;
	
	public String getActiveTime() {
		return activeTime;
	}
	public void setActiveTime(String activeTime) {
		this.activeTime = activeTime;
	}

	//阅读名单
	static class ReadingList{
		private String city; //城市
		
		public String getCity() {
			return city;
		}
		public void setCity(String city) {
			this.city = city;
		}
		/*public ReadingList() {
			super();
			// TODO Auto-generated constructor stub
		}*/
		
	}
}

外部类调用内部类:

MessageCenterVo.ReadingList list = new MessageCenterVo.ReadingList()

(2)内部类映射写法

<resultMap type="com.grainRain.response.MessageCenterVo" id="messageVo">
	<result property="cityName" column="cityName" />
	<collection property="resdingList" ofType="com.grainRain.response.MessageCenterVo$ReadingList">
		<result property="city" column="city"></result>
	</collection>
</resultMap>

三、新增返回主键

(1)当表没有设置主键

<insert id="insertAndGetId" useGeneratedKeys="true" keyProperty="userId" parameterType="com.chenzhou.mybatis.User">
    insert into user(userName,password,comment)
    values(#{userName},#{password},#{comment})
</insert>

useGeneratedKeys="true" 表示给主键设置自增长
keyProperty="userId"  表示将自增长后的Id赋值给实体类中的userId字段。

(2)表设置有主键

 <!-- 插入一个商品 -->
    <insert id="insertProduct" parameterType="domain.model.ProductBean" >
       <selectKey resultType="java.lang.Long" order="AFTER" keyProperty="productId">
          SELECT LAST_INSERT_ID()
      </selectKey>
        INSERT INTO t_product(productName,productDesrcible,merchantId)values(#{productName},#{productDesrcible},#{merchantId});
    </insert>

四、trim标签与foreach标签组合使用

<if test="exceptions!=null">
	<trim prefix="AND(" suffix=")" prefixOverrides="OR">
		<foreach collection="exceptions" item="exception" index="index" >
			<if test="exception==1"><!-- 到店超时 -->
				OR dd.arriveOvertime=1  
			</if>
			<if test="exception==2"><!-- 取货超时 -->
				OR dd.getOvertime=1 
			</if>
			<if test="exception==3"> <!-- 送达超时 -->
				OR dd.deliveryOvertime=1 
			</if>
			<if test="exception==4"> <!-- 送达位置异常 -->
				OR dd.errorDriverGetReceiveLocation=1
			</if>
			<if test="exception==5"> <!-- 连击 -->
				OR (UNIX_TIMESTAMP(dd.driverDeliveryTime)-UNIX_TIMESTAMP(dd.driverGetTime))&lt;60
			</if>
			<if test="exception==6"> <!-- 严重超时 -->
				OR dd.seriousOvertime=1
			</if>
		</foreach>
	</trim>
</if>

prefix:在trim标签内sql语句加上前缀。
suffix:在trim标签内sql语句加上后缀。
suffixOverrides:指定去除多余的后缀内容,如:suffixOverrides=",",去除trim标签内sql语句多余的后缀","。
prefixOverrides:指定去除多余的前缀内容

五、批量更新与case when结合使用

    <update id="agreeRefund">
		UPDATE t_delivery_item 
		SET
			state = CASE itemId
			<foreach collection="items" item="deliveryItem">
				WHEN #{deliveryItem.itemId} THEN IF((#{deliveryItem.itemAuantity} - RefundingNum)=0,0,1)
			</foreach>
			END,
			RefundingNum = CASE itemId
			<foreach collection="items" item="deliveryItem">
				WHEN #{deliveryItem.itemId} THEN RefundingNum - #{deliveryItem.itemAuantity}
			</foreach>
			END,
			RefundedNum = CASE itemId
			<foreach collection="items" item="deliveryItem">
				WHEN #{deliveryItem.itemId} THEN RefundedNum + #{deliveryItem.itemAuantity}
			</foreach>
			END
		WHERE
			orderCode=#{orderCode} AND itemId IN
		<foreach collection="items" item="deliveryItem" separator="," open="(" close=")">
           #{deliveryItem.itemId}
        </foreach>
    </update>
<update id="lockStock" parameterType="com.macro.mall.request.CartPromotionItem">
  		UPDATE pms_sku_stock
  		SET
  			lock_stock = CASE id 
  			<foreach collection="cartPromotionItemList" item="promotionItem">
				WHEN #{promotionItem.productSkuId} THEN lock_stock + #{promotionItem.quantity} + #{promotionItem.restrictQuantity}
			</foreach>
			END,
			version = CASE id 
  			<foreach collection="cartPromotionItemList" item="promotionItem">
				WHEN #{promotionItem.productSkuId} THEN version=version+1
			</foreach>
  			END
  		WHERE
  			version = CASE id 
  			<foreach collection="cartPromotionItemList" item="promotionItem">
				WHEN #{promotionItem.productSkuId} THEN version=version+1
			</foreach>
  			END
			AND id IN
			<foreach collection="cartPromotionItemList" item="promotionItem" separator="," open="(" close=")">
	           #{promotionItem.productSkuId}
	        </foreach>
  </update>

六、MySql解析JSON字符串自定义函数

DELIMITER $$  
 DROP FUNCTION IF EXISTS fn_parseJson$$  

 CREATE FUNCTION fn_parseJson(p_jsonstr VARCHAR(255) character set utf8, p_key VARCHAR(255)) RETURNS VARCHAR(255)
 BEGIN  
DECLARE rtnVal VARCHAR(255) DEFAULT '';  
   DECLARE v_key VARCHAR(255);

   SET v_key = CONCAT('"', p_key, '":');
   SET @v_flag = p_jsonstr REGEXP v_key;

IF(@v_flag = 0) THEN 
SET rtnVal = '';
ELSE
SELECT val INTO rtnVal FROM (
SELECT @start_pos := locate(v_key, p_jsonstr), 
@end_pos := @start_pos + length(v_key), 
@tail_pos := if(locate(",", p_jsonstr, @end_pos) = 0, locate("}", p_jsonstr, @end_pos), locate(",", p_jsonstr, @end_pos)), 
substring(p_jsonstr, @end_pos + 1, @tail_pos - @end_pos - 2) as val) as t;   
   END IF;

   RETURN rtnVal;  

 END $$  

DELIMITER;

七、以半分钟进行分组

SELECT sum(revNum),dataStartTime FROM 
(
SELECT DATE_FORMAT( concat(date(dataStartTime),' ',HOUR(dataStartTime),':',floor( MINUTE(dataStartTime)/30 )*30) ,'%Y-%m-%d %H:%i')  AS dataStartTime 
FROM devicedata 
) a
GROUP BY DATE_FORMAT( dataStartTime ,'%Y-%m-%d %H:%i')

八、以年、月、日、时、分、秒进行分组

%M 月名字(January……December) 
%W 星期名字(Sunday……Saturday) 
%D 有英语前缀的月份的日期(1st, 2nd, 3rd, 等等。) 
%Y 年, 数字, 4 位 
%y 年, 数字, 2 位 
%a 缩写的星期名字(Sun……Sat) 
%d 月份中的天数, 数字(00……31) 
%e 月份中的天数, 数字(0……31) 
%m 月, 数字(01……12) 
%c 月, 数字(1……12) 
%b 缩写的月份名字(Jan……Dec) 
%j 一年中的天数(001……366) 
%H 小时(00……23) 
%k 小时(0……23) 
%h 小时(01……12) 
%I 小时(01……12) 
%l 小时(1……12) 
%i 分钟, 数字(00……59) 
%r 时间,12 小时(hh:mm:ss [AP]M) 
%T 时间,24 小时(hh:mm:ss) 
%S 秒(00……59) 
%s 秒(00……59) 
%p AM或PM 
%w 一个星期中的天数(0=Sunday ……6=Saturday ) 
%U 星期(0……52), 这里星期天是星期的第一天 
%u 星期(0……52), 这里星期一是星期的第一天 
%% 一个文字“%”。

1、以年分组
SELECT year(END_TIME) time from zfzb_equip GROUP BY year(END_TIME)

SELECT DATE_FORMAT(END_TIME,'%Y') time from zfzb_equip GROUP BY DATE_FORMAT(END_TIME,'%Y')

2、以月分组
SELECT month(END_TIME) time from zfzb_equip GROUP BY month(END_TIME)

SELECT DATE_FORMAT(END_TIME,'%Y-%m') time from zfzb_equip GROUP BY DATE_FORMAT(END_TIME,'%Y-%m')

3、以日分组
SELECT date(END_TIME) from zfzb_equip GROUP BY date(END_TIME)

SELECT DATE_FORMAT(END_TIME,'%Y%m%Y%m%d') time from zfzb_equip GROUP BY DATE_FORMAT(END_TIME,'%Y%m%d')

九、获取某一年的月份列表

<sql id="getOneYearMonth">
        SELECT
	    CASE
        WHEN length(mon) = 1 THEN
            concat(
                @y,
                '-0',
                mon
            )
        else concat(@y,'-',mon)
        END month
        FROM
            (
                SELECT
                    @m :=@m + 1 mon
                FROM
                    system_menu,
                    (SELECT @m := 0,@y:=#{year}) a
        LIMIT 12) aa
    </sql>

十、列数据累加

SELECT
	g.grantno,
	g.servicefee / g.commission,
	g.commission,
	g.confirmtime,
	(
		@sumSalary := @sumSalary + g.commission
	) AS count
FROM
	grant_commission g,
	(SELECT @sumSalary := 0) b
WHERE
	g.enterpriseid = 57
AND g.state IN (5, 6)
AND g.confirmtime >= '2020-04-01 00:00:00'
ORDER BY
	g.confirmtime

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

写代码也写生活

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值