關於Mybatis中SQL語句的整理

隨着業務的發展,愈來愈多的應用系統都從一個大的系統分拆成多個小的系統,各個系統之間經過必定的通訊協議進行數據交換。這樣就會致使一些小的應用系統本身不用去進行數據庫的操做,只須要進行一些rpc調用或者緩存就能夠拿到數據進行展現。我以前參與的一個項目就是這樣的狀況,而我也是將近7個多月的時間沒有寫過一行SQL。html

近期參與的一個項目的數據大多都市基於數據庫來進行數據交互的,因此免不了的要寫大量的SQL,因此本篇就總結一下一些SQL的基本寫法,以備後用。java

建表

CREATE TABLE IF NOT EXISTS `user_test` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '自增加id',
  `user_name` varchar(128) NOT NULL COMMENT '用戶名',
   PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用戶表';

複製代碼

查詢

  • 簡單的查詢
<select id="queryUserByName" resultMap="userMap" parameterType="java.lang.String">
	SELECT * FROM user_test WHERE user_name = #{userName}
 </select>
複製代碼

須要注意的是若是這裏不指定parameterType,則默認會識別處理;若是指定了類型,則傳入的值就須要和當前指定的類型保持一致,否則就會出現數據類型轉換異常。sql

  • 簡單分頁查詢
<select id="queryUsersList" resultMap="userMap">
    SELECT * FROM user_test WHERE 1=1 
        <if test="keyword != null and keyword != ''" >
            AND user_name LIKE concat('%',#{keyword},'%')
        </if>
    LIMIT #{currentPage},#{pageSize}
</select>
複製代碼
  • left join

app_info表和app_verion表分別存儲的是應用信息和應用版本信息。如今要根據appId和versionId查出一個應用的具體信息【包括信息信息和版本信息】數據庫

<select id="getAppDetail" resultMap="appDeatilMap">
    	select  m.id id,
		m.app_name appName,
		n.version version,
		from app_info m
		LEFT JOIN app_version n ON m.id = n.app_id 
		where m.id = #{appId} and n.id = #{versionId}
    </select>
複製代碼
  • 查詢條件是list
<select id="queryAppByAppNames" resultMap="AppMap" parameterType="java.util.List">
	select 
		a.app_name appName,
		b.version version
	from starter_info a,starter_version b 
	where 
		a.id = b.app_id 
		and a.id in 
		(
        		select id from app_info where app_name in 
        		<foreach collection="list" item="item" index="index" open="(" close=")" separator=",">
        			#{item}
        		</foreach>
		)
</select>

複製代碼

更新

  • 簡單的更新
<update id="updateApp" parameterType="java.util.List">
    UPDATE app_info
        SET 
            app_name = #{appName}
        WHERE 
            app_id = #{appId}
</update>
複製代碼
  • 批量更新

有這樣一個需求,把 app_info表中id 爲1,2,3的app的app_name改成appName1,appName2,appName3;緩存

使用 case ..when ..then 這樣的語法結構來完成:bash

case 是當前的條件,when表示條件值,then後面是當前目前更新字段的值;app

下面的說明:當前id=#{item.appId}時,app_name=#{item.appName}ide

<update id="updateApps" parameterType="java.util.List">
	UPDATE app_info set app_name =
	<foreach collection="applList" item="item" index="index" separator=" " open="case ID" close="end">
		when #{item.appId,jdbcType=INTEGER} then #{item.appName,jdbcType=INTEGER}
	</foreach>
	
	where id in
	<foreach collection="appList" index="index" item="item" separator="," open="(" close=")">
		#{item.appId,jdbcType=INTEGER}
	</foreach>
</update>
複製代碼

OK,如今於這樣的須要:性能

根據應用類型的不一樣,更新不一樣的運行環境配置;ui

{
    [
        {
            "appType":"applet",
            "cpu":5,
            "memory":4,
            "card":3,
            "nums":2,
            "network":1,
            "isInUse":1
        },
        {
            "appType":"bs",
            "cpu":5,
            "memory":4,
            "card":3,
            "nums":2,
            "network":1,
            "isInUse":1

        },
        {
            "appType":"cs",
            "cpu":5,
            "memory":4,
            "card":3,
            "nums":2,
            "network":1,
            "isInUse":1
        },
        //有幾個放幾個
    ]
}
複製代碼

trim屬性說明

  • 1.prefix,suffix 表示在trim標籤包裹的部分的前面或者後面添加內容
  • 2.若是同時有prefixOverrides,suffixOverrides 表示會用prefix,suffix覆蓋Overrides中的內容。
  • 3.若是隻有prefixOverrides,suffixOverrides 表示刪除開頭的或結尾的xxxOverides指定的內容。
<update id="updateBatchApp" parameterType="java.util.List">
	UPDATE app_info
	<trim prefix="set" suffixOverrides=",">
		<trim prefix="cpu = case" suffix="end,">
			<foreach collection="modelList" item="item" index="index">
				<if test="item != null">
					when app_type =#{item.appType} then #{item.cpu}
				</if>
			</foreach>
		</trim>
		<trim prefix="memory = case" suffix="end,">
			<foreach collection="modelList" item="item" index="index">
				<if test="item != null">
					when app_type =#{item.appType} then #{item.memory}
				</if>
			</foreach>
		</trim>
		<trim prefix="card = case" suffix="end,">
			<foreach collection="modelList" item="item" index="index">
				when app_type =#{item.appType} then #{item.card}
			</foreach>
		</trim>
		<trim prefix="nums = case" suffix="end,">
			<foreach collection="modelList" item="item" index="index">
				when app_type =#{item.appType} then #{item.nums}
			</foreach>
		</trim>
		<trim prefix="network = case" suffix="end,">
			<foreach collection="modelList" item="item" index="index">
				when app_type =#{item.appType} then #{item.network}
			</foreach>
		</trim>
		<trim prefix="is_in_use = case" suffix="end,">
			<foreach collection="modelList" item="item" index="index">
				when app_type =#{item.appType} then #{item.isInUse}
			</foreach>
		</trim>
	</trim>
	where app_id = #{appId}
</update>
複製代碼

關於性能問題沒作研究,以前看過關於不一樣更新語句寫法的一篇性能的分析,你們有興趣能夠看下:批量更新數據兩種方法效率對比

刪除

  • 簡單刪除
DELETE FROM app_info where id = #{id}
複製代碼
  • 批量刪除
<delete id="deleteApps" parameterType="java.util.List">
	DELETE FROM app_info where  app_id in 
    	<foreach item="item" collection="appIds" open="(" separator="," close=")">
            #{item}
        </foreach>
</delete>
複製代碼

時間字符串 order by

不知道各位是否遇到過,以前的前輩們在項目中將時間用字符串的方式存在DB中,而不是使用DATE,而後有一天你的前輩走了,你的主管說查出來按時間來排序....;呵呵,好!!!

<select id="querySysParamList" resultMap="sysParamDO">
    SELECT * FROM app_info WHERE 1=1
        <if test="keyword != null and keyword != ''" >
            AND app_name LIKE concat('%',#{keyword},'%')
        </if>
    ORDER BY DATE_FORMAT(update_time,'%H %k %I %r %T %S %w') DESC
</select>
複製代碼

字符串轉爲日期格式 SELECT DATE_FORMAT('2011-09-20 08:30:45', '%Y-%m-%d %H:%i:%S');

把日期轉爲字符串格式 SELECT DATE_FORMAT(NOW(), '%Y-%m-%d %H:%i:%S');

附:

%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), 這裏星期一是星期的第一天 
%% 一個文字「%」。
複製代碼

先記錄這些,有坑再補!

參考:http://www.runoob.com/sql/sql-tutorial.html

相關文章
相關標籤/搜索