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

mybatis動(dòng)態(tài)生成sql語句的實(shí)現(xiàn)示例

 更新時(shí)間:2024年11月05日 10:15:14   作者:代碼代碼快快顯靈  
在MyBatis中,動(dòng)態(tài)SQL是一個(gè)非常重要的特性,它允許我們根據(jù)條件動(dòng)態(tài)地生成SQL語句,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

在 Java 編程中,我們常常需要將數(shù)據(jù)傳遞給 SQL 查詢,特別是在動(dòng)態(tài)生成 SQL 語句時(shí),通常會(huì)用到 Map 這種集合類。Map 可以將多個(gè)鍵值對傳遞給 SQL 語句的占位符,完成動(dòng)態(tài)參數(shù)綁定的功能。我們下面詳細(xì)講解圖中的知識(shí)點(diǎn)。

1. Map 的基本用法

Map 是 Java 集合框架中的一種數(shù)據(jù)結(jié)構(gòu),它以鍵值對 (key-value) 的形式存儲(chǔ)數(shù)據(jù)。Map 中的鍵唯一且不能重復(fù),而值可以重復(fù)。常用的實(shí)現(xiàn)類包括 HashMap、TreeMap 等。

示例代碼

Map<String, Object> map = new HashMap<>();
map.put("k1", "1111");
map.put("k2", "比亞迪漢");
map.put("k3", 10.0);
map.put("k4", "2020-11-11");
map.put("k5", "電車");

這里我們創(chuàng)建了一個(gè) HashMap,并通過 put 方法將一些數(shù)據(jù)存入 Map。鍵是 String 類型,值是 Object 類型,意味著可以存放不同類型的數(shù)據(jù)(如字符串、數(shù)字、日期等)。

2. 占位符 #{} 的使用

在執(zhí)行 SQL 語句時(shí),為了防止 SQL 注入和簡化代碼,我們經(jīng)常使用占位符將 SQL 參數(shù)動(dòng)態(tài)地傳入。( ? 是 JDBC 中的占位符,用于預(yù)編譯 SQL 語句中的參數(shù)。在使用 JDBC 時(shí),SQL 語句通常是預(yù)編譯的,? 用于表示一個(gè)位置,在執(zhí)行時(shí)由具體的參數(shù)替換。占位符 #{} 這一語法主要用于一些持久化框架,如 MyBatis。

SQL 語句示例

insert into t_car(id,car_num,brand,guide_price,produce_time,car_type) 
values(null, #{k1}, #{k2}, #{k3}, #{k4}, #{k5});

在這個(gè) SQL 語句中,#{k1}、#{k2} 等占位符將會(huì)在運(yùn)行時(shí)被替換為 Map 中對應(yīng)的值??蚣軙?huì)根據(jù)占位符的鍵來查找 Map 中的值并動(dòng)態(tài)替換。如果鍵不存在,則返回 null。這個(gè)語句通常配置在通常用于 MyBatis 的 SQL 映射的XML文件中

注意

  • 如果 Map 中沒有提供某個(gè)占位符對應(yīng)的值,查詢執(zhí)行時(shí)可能會(huì)插入 null,這可能導(dǎo)致意外的行為。
  • 使用占位符 #{} 可以防止 SQL 注入,因?yàn)榭蚣茉趫?zhí)行時(shí)會(huì)自動(dòng)進(jìn)行預(yù)處理。

3. Map 鍵名與數(shù)據(jù)庫字段名的對應(yīng)關(guān)系

為了使代碼更加易讀、維護(hù)更加方便,我們通常建議將 Map 中的鍵名與數(shù)據(jù)庫字段名保持一致。這樣一來,不僅能夠直觀地映射參數(shù),還能避免因鍵名不統(tǒng)一而導(dǎo)致的問題。

map.put("carNum", "1111");
map.put("brand", "比亞迪漢2");
map.put("guidePrice", 10.0);
map.put("produceTime", "2020-11-11");
map.put("carType", "電車");

在這個(gè)例子中,我們將 Map 的鍵名改為 carNumbrand 等,和數(shù)據(jù)庫表的列名一致。這樣一來,代碼就更容易理解和維護(hù)。

SQL 語句

insert into t_car(id,car_num,brand,guide_price,produce_time,car_type) 
values(null, #{carNum}, #{brand}, #{guidePrice}, #{produceTime}, #{carType});

POJO 類實(shí)現(xiàn)動(dòng)態(tài)傳參

1. POJO 類與 SQL 占位符傳遞

POJO(Plain Old Java Object) 是指普通的 Java 對象,通常用作數(shù)據(jù)傳輸對象。在 Java 應(yīng)用中,我們可以通過 POJO 類的屬性來傳遞 SQL 語句中的參數(shù)。

Car car = new Car(null, "3333", "比亞迪秦", 30.0, "2020-11-11", "新能源");

在這個(gè)例子中,Car 是一個(gè) POJO 類,包含一些車輛信息的屬性。通過實(shí)例化這個(gè)類,我們可以將具體的值傳入到 SQL 語句中的占位符。

2. 占位符 #{} 的使用

在 MyBatis 等持久化框架中,使用占位符 #{} 來表示將 POJO 的屬性值注入到 SQL 語句中。大括號 {} 里面填寫的內(nèi)容是 POJO 類的屬性名(嚴(yán)格意義上來說:如果使用P0J0對象傳遞值的話,這個(gè){}里面寫的是get方法的方法名去掉get,然后將剩下的單詞首字母小寫,然后放進(jìn)去。

SQL 語句示例

insert into t_car(id,car_num,brand,guide_price,produce_time,car_type) 
values(null, #{carNum}, #{brand}, #{guidePrice}, #{produceTime}, #{carType});

3. 占位符與屬性對應(yīng)的規(guī)則

MyBatis 會(huì)自動(dòng)根據(jù) POJO 類中的屬性名來查找對應(yīng)的 getter 方法。如果 POJO 類中沒有提供對應(yīng)的 getter 方法,則會(huì)報(bào)錯(cuò)。

錯(cuò)誤示例

There is no getter for property named 'xyz' in 'class com.powernode.mybatis.pojo.Car'

這是因?yàn)?MyBatis 嘗試通過 getXyz() 方法來獲取 xyz 屬性的值,但 POJO 類中沒有定義這個(gè)方法。為了避免這種錯(cuò)誤,我們需要在 POJO 類中提供每個(gè)屬性的 getter 和 setter 方法。

4. 如何解決沒有 getter 方法的問題?

如果遇到?jīng)]有對應(yīng) getter 方法的情況,可以通過在 POJO 類中手動(dòng)添加相應(yīng)的 getter 方法來解決。比如:

public String getXyz() {
    return xyz;
}

5. 占位符 #{} 的使用規(guī)則

通過這個(gè)錯(cuò)誤示例,我們可以總結(jié)出占位符的使用規(guī)則:MyBatis 是通過反射機(jī)制來調(diào)用 getter 方法。也就是說,在 #{} 占位符中寫的內(nèi)容(如 #{carNum})并不直接對應(yīng) POJO 的屬性名,而是對應(yīng)屬性的 getter 方法。

規(guī)則

  • 占位符 #{} 中的內(nèi)容是首字母小寫形式。
  • 占位符內(nèi)部自動(dòng)調(diào)用屬性的 getter 方法,因此命名應(yīng)符合 Java 的命名規(guī)范。例如:
    • getUsername() 對應(yīng)的占位符為 #{username}
    • getEmail() 對應(yīng)的占位符為 #{email}

占位符 #{} 中的內(nèi)容確實(shí)是與 POJO 類的屬性相關(guān),但 MyBatis 實(shí)際上是通過 調(diào)用 POJO 類的 getter 方法 來獲取這些值的,而不是直接訪問屬性本身。因此,為了確保 MyBatis 能正確地映射 SQL 參數(shù),POJO 類中的 getter 方法必須與占位符中的名字相匹配。 

刪除DELETE操作:

 1. 刪除操作的實(shí)現(xiàn)

int count = sqlSession.delete("deleteById", 59);

這行代碼展示了通過 sqlSession.delete() 方法來執(zhí)行刪除操作,其中:

  • sqlSession:MyBatis中的會(huì)話對象,允許我們與數(shù)據(jù)庫進(jìn)行交互。
  • "deleteById":這是Mapper XML文件中定義的SQL語句的唯一標(biāo)識(shí)符,用來指定刪除操作。
  • 59:這是要傳遞給SQL語句的參數(shù),即要?jiǎng)h除的記錄的ID

2. MyBatis Mapper 文件中的SQL語句 

<delete id="deleteById">
    delete from t_car where id = #{fdsfd}
</delete>

這是在MyBatis的Mapper XML文件中定義的刪除操作,具體解釋如下:

  • <delete id="deleteById">:這是定義一個(gè)刪除操作的方法,id 是這個(gè)方法的唯一標(biāo)識(shí)符,名稱為 deleteById,與Java代碼中調(diào)用的 deleteById 相對應(yīng)。
  • delete from t_car where id = #{fdsfd}:這是一個(gè)標(biāo)準(zhǔn)的SQL刪除語句,意思是從表 t_car 中刪除 id 為 #{fdsfd} 的記錄。
    • #{fdsfd}:這是MyBatis的參數(shù)占位符,表示將傳遞的參數(shù)(在Java代碼中傳遞的 59)注入到這個(gè)位置。fdsfd 是參數(shù)名,可以根據(jù)需要定義。

3. 占位符的說明

注意:如果占位符只有一個(gè),那么 #{} 的大括號里可以隨意。但是最好見名知意。

這里說明了 #{} 是MyBatis的占位符,用于綁定參數(shù)。雖然在某些情況下可以隨意使用參數(shù)名(如 fdsfd),但是為了代碼的可讀性和維護(hù)性,建議使用有意義的名稱,比如 id。

例如,改為:

<delete id="deleteById">
    delete from t_car where id = #{id}
</delete>

這樣更直觀,容易理解。

4. 整體流程總結(jié)

  • 在Java代碼中,我們通過 sqlSession.delete("deleteById", 59) 來調(diào)用Mapper文件中定義的 deleteById 刪除方法,并傳遞 id = 59。
  • MyBatis會(huì)將 59 替換到 delete from t_car where id = #{id} 的SQL語句中,生成最終的SQL語句 delete from t_car where id = 59 并執(zhí)行,最終刪除 t_car 表中 id 為 59 的記錄。

更新操作:

1. 更新操作的SQL語句

<update id="updateById">
    update t_car set
        car_num=#{carNum},
        brand=#{brand},
        guide_price=#{guidePrice},
        produce_time=#{produceTime},
        car_type=#{carType}
    where
        id = #{id}
</update>

這是在MyBatis的Mapper XML文件中定義的更新操作。解釋如下:

  • <update id="updateById">:定義一個(gè)更新操作,id 是唯一標(biāo)識(shí)符,這里使用 updateById,與Java代碼中的方法名一致。
  • update t_car set ... where id = #{id}:這是SQL的更新語句,意圖是將 t_car 表中的某條記錄進(jìn)行更新,具體是通過 id 來定位記錄,然后對表中的多個(gè)字段進(jìn)行更新。

這里使用 #{} 作為MyBatis的占位符,類似于之前的刪除操作。它會(huì)在執(zhí)行時(shí)將參數(shù)替換為實(shí)際值。具體字段說明:

  • #{carNum}:汽車編號
  • #{brand}:品牌
  • #{guidePrice}:指導(dǎo)價(jià)格
  • #{produceTime}:生產(chǎn)日期
  • #{carType}:汽車類型
  • #{id}:記錄的唯一標(biāo)識(shí)符,即要更新的汽車記錄的 id

2. Java代碼中的更新操作

Car car = new Car(4L, "9999", "凱美瑞", 30.3, "1999-11-10", "燃油車");
int count = sqlSession.update("updateById", car);

這里通過 new Car() 創(chuàng)建了一輛 Car 對象,包含了所有要更新的屬性。各個(gè)屬性與Mapper XML中的占位符對應(yīng)。

  • 4L:表示汽車的 id,也就是SQL語句中 id 字段要更新的記錄。null 不能賦值給基本類型 long,但可以賦值給 Long 這樣的包裝類,所以使用)
  • "9999":對應(yīng) carNum,汽車編號。
  • "凱美瑞":對應(yīng) brand,汽車品牌。
  • 30.3:對應(yīng) guidePrice,指導(dǎo)價(jià)格。
  • "1999-11-10":對應(yīng) produceTime,生產(chǎn)日期。
  • "燃油車":對應(yīng) carType,汽車類型。

然后調(diào)用 sqlSession.update("updateById", car); 進(jìn)行更新操作。MyBatis會(huì)將 car 對象的屬性傳遞給對應(yīng)的SQL語句中的占位符,生成最終的SQL語句并執(zhí)行更新。

3. 詳細(xì)流程說明

MyBatis會(huì)根據(jù)Java代碼中的 car 對象的屬性,替換Mapper XML中的占位符,生成最終的SQL語句。

假設(shè) car 對象的 id 是4,那么生成的SQL語句大致如下

update t_car set
    car_num='9999',
    brand='凱美瑞',
    guide_price=30.3,
    produce_time='1999-11-10',
    car_type='燃油車'
where
    id = 4;

執(zhí)行這條SQL語句后,t_car 表中 id 為4的記錄就會(huì)被更新成新值。

更新后,sqlSession.update() 方法會(huì)返回受影響的行數(shù),即 count。

select查找操作 

1. MyBatis 中的 select 標(biāo)簽

作用:MyBatis 使用 select 標(biāo)簽來編寫 SQL 查詢語句,定義如何從數(shù)據(jù)庫中獲取數(shù)據(jù)。在這個(gè)例子中,它用于根據(jù) id 字段查詢 t_car 表中的記錄。

SQL 語句解釋

<select id="selectById" resultType="com.powernode.mybatis.pojo.Car">
    select * from t_car where id = #{id}
</select>

id 屬性id="selectById" 是一個(gè)唯一標(biāo)識(shí)符,表示這條 SQL 語句在 MyBatis 配置中的 ID。當(dāng)你在代碼中調(diào)用 sqlSession.selectOne("selectById", 參數(shù)) 時(shí),MyBatis 會(huì)根據(jù)這個(gè) ID 找到對應(yīng)的 SQL 語句。

SQL 查詢select * from t_car where id = #{id} 是實(shí)際的 SQL 語句。#{id} 是 MyBatis 的動(dòng)態(tài) SQL 占位符,它會(huì)在運(yùn)行時(shí)將你傳入的參數(shù)(比如 1)替換為實(shí)際的查詢條件。

  • #{} 是 MyBatis 語法,用于從傳遞的參數(shù)中獲取值,防止 SQL 注入。
  • select * 是查詢所有列,你可以根據(jù)需要替換為具體的列名(例如:select id, name, brand)。

2. resultType 屬性

作用resultType 屬性告訴 MyBatis 查詢結(jié)果應(yīng)該映射成什么樣的 Java 對象。也就是說,當(dāng)從數(shù)據(jù)庫中獲取到數(shù)據(jù)后,MyBatis 會(huì)根據(jù) resultType 中指定的類型來創(chuàng)建該類型的對象,并將查詢結(jié)果封裝到這個(gè)對象中。

在此例子中的使用

resultType="com.powernode.mybatis.pojo.Car"

這里 resultType="com.powernode.mybatis.pojo.Car" 指定了 Car 類為查詢結(jié)果的映射對象類型。即查詢到的 t_car 表中的記錄會(huì)被封裝成 Car 類的實(shí)例。

全限定類名:com.powernode.mybatis.pojo.Car 是 Car 類的全限定類名,即包括了包名和類名。這是 MyBatis 推薦的寫法,因?yàn)檫@樣可以確保避免類名沖突,并確保 MyBatis 能找到正確的類。

resultType 的作用機(jī)制

查詢結(jié)果(即數(shù)據(jù)庫中的一條記錄)會(huì)被轉(zhuǎn)換為 Java 對象。MyBatis 會(huì)根據(jù)數(shù)據(jù)庫表中的列名與 Car 類的屬性名進(jìn)行匹配,如果列名與屬性名相同,MyBatis 就會(huì)自動(dòng)將查詢結(jié)果中的列值賦給對應(yīng)的屬性。

例如:假設(shè) t_car 表有以下列:

  • id,name,brand
  • 對應(yīng) Car 類的屬性為:idnamebrand,MyBatis 會(huì)自動(dòng)將數(shù)據(jù)庫中的 id 列的值賦給 Car 類中的 id 屬性,依此類推。

注意事項(xiàng)

如果數(shù)據(jù)庫中的列名和 Java 類中的屬性名不一致,你需要使用別名(AS)或者 resultMap 進(jìn)行手動(dòng)映射。

1. 假設(shè)的數(shù)據(jù)庫表 t_car

CREATE TABLE t_car (
    car_id INT PRIMARY KEY,
    car_name VARCHAR(50),
    car_brand VARCHAR(50)
);

在這個(gè)表中,列名是 car_idcar_name, 和 car_brand。

Java 類 Car

public class Car {
    private int id;
    private String name;
    private String brand;

    // Getters and setters
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }
}

在 Java 類 Car 中,屬性名分別是 idname, 和 brand,顯然與數(shù)據(jù)庫表 t_car 的列名不一致。

解決辦法:使用 resultMap 進(jìn)行手動(dòng)映射

由于列名和屬性名不一致,直接使用 resultType 是無法自動(dòng)映射的,這時(shí)我們可以使用 resultMap 進(jìn)行手動(dòng)映射。

3. MyBatis 映射配置:起別名

<select id="selectById" resultType="com.powernode.mybatis.pojo.Car">
    select car_id as id, car_name as name, car_brand as brand
    from t_car
    where car_id = #{id}
</select>

在這個(gè)配置中:

  • car_id as id:把 car_id 列的查詢結(jié)果映射為 id,從而與 Java 類 Car 的 id 屬性對應(yīng)。
  • car_name as name:把 car_name 列的查詢結(jié)果映射為 name,與 Car 類中的 name 屬性對應(yīng)。
  • car_brand as brand:把 car_brand 列的查詢結(jié)果映射為 brand,與 Car 類中的 brand 屬性對應(yīng)。

SQL 查詢select * from t_car where car_id = #{id},通過 #{id} 來傳遞 Java 方法中的參數(shù)。

這樣,通過使用 AS 設(shè)置別名,可以直接在 SQL 語句中將數(shù)據(jù)庫的列名與 Java 類的屬性名進(jìn)行對應(yīng),而無需修改數(shù)據(jù)庫或 Java 類。

3. selectOne 方法

作用selectOne 是 MyBatis 提供的一個(gè)方法,用于執(zhí)行返回單條記錄的查詢。當(dāng)我們確定查詢的結(jié)果是唯一的(例如,查詢主鍵),可以使用這個(gè)方法。如果查詢結(jié)果返回多條記錄,MyBatis 會(huì)拋出異常(TooManyResultsException)。

用法解釋

Car car = sqlSession.selectOne("selectById", 1);

sqlSession 是 MyBatis 中操作數(shù)據(jù)庫的會(huì)話對象,類似于 JDBC 中的 Connection 對象。

selectOne("selectById", 1):調(diào)用了 selectById 這個(gè) SQL 查詢,并傳遞了參數(shù) 1。這個(gè) 1 會(huì)替換 SQL 中的 #{id} 占位符,最終執(zhí)行的 SQL 會(huì)是:

select * from t_car where id = 1;

返回的結(jié)果會(huì)是一個(gè) Car 對象,存儲(chǔ)在變量 car 中。

 select查所有的數(shù)據(jù)

sql語句

<select id="selectAll" resultType="com.powernode.mybatis.pojo.Car">
    select
        id,
        car_num as carNum,
        brand,
        guide_price as guidePrice,
        produce_time as produceTime,
        car_type as carType
    from t_car
</select>

在這個(gè)查詢中,使用了別名將數(shù)據(jù)庫表中的列名映射到 Java 類 Car 中的屬性名:

  • car_num as carNum:將數(shù)據(jù)庫中的 car_num 列映射到 Car 類中的 carNum 屬性。
  • guide_price as guidePrice:將數(shù)據(jù)庫中的 guide_price 列映射到 Car 類中的 guidePrice 屬性。
  • produce_time as produceTime:將數(shù)據(jù)庫中的 produce_time 列映射到 Car 類中的 produceTime 屬性。
  • car_type as carType:將數(shù)據(jù)庫中的 car_type 列映射到 Car 類中的 carType 屬性。

Java 代碼中的 selectList 調(diào)用 

List<Car> cars = sqlSession.selectList("selectAll");
  • selectList 方法:MyBatis 中的 selectList 方法用于返回一個(gè) List 集合,集合中的每個(gè)元素是從數(shù)據(jù)庫查詢到的每一條記錄的 Java 對象。在這個(gè)例子中,查詢結(jié)果將會(huì)封裝為一個(gè) Car 對象的列表。

  • resultType 屬性:在 SQL 配置中,resultType 依然用于指定封裝查詢結(jié)果的 Java 類類型,這里是 com.powernode.mybatis.pojo.Car,表示查詢結(jié)果會(huì)封裝成 Car 類的對象。

注意事項(xiàng)

  • resultType 指定的類型:需要注意的是,resultType 并不是指定集合的類型,而是指定集合中的每個(gè)元素類型。在這個(gè)例子resultType="com.powernode.mybatis.pojo.Car",意味著 MyBatis 會(huì)將查詢結(jié)果的每一條記錄封裝為 Car 對象。

  • selectList 返回的結(jié)果:調(diào)用 selectList("selectAll") 會(huì)返回一個(gè) List 集合,集合中的每個(gè)元素對應(yīng)于查詢結(jié)果中的一條記錄,并會(huì)封裝為指定的 Car 對象。

到此這篇關(guān)于mybatis動(dòng)態(tài)生成sql語句的實(shí)現(xiàn)示例的文章就介紹到這了,更多相關(guān)mybatis動(dòng)態(tài)生成sql語句內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論