亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

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

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

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

1. Map 的基本用法

Map 是 Java 集合框架中的一種數(shù)據(jù)結構,它以鍵值對 (key-value) 的形式存儲數(shù)據(jù)。Map 中的鍵唯一且不能重復,而值可以重復。常用的實現(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)建了一個 HashMap,并通過 put 方法將一些數(shù)據(jù)存入 Map。鍵是 String 類型,值是 Object 類型,意味著可以存放不同類型的數(shù)據(jù)(如字符串、數(shù)字、日期等)。

2. 占位符 #{} 的使用

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

SQL 語句示例

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

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

注意

  • 如果 Map 中沒有提供某個占位符對應的值,查詢執(zhí)行時可能會插入 null,這可能導致意外的行為。
  • 使用占位符 #{} 可以防止 SQL 注入,因為框架在執(zhí)行時會自動進行預處理。

3. Map 鍵名與數(shù)據(jù)庫字段名的對應關系

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

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

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

SQL 語句

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

POJO 類實現(xiàn)動態(tài)傳參

1. POJO 類與 SQL 占位符傳遞

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

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

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

2. 占位符 #{} 的使用

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

SQL 語句示例

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

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

MyBatis 會自動根據(jù) POJO 類中的屬性名來查找對應的 getter 方法。如果 POJO 類中沒有提供對應的 getter 方法,則會報錯。

錯誤示例

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

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

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

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

public String getXyz() {
    return xyz;
}

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

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

規(guī)則

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

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

刪除DELETE操作:

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

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

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

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

2. MyBatis Mapper 文件中的SQL語句 

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

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

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

3. 占位符的說明

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

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

例如,改為:

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

這樣更直觀,容易理解。

4. 整體流程總結

  • 在Java代碼中,我們通過 sqlSession.delete("deleteById", 59) 來調用Mapper文件中定義的 deleteById 刪除方法,并傳遞 id = 59。
  • MyBatis會將 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">:定義一個更新操作,id 是唯一標識符,這里使用 updateById,與Java代碼中的方法名一致。
  • update t_car set ... where id = #{id}:這是SQL的更新語句,意圖是將 t_car 表中的某條記錄進行更新,具體是通過 id 來定位記錄,然后對表中的多個字段進行更新。

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

  • #{carNum}:汽車編號
  • #{brand}:品牌
  • #{guidePrice}:指導價格
  • #{produceTime}:生產(chǎn)日期
  • #{carType}:汽車類型
  • #{id}:記錄的唯一標識符,即要更新的汽車記錄的 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 對象,包含了所有要更新的屬性。各個屬性與Mapper XML中的占位符對應。

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

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

3. 詳細流程說明

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

假設 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的記錄就會被更新成新值。

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

select查找操作 

1. MyBatis 中的 select 標簽

作用:MyBatis 使用 select 標簽來編寫 SQL 查詢語句,定義如何從數(shù)據(jù)庫中獲取數(shù)據(jù)。在這個例子中,它用于根據(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" 是一個唯一標識符,表示這條 SQL 語句在 MyBatis 配置中的 ID。當你在代碼中調用 sqlSession.selectOne("selectById", 參數(shù)) 時,MyBatis 會根據(jù)這個 ID 找到對應的 SQL 語句。

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

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

2. resultType 屬性

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

在此例子中的使用

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

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

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

resultType 的作用機制

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

例如:假設 t_car 表有以下列:

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

注意事項

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

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

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

在這個表中,列名是 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 進行手動映射

由于列名和屬性名不一致,直接使用 resultType 是無法自動映射的,這時我們可以使用 resultMap 進行手動映射。

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>

在這個配置中:

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

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

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

3. selectOne 方法

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

用法解釋

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

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

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

select * from t_car where id = 1;

返回的結果會是一個 Car 對象,存儲在變量 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>

在這個查詢中,使用了別名將數(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 調用 

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

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

注意事項

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

  • selectList 返回的結果:調用 selectList("selectAll") 會返回一個 List 集合,集合中的每個元素對應于查詢結果中的一條記錄,并會封裝為指定的 Car 對象。

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

相關文章

最新評論