動態拼接SQL語句

來源:互聯網
上載者:User

標籤:update   測試   res   com   字元   查詢   logs   變數   add   

1.參考官方文檔
? if:字元判斷
? choose (when, otherwise):分支選擇
? trim (where, set):字串截取;其中where標籤封裝查詢條件,set標籤封裝修改條件
? foreach

2.if案例

1)在EmployeeMapper介面中添加一個方法:
//攜帶了哪個欄位,查詢條件就帶上哪個欄位的值
public List<Employee> getEmployeeByConditionIf(Employee employee);

2).如果要寫下列的SQL語句,只要是不為空白,就作為查詢條件,如下所示,這樣寫實際上是有問題的,所以我們要寫成動態SQL語句:
<select id="getEmployeeByConditionIf" resultType="com.neuedu.entity.Employee">
select *from tbl_employee where id = #{id} and user_name = #{userName} and email = #{email} and gender = #{gender}
</select>

3)用if標籤改寫為動態SQL,如下所示:

<select id="getEmployeeByConditionIf" resultType="com.neuedu.entity.Employee">select *from tbl_employee where  <!--test:判斷運算式(OGNL)OGNL參照PPT或者官方文檔。c:if test從參數中取值進行判斷遇見特殊符號,應該去寫逸出字元:參考W3CSchool>>HTML>>ISO8859  -->  <if test="id != null">id = #{id}  </if>  <if test="userName != null && userName !=‘‘">and user_name = #{userName}   </if>  <if test="email != null and email.trim() != """>and email = #{email}  </if>  <!-- ognl會進行字串和數位轉換判斷;"0"==0,"1"==1 -->  <if test="gender == 0 or gender == 1">and gender = #{gender}   </if></select>

   4).測試代碼:

@Testpublic void testGetEmployee(){EmployeeMapper mapper = openSession.getMapper(EmployeeMapper.class);Employee employee = new Employee();employee.setId(1);employee.setUserName("張三丰");employee.setEmail("[email protected]");employee.setGender(1); List<Employee> list = mapper.getEmployeeByConditionIf(employee);System.out.println(list);}

  

但是仔細來說,上面的sql語句是有問題的,當我們不給動態sql語句傳遞id值的時候,sql語句的拼裝就會有問題!
解決辦法:
       1>.給where後面加上1=1,以後的條件都可以使用and xxx了
       2>.mybatis可以使用where標籤來將所有的查詢條件包括在內。mybatis就會將where標籤中拼裝的sql,
         多出來的and或者or去掉!//需要注意:where標籤只會去掉第一個多出來的and或者or
      3.>也就是說使用where標籤有時候還是不能解決問題的,那怎麼辦呢?我們這裡可以使用trim標籤!

2.trim標籤:可以自訂字串的截取規則

<select id="getEmployeeByConditionIf" resultType="com.neuedu.entity.Employee">select *from tbl_employee<!-- 後面多出的and或者or where標籤不能夠解決   prefix="":首碼:trim標籤體重是整個字串拼串後的結果。 prefix給拼串後的整個字串加一個首碼   prefixOverrides="":首碼覆蓋:去掉整個字串前面多餘的字元   suffix="":尾碼 suffix給拼串後的整個字串加一個尾碼   suffixOverrides="": 尾碼覆蓋:去掉整個字串後面多餘的字元 --> <trim prefix="where" suffixOverrides="and">  <if test="id != null">id = #{id} and  </if>  <if test="userName != null && userName !=‘‘">user_name = #{userName} and    </if>  <if test="email != null and email.trim() != """>email = #{email} and   </if>  <!-- ognl會進行字串和數位轉換判斷;"0"==0,"1"==1 -->  <if test="gender==0 or gender==1">   gender = #{gender}  </if></trim></select>

  3.choose標籤:分支選擇,類似於Java中的帶了break的switch...case

     

choose (when, otherwise):如果帶了id,就用id查,如果帶了userName就用userName查,只會進入其中一個!

案例示範:
     1>.在EmployeeMapper介面中添加一個方法:
            public List<Employee> getEmployeeByConditionChoose(Employee employee);
        2>.sql對應檔

<!-- public List<Employee> getEmployeeByConditionChoose(Employee employee); --><select id="getEmployeeByConditionChoose" resultType="com.neuedu.entity.Employee">select *from tbl_employee<where><!-- 如果帶了id,就用id查,如果帶了userName就用userName查,只會進入其中一個! --><choose><when test="id != null">id = #{id}</when><when test="userName != null">user_name like #{userName}</when><when test="email != null">   email = #{email}</when><otherwise>1=1</otherwise></choose></where></select>

  

4.trim 中的set標籤(where, set):字串截取;其中where標籤封裝查詢條件,set標籤封裝修改條件
set元素會動態前置set關鍵字,同時也會消除無關的逗號。

        1).在EmployeeMapper中添加一個更新的方法,如下所示:
              public void updateEmp(Employee employee);
         2)在sql對應檔中,填寫相應的sql語句,如下所示【set標籤可以將欄位後面的逗號去掉】:

<update id="updateEmp">update tbl_employee <set><if test="userName != null">user_name = #{userName},</if><if test="email != null">email = #{email},</if><if test="gender != null">gender = #{gender},</if></set>where id = #{id}</update>

  測試類別代碼為:

@Testpublic void testGetEmployee(){EmployeeMapper mapper = openSession.getMapper(EmployeeMapper.class);Employee employee = new Employee();employee.setId(1);employee.setUserName("哈哈");employee.setEmail("[email protected]");employee.setGender(1);mapper.updateEmp(employee);}//當然上面的set標籤我們也可以使用trim標籤來代替,如下所示:<update id="updateEmp">update tbl_employee <trim prefix="set" suffixOverrides=","><if test="userName != null">user_name = #{userName},</if><if test="email != null">email = #{email},</if><if test="gender != null">gender = #{gender},</if></trim>where id = #{id}</update>

  5.foreach:遍曆元素

動態SQL的另一個常用的操作是需要對一個集合進行遍曆,通常在構建in條件陳述式的時候!
foreach元素允許指定一個集合,聲明集合項目和索引變數,並可以指定開閉匹配的字串以及在迭代之間放置分隔字元。

案例示範:
         1>.在EmployeeMapper介面中加入一個方法,如下所示:
            public List<Employee> getEmpsByConditionForeach(@Param("ids") List<Integer> ids);
         2>.在MyBatis的sql對應檔中寫相應的代碼:

<!-- public List<Employee> getEmpsByConditionForeach(List<Integer> ids); --><select id="getEmpsByConditionForeach" resultType="com.neuedu.entity.Employee">select * from  tbl_employee where id in<!-- collection:指定要遍曆的集合item:將當前遍曆出的元素賦值給指定的變數separator:每個元素之間的分隔字元open:遍曆出所有記過拼接一個開始的字元close:遍曆出所有結果拼接一個結束的字元 --><foreach collection="ids" open="(" close=")" separator="," item="id">#{id}</foreach></select>

     3.>測試類別代碼為:

@Testpublic void testGetEmployee(){EmployeeMapper mapper = openSession.getMapper(EmployeeMapper.class);List<Integer> asList = Arrays.asList(1,2,3,4);List<Employee> emps = mapper.getEmpsByConditionForeach(asList);for (Employee employee : emps) {System.out.println(employee);}}

  

foreach標籤還可以用於批量儲存資料,如下所示:

1.在EmployeeMapper介面類中添加批量插入的方法:
public void addEmps(@Param("emps") List<Employee> emps);

2.在EmployeeMapper.xml的sql對應檔中添加響應的語句:

<!-- public void addEmps(@Param("emps") List<Employee> emps); -->
<!-- MySQL下批量儲存:可以foreach遍曆,mysql支援values(),(),()文法 -->
<insert id="addEmps">
INSERT INTO tbl_employee(user_name,gender,email,d_id) VALUES
<foreach collection="emps" item="emp" separator=",">
(#{emp.userName},#{emp.gender},#{emp.email},#{emp.depart.id})
</foreach>
</insert>
3.測試代碼:
@Test
public void testGetEmployee(){
EmployeeMapper mapper = openSession.getMapper(EmployeeMapper.class);
List<Employee> emps = new ArrayList<Employee>();
emps.add(new Employee(0, 1, "allen", "[email protected]", new Department(1)));
emps.add(new Employee(0, 0, "tom", "[email protected]", new Department(2)));
emps.add(new Employee(0, 1, "mux", "[email protected]", new Department(1)));
mapper.addEmps(emps);
}

動態拼接SQL語句

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.