SQLステートメントの条件では、セキュリティ判断が必要な場合があります。たとえば、特定の条件に応じてクエリするときに渡されたパラメーターが空の場合、この時点でクエリの結果は空になる可能性があります。おそらく、パラメーターを空にする必要がある場合、すべての情報が見つかります。 OracleのシーケンスとMySQL関数を使用して、IDを生成します。この時点で、動的SQLを使用できます。以下はすべて、mysqlの構文と関数(文字列リンク関数concatなど)です。
SelectKeyタグ
INSERTステートメントでは、Oracleは多くの場合、MySQLのシーケンスと関数を使用して挿入テーブルの主要なキーを自動的に生成し、この生成されたプライマリキーを返すにはメソッドが必要です。この効果は、MyBatisのSelectKeyタグを使用して実現できます。次の例は、MySQLデータベースカスタム関数Nextval( 'student')を使用してキーを生成し、Passed EntityクラスのStudentIDプロパティに設定することです。したがって、この方法を実行した後、エッジはこのエンティティクラスを通じて生成されたキーを取得できます。
<! - 学生自動プライマリキーを挿入 - > <ID = "createStudentAutokey" parametertype = "liming.student.manager.data.model.studententity" keyproperty = "desutent"> <selectkey keyproperty = "desudent" resudent "resulttype =" string = " Student_tbl(Student_id、sustent_sex、desuted_birthday、sudent_photo、class_id、place_id)values(#{sudinedname}、#{sudintsbirthday}、{sudentsphoto、javatype = byte []、jdbctype typeHandler = org.apache.ibatis.type.blobtypehandler}、#{classId}、#{placeId})</insert>
インターフェイスメソッドを呼び出し、自動キー生成を取得します
StudentEntity Entity = new StudentEntity(); entity.setStudentName( "Hello Dawn"); entity.setStudentsex(1); entity.setStudentBirthday(dateutil.parse( "1985-05-28")); entity.setclassid( "20000001"); entity.setplaceid( "70000001"); this.dynamicsqlmapper.createstudentautokey(entity); System.out.println( "新しい学生ID:" + entity.getStudentid());
SelectKeyステートメントプロパティ構成の詳細:
| 財産 | 説明する | 値を取得します |
| keyproperty | SelectKeyステートメントによって生成される結果に対して設定する必要がある属性。 | |
| resultType | 結果タイプを生成します。 MyBatisでは、文字列やINTタイプなどの基本的なデータ型を使用できます。 | |
| 注文 | 1:前に、最初にプライマリキーが選択され、次にキープロパティが設定され、挿入ステートメントが実行されます。 2:後、最初に挿入ステートメントを実行し、次にSelectKeyステートメントを実行します。 | 前に 後 |
| StatementType StatementType | MyBatisは、声明、準備、および作成可能な声明フォームをサポートし、声明、準備、およびcallable -statementの応答に対応しています。 | 声明 準備した 呼び出すことができます |
タグの場合
タグを多くのタイプのSQLステートメントで使用できる場合は、例としてクエリを取りましょう。まず、非常に普通のクエリを見てみましょう。
<
ただし、現時点でStudentNameまたはStudentSexがnullである場合、このステートメントはエラーを報告する可能性が高いか、クエリの結果が空です。この時点で、IF Dynamic SQLステートメントを使用して、最初に判断を下します。値が空の文字列にヌルまたは等しい場合、この状態で判断を下し、柔軟性を高めません。
パラメーターは、エンティティクラスの学生の意見です。エンティティクラスのすべての属性は判断され、それらが空でない場合、判断条件が実行されます。
<! - 2 if(判断パラメーター) - エンティティクラスが条件として空でないプロパティを使用 - > <select id = "getstudentlist_if" resultmap_studenterty "parametertype =" liming.student.student.manager.data.model.studententity "> St.student_birthday、St.student_photo、St.class_id、St.place_id from Student_tbl st where where <if <if <"sudentnname!= null"> st.student_name like concat( '%'、#{desudentname、jdbctype = varchar})、 '%およびSt.student_sex =#{sustentsex、jdbctype = integer} </if> <if> <"studentbirthday!= null"> and st.student_birthday = {studentbirthday、jdbctype = date} </if> <> "classid! jdbctype = varchar} </if> <if test = "clessentity!= null and crassentity.classid!= null and classentity.classid!= ''"> and s.bctype.classid、jdbctype = varchar} < jdbctype = varchar} </if> <if test = "placeentity!= null and placeNtity.placeId.placeId.placeId.placeid. '"> and st.place_id = {placeent.placeid、jdbctype = varchar} </if> if> <> "student! jdbctype = varchar} </if> </select>使用する場合、使用する場合は、新しいエンティティクラスの条件を制限する必要があります。条件に対応する値を添付するだけです。それどころか、値を割り当てなければ、どこで判断することはできません。
public void select_test_2_1(){studententity entity = new StudentEntity(); entity.setStudentName( ""); entity.setStudentsex(1); entity.setStudentBirthday(dateutil.parse( "1985-05-28")); entity.setclassid( "20000001"); //entity.setPlaceId("70000001 "); List <StudentEntity> list = this.dynamicsqlmapper.getStudentlist_if(entity); for(studentsity e:list){system.out.println(e.tostring()); }}
+条件付き判断の場合
このような組み合わせは、タグの場合、より多くを使用する条件でエラーを引き起こす可能性があります。 Javaコードが次のように呼び出された場合、例として3.1でクエリステートメントを取得しましょう。
@test public void select_test_2_1(){studententity entity = new StudentEntity(); entity.setStudentName(null); entity.setStudentsex(1); List <StudentEntity> list = this.dynamicsqlmapper.getStudentlist_if(entity); for(studentsity e:list){system.out.println(e.tostring()); }}上記の例がnullの場合、Student_name列は審査されず、「WHEREおよび」キーワードの追加エラーSQLが直接導出されます。
この時点で、動的なステートメントを使用して問題を解決することができます。この「ここで」タグには、タグが含まれている場合、返品値がある場合、「where」が挿入されることがわかります。さらに、タグによって返されたコンテンツがから始まる場合、またはまたは削除されます。
上記の例は次のように変更されています。
< St.student_birthday、St.student_photo、St.class_id、St.place_id from Student_tbl st <where> <if studentname!= null」 "> and St.student_sex =#{sustentsex、jdbctype = integer} </if> <if> <if>" StudentBirthday!= null "> and s.student_birthday = {studentbirthday、jdbctype = date} </if> <if> <" classid!= "nurr and '' jdbctype = varchar} </if> <if test = "classentity!= null and crassentity.classid.classid!= ''"> and st.class_id =#{classentity.classid、jdbctype = varchar} </if> <test = "placeid!= null and!= '" "> and s.place_id jdbceid、 </if> <if> <test = "placeentity!= null and placeentity.placeid!= null and placeNtity.placeid.placeid.placeId. ''"> and {placeNtity.placeID、jdbctype = varchar} </if> <if> <if> "dustentid!= null and sudentid!= '" </if> </where> </select> if + setのステートメントを更新します
IFタグが更新ステートメントで使用されていない場合、パラメーターnullがある場合、エラーが発生します。
更新ステートメントでタグを使用する場合、前のIFが実行されない場合、コンマ冗長エラーが発生する可能性があります。セットタグを使用して、セットキーワードを動的に構成し、条件の終わりに追加された無関係なコンマを削除します。
if+セットタグで変更した後、アイテムがnullの場合、更新されませんが、元のデータベース値は維持されます。次の例:
< #{sudentnname}、</if> <if> "sustentsex!= null and sustentsex!= ''"> sustent_tbl.student_sex =#{sustedsex}、</if> <if> <"desudentbirthday!= null"> sudent_tbl.student_birthday =#{desudentbirthday < "> desudent_tbl.student_photo =#{sustentphoto、javatype = byte []、jdbctype = blob、typehandler = org.apache.ibatis.type.blobtypehandler}、</if> <if> <if test =" classid!= '' "if sudunts_id_id_id_id = < != '' '"> sustent_tbl.place_id =#{placeid} </if> </set> where sustent_tbl.student_id =#{sustentid}; </update>タグ/セットタグの代わりに +トリムの場合
トリムは、冗長なキーワードタグに移動するためのより柔軟な場所であり、場所と設定の効果を練習できます。
どこではなくトリム
< St.Place_id from Student_tbl st <trim prefix = "where" prefixoverrides = "and |または"> <if testent = "sudentName!= null"> st.student_name like concat( '%'、#{sudintsname、jdbctype = varchar})、 '%')、 '%')< St.student_sex =#{sustentsex、jdbctype = integer} </if> <if> "sustentbirthday!= null"> and s.student_birthday = {desudentbirthday、jdbctype = date} </if> <if> <> "classid!= null and" classid! jdbctype = varchar} </if> <if test = "clessentity!= null and crassentity.classid!= null and classentity.classid!= ''"> and s.bctype.classid、jdbctype = varchar} < jdbctype = varchar} </if> <if test = "placeentity!= null and placeNtity.placeId.placeId.placeId.placeid. '"> and st.place_id = {placeent.placeid、jdbctype = varchar} </if> if> <> "student! jdbctype = varchar} </if> </trim> </select>
セットの代わりにトリム
<! - if/trim set(Judgement Parameter) - エンティティクラスが空でない属性を更新 - > <update id = "updatestudent_if_trim" parametertype = "liming.student.manager.data.model.studententity"> update susteent_tbl! != '' "> desuted_tbl.student_name =#{sustentname}、</if> <if> <if>" sudentsex!= null and sustentsex!= '' "> sudent_tbl.student_sex =#{desudentsex}、</if> <if> <> sudentbirthday #{desudentbirthday}、</if> <if test = "sudentphoto!= null"> sudent_tbl.student_photo =#{desudentphoto、javatype = byte []、jdbctype = blob、typehandler = org.apache.ibatis.type.blobtepehhnedler}、 'if> Student_tbl.class_id =#{classid}、</if> <if> <if> "placeid!= ''"> sustent_tbl.place_id =#{placeid} </if> </trim> where desudent_tbl.student_id =#{desudent} </update>選択(いつ、それ以外)
すべての条件を適用したくない場合がありますが、複数のオプションから1つを選択するだけです。 IFタグを使用する場合、テストの式が真である限り、IFタグの条件が実行されます。 MyBatisは選択要素を提供します。タグが(および)との関係であり、選択が(または)との関係である場合。
選択タグは、タグが順番に有効である場合、内部内のテスト条件が内部のテスト条件を判断することです。有効な場合、選択は終了します。選択したすべての条件が満たされていない場合、それ以外の場合はSQLが実行されます。 JavaのSwitchステートメントと同様に、Switch、場合はSwitch、およびその他のデフォルトを選択します。
たとえば、次の例は、制限されて使用できるすべての条件を書き留めます。 [タグ時に上から下]にテストを使用して、SQL実行を選択します。セキュリティ上の考慮事項については、選択を締めくくる場所を使用し、エラーよりも多くのキーワードを配置します。
<! - 6 choose(判断パラメーター) - 条件として順番に空にないエンティティクラスの最初のプロパティを取得 - > <select id = "getStudentList_choose" resultmap_studententity "parametertype =" liming.student.manager.data.model.studentity " St.student_sex、St.student_birthday、St.student_photo、St.class_id、St.class_id from Student_tbl st <where> <coice> <when test = "sudtentnaname!= null"> st.student_name like concat(concat( '%'、#{sudentName、jdbctype = varchar = != null and Studentsex!= '' "> and St.student_sex =#{sudentsex、jdbctype = integer} </when> <when>" studentbirthday!= null "> and s.student_birthday =#{desudentbirthday、jdbctype = null! St.class_id = {classid、jdbctype = varchar} </when> <test = "clessentity!= null and classentity.classid!= ''"> and st.class_id = {classid.classid、jdbctype = varchar} </when test = "placeid!= placeid! jdbctype = varchar} </when> <when test = "placeentity!= null and placentity.placeid.placeid.placeid.placeid.!= ''"> {placeent.placeid、jdbctype = varchar} </when when when> <when> "studentid!= null and studid! jdbctype = varchar} </when> <sids> </rething> </chood> </where> </select>
foreach
動的SQLは、主にコレクションを繰り返すために、通常は条件で非常に必要です。リストインスタンスは「リスト」をキーとして使用し、配列インスタンスは「配列」をキーとして使用します。
foreach要素は非常に強力であり、コレクションを指定し、要素本体内で使用できるコレクションアイテムとインデックス変数を宣言することができます。また、開いた文字列と閉じた文字列を指定して、繰り返しに分離器を配置することもできます。この要素は非常にスマートであり、偶然に余分なセパレーターを追加しません。
注:MyBatisにパラメーターオブジェクトとしてリストインスタンスまたは配列を渡すことができます。これを行うと、MyBatisは名前をキーとして自動的にマップにラップします。リストインスタンスは「リスト」をキーとして使用し、配列インスタンスは「配列」をキーとして使用します。
このセクションでは、XML構成ファイルとXMLマッピングファイルについて説明します。次のセクションでは、Java APIについて詳しく説明するため、作成した最も効率的なマッピングを取得できます。
1。パラメーターの例を配列として記述します
インターフェースのメソッド宣言:
パブリックリスト<StudtentInentity> getStudEntListByClassIDS_FOREACH_ARRAY(String [] ClassIds);
動的SQLステートメント:
<! - 7.1 foreach(ループアレイパラメーター) - 条件として - > <select id = "getstudentlistbyclassids_foreach_array" resultmap_studententity "> student_tbl stからst.class_id in <foreach collection = "array" item = "classids" open = "(" separator = "、" close = ")">#{classids} </foreach> </select>
コードをテストして、200001と20000002の2つのクラスで学生を照会します。
@test public void test7_foreach(){string [] classids = {"20000001"、 "20000002"};リスト<StudentEntity> list = this.dynamicsqlmapper.getStudentListByClassids_Foreach_Array(classIds); for(studentsity e:list){system.out.println(e.tostring()); }} 2。パラメーターリストの例を書きます
インターフェースのメソッド宣言:
public List <StudtentInentity> getStudEntListByClassIDS_FOREACH_LIST(List <String> classIdlist);
動的SQLステートメント:
<! - 7.2 foreach(loop list <string> parameter) - inther in in in in - > <select id = "getstudentlistbyclassids_foreach_list" resultmap_studententity "> St.Place_id from Student_tbl st where where s.class_id in <foreach collection = "list" item = "classidlist" open = "(" separator = "、" close = ")">#{classidlist} </foreach> </select>
コードをテストして、200001と20000002の2つのクラスで学生を照会します。
@test public void test7_2_foreach(){arraylist <string> classidlist = new arraylist <string>(); classidlist.add( "20000001"); classidlist.add( "20000002"); List <StudentEntity> list = this.dynamicsqlmapper.getStudentListbyClassids_foreach_list(classIdlist); for(studentsity e:list){system.out.println(e.tostring()); }}3.パラメーターを自分でマップのタイプにカプセル化する
<select id = "dynamicforeach3test" resultType = "blog"> select * from t_blog from t_blog from "%"#{title} "%"とid in <foreach collection = "ids" item = "item" open = "(" deparator = "、" close = ")"> {ite上記のコレクションの値はIDSであり、これは渡されたパラメーターマップの鍵であり、対応するマッパーコード:
public List <blog> dynamicforeach3test(map <string、object> params);
対応するテストコード:
@test public void dynamicforeach3test(){sqlsession session = util.getsqlsessionfactory()。opensession(); blogmapper blogmapper = session.getMapper(blogmapper.class);最終リスト<integer> ids = new arraylist <integer>(); ids.add(1); ids.add(2); ids.add(3); ids.add(6); ids.add(7); ids.add(9); map <string、object> params = new hashmap <string、object>(); params.put( "ids"、ids); params.put( "title"、 "china");リスト<Blog> blogs = blogmapper.dynamicforeach3test(params); for(blog blog:blogs)system.out.println(blog); session.close(); }