【mysql&mybatis】小白工作中遇到的那些規範與坑系列(不定時更新)

這裏是剛轉行的程序媛小白,僅以此博客總結自己學到的經驗以及遇到的一些坑。
個人學習交流用,請勿用作商用。
轉載需徵得我同意。

MySql

建表規範

CREATE TABLE `xxx_admin` (
  `id` bigint(11) NOT NULL AUTO_INCREMENT COMMENT '自增id',
  `uid` bigint(20) NOT NULL COMMENT '賬號id',
  `content_id` varchar(20) NOT NULL COMMENT '內容id',
  `type` tinyint(4) NOT NULL COMMENT '審覈類型 0/ 1/ 2/ 3/ 4/',
  `content` varchar(500) NOT NULL COMMENT '審覈內容鏈接',
  `status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '審覈狀態 0/待處理 1/已通過 2/未通過 3/已失效',
  `operator` varchar(255) DEFAULT NULL COMMENT '操作者',
  `delete_flag` tinyint(4) NOT NULL DEFAULT '0' COMMENT '0/未刪除 1/已刪除',
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  UNIQUE KEY `content_uk` (`content_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8mb4 COMMENT='審覈xxx';

字段類型對應
字段類型對應
注意:
type用tinyint,java數據類型對應Byte,且需建立對應Enum類(Enum規範放java裏面講)
create_time與update_time自動創建與更新
每一個字段最後最好都加上註釋
主鍵id,索引根據需求建立
建表要注意可擴展性

MyBatis

xml文件的建立

<?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="mapper類路徑">
    <resultMap id="BaseResultMap" type="entity類路徑">
        <id column="id" jdbcType="BIGINT" property="id" />
        <result column="uid" jdbcType="BIGINT" property="uid" />
        <result column="type" jdbcType="TINYINT" property="type" />
        <result column="content" jdbcType="VARCHAR" property="content" />
        <result column="update_time" jdbcType="TIMESTAMP" property="updateTime" />
        <result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
    </resultMap>
	
	......sql語句
	
</mapper>

id column一定要填在sql表中設置爲主鍵的那個字段(一般情況下就是id)
property爲entity類中java對應sql的變量名稱

xml文件常用的那些語句規範及技巧

需要注意的規範

<sql id="Base_Column_List">
    id, `uid`, `type`, `content`, create_time, update_time
  </sql>

注意:此語句僅可使用在select語句中

使用好foreach語句,大大優化增改查效率
使用場合:
1.以多個同一字段爲條件進行循環查詢時
2.以多個同一字段爲條件而其他條件不變進行循環更新時
3.以多個同一字段爲條件而其他條件不變進行循環插入時

注意:
需要進行循環的字段在java的數據類型爲List

規範:
1.當只有一個字段爲條件時

 <select id="listUserXXXByUserId" parameterType="java.util.List" resultMap="BaseResultMap">
    select
    <include refid="Base_Column_List"/>
    from ***
    where user_id in
    <foreach collection="list" index="index" item="userIds" open="(" separator="," close=")">
        #{userIds}
    </foreach>
</select>

parameterType爲List,item爲java變量名,collection爲sql字段名,#{}內爲傳入的java變量名

2.當有多個字段爲條件但變化字段只有一個時

	<update id="updateXXXAdmin" parameterType="傳入的類的路徑">
		update xxx set
		<if test="deletedFlag != null">
			deleted_flag = #{deletedFlag},
		</if>
    	<if test="operator != null">
        	operator = #{operator},
    	</if>
    	<if test="adminState != null">
        	admin_state = #{adminState}
    	</if>
    	where user_id in
    	<foreach collection="userId" index="index" item="userId" open="(" separator="," close=")">
        	#{userId}
    	</foreach>
	</update>

parameterType爲傳入的類的路徑,item、collection、#{}兼爲變化的與sql字段相對應的java變量名(其實這塊我也不太懂,但是這麼做是最穩妥的)

善於使用if語句,爲後續需求更新留有餘地
1.查詢操作時

	<select id="selectByConditions" parameterType="類路徑" resultMap="BaseResultMap">
        select
        <include refid="Base_Column_List"/>
        from XXXX
        where 1=1
        <if test="type != null">
            and `type` = #{type}
        </if>
        <if test="startTime != null">
            and create_time <![CDATA[>]]> #{startTime}
        </if>
        <if test="endTime != null">
            and create_time <![CDATA[<]]> #{endTime}
        </if>
        <if test="uid != null">
            and uid in
            <foreach collection="uid" index="index" item="uid" open="(" separator="," close=")">
                #{uid}
            </foreach>
        </if>
        order by create_time DESC
    </select>

2.插入操作時

    <insert id="insertXXX" parameterType="xxxx">
        insert into xxxx
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="uid != null">
                uid,
            </if>
            <if test="content != null">
                content,
            </if>
            <if test="type != null">
                `type`,
            </if>
        </trim>
        <trim prefix="values (" suffix=")" suffixOverrides=",">
            <if test="uid != null">
                #{uid,jdbcType=BIGINT},
            </if>
            <if test="content != null">
                #{content,jdbcType=VARCHAR},
            </if>
            <if test="type != null">
                #{type,jdbcType=TINYINT},
            </if>
        </trim>
    </insert>

3.更新操作時

	<update id="updateByPrimaryKeySelective" parameterType="類路徑">
        update XXX
        <set>
            <if test="userId != null">
                user_id = #{userId,jdbcType=BIGINT},
            <if test="createTime != null">
                create_time = #{createTime,jdbcType=TIMESTAMP},
            </if>
            <if test="updateTime != null">
                update_time = #{updateTime,jdbcType=TIMESTAMP},
            </if>
        </set>
        where id = #{id,jdbcType=BIGINT}
    </update>

查詢時where與if相連用的坑

	<select id="selectByConditions" parameterType="類路徑" resultMap="BaseResultMap">
        select
        <include refid="Base_Column_List"/>
        from XXXX
        where 1=1
        <if test="type != null">
            and `type` = #{type}
        </if>
        <if test="startTime != null">
            and create_time <![CDATA[>]]> #{startTime}
        </if>
        <if test="endTime != null">
            and create_time <![CDATA[<]]> #{endTime}
        </if>
        order by create_time DESC
    </select>

where與多個if連用時,千萬要注意and
在上述代碼中,我用了三個if,如果我沒有在where後面加上1=1,只要有一個if成立,where後面會直接跟上and xxx = # {xxx},那麼我這段sql語句會直接報錯,因爲sql語法不正確。
所以,爲了防止此類發生,有兩個辦法。
1. 去掉 第一個 if條件語句中的and(注意: 此做法有風險,因爲你無法判斷第一個是否滿足條件,若不滿足,又會執行之後的if條件語句,若之後的if條件滿足,而其中因爲有and,於是又會報錯,除非你確定第一個字段的值一定不會爲空,那可以不用弄成if條件語句。)
2. 在where條件後面添加上1 = 1 ,此做法可保證假若之後條件兼不滿足,仍可查出數據且不報錯。

有關時間需求的操作語句
1.查詢結果按時間倒序展示且進行分頁

    <select id="selectXXXByConditions" parameterType="類路徑" resultMap="BaseResultMap">
        select
        <include refid="Base_Column_List" />
        from XXX
        where 1=1
        <if test="uid != null">
            and user_id = #{uid}
        </if>
        <if test="startTime != null">
            and create_time <![CDATA[>]]> #{startTime}
        </if>
        <if test="endTime != null">
            and create_time <![CDATA[<]]> #{endTime}
        </if>
        order by create_time DESC LIMIT #{offset}, #{limit}
    </select>

offset爲一頁的數量,limit爲頁數。

<![CDATA[ ]]>爲轉義符,這裏轉義“>”和“<”符號

下面是按時間倒敘展示生效語句

order by create_time DESC

3.查詢一個月以內的數據

    <select id="selectXXX" parameterType="類路徑" resultMap="BaseResultMap">
        select
        <include refid="Base_Column_List"/>
        from XXX
        where uid = #{uid} and create_time >= curdate()-interval 1 month
        <if test="type != null">
            and `type` = #{type}
        </if>
    </select>

生效語句

create_time >= curdate()-interval 1 month

有關數量需求的操作語句
1.求數據條數總數量

select count(*/需求字段) from xxx

2.求數據內容總和

select sum(需求字段) from xxx
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章