Mybatis動態(tài)sql中@Param使用詳解
Mybatis中的@param注解的使用場景
1、方法有多個參數(shù)
2、方法參數(shù)要取別名
3、XML 中的 SQL 使用了 $
4、動態(tài)sql中參數(shù)是非自定義pojo類型
前三種,相信大家都非常熟練,這里不再多說,這里主要說下第四種。
當方法的參數(shù)為非自定義pojo類型,且使用了動態(tài)sql,那么就需要在參數(shù)前加上@Param注解。
測試:(此處使用SpringBoot2.0+ 、Mybatis-Plus)
數(shù)據(jù)庫數(shù)據(jù)

代碼
pojo:
/**
* @author: HanXu
* on 2019/12/18
* Class description:
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Test {
private Integer id;
private String name;
private Integer age;
private Integer num;
}mapper接口:
/**
* @author: HanXu
* on 2019/12/18
* Class description:
*/
public interface TestMapper extends BaseMapper<Test> {
Test sel(Test t);
Test seli(Integer id);
Test seli2(@Param("id")Integer id);
Test sels(String s);
Test sels2(@Param("s")String s);
}對應的xml文件:
<?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="hx.insist.demo.mapper.TestMapper">
<select id="sel" parameterType="hx.insist.demo.domain.Test" resultType="hx.insist.demo.domain.Test">
select * from test
where 1 = 1
<if test="id!=null">
and id = #{id}
</if>
<if test="name!=null">
and name = #{name}
</if>
<if test="age!=null">
and age = #{age}
</if>
<if test="num!=null">
and num = #{num}
</if>
</select>
<select id="seli" parameterType="Integer" resultType="hx.insist.demo.domain.Test">
select * from test
where 1 = 1
<if test="id!=null">
and id = #{id}
</if>
</select>
<select id="seli2" parameterType="Integer" resultType="hx.insist.demo.domain.Test">
select * from test
where 1 = 1
<if test="id!=null">
and id = #{id}
</if>
</select>
<select id="sels" resultType="hx.insist.demo.domain.Test">
select * from test
where 1 = 1
<if test="s!=null">
and name = #{s}
</if>
</select>
<select id="sels2" resultType="hx.insist.demo.domain.Test">
select * from test
where 1 = 1
<if test="s!=null">
and name = #{s}
</if>
</select>
</mapper>service層:
/**
* @author: HanXu
* on 2019/12/18
* Class description:
*/
@Service
public class TestService {
@Resource
private TestMapper testMapper;
//測試自定義的存在setter方法的對象
public void selTest(){
Test t = new Test();
t.setId(1);
Test sel = testMapper.sel(t);
System.out.println(sel);
}
//測試Integer
public void seliTest(){
Test seli = testMapper.seli(1);
System.out.println(seli);
}
//測試String
public void selsTst(){
Test aaa = testMapper.sels("aaa");
System.out.println(aaa);
}
//測試Integer,且寫了@Param
public void seliTest2(){
Test seli = testMapper.seli2(1);
System.out.println(seli);
}
//測試String,且寫了@Param
public void selsTest2(){
Test test = testMapper.sels2("aaa");
System.out.println(test);
}
}controller層:
@GetMapping("testT")
public ResponseEntity test(){
testService.selTest();
return ResponseEntity.ok().build();
}
@GetMapping("testI")
public ResponseEntity testi(){
testService.seliTest();
return ResponseEntity.ok().build();
}
@GetMapping("testS")
public ResponseEntity tests(){
testService.selsTst();
return ResponseEntity.ok().build();
}
@GetMapping("testI2")
public ResponseEntity testI2(){
testService.seliTest2();
return ResponseEntity.ok().build();
}
@GetMapping("testS2")
public ResponseEntity testS2(){
testService.selsTest2();
return ResponseEntity.ok().build();
}測試結果
測試Test seli(Integer id);


測試Test seli2(@Param(“id”)Integer id);


測試Test sels(String s);


測試Test sels2(@Param(“s”)String s);


測試Test sel(Test t);


結論
上述5個測試用例中 分為三對:
Test sel(Test t);//5
Test seli(Integer id);//1
Test seli2(@Param("id")Integer id);//2
Test sels(String s);//3
Test sels2(@Param("s")String s);//41和2是一對測試,除了2比1多了一個@Param注解之外其他全部相同,測試結果表示:加了注解的能正確執(zhí)行,未加注解的不能正確執(zhí)行。
3和4是一對測試,除了4比3多了一個@Param注解之外其他全部相同,測試結果表示:加了注解的能正確執(zhí)行,未加注解的不能正確執(zhí)行。
5和1、3是一對測試,不同之處在于5中的參數(shù)是自定義pojo,里面每個屬性都有setter、getter方法,結果表示:在不加@Param注解的情況下,自定義pojo作為參數(shù)可以正常執(zhí)行,非自定義pojo(沒有參數(shù)的getter方法)作為參數(shù)不能正常執(zhí)行。
以上基于sql語句中使用了動態(tài)sql(存在不確定的語句)
我的猜想:
這跟Mybatis內部實現(xiàn)有關。當你使用動態(tài)sql時,#{}去拿你的參數(shù)時,默認將參數(shù)當成了pojo類型,去取對應屬性的getter方法,而這時如果你的參數(shù)不是pojo類型,是一個java定義好的類型,比如參數(shù)為Integer id,String s,使用#{}得到它的值時,Mybatis就會去直接取相應的getter方法,比如反射Integer類,取getId()方法 、反射String類,取getS()方法,但是這些類中并沒有相應的方法,那么就會報錯:
org.apache.ibatis.reflection.ReflectionException: There is no getter for property named ‘id’ in ‘class java.lang.Integer’
org.apache.ibatis.reflection.ReflectionException: There is no getter for property named ‘s’ in ‘class java.lang.String’
到此這篇關于Mybatis動態(tài)sql中@Param使用詳解的文章就介紹到這了,更多相關Mybatis動態(tài)sql內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Spring Boot 與 Kotlin 上傳文件的示例代碼
這篇文章主要介紹了Spring Boot 與 Kotlin 上傳文件的示例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-01-01
spring boot使用WebClient調用HTTP服務代碼示例
這篇文章主要介紹了spring boot使用WebClient調用HTTP服務代碼示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2019-12-12
Java實現(xiàn)基于JDBC操作mysql數(shù)據(jù)庫的方法
這篇文章主要介紹了Java實現(xiàn)基于JDBC操作mysql數(shù)據(jù)庫的方法,結合實例形式分析了java使用JDBC實現(xiàn)針對mysql數(shù)據(jù)庫的連接、查詢、輸出等相關操作技巧,需要的朋友可以參考下2017-12-12

