動的SQL文

9992 ワード

三、動的SQL文
        場合によっては、sql文where条件では、性別検索などのセキュリティ判断が必要です.入力されたパラメータが空であれば、クエリの結果が空になる可能性があります.パラメータが空であれば、すべての情報を検出する必要があるかもしれません.これは、動的sqlを使用して、パラメータが要求に合致しない場合、このクエリー条件を判断しない判断を追加することができます.        以下ではmysql構文と関数(文字列リンク関数CONCATなど)を使用します.
        ソースコードhttp://limingnihao.javaeye.com/admin/blogs/782190ページの一番下
3.1 ifラベル
 普通のクエリーです.
    <!--     list,like   -->  
    <select id="getStudentListLikeName" parameterType="StudentEntity" resultMap="studentResultMap">  
        SELECT * from STUDENT_TBL ST    
    WHERE ST.STUDENT_NAME LIKE CONCAT(CONCAT('%', #{studentName}),'%')   
    </select>  

ただし、studentNameがnullまたは空の文字列の場合、この文はエラーを報告したり、クエリの結果が空になったりする可能性があります.このときif動的sql文を用いて先に判断し,nullまたは空の文字列に等しい値であれば,この条件の判断は行わない.
次のように変更します.
<!--     list,like   -->  
<select id=" getStudentListLikeName " parameterType="StudentEntity" resultMap="studentResultMap">  
    SELECT * from STUDENT_TBL ST   
    <if test="studentName!=null and studentName!='' ">  
        WHERE ST.STUDENT_NAME LIKE CONCAT(CONCAT('%', #{studentName}),'%')   
    </if>  
</select> 

 この場合、studentNameの値がnullまたは’’’である場合、where条件の判断は行われないので、studentNameの値がnullまたは’’’’の値である場合、この条件は付随しないので、クエリ結果はすべてである.
 パラメータはJavaのエンティティクラスであるため、すべての条件を付加することができ、使用時に柔軟である.newのようなエンティティクラスでは、その条件を制限する必要があり、対応する値を添付するだけでwhereという条件になり、逆に値を付与しなくてもwhereで判断できない.
   コードのwhereラベルは、3.2.1を参照してください.
    <!--     list,like  ,=  、=  、=  ,  where,  entity   -->  
    <select id="getStudentListWhereEntity" parameterType="StudentEntity" resultMap="studentResultMap">  
        SELECT * from STUDENT_TBL ST   
        <where>  
            <if test="studentName!=null and studentName!='' ">  
                ST.STUDENT_NAME LIKE CONCAT(CONCAT('%', #{studentName}),'%')   
            </if>  
            <if test="studentSex!= null and studentSex!= '' ">  
                AND ST.STUDENT_SEX = #{studentSex}   
            </if>  
            <if test="studentBirthday!=null">  
                AND ST.STUDENT_BIRTHDAY = #{studentBirthday}   
            </if>  
            <if test="classEntity!=null and classEntity.classID !=null and classEntity.classID!='' ">  
                AND ST.CLASS_ID = #{classEntity.classID}   
            </if>  
        </where>  
    </select>  

調べてみると、名前には「李」、男性、誕生日は「1985-05-28」、クラスは「20000000」の学生がいます.
    StudentEntity entity = new StudentEntity();   
    entity.setStudentName(" ");   
    entity.setStudentSex(" ");   
    entity.setStudentBirthday(StringUtil.parse("1985-05-28"));   
    entity.setClassEntity(classMapper.getClassByID("20000002"));   
    List<StudentEntity> studentList = studentMapper.getStudentListWhereEntity(entity);   
    for( StudentEntity entityTemp : studentList){   
        System.out.println(entityTemp.toString());   
    }  

3.2 where、set、trimラベル
3.2.1 where
ifラベルが多い場合、このような組み合わせはエラーを引き起こす可能性があります.たとえば、likeの名前は、性別などを指定します.
    <!--     list,like  ,=   -->  
    <select id="getStudentListWhere" parameterType="StudentEntity" resultMap="studentResultMap">  
        SELECT * from STUDENT_TBL ST   
            WHERE   
            <if test="studentName!=null and studentName!='' ">  
                ST.STUDENT_NAME LIKE CONCAT(CONCAT('%', #{studentName}),'%')   
            </if>  
            <if test="studentSex!= null and studentSex!= '' ">  
                AND ST.STUDENT_SEX = #{studentSex}   
            </if>  
    </select>  

  上記の例では、パラメータstudentNameがnullまたは’’’である場合、またはこのsqlが「WHERE AND」のようなキーワードの余分なエラーSQLに結合される可能性があります. この場合、where動的文を使用して解決できます.この「where」タブには、含まれるラベルに戻り値がある場合、「where」が挿入されることがわかります.また、ラベルがANDまたはORで始まる場合は削除されます. 次のように変更します.
    <!--     list,like  ,=   -->  
    <select id="getStudentListWhere" parameterType="StudentEntity" resultMap="studentResultMap">  
        SELECT * from STUDENT_TBL ST   
        <where>  
            <if test="studentName!=null and studentName!='' ">  
                ST.STUDENT_NAME LIKE CONCAT(CONCAT('%', #{studentName}),'%')   
            </if>  
            <if test="studentSex!= null and studentSex!= '' ">  
                AND ST.STUDENT_SEX = #{studentSex}   
            </if>  
        </where>  
    </select>  

3.2.2 set
update文でifラベルを使用する場合、前のifが実行されていない場合、カンマに余分なエラーが発生する可能性があります.setラベルを使用して、SETキーワードを動的に構成し、条件の末尾に追加された関連のないカンマを削除します.ifラベルが使用されていない場合、nullのパラメータがある場合、次の例でエラーが発生します.
    <!--        -->  
    <update id="updateStudent" parameterType="StudentEntity">  
        UPDATE STUDENT_TBL   
           SET STUDENT_TBL.STUDENT_NAME = #{studentName},   
               STUDENT_TBL.STUDENT_SEX = #{studentSex},   
               STUDENT_TBL.STUDENT_BIRTHDAY = #{studentBirthday},   
               STUDENT_TBL.CLASS_ID = #{classEntity.classID}   
         WHERE STUDENT_TBL.STUDENT_ID = #{studentID};   
    </update>  

 set+ifラベルを使用して変更すると、nullの場合は更新せず、データベースの元の値を維持します.次の例を示します.
    <!--        -->  
    <update id="updateStudent" parameterType="StudentEntity">  
        UPDATE STUDENT_TBL   
        <set>  
            <if test="studentName!=null and studentName!='' ">  
                STUDENT_TBL.STUDENT_NAME = #{studentName},   
            </if>  
            <if test="studentSex!=null and studentSex!='' ">  
                STUDENT_TBL.STUDENT_SEX = #{studentSex},   
            </if>  
            <if test="studentBirthday!=null ">  
                STUDENT_TBL.STUDENT_BIRTHDAY = #{studentBirthday},   
            </if>  
            <if test="classEntity!=null and classEntity.classID!=null and classEntity.classID!='' ">  
                STUDENT_TBL.CLASS_ID = #{classEntity.classID}   
            </if>  
        </set>  
        WHERE STUDENT_TBL.STUDENT_ID = #{studentID};   
    </update>  

3.2.3 trim
 trimはより柔軟な余分なキーワードのラベルであり、whereとsetの効果を実践することができます.
 where例の等価trim文:
<!--     list,like  ,=   -->  
<select id="getStudentListWhere" parameterType="StudentEntity" resultMap="studentResultMap">  
    SELECT * from STUDENT_TBL ST   
    <trim prefix="WHERE" prefixOverrides="AND|OR">  
        <if test="studentName!=null and studentName!='' ">  
            ST.STUDENT_NAME LIKE CONCAT(CONCAT('%', #{studentName}),'%')   
        </if>  
        <if test="studentSex!= null and studentSex!= '' ">  
            AND ST.STUDENT_SEX = #{studentSex}   
        </if>  
    </trim>  
</select> 

set例の等価trim文:
    <!--        -->  
    <update id="updateStudent" parameterType="StudentEntity">  
        UPDATE STUDENT_TBL   
        <trim prefix="SET" suffixOverrides=",">  
            <if test="studentName!=null and studentName!='' ">  
                STUDENT_TBL.STUDENT_NAME = #{studentName},   
            </if>  
            <if test="studentSex!=null and studentSex!='' ">  
                STUDENT_TBL.STUDENT_SEX = #{studentSex},   
            </if>  
            <if test="studentBirthday!=null ">  
                STUDENT_TBL.STUDENT_BIRTHDAY = #{studentBirthday},   
            </if>  
            <if test="classEntity!=null and classEntity.classID!=null and classEntity.classID!='' ">  
                STUDENT_TBL.CLASS_ID = #{classEntity.classID}   
            </if>  
        </trim>  
        WHERE STUDENT_TBL.STUDENT_ID = #{studentID};   
    </update>  

3.3 choose (when, otherwise)
         すべての条件を適用するのではなく、複数のオプションから1つを選択したい場合があります.MyBatisはchoose要素を提供し、whenの条件が成立するかどうかを順番に判断し、成立があればchooseは終了する.chooseのすべてのwhenの条件が満たされない場合、otherwiseのsqlが実行されます.Javaのswitch文と同様にchooseはswitch、whenはcase、otherwiseはdefaultです.         ifは(and)との関係であり、chooseはまたは(or)の関係である.
         例えば以下の例では,同様にすべての制限可能な条件を記入し,使用する.条件の順序を選択し、whenラベルの上から下へ
    <!--     list,like  、 =  、 =  、 =  ,  choose -->  
    <select id="getStudentListChooseEntity" parameterType="StudentEntity" resultMap="studentResultMap">  
        SELECT * from STUDENT_TBL ST   
        <where>  
            <choose>  
                <when test="studentName!=null and studentName!='' ">  
                        ST.STUDENT_NAME LIKE CONCAT(CONCAT('%', #{studentName}),'%')   
                </when>  
                <when test="studentSex!= null and studentSex!= '' ">  
                        AND ST.STUDENT_SEX = #{studentSex}   
                </when>  
                <when test="studentBirthday!=null">  
                    AND ST.STUDENT_BIRTHDAY = #{studentBirthday}   
                </when>  
                <when test="c