myBatis --(5)動態sql

動態sql是myBatis中至關有用的一個知識點,整體來講,動態sql有以下幾類:sql

1>if語句(簡單的條件判斷)
mybatis

2>choose(至關於case when),即C語言中的switth
oracle

3>trim(對包含的內容加上prefix(前綴)、或者suffix(後綴)等)
ide

4>where(簡化SQL語句中where條件判斷)
ui

5>set(用於 更新時設置)
code

6>foreach(實現myBatis in語句查詢時有用)
xml

以下例子均是普通sql操做的例子,若是採用oracle中的存儲過程時,請直接看後面講解。
blog

1、if語句
ip

使用環境舉例:查詢招聘列表,根據地點、薪資、工做經驗等篩選條件進行篩選。rem

分析:這個時候,條件是動態的,能夠所有選擇,也能夠只選擇一部分。

動態SQL語句以下

    <select id="getMyJobList" parameterType="com.zhiji.caren.VO.AttentionMyParams"
        resultMap="BaseResultMapJobList">

        SELECT
        tall.LOCATION_ID,
        tall.LOCATION_NAME,
        tall.JOB_ID,
        tall.JOB_NAME,
        tall.NEGOTIABLE_FLAG,
        tall.SALARY_MAX,
        tall.SALARY_MIN,
        tall.ADD_TIME,
        tall.ENTERPRISE_ID,
        tall.ENTERPRISE_NAME,
        tall.ENTERPRISE_LOGO,
        tall.WORK_YEARS_ID,
        tall.WORK_YEARS_INFO,
        IFNULL( tujf.FOCUS_FLAG,0) as
        flag
        FROM
        (SELECT
        tj.JOB_ID,
        tj.LOCATION_ID,
        tl.LOCATION_NAME,
        tj.JOB_NAME,
        tj.NEGOTIABLE_FLAG,
        tj.SALARY_MAX,
        tj.SALARY_MIN,
        tj.ADD_TIME,
        tj.ENTERPRISE_ID,
        te.ENTERPRISE_NAME,
        te.ENTERPRISE_LOGO,
        twy.WORK_YEARS_ID,
        twy.WORK_YEARS_INFO,
        '' AS flag
        FROM
        t_job
        tj,t_location tl,t_enterprise te,t_hr th,t_work_years
        twy,t_job_category tjc,t_job_type tjt
        WHERE tj.LOCATION_ID =
        tl.LOCATION_ID
        AND tl.LOCATION_LEVEL = 2
        AND tl.USE_FLAG = 1
        AND
        tj.ENTERPRISE_ID = te.ENTERPRISE_ID
        AND te.USE_FLAG = 1
        AND tj.HR_ID =
        th.HR_ID
        AND th.USE_FLAG = 1
        AND tj.WORK_YEARS_ID = twy.WORK_YEARS_ID
        AND tj.JOB_CATEGORY_ID = tjc.JOB_CATEGORY_ID
        AND tjc.USE_FLAG = 1
        AND
        tj.JOB_TYPE_ID = tjt.JOB_TYPE_ID
        AND tjt.USE_FLAG = 1
        <if test="jobCategoryId != null">
            AND
            tjc.JOB_CATEGORY_ID = #{jobCategoryId}
        </if>
        <if test="locationId != null">
            AND
            tl.LOCATION_ID = #{locationId}
        </if>
        <if test="workYearId != null">
            AND
            twy.WORK_YEARS_ID = #{workYearId}
        </if>
        <if test="jobTypeId != null">
            AND
            tjt.JOB_TYPE_ID = #{jobTypeId}
        </if>
        <if test="lastTime != null">
            AND
            tj.ADD_TIME &lt;= #{lastTime}
        </if>
        GROUP BY
        tj.JOB_ID
        ORDER BY
        tj.ADD_TIME DESC) tall
        left join
        (select JOB_ID
        as
        FOCUS_JOB_ID,'1' as FOCUS_FLAG from
        t_user_job_focus where
        user_id =
        #{userId} and TYPE = '01') tujf
        on
        tall.JOB_ID = tujf.FOCUS_JOB_ID
        LIMIT
        #{pageIndex}

    </select>

備註:很明顯,上面的if判斷能夠知足需求,只有當輸入的條件不爲空時(即選擇了該篩選條件),SQL查詢條件才帶上這個篩選條件;不然,不帶上這個篩選條件(即沒有選擇這個篩選條件)。

2、choose

它至關於C語言中的switch case。

適用場景:多選一的時候。

choose標籤是按照順序判斷其內部when標籤中的test條件是否成立,若是一旦成立,則choose語句結束;當choose中全部when條件都不知足時,則執行otherwise中的sql。

如上例子:篩選條件由多選變成單選

動態SQL語句以下

<select id="getMyJobList" parameterType="com.zhiji.caren.VO.AttentionMyParams"
        resultMap="BaseResultMapJobList">

        SELECT
        tall.LOCATION_ID,
        tall.LOCATION_NAME,
        tall.JOB_ID,
        tall.JOB_NAME,
        tall.NEGOTIABLE_FLAG,
        tall.SALARY_MAX,
        tall.SALARY_MIN,
        tall.ADD_TIME,
        tall.ENTERPRISE_ID,
        tall.ENTERPRISE_NAME,
        tall.ENTERPRISE_LOGO,
        tall.WORK_YEARS_ID,
        tall.WORK_YEARS_INFO,
        IFNULL( tujf.FOCUS_FLAG,0) as
        flag
        FROM
        (SELECT
        tj.JOB_ID,
        tj.LOCATION_ID,
        tl.LOCATION_NAME,
        tj.JOB_NAME,
        tj.NEGOTIABLE_FLAG,
        tj.SALARY_MAX,
        tj.SALARY_MIN,
        tj.ADD_TIME,
        tj.ENTERPRISE_ID,
        te.ENTERPRISE_NAME,
        te.ENTERPRISE_LOGO,
        twy.WORK_YEARS_ID,
        twy.WORK_YEARS_INFO,
        '' AS flag
        FROM
        t_job
        tj,t_location tl,t_enterprise te,t_hr th,t_work_years
        twy,t_job_category tjc,t_job_type tjt
        WHERE tj.LOCATION_ID =
        tl.LOCATION_ID
        AND tl.LOCATION_LEVEL = 2
        AND tl.USE_FLAG = 1
        AND
        tj.ENTERPRISE_ID = te.ENTERPRISE_ID
        AND te.USE_FLAG = 1
        AND tj.HR_ID =
        th.HR_ID
        AND th.USE_FLAG = 1
        AND tj.WORK_YEARS_ID = twy.WORK_YEARS_ID
        AND tj.JOB_CATEGORY_ID = tjc.JOB_CATEGORY_ID
        AND tjc.USE_FLAG = 1
        AND
        tj.JOB_TYPE_ID = tjt.JOB_TYPE_ID
        AND tjt.USE_FLAG = 1
        <choose>
        <when test="jobCategoryId != null">
            AND
            tjc.JOB_CATEGORY_ID = #{jobCategoryId}
        </when>
        <when test="locationId != null">
            AND
            tl.LOCATION_ID = #{locationId}
        </when>
        <when test="workYearId != null">
            AND
            twy.WORK_YEARS_ID = #{workYearId}
        </when>
        <when test="jobTypeId != null">
            AND
            tjt.JOB_TYPE_ID = #{jobTypeId}
        </when>
        <when test="lastTime != null">
            AND
            tj.ADD_TIME &lt;= #{lastTime}
        </when>
        <otherwise>
            AND
                1=1
        </otherwise>
        </choose>        
        GROUP BY
        tj.JOB_ID
        ORDER BY
        tj.ADD_TIME DESC) tall
        left join
        (select JOB_ID
        as
        FOCUS_JOB_ID,'1' as FOCUS_FLAG from
        t_user_job_focus where
        user_id =
        #{userId} and TYPE = '01') tujf
        on
        tall.JOB_ID = tujf.FOCUS_JOB_ID
        LIMIT
        #{pageIndex}

    </select>

說明:上述的SQL語句完成 篩選條件 多選一的時候。即篩選條件始終是隻能選擇一個或者不選。

3、trim

這個通常用得不多,我舉一段用代碼生成器生成的例子,以下

    <insert id="insertSelective" parameterType="com.zhiji.caren.model.Job">
        insert into t_job
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="jobId != null">
                JOB_ID,
            </if>
            <if test="jobName != null">
                JOB_NAME,
            </if>
            <if test="jobTypeId != null">
                JOB_TYPE_ID,
            </if>
            <if test="jobDepartment != null">
                JOB_DEPARTMENT,
            </if>
            <if test="enterpriseId != null">
                ENTERPRISE_ID,
            </if>
            <if test="jobCategoryId != null">
                JOB_CATEGORY_ID,
            </if>
            <if test="salaryMin != null">
                SALARY_MIN,
            </if>
            <if test="salaryMax != null">
                SALARY_MAX,
            </if>
            <if test="locationId != null">
                LOCATION_ID,
            </if>
            <if test="hrId != null">
                HR_ID,
            </if>
            <if test="workYearsId != null">
                WORK_YEARS_ID,
            </if>
            <if test="eduRequirementId != null">
                EDU_REQUIREMENT_ID,
            </if>
            <if test="jobDescription != null">
                JOB_DESCRIPTION,
            </if>
            <if test="jobAddress != null">
                JOB_ADDRESS,
            </if>
            <if test="auditFlag != null">
                AUDIT_FLAG,
            </if>
            <if test="stikyFlag != null">
                STIKY_FLAG,
            </if>
            <if test="negotiableFlag != null">
                NEGOTIABLE_FLAG,
            </if>
            <if test="hrInfoFlag != null">
                HR_INFO_FLAG,
            </if>
            <if test="useFlag != null">
                USE_FLAG,
            </if>
            <if test="validTime != null">
                VALID_TIME,
            </if>
            <if test="updUserId != null">
                UPD_USER_ID,
            </if>
            <if test="addTime != null">
                ADD_TIME,
            </if>
            <if test="updTime != null">
                UPD_TIME,
            </if>
        </trim>
        <trim prefix="values (" suffix=")" suffixOverrides=",">
            <if test="jobId != null">
                #{jobId,jdbcType=INTEGER},
            </if>
            <if test="jobName != null">
                #{jobName,jdbcType=VARCHAR},
            </if>
            <if test="jobTypeId != null">
                #{jobTypeId,jdbcType=INTEGER},
            </if>
            <if test="jobDepartment != null">
                #{jobDepartment,jdbcType=VARCHAR},
            </if>
            <if test="enterpriseId != null">
                #{enterpriseId,jdbcType=INTEGER},
            </if>
            <if test="jobCategoryId != null">
                #{jobCategoryId,jdbcType=INTEGER},
            </if>
            <if test="salaryMin != null">
                #{salaryMin,jdbcType=INTEGER},
            </if>
            <if test="salaryMax != null">
                #{salaryMax,jdbcType=INTEGER},
            </if>
            <if test="locationId != null">
                #{locationId,jdbcType=INTEGER},
            </if>
            <if test="hrId != null">
                #{hrId,jdbcType=INTEGER},
            </if>
            <if test="workYearsId != null">
                #{workYearsId,jdbcType=INTEGER},
            </if>
            <if test="eduRequirementId != null">
                #{eduRequirementId,jdbcType=INTEGER},
            </if>
            <if test="jobDescription != null">
                #{jobDescription,jdbcType=VARCHAR},
            </if>
            <if test="jobAddress != null">
                #{jobAddress,jdbcType=VARCHAR},
            </if>
            <if test="auditFlag != null">
                #{auditFlag,jdbcType=CHAR},
            </if>
            <if test="stikyFlag != null">
                #{stikyFlag,jdbcType=INTEGER},
            </if>
            <if test="negotiableFlag != null">
                #{negotiableFlag,jdbcType=INTEGER},
            </if>
            <if test="hrInfoFlag != null">
                #{hrInfoFlag,jdbcType=INTEGER},
            </if>
            <if test="useFlag != null">
                #{useFlag,jdbcType=INTEGER},
            </if>
            <if test="validTime != null">
                #{validTime,jdbcType=CHAR},
            </if>
            <if test="updUserId != null">
                #{updUserId,jdbcType=INTEGER},
            </if>
            <if test="addTime != null">
                #{addTime,jdbcType=CHAR},
            </if>
            <if test="updTime != null">
                #{updTime,jdbcType=CHAR},
            </if>
        </trim>
    </insert>

上述是一條insert語句,去掉動態標籤部分,學過SQL的人都應該看得懂。

這段代碼<trim prefix="(" suffix=")" suffixOverrides=",">解釋以下:

從<trim prefix="(" suffix=")" suffixOverrides=",">開始,以下那段代碼後綴遇到","時,將那段代碼用()括起來,同時,去掉最後的那個","號。

中間這段代碼<trim prefix="values (" suffix=")" suffixOverrides=",">解釋以下:

從<trim prefix="values (" suffix=")" suffixOverrides=",">開始,以下那段代碼後綴遇到","時,那段代碼的前面加上 values (,後面用 ")"代替","。

4、where

直接看例子

    <select id="getMyJobListPart" parameterType="com.zhiji.caren.VO.AttentionMyParams"
        resultMap="BaseResultMapJobList">
    
        SELECT
        tallTwo.JOB_ID,
        tallTwo.LOCATION_ID,
        tallTwo.LOCATION_NAME,
        tallTwo.JOB_NAME,
        tallTwo.NEGOTIABLE_FLAG,
        tallTwo.SALARY_MAX,
        tallTwo.SALARY_MIN,
        tallTwo.ADD_TIME,
        tallTwo.ENTERPRISE_ID,
        tallTwo.ENTERPRISE_NAME,
        tallTwo.ENTERPRISE_LOGO,
        tallTwo.WORK_YEARS_ID,
        tallTwo.WORK_YEARS_INFO,
        tallTwo.HR_ID,
        tallTwo.JOB_CATEGORY_ID,
        IFNULL( tujf.FOCUS_FLAG,0) as flag
        FROM
        (SELECT
        tall.JOB_ID,
        tall.LOCATION_ID,
        tl.LOCATION_NAME,
        tall.JOB_NAME,
        tall.NEGOTIABLE_FLAG,
        tall.SALARY_MAX,
        tall.SALARY_MIN,
        tall.ADD_TIME,
        tall.ENTERPRISE_ID,
        te.ENTERPRISE_NAME,
        te.ENTERPRISE_LOGO,
        tall.WORK_YEARS_ID,
        twy.WORK_YEARS_INFO,
        tall.HR_ID,
        tall.JOB_CATEGORY_ID,
        tall.JOB_TYPE_ID
        FROM
        (
        SELECT
        tj.JOB_ID,
        tj.LOCATION_ID,
        tj.JOB_NAME,
        tj.NEGOTIABLE_FLAG,
        tj.SALARY_MAX,
        tj.SALARY_MIN,
        tj.ADD_TIME,
        tj.ENTERPRISE_ID,
        tj.WORK_YEARS_ID,
        tj.HR_ID,
        tj.JOB_CATEGORY_ID,
        tj.JOB_TYPE_ID
        FROM
        t_job tj
        <if test="salaryId != null">
            ,t_salary ts
        </if>
        WHERE
        1 = 1
        <if test="salaryId != null">
            AND ts.SALARY_ID = #{salaryId}
            AND ts.SALARY_MAX
            &gt;=tj.SALARY_MAX
            AND ts.SALARY_MIN &lt;= tj.SALARY_MIN
        </if>
        <if test="locationId != null">
            AND
            tj.LOCATION_ID = #{locationId}
        </if>
        <if test="workYearId != null">
            AND
            tj.WORK_YEARS_ID = #{workYearId}
        </if>
        <if test="jobCategoryId != null">
            AND
            tj.JOB_CATEGORY_ID =
            #{jobCategoryId}
        </if>
        <if test="jobTypeId != null">
            AND
            tj.JOB_TYPE_ID = #{jobTypeId}
        </if>
        <if test="lastTime != null">
            AND
            tj.ADD_TIME &lt;= #{lastTime}
        </if>
        GROUP BY tj.JOB_ID
        ORDER BY tj.ADD_TIME DESC
        ) tall
        LEFT JOIN t_location
        tl ON tall.LOCATION_ID = tl.LOCATION_ID
        AND tl.LOCATION_LEVEL = 2
        AND
        tl.USE_FLAG = 1
        LEFT JOIN t_enterprise te ON tall.ENTERPRISE_ID =
        te.ENTERPRISE_ID
        AND te.USE_FLAG = 1
        LEFT JOIN t_hr th ON tall.HR_ID =
        th.HR_ID
        AND th.USE_FLAG = 1
        LEFT JOIN t_work_years twy ON
        tall.WORK_YEARS_ID = twy.WORK_YEARS_ID
        LEFT JOIN t_job_category tjc ON
        tall.JOB_CATEGORY_ID = tjc.JOB_CATEGORY_ID
        AND tjc.USE_FLAG = 1
        LEFT JOIN t_job_type tjt ON
        tall.JOB_TYPE_ID = tjt.JOB_TYPE_ID
        AND tjt.USE_FLAG = 1)
        tallTwo
        LEFT JOIN (select JOB_ID as FOCUS_JOB_ID,'1' as FOCUS_FLAG from
        t_user_job_focus where user_id = #{userId} and TYPE = '01') tujf
        ON
        tallTwo.JOB_ID = tujf.FOCUS_JOB_ID
        LIMIT #{pageIndex}
    
    </select>

如上動態SQL中有一個 where 1=1的地方,本來的狀況應該寫成這樣

        WHERE
        <if test="salaryId != null">
            ts.SALARY_ID = #{salaryId}
            AND ts.SALARY_MAX
            &gt;=tj.SALARY_MAX
            AND ts.SALARY_MIN &lt;= tj.SALARY_MIN
        </if>

本來的狀況下 當salaryId無值時,就會出現問題。改用where標籤修改爲以下:

        tj.JOB_CATEGORY_ID,
        tj.JOB_TYPE_ID
        FROM
        t_job tj
        <if test="salaryId != null">
            ,t_salary ts
        </if>
        <where>
        <if test="salaryId != null">
             ts.SALARY_ID = #{salaryId}
            AND ts.SALARY_MAX
            &gt;=tj.SALARY_MAX
            AND ts.SALARY_MIN &lt;= tj.SALARY_MIN
        </if>
        ......
        </where>
        GROUP BY tj.JOB_ID
        ......

說明:這種寫法是 當<where>後的判斷語句中有一條成立時,會在成立的語句以前加上where;若是成立的語句以前有AND或者OR,則mybatis會自動的去掉AND或OR。

5、set

主要是在update語句時使用

以下是我用代碼生成器生成的一段代碼以下

    <update id="updateByPrimaryKeySelective" parameterType="com.zhiji.caren.model.Job">
        update t_job
        <set>
            <if test="jobName != null">
                JOB_NAME = #{jobName,jdbcType=VARCHAR},
            </if>
            <if test="jobTypeId != null">
                JOB_TYPE_ID = #{jobTypeId,jdbcType=INTEGER},
            </if>
            <if test="jobDepartment != null">
                JOB_DEPARTMENT = #{jobDepartment,jdbcType=VARCHAR},
            </if>
            <if test="enterpriseId != null">
                ENTERPRISE_ID = #{enterpriseId,jdbcType=INTEGER},
            </if>
            <if test="jobCategoryId != null">
                JOB_CATEGORY_ID = #{jobCategoryId,jdbcType=INTEGER},
            </if>
            <if test="salaryMin != null">
                SALARY_MIN = #{salaryMin,jdbcType=INTEGER},
            </if>
            <if test="salaryMax != null">
                SALARY_MAX = #{salaryMax,jdbcType=INTEGER},
            </if>
            <if test="locationId != null">
                LOCATION_ID = #{locationId,jdbcType=INTEGER},
            </if>
            <if test="hrId != null">
                HR_ID = #{hrId,jdbcType=INTEGER},
            </if>
            <if test="workYearsId != null">
                WORK_YEARS_ID = #{workYearsId,jdbcType=INTEGER},
            </if>
            <if test="eduRequirementId != null">
                EDU_REQUIREMENT_ID =
                #{eduRequirementId,jdbcType=INTEGER},
            </if>
            <if test="jobDescription != null">
                JOB_DESCRIPTION = #{jobDescription,jdbcType=VARCHAR},
            </if>
            <if test="jobAddress != null">
                JOB_ADDRESS = #{jobAddress,jdbcType=VARCHAR},
            </if>
            <if test="auditFlag != null">
                AUDIT_FLAG = #{auditFlag,jdbcType=CHAR},
            </if>
            <if test="stikyFlag != null">
                STIKY_FLAG = #{stikyFlag,jdbcType=INTEGER},
            </if>
            <if test="negotiableFlag != null">
                NEGOTIABLE_FLAG = #{negotiableFlag,jdbcType=INTEGER},
            </if>
            <if test="hrInfoFlag != null">
                HR_INFO_FLAG = #{hrInfoFlag,jdbcType=INTEGER},
            </if>
            <if test="useFlag != null">
                USE_FLAG = #{useFlag,jdbcType=INTEGER},
            </if>
            <if test="validTime != null">
                VALID_TIME = #{validTime,jdbcType=CHAR},
            </if>
            <if test="updUserId != null">
                UPD_USER_ID = #{updUserId,jdbcType=INTEGER},
            </if>
            <if test="addTime != null">
                ADD_TIME = #{addTime,jdbcType=CHAR},
            </if>
            <if test="updTime != null">
                UPD_TIME = #{updTime,jdbcType=CHAR},
            </if>
        </set>
        where JOB_ID = #{jobId,jdbcType=INTEGER}
    </update>

看得懂純SQL的人應該能看懂如上代碼,<set>標籤的做用主要是在中間那段代碼的前面加上 set。以下是我沒有使用<set>標籤的更新語句,閱讀者對比看下就能懂了。

    <update id="updateByPrimaryKey" parameterType="com.zhiji.caren.model.Job">
        update t_job
        set
        JOB_NAME = #{jobName,jdbcType=VARCHAR},
        JOB_TYPE_ID =
        #{jobTypeId,jdbcType=INTEGER},
        JOB_DEPARTMENT =
        #{jobDepartment,jdbcType=VARCHAR},
        ENTERPRISE_ID =
        #{enterpriseId,jdbcType=INTEGER},
        JOB_CATEGORY_ID =
        #{jobCategoryId,jdbcType=INTEGER},
        SALARY_MIN =
        #{salaryMin,jdbcType=INTEGER},
        SALARY_MAX =
        #{salaryMax,jdbcType=INTEGER},
        LOCATION_ID =
        #{locationId,jdbcType=INTEGER},
        HR_ID = #{hrId,jdbcType=INTEGER},
        WORK_YEARS_ID = #{workYearsId,jdbcType=INTEGER},
        EDU_REQUIREMENT_ID =
        #{eduRequirementId,jdbcType=INTEGER},
        JOB_DESCRIPTION =
        #{jobDescription,jdbcType=VARCHAR},
        JOB_ADDRESS =
        #{jobAddress,jdbcType=VARCHAR},
        AUDIT_FLAG =
        #{auditFlag,jdbcType=CHAR},
        STIKY_FLAG = #{stikyFlag,jdbcType=INTEGER},
        NEGOTIABLE_FLAG = #{negotiableFlag,jdbcType=INTEGER},
        HR_INFO_FLAG =
        #{hrInfoFlag,jdbcType=INTEGER},
        USE_FLAG = #{useFlag,jdbcType=INTEGER},
        VALID_TIME = #{validTime,jdbcType=CHAR},
        UPD_USER_ID =
        #{updUserId,jdbcType=INTEGER},
        ADD_TIME = #{addTime,jdbcType=CHAR},
        UPD_TIME = #{updTime,jdbcType=CHAR}
        where JOB_ID =
        #{jobId,jdbcType=INTEGER}
    </update>

6、foreach

我用得比較少,這裏不贅述,有須要的朋友能夠參考以下地址

http://haohaoxuexi.iteye.com/blog/1338557

相關文章
相關標籤/搜索