久久精品人人爽,华人av在线,亚洲性视频网站,欧美专区一二三

MySQL動態SQL拼接怎么實現

133次閱讀
沒有評論

共計 6986 個字符,預計需要花費 18 分鐘才能閱讀完成。

這篇“MySQL 動態 SQL 拼接怎么實現”文章的知識點大部分人都不太理解,所以丸趣 TV 小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“MySQL 動態 SQL 拼接怎么實現”文章吧。

一、動態 sql 拼接目標

能夠使用 mybatis 的標簽實現動態 SQL 拼接

分析

我們在前邊的學習過程中,使用的 SQL 語句都非常簡單。而在實際業務開發中,我們的 SQL 語句通常是動態拼接而成的,比如:條件搜索功能的 SQL 語句。

#  提供了一個功能:用戶可以在頁面上根據 username、sex、address 進行搜索
#  用戶輸入的搜索條件:可以是一個條件,也可能是兩個、三個
#  只輸入一個條件:姓名是 王 
SELECT * FROM USER WHERE username LIKE  % 王 % 
#  只輸入一個條件:性別是“男”SELECT * FROM USER WHERE sex =  男 
#  輸入兩個條件:姓名“王”,性別“男”SELECT * FROM USER WHERE username LIKE  % 王 %  AND sex =  男 
#  輸入三個條件:姓名“王”,性別“男”,地址“北京”SELECT * FROM USER WHERE username LIKE  % 王 %  AND sex =  男  AND address LIKE  % 北京 %

在 Mybatis 中,SQL 語句是寫在映射配置的 XML 文件中的。Mybatis 提供了一些 XML 的標簽,用來實現動態 SQL 的拼接。

常用的標簽有:

if /if:用來進行判斷,相當于 Java 里的 if 判斷

where /where:通常和 if 配合,用來代替 SQL 語句中的 where 1=1

foreach /foreach:用來遍歷一個集合,把集合里的內容拼接到 SQL 語句中。例如拼接:in (value1, value2, …)

sql /sql:用于定義 sql 片段,達到重復使用的目的

講解 1. 準備 Mybatis 環境

創建 java 項目,導入 jar 包;準備 JavaBean

創建映射器接口 UserDao

創建映射配置文件 UserDao.xml

創建全局配置文件 SqlMapConfig.xml

創建日志配置文件 log4j.properties

2. if 標簽:語法介紹

if test= 判斷條件,使用 OGNL 表達式進行判斷 
 SQL 語句內容,  如果判斷為 true,這里的 SQL 語句就會進行拼接 /if

使用示例

根據用戶的名稱和性別搜索用戶信息。把搜索條件放到 User 對象里,傳遞給 SQL 語句

映射器接口 UserDao 上加方法

package com.demo.dao;import com.demo.domain.User;import java.util.List;public interface UserDao {
 /**
 *  根據 username 和 sex 搜索用戶
 * @param user  封裝了搜索條件的 User 對象
 * @return  搜索的結果
 */
 List User  search2(User user);}

映射文件 UserDao.xml 里配置 statement

?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= com.itheima.dao.UserDao 
  !--
 if 標簽:用于條件判斷
  語法:if test= 用 OGNL 表達式判斷   如果判斷為 true,這里的內容會拼接上去   /if 
  注意:標簽里寫 OGNL 表達式,不要再加 #{}、${}
  常用的 OGNL 表達式:  比較:,  ,  =,  =, ==, !=  或者  gt, lt, gte, lte, eq, neq
  邏輯:,||,!  或者  and, or, not
  調用方法:username.length(), list.size()
 -- 
  select id= search2  resultType= User 
 select * from user where 1=1  if test= username != null and username.length() 0 
 and username like  % #{username} %   /if 
  if test= sex != null and sex.length() 0 
 and sex = #{sex}  /if 
  /select /mapper

功能測試,在測試類里加測試方法

package com.demo;import com.demo.dao.UserDao;import com.demo.domain.User;import org.apache.ibatis.io.Resources;import org.apache.ibatis.session.SqlSession;import org.apache.ibatis.session.SqlSessionFactory;import org.apache.ibatis.session.SqlSessionFactoryBuilder;import org.junit.After;import org.junit.Before;import org.junit.Test;import java.io.IOException;import java.io.InputStream;import java.util.List;public class SqlTest {
 private UserDao userDao;
 private SqlSession session;
 private InputStream is;
 /**
 *  要求:根據 username 和 sex 搜索用戶
 *  搜索條件放到 user 對象里
 */
 @Test
 public void testSearch(){ User user = new User();
 // user.setUsername( 王 
 // user.setSex( 男 
 List User  userList = userDao.search2(user);
 userList.forEach(System.out::println);
 }

 public void init() throws IOException {  //1.  讀取全局配置文件  is = Resources.getResourceAsStream( SqlMapConfig.xml  //2.  得到一個 SqlSession 對象  SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);  session = factory.openSession();  userDao = session.getMapper(UserDao.class);  }  @After  public void destroy() throws IOException { session.close();  is.close();  }}

3. where 標簽語法介紹

在剛剛的練習的 SQL 語句中,我們寫了 where 1=1。如果不寫的話,SQL 語句會出現語法錯誤。Mybatis 提供了一種代替 where 1= 1 的技術:where /where 標簽。

代碼示例

把上一章節的實現代碼進行優化,使用 where /where 標簽代替 where 1=1

映射器 UserDao 的 search2 方法:已有,不用修改

/**
 *  根據 username 和 sex 搜索用戶
 * @param user  封裝了搜索條件的 User 對象
 * @return  搜索的結果
 */List User  search2(User user);

在映射文件 UserDao.xml 里修改 SQL 語句

!--
 where 標簽:讓 Mybatis 幫我們生成一個 where 關鍵字
 Mybatis 會智能判斷:  如果一個條件都沒有,就不生成 where 關鍵字
  如果有條件,會判斷是否有多余的 and 關鍵字,把多余的 and 去掉
  注意:建議把所有的 where 條件都放到 where 標簽里邊
 -- select id= search2  resultType= User 
 select * from user  where 
  if test= username != null and username.length() 0 
 and username like  % #{username} %   /if 
  if test= sex != null and sex.length() 0 
 and sex = #{sex}  /if 
  /where /select

在測試類里進行功能測試:測試方法不需要修改

@Testpublic void testSearch(){ User user = new User();
 // user.setUsername( 王 
 // user.setSex( 男 
 List User  userList = userDao.search2(user);
 userList.forEach(System.out::println);}

4. foreach 標簽語法介紹

foreach 標簽,通常用于循環遍歷一個集合,把集合的內容拼接到 SQL 語句中。例如,我們要根據多個 id 查詢用戶信息,SQL 語句:

select * from user where id = 1 or id = 2 or id = 3;select * from user where id in (1, 2, 3);

假如我們傳參了 id 的集合,那么在映射文件中,如何遍歷集合拼接 SQL 語句呢?可以使用 foreach 標簽實現。

!--
foreach 標簽:collection:被循環遍歷的對象,使用 OGNL 表達式獲取,注意不要加 #{}
 open:循環之前,拼接的 SQL 語句的開始部分
 item:定義變量名,代表被循環遍歷中每個元素,生成的變量名
 separator:分隔符
 close:循環之后,拼接 SQL 語句的結束部分
 標簽體:使用 #{OGNL} 表達式,獲取到被循環遍歷對象中的每個元素
-- foreach collection=  open= id in( item= id  separator= ,  close=) 
 #{id} /foreach

使用示例

有搜索條件類 QueryVO 如下:

package com.itheima.domain;public class QueryVO { private Integer[] ids;
 public Integer[] getIds() {
 return ids;
 }
 public void setIds(Integer[] ids) {
 this.ids = ids;
 }}

在映射器 UserDao 里加方法

/**
 * QueryVO 里有一個 Integer[] ids
 *  要求:根據 ids 查詢對應的用戶列表
 */List User  search3(QueryVO vo);

在映射文件 UserDao.xml 里配置 statement

  !--
 foreach 標簽:用于循環遍歷
 collection:被循環的集合 / 數組
 item:定義一個變量
 separator:定義拼接時的分隔符
 open:拼接字符串時的開始部分
 close:拼接字符串時的結束部分
  相當于  for(Integer id: ids){}
 select * from user where id in(41, 42, 45)
 -- 
  select id= search3  resultType= User 
  !--select * from user where id in(41, 42, 45)-- 
 select * from user where  foreach collection= ids  open= id in( item= id  separator= ,  close=) 
 #{id}  /foreach 
  /select

功能測試

 @Test
 public void testSearch3(){ QueryVO vo = new QueryVO();
 vo.setIds(new Integer[]{41,42,43,44,45});
 List User  userList = userDao.search3(vo);
 userList.forEach(System.out::println);
 }

5. sql 標簽

在映射文件中,我們發現有很多 SQL 片段是重復的,比如:select * from user。Mybatis 提供了一個 sql 標簽,把重復的 SQL 片段抽取出來,可以重復使用。

語法介紹

在映射文件中定義 SQL 片段:

sql id= 唯一標識 sql 語句片段 /sql

在映射文件中引用 SQL 片段:

include refid= sql 片段的 id /include

使用示例

在查詢用戶的 SQL 中,需要重復編寫:select * from user。把這部分 SQL 提取成 SQL 片段以重復使用

要求:QueryVO 里有 ids,user 對象。根據條件進行搜索

修改 QueryVO,增加成員變量 user

package com.itheima.domain;/**
 * @author liuyp
 * @date 2021/09/07
 */public class QueryVO { private Integer[] ids;
 private User user;
 //get/set 方法……}

在映射器 UserDao 里加方法

 /**
 *  動態 SQL 拼接的綜合應用:if、where、foreach
 *  要求:QueryVo 里有 ids、username、sex 值,根據這些值進行搜索
 */
 List User  search4(QueryVO vo);

在映射文件 UserDao.xml 里配置 statement

select id= search4  resultType= User 
  !--select * from user-- 
  include refid= selUser / 
  where 
  if test= ids != null and ids.length   0 
  foreach collection= ids  open= and id in( item= id  separator= ,  close=) 
 #{id}  /foreach 
  /if 
  !-- if test= user != null 
  if test= user.username != null and user.username.length()   0 
 and username like  % #{user.username} % 
  /if 
  if test= user.sex != null and user.sex.length()   0 
 and sex = #{user.sex}
  /if 
  /if -- 
  include refid= userCondition / 
  /where /select !--
 sql 標簽:用于定義一個 sql 片段
 include 標簽:什么時候要引用某個 SQL 片段,就使用 include 標簽
  注意:引入 SQL 片段之后,最終的 SQL 語句必須要完全符合語法
 -- sql id= selUser select * from user /sql sql id= userCondition 
  if test= user != null 
  if test= user.username != null and user.username.length()   0 
 and username like  % #{user.username} %   /if 
  if test= user.sex != null and user.sex.length()   0 
 and sex = #{user.sex}  /if 
  /if /sql

在測試類里加測試方法

 @Test
 public void testSearch4(){ QueryVO vo = new QueryVO();
 vo.setIds(new Integer[]{41,42,43,44,45});
 // User user = new User();
 // user.setUsername( 王 
 // user.setSex( 男 
 // vo.setUser(user);
 List User  userList = userDao.search4(vo);
 userList.forEach(System.out::println);
 }

以上就是關于“MySQL 動態 SQL 拼接怎么實現”這篇文章的內容,相信大家都有了一定的了解,希望丸趣 TV 小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注丸趣 TV 行業資訊頻道。

正文完
 
丸趣
版權聲明:本站原創文章,由 丸趣 2023-07-13發表,共計6986字。
轉載說明:除特殊說明外本站除技術相關以外文章皆由網絡搜集發布,轉載請注明出處。
評論(沒有評論)
主站蜘蛛池模板: 长治市| 黄石市| 凤凰县| 瑞丽市| 三原县| 博湖县| 商都县| 石城县| 东宁县| 乌海市| 五寨县| 仙居县| 尉犁县| 萍乡市| 威宁| 宜阳县| 辽宁省| 习水县| 德安县| 苍山县| 油尖旺区| 横峰县| 自贡市| 塘沽区| 宁都县| 随州市| 彰武县| 金阳县| 河北区| 四平市| 鹤峰县| 南安市| 铜鼓县| 潜江市| 静海县| 海丰县| 兴义市| 朝阳市| 金昌市| 临湘市| 高陵县|