歡迎您光臨本站 註冊首頁

Mybatis之#{}與${}的區別使用詳解

←手機掃碼閱讀     zhang3221994 @ 2020-06-16 , reply:0

1.兩種取值方式的差異

mapper.xml對映檔案

  select * from t_emp WHERE emp_id=${id} and emp_name=#{name}

 

java查詢程式碼 params 為 id=1 ,name=」小紅」

  @Test    public void testSelect() {      InputStream resourceAsStream = ConfigTest.class.getResourceAsStream("../classes/mybatis-config.xml");      SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);      SqlSession sqlSession = sqlSessionFactory.openSession();      EmployeeMapper mapper2 = sqlSession.getMapper(EmployeeMapper.class);        Employee employee2 = mapper2.selectEmployeeByCondition2(1,"xiaohong");      System.out.println(employee2);    }

 

結果

==>  Preparing: select * from t_emp WHERE emp_id=1 and emp_name=?
 ==> Parameters: xiaohong(String)
 <==    Columns: emp_id, emp_name, emp_email, emp_tel, emp_dep, emp_status
 <==        Row: 1, xiaohong , 123@qq.com, 123, 1, 0
 <==      Total: 112345

1.1 #{}

從上述程式碼可以看出 #{} 在原生jdbc語句中會用 ?佔位符來表示。這樣做可以防止sql注入

1.2${}

從上述程式碼可以看出 ${} 是直接把param 拼到原生sql上

2.什麼時候該使用什麼方式

從上述示例可以看出 #{} 與${}的作用都是取值,同時#{}還可以防止sql注入更安全。是否表示在以後程式碼中就用#{}呢? 當然不是這樣的,比如某電商系統的訂單表資料量太龐大,不得以分表來儲存資料。該電商的工程師最後決定將該表按年月進行分表(t_order_201701,t_order_201702…)。這個時候我們該採用那個中方式進行查詢呢,如我要查詢17年6月份的全部訂單?
 你可能想當然的認為這個容易,只要把年月動態傳入到sql中就可以瞭如下:

  select * from t_order_#{createYM} WHERE DATE_FORMAT(create_date,'%Y%m')=${createYM}+''123

 

結果

==>  Preparing: select * from from t_order_? WHERE DATE_FORMAT(create_date,'%Y%m')='201706'
 ==> Parameters: 201706(Integer)12

很顯然該語句是執行不了的,此時就要採用${}

  select * from t_order_${createYM} WHERE DATE_FORMAT(create_date,'%Y%m')=${createYM}+''

 

拼裝的原生jdbcsql

==>  Preparing: select * from from t_order_201706 WHERE DATE_FORMAT(create_date,'%Y%m')='201706'
 ==> Parameters: 201706(Long)12

很顯然這條sql可以執行。

3.總結

動態 sql 是 mybatis 的主要特性之一,在 mapper 中定義的引數傳到 xml 中之後,在查詢之前 mybatis 會對其進行動態解析。mybatis 為我們提供了兩種支援動態 sql 的語法:#{} 以及 ${} 。
 

1、#相當於對資料 加上 雙引號,$相當於直接顯示資料。
 2、#{} : 根據引數的型別進行處理,比如傳入String型別,則會為引數加上雙引號。#{} 傳參在進行SQL預編譯時,會把引數部分用一個佔位符 ? 代替,這樣可以防止 SQL注入。
 3、${} : 將引數取出不做任何處理,直接放入語句中,就是簡單的字串替換,並且該引數會參加SQL的預編譯,需要手動過濾引數防止 SQL注入。
 4、因此 mybatis 中優先使用 #{};當需要動態傳入 表名或列名時,再考慮使用 ${} , 比較特殊,他的應用場景是需要動態傳入表名或列名時使用,mybatis 排序時使用orderby動態引數時需要注意,用$而不是#
  


[zhang3221994 ] Mybatis之#{}與${}的區別使用詳解已經有363次圍觀

http://coctec.com/docs/java/show-post-238762.html