MyBatis參數(shù)處理與查詢結(jié)果映射實例詳解
實際開發(fā)中應(yīng)用細(xì)節(jié)
#{}和${}的區(qū)別?
‘#{}’:先編譯sql語句,再給占位符傳值,底層是PreparedStatement實現(xiàn),可以防止sql注入,比較常用。
‘#{}’傳來的字符串類型的數(shù)據(jù)會自帶單引號,比如:user_name=#{name} 會編譯為 user_name=‘張三’
${}:先進(jìn)行sql語句拼接,再編譯sql語句,底層是Statement實現(xiàn)。存在sql注入現(xiàn)象。只有在需要進(jìn)行sql關(guān)鍵字拼接的情況下才會用到。
${}傳來的字符串類型的數(shù)據(jù)不帶單引號,比如:user_name=#{name} 會編譯為 user_name=張三 。這樣會報語法錯誤。
優(yōu)先使用#{}
那么什么時候使用${}呢?
在使用sql拼接的時候會用到,比如一個數(shù)據(jù)的查詢結(jié)果是升序還是降序有前端傳來的參數(shù)決定。因此使用${}更合適:
order by age=${orderType} 會編譯為 order by age=asc。
如果使用#{}處理的話會編譯為order by age=‘asc’ 會報語法錯誤!
當(dāng)拼接表名時也會用到。
一些數(shù)據(jù)會分表存儲。比如日志表,因為日志數(shù)據(jù)會非常大,可以每天生成一個日志表,每張表以當(dāng)天的日期作為名稱,例如:
log_2022-02-11、log_2022-02-12、log_2022-02-13.
這樣查某一天的日志時,可以將log_和日期進(jìn)行拼接 然后查詢,此時就要用到${}
批量刪除
批量刪除時,參數(shù)一般為字符串,比如傳來的參數(shù)id值為:‘1,2,3,4’。直接用where id in (#{id})會失效。
這里應(yīng)該使用$() 。sql會編譯為where id in (1,2,3,4) 結(jié)果執(zhí)行成功。
模糊查詢
方案一:使用sql語句拼接 where name like '%${name}%'
方案二:使用concat函數(shù) where name like concat('%',#{name},'%') 此時會編譯為 where name like concat('%','漲三','%') 執(zhí)行成功。
方案三:where name like "%"#{name}"%"
別名機制
當(dāng)XxxMapper.xml中resultType的值太長,也就是返回值的全限定類名太長,可以使用別名機制。
先在mybatis-config.xml中配置如下:
<!-- 起別名,typeAliases標(biāo)簽要放在properties、settings 標(biāo)簽后面-->
<typeAliases>
<!-- type:指定給哪個類型起別名
alias:指定別名。別名不區(qū)分大小寫
然后在CarMapper.xml文件中就可以直接使用別名car來代替全類名com.ali.pojo.Car了
-->
<typeAlias type="com.ali.pojo.Car" alias="car"/>
</typeAliases>這里的alias屬性其實可以省略。當(dāng)alias省略時,別名就是類的簡名,比如:
<typeAlias type="com.ali.pojo.Car"/> 的別名就是car、CAR等,不區(qū)分大小寫。
? 還有更加方便的一種方式,可以指定包名,mybatis會自動給這個包下的所i有類起別名,別名就是類名:
<typeAliases>
<package name="com.ali.pojo"/>
</typeAliases>在CarMapper.xml中就可以使用別名了
<select id="selectCarById" resultType="car">
SELECT id, car_num AS carNum, brand, guide_price AS guidePrice, produce_time AS produceTime, car_type AS carType
FROM t_car
WHERE id = #{id}
</select>注意:這里的別名不區(qū)分大小寫。即使寫成resultType="Car" 也會執(zhí)行成功!
mapper的配置
<mappers>
<!-- 執(zhí)行xxxMapper.xml文件中的SQL語句-->
<!-- resource屬性自動從類的路徑下加載xxxMapper.xml文件
url屬性直接從文件系統(tǒng)絕對路徑加載xxxMapper.xml文件,不推薦,移植性太差。
class屬性指定一個全限定接口名,mybaits會去這個接口的同級目錄下查找對應(yīng)Mapepr.xml文件
比如以下配置,Mybatis會去com.ali.mapper包下查找CarMapper.xml文件。
-->
<mapper class="com.ali.mapper.CarMapper"/>
<mapper resource="CarMapper.xml"/>
<!--package:表示從指定的包下查找所有的xxxMapper.xml文件,并且自動加載它們。
前提必須把xml文件和接口放在統(tǒng)計目錄下。并且名字一致。
實際開發(fā)中 使用這種方式-->
<package name="com.ali.mapper"/>
</mappers>插入數(shù)據(jù)時獲取自動生成的主鍵
<!-- useGeneratedKeys="true" 表示使用JDBC的getGeneratedKeys方法獲取數(shù)據(jù)庫自動生成的主鍵值,
keyProperty="id"表示將獲取到的主鍵值封裝到Car對象的id屬性中。-->
<insert id="insertCarGetId" useGeneratedKeys="true" keyProperty="id">
INSERT INTO t_car (id, car_num, brand,guide_price,produce_time,car_type)
VALUES (null, #{carNum}, #{brand},#{guidePrice},#{produceTime},#{carType})
</insert>這樣設(shè)置后,在新增時傳入的car對象在sql執(zhí)行完后,主鍵的值可以從car.getId()方法中獲得。
MyBatis參數(shù)處理
簡單類型參數(shù)
byte、int、short、long、char、float、double、String、Date,及其對應(yīng)的包裝類都適用簡單類型參數(shù)。
下面以Long類型為例:
<!-- 對應(yīng)的接口方法: Car selectCarById(Long id);
parameterType屬性:指定傳入?yún)?shù)的類型。在這個例子中,傳入?yún)?shù)是一個Long類型的id。
mybatis框架自帶類型推斷機制,所以大部分情況下parameterType屬性可以省略不寫,
-->
<select id="selectCarById" resultType="car" parameterType="java.lang.Long">
SELECT id, car_num AS carNum, brand, guide_price AS guidePrice, produce_time AS produceTime, car_type AS carType
FROM t_car
WHERE id = #{id}
</select>Map參數(shù)
<!-- 對應(yīng)的接口方法: int insertCar(Map<String,Object> map);
參數(shù)類型時map集合。
-->
<insert id="insertCar" parameterType="map">
INSERT INTO t_car (id, car_num, brand,guide_price,produce_time,car_type)
VALUES (null, #{carNum}, #{brand},#{guidePrice},#{produceTime},#{carType})
</insert>實體類參數(shù)
<!--對應(yīng)的接口方法: int insertCarByPojo(Car car);
參數(shù)類型是Pojo類。-->
<insert id="insertCarByPojo" >
INSERT INTO t_car (id, car_num, brand,guide_price,produce_time,car_type)
VALUES (null, #{carNum}, #{brand},#{guidePrice},#{produceTime},#{carType})
</insert>多參數(shù)
<!--對應(yīng)的接口方法: List<Car> selectCarByNameAndCarType(String name,String carType);
這種多參數(shù)的情況,mybatis框架會將多個參數(shù)封裝成一個map集合,并且map會這樣設(shè)置:
map.put("arg0",第一個參數(shù)值); map.put("arg1",第二個參數(shù)值);
map.put("param1",第一個參數(shù)值); map.put("param2",第二個參數(shù)值);
所以#{arg0} 和#{param1}都可以獲取到第一個參數(shù)值,#{arg1}和#{param2}都可以獲取到第二個參數(shù)值。
-->
<select id="selectCarByNameAndCarType" resultType="car" parameterType="java.lang.Long">
SELECT id, car_num AS carNum, brand, guide_price AS guidePrice, produce_time AS produceTime, car_type AS carType
FROM t_car
WHERE brand = #{arg0} and car_type = #{arg1}
</select>
@Param注解
<!--對應(yīng)的接口方法: List<Car> selectCarByNameAndCarType2(@Param("name") String name,@Param("carType") String carType);
@Param注解會將底層封裝的map中arg0、arg1替換成我們指定的key值name和carType。
param1、param2不會被替換,可以繼續(xù)使用
-->
<select id="selectCarByNameAndCarType2" resultType="car" parameterType="java.lang.Long">
SELECT id, car_num AS carNum, brand, guide_price AS guidePrice, produce_time AS produceTime, car_type AS carType
FROM t_car
WHERE brand = #{name} and car_type = #{carType}
</select>
MyBatis查詢語句
當(dāng)sql返回多條記錄時,不能使用單個pojo對象接收,不然會報錯。
單條查詢時,用List接收是沒有任何問題的。
返回Map
當(dāng)返回的數(shù)據(jù),沒有合適的實體類對應(yīng)的話,可以采用Map接收。key是字段名,value是字段值。
當(dāng)返回多條數(shù)據(jù)時,使用List接收。
<!-- 對應(yīng)的接口方法: Map<String,Object> selectCarByIdRetMap(Long id);
resultType="map"表示將查詢結(jié)果封裝成一個map集合,map的key是列名,value是列值。
如果需要查詢多條記錄并封裝成map集合,可以使用resultType="list"來封裝成一個list集合,list集合中的每個元素都是一個map集合。
-->
<select id="selectCarByIdRetMap" resultType="map" >
SELECT id, car_num AS carNum, brand, guide_price AS guidePrice, produce_time AS produceTime, car_type AS carType
FROM t_car
WHERE id = #{id}
</select>
返回Map<String,Map>
以每條記錄的主鍵作為key,一條記錄作為value
<!-- 接口對應(yīng)的方法:
@MapKey("id") // 這個注解表示map的key是id列的值,value是整個記錄封裝成的map集合。
List<Map<Long,Map<String,Object>> selectAllCarRetMap();
-->
<select id="selectAllCarRetMap" resultType="map">
SELECT id, car_num AS carNum, brand, guide_price AS guidePrice, produce_time AS produceTime, car_type AS carType
FROM t_car
</select>
resultMap結(jié)果映射
查詢結(jié)果的列名和Java對象的屬性名對應(yīng)不上怎么辦?
方案一:as 起別名
方案二:使用resultMap進(jìn)行結(jié)果映射
方案三:開啟駝峰命名自動映射
<!--定義一個結(jié)果映射,在結(jié)果映射中,指定數(shù)據(jù)庫表的字段和Java對象的屬性之間的映射關(guān)系。
id屬性是結(jié)果映射的唯一標(biāo)識,將來要用在select標(biāo)簽中;type屬性是結(jié)果映射對應(yīng)的Java類型。-->
<resultMap id="carResultMap" type="Car">
<!--建議配上主鍵,因為主鍵在結(jié)果映射中有特殊的意義,
主鍵會被mybatis框架緩存起來,如果查詢結(jié)果中有重復(fù)的主鍵值,mybatis框架會將它們封裝成同一個Java對象。-->
<id property="id" column="id"></id>
<!--property指定Java對象的屬性,column指定數(shù)據(jù)庫表的字段。
當(dāng)數(shù)據(jù)庫表的字段名和Java對象的屬性名一致時,可以不配置-->
<result property="carNum" column="car_num"></result>
<result property="guidePrice" column="guide_price"></result>
<result property="produceTime" column="produce_time"></result>
<result property="carType" column="car_type"></result>
</resultMap>
<!--resultMap表示指定使用哪個結(jié)果映射,resultMap的值時resultMap標(biāo)簽的id-->
<select id="selectAllCarResultMap" resultMap="carResultMap">
SELECT * FROM t_car
</select>
開啟駝峰命名自動映射
前提時Java的屬性名和數(shù)據(jù)庫表的字段名必須符合命名規(guī)范。
可以將car_type對應(yīng)為carType
在mybatis-config.xml文件中進(jìn)行如下配置即可開啟該功能,默認(rèn)值是false:
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>返回總記錄條數(shù)
<!-- 對應(yīng)的接口方法: long selectTotalCount(); -->
<select id="selectTotalCount" resultType="long">
SELECT count(*) FROM t_car
</select>到此這篇關(guān)于MyBatis參數(shù)處理與查詢結(jié)果映射及細(xì)節(jié)處理的文章就介紹到這了,更多相關(guān)mybatis參數(shù)處理與查詢結(jié)果映射內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- mybatis collection關(guān)聯(lián)查詢多個參數(shù)方式
- Mybatis使用collection標(biāo)簽進(jìn)行樹形結(jié)構(gòu)數(shù)據(jù)查詢時攜帶外部參數(shù)查詢
- Mybatis如何通過出入Map參數(shù)作為條件進(jìn)行查詢
- mybatis-plus 如何判斷參數(shù)是否為空并作為查詢條件
- mybatis-plus?查詢傳入?yún)?shù)Map,返回List<Map>方式
- mybatis利用association或collection傳遞多參數(shù)子查詢
- mybatis interceptor 處理查詢參數(shù)及查詢結(jié)果的實例代碼
- 基于mybatis查詢結(jié)果映射不到對象的處理
相關(guān)文章
Java常見問題之javac Hello.java找不到文件的解決方法
剛開始編寫java代碼時,肯定會遇到各種各樣的bug,當(dāng)然對于初學(xué)者這也是能理解的,下面這篇文章主要給大家介紹了關(guān)于Java常見問題之javac Hello.java找不到文件解決的相關(guān)資料,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下。2018-01-01
Java編譯錯誤信息提示java.lang.ExceptionInInitializer解決
這篇文章主要介紹了Java編譯錯誤信息提示java.lang.ExceptionInInitializer的分析講解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07
SWT(JFace) Wizard(Eclipse插件編程必備)
SWT(JFace)小制作:Wizard(Eclipse插件編程必備)2009-06-06
Java實現(xiàn)讀取Word模板文檔并替換內(nèi)容生成新文檔
在實際開發(fā)中,經(jīng)常會遇到需要根據(jù) Word 模板生成特定文檔的需求,下面小編就來為大家介紹一下如何使用 Apache POI 庫來讀取 Word 模板文檔,然后替換其中的指定內(nèi)容最后生成新的文檔吧2025-02-02
關(guān)于Android觸摸事件分發(fā)的原理詳析
觸摸事件分發(fā)機制一直以來都是Android中比較重要的一大塊,自定義view,各種復(fù)雜的自定義手勢交互都與觸摸事件分發(fā)機制關(guān)系密,下面這篇文章主要給大家介紹了關(guān)于Android觸摸事件分發(fā)原理的相關(guān)資料,需要的朋友可以參考下2022-01-01
springBoot集成mybatis 轉(zhuǎn)換為 mybatis-plus方式
這篇文章主要介紹了springBoot集成mybatis 轉(zhuǎn)換為 mybatis-plus方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-12-12
Spring中@Value設(shè)置默認(rèn)值問題解決
本文主要介紹了Spring中@Value設(shè)置默認(rèn)值問題解決,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-07-07

