欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

MySQL動態(tài)SQL拼接實例詳解

 更新時間:2022年12月15日 12:42:39   作者:一切如你i  
動態(tài)SQL呢?首先是SQL語句,是根據(jù)條件來拼接SQL,下面這篇文章主要給大家介紹了關(guān)于MySQL動態(tài)SQL拼接的相關(guān)資料,文中通過實例代碼介紹的非常詳細(xì),需要的朋友可以參考下

目標(biāo)

能夠使用mybatis的標(biāo)簽實現(xiàn)動態(tài)SQL拼接

分析

我們在前邊的學(xué)習(xí)過程中,使用的SQL語句都非常簡單。而在實際業(yè)務(wù)開發(fā)中,我們的SQL語句通常是動態(tài)拼接而成的,比如:條件搜索功能的SQL語句。

# 提供了一個功能:用戶可以在頁面上根據(jù)username、sex、address進(jìn)行搜索
# 用戶輸入的搜索條件:可以是一個條件,也可能是兩個、三個

# 只輸入一個條件:姓名是"王"
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的標(biāo)簽,用來實現(xiàn)動態(tài)SQL的拼接。

? 常用的標(biāo)簽有:

  • <if></if>:用來進(jìn)行判斷,相當(dāng)于Java里的if判斷
  • <where></where>:通常和if配合,用來代替SQL語句中的where 1=1
  • <foreach></foreach>:用來遍歷一個集合,把集合里的內(nèi)容拼接到SQL語句中。例如拼接:in (value1, value2, ...)
  • <sql></sql>:用于定義sql片段,達(dá)到重復(fù)使用的目的

講解

1. 準(zhǔn)備Mybatis環(huán)境

  • 創(chuàng)建java項目,導(dǎo)入jar包;準(zhǔn)備JavaBean
  • 創(chuàng)建映射器接口UserDao
  • 創(chuàng)建映射配置文件UserDao.xml
  • 創(chuàng)建全局配置文件SqlMapConfig.xml
  • 創(chuàng)建日志配置文件log4j.properties

2. <if>標(biāo)簽:

語法介紹

<if test="判斷條件,使用OGNL表達(dá)式進(jìn)行判斷">
	SQL語句內(nèi)容, 如果判斷為true,這里的SQL語句就會進(jìn)行拼接
</if>

使用示例

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

映射器接口UserDao上加方法

package com.demo.dao;
import com.demo.domain.User;
import java.util.List;

public interface UserDao {
    /**
     * 根據(jù)username和sex搜索用戶
     * @param user 封裝了搜索條件的User對象
     * @return 搜索的結(jié)果
     */
    List<User> search1(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標(biāo)簽:用于條件判斷
        語法:<if test="用OGNL表達(dá)式判斷"> 如果判斷為true,這里的內(nèi)容會拼接上去 </if>
        注意:標(biāo)簽里寫OGNL表達(dá)式,不要再加#{}、${}
        常用的OGNL表達(dá)式:
            比較:>, <, >=, <=, ==, != 或者 gt, lt, gte, lte, eq, neq
            邏輯:&&,||,! 或者 and, or, not
            調(diào)用方法:username.length(),  list.size()
    -->
    <select id="search1" 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;

    /**
     * 要求:根據(jù)username和sex搜索用戶
     *      搜索條件放到user對象里
     */
    @Test
    public void testSearch(){
        User user = new User();
        // user.setUsername("王");
        // user.setSex("男");

        List<User> userList = userDao.search1(user);
        userList.forEach(System.out::println);
    }

    @Before
    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>標(biāo)簽

語法介紹

在剛剛的練習(xí)的SQL語句中,我們寫了where 1=1。如果不寫的話,SQL語句會出現(xiàn)語法錯誤。Mybatis提供了一種代替where 1=1的技術(shù):<where></where>標(biāo)簽。

代碼示例

? 把上一章節(jié)的實現(xiàn)代碼進(jìn)行優(yōu)化,使用<where></where>標(biāo)簽代替where 1=1

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

/**
 * 根據(jù)username和sex搜索用戶
 * @param user 封裝了搜索條件的User對象
 * @return 搜索的結(jié)果
 */
List<User> search1(User user);

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

<!--
    where標(biāo)簽:讓Mybatis幫我們生成一個where關(guān)鍵字
        Mybatis會智能判斷:
            如果一個條件都沒有,就不生成where關(guān)鍵字
            如果有條件,會判斷是否有多余的and關(guān)鍵字,把多余的and去掉
        注意:建議把所有的where條件都放到where標(biāo)簽里邊
    -->
<select id="search1" 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>

在測試類里進(jìn)行功能測試:測試方法不需要修改

@Test
public void testSearch(){
    User user = new User();
    // user.setUsername("王");
    // user.setSex("男");

    List<User> userList = userDao.search1(user);
    userList.forEach(System.out::println);
}

4. <foreach>標(biāo)簽 語法介紹

? foreach標(biāo)簽,通常用于循環(huán)遍歷一個集合,把集合的內(nèi)容拼接到SQL語句中。例如,我們要根據(jù)多個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標(biāo)簽實現(xiàn)。

<!--
foreach標(biāo)簽:
	屬性:
		collection:被循環(huán)遍歷的對象,使用OGNL表達(dá)式獲取,注意不要加#{}
		open:循環(huán)之前,拼接的SQL語句的開始部分
		item:定義變量名,代表被循環(huán)遍歷中每個元素,生成的變量名
		separator:分隔符
		close:循環(huán)之后,拼接SQL語句的結(jié)束部分
	標(biāo)簽體:
		使用#{OGNL}表達(dá)式,獲取到被循環(huán)遍歷對象中的每個元素
-->
<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
     * 要求:根據(jù)ids查詢對應(yīng)的用戶列表
     */
List<User> search2(QueryVO vo);

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

    <!--
    foreach標(biāo)簽:用于循環(huán)遍歷
        collection:被循環(huán)的集合/數(shù)組
        item:定義一個變量
        separator:定義拼接時的分隔符
        open:拼接字符串時的開始部分
        close:拼接字符串時的結(jié)束部分

        相當(dāng)于 for(Integer id: ids){}
        select * from user where id in(41, 42, 45)
    -->
    <select id="search2" 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 testSearch2(){
        QueryVO vo = new QueryVO();
        vo.setIds(new Integer[]{41,42,43,44,45});
        List<User> userList = userDao.search2(vo);
        userList.forEach(System.out::println);
    }

5. <sql>標(biāo)簽

在映射文件中,我們發(fā)現(xiàn)有很多SQL片段是重復(fù)的,比如:select * from user。Mybatis提供了一個<sql>標(biāo)簽,把重復(fù)的SQL片段抽取出來,可以重復(fù)使用。

語法介紹

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

<sql id="唯一標(biāo)識">sql語句片段</sql>

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

<include refid="sql片段的id"></include>

使用示例

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

要求:QueryVO里有ids,user對象。根據(jù)條件進(jìn)行搜索 修改QueryVO,增加成員變量user

package com.itheima.domain;

/**
 * @author liuyp
 * @date 2021/09/07
 */
public class QueryVO {
    private Integer[] ids;
    private User user;

    //get/set方法……
}

在映射器UserDao里加方法

    /**
     * 動態(tài)SQL拼接的綜合應(yīng)用:if、where、foreach
     * 要求:QueryVo里有ids、username、sex值,根據(jù)這些值進(jìn)行搜索
     */
    List<User> search3(QueryVO vo);

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

<select id="search3" 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標(biāo)簽:用于定義一個sql片段
    include標(biāo)簽:什么時候要引用某個SQL片段,就使用include標(biāo)簽
    注意:引入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 testSearch3(){
        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.search3(vo);
        userList.forEach(System.out::println);
    }

總結(jié)

到此這篇關(guān)于MySQL動態(tài)SQL拼接的文章就介紹到這了,更多相關(guān)MySQL動態(tài)SQL拼接內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • MySQL遠(yuǎn)程訪問設(shè)置終極方法

    MySQL遠(yuǎn)程訪問設(shè)置終極方法

    這篇文章主要介紹了MySQL遠(yuǎn)程訪問設(shè)置終極方法,本文總結(jié)了多種設(shè)置方法和技巧,是解決遠(yuǎn)程訪問的終極解決方案,需要的朋友可以參考下
    2014-12-12
  • mysql中find_in_set()函數(shù)用法及自定義增強(qiáng)函數(shù)詳解

    mysql中find_in_set()函數(shù)用法及自定義增強(qiáng)函數(shù)詳解

    這篇文章主要給大家介紹了關(guān)于mysql中find_in_set()函數(shù)用法及自定義增強(qiáng)函數(shù)的相關(guān)資料,在MySQL 數(shù)據(jù)庫中進(jìn)行復(fù)雜的查詢語句,例如對多個字段進(jìn)行篩選和排序,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-06-06
  • MySQL COUNT函數(shù)的使用與優(yōu)化

    MySQL COUNT函數(shù)的使用與優(yōu)化

    優(yōu)化COUNT函數(shù)的查詢在 MySQL 中最容易被誤解的話題中能夠排進(jìn)前10名,我們可以在網(wǎng)上搜索了解更多關(guān)于 COUNT 優(yōu)化的誤解信息。在進(jìn)行優(yōu)化前,理解 COUNT 到底做了什么很重要。
    2021-05-05
  • MySQL事務(wù)管理的作用詳解

    MySQL事務(wù)管理的作用詳解

    事務(wù)就是一組DML語句組成,這些語句在邏輯上存在相關(guān)性,這一組DML語句要么全部成功,要么全部失敗,是一個整體。MySQL提供一種機(jī)制,保證我們達(dá)到這樣的效果。事務(wù)還規(guī)定不同的客戶端看到的數(shù)據(jù)是不相同的
    2022-08-08
  • MySQL中實現(xiàn)分頁操作的實戰(zhàn)指南

    MySQL中實現(xiàn)分頁操作的實戰(zhàn)指南

    MySQL的分頁似乎一直是個問題,下面這篇文章主要給大家介紹了關(guān)于MySQL中實現(xiàn)分頁操作的相關(guān)資料,文中通過圖文以及實例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-08-08
  • MySQL ALTER語法的運用方法

    MySQL ALTER語法的運用方法

    我們今天主要向大家介紹的是MySQL ALTER語法的實際運用,如果你對這一技術(shù),心存好奇的話,以下的文章將會揭開它的神秘面紗。
    2010-11-11
  • Dbeaver連接MySQL數(shù)據(jù)庫及錯誤Connection?refusedconnect處理方法

    Dbeaver連接MySQL數(shù)據(jù)庫及錯誤Connection?refusedconnect處理方法

    這篇文章主要介紹了dbeaver連接MySQL數(shù)據(jù)庫及錯誤Connection?refusedconnect處理方法,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-08-08
  • MySQL優(yōu)化之表結(jié)構(gòu)優(yōu)化的5大建議(數(shù)據(jù)類型選擇講的很好)

    MySQL優(yōu)化之表結(jié)構(gòu)優(yōu)化的5大建議(數(shù)據(jù)類型選擇講的很好)

    很多人都將 數(shù)據(jù)庫設(shè)計范式 作為數(shù)據(jù)庫表結(jié)構(gòu)設(shè)計“圣經(jīng)”,認(rèn)為只要按照這個范式需求設(shè)計,就能讓設(shè)計出來的表結(jié)構(gòu)足夠優(yōu)化,既能保證性能優(yōu)異同時還能滿足擴(kuò)展性要求
    2014-03-03
  • mysql優(yōu)化之like和=性能詳析

    mysql優(yōu)化之like和=性能詳析

    這篇文章主要給大家介紹了關(guān)于mysql優(yōu)化之like和=性能的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • MySQL數(shù)據(jù)庫分組查詢group by語句詳解

    MySQL數(shù)據(jù)庫分組查詢group by語句詳解

    這篇文章主要介紹了MySQL數(shù)據(jù)庫分組查詢group by語句詳解,文中含有詳細(xì)示例代碼說明解析,有需要的朋友可以借鑒參考想=下,希望能夠有所幫助
    2021-09-09

最新評論