(第5天)mybatis接口方法入參類型


繼續學習mybatis的多參數傳遞

package com.chen.dao;

import java.util.List;

import com.chen.GoodsInfo;

public interface GoodsDao2 {
	/**
	 * 
	 * 1.單個的參數Mybatis不會做特殊處理
	 *     #{這里隨便寫什么都可以}    它都能把這里面的值取到
	 * 2.傳入對象POJO(普通的java類)..
	 * 		#{對象的屬性名稱}
	 * 3.多個參數。
	 */
	//查詢所有   (查詢所有不需要參數)
	public List<GoodsInfo>  selAll();
	//查詢單一  (返回的一定是個對象,而不是集合;需要參數)
	public GoodsInfo  selOne(String id);
	
	//新增
	public void insertGoods(GoodsInfo a);
	
	//修改
	public void updateGoods(GoodsInfo a);
	
	//刪除
	public void deleteGoods(String id);
        
        //多條件查詢(今天學習內容)
	public List<GoodsInfo> querylist(String name ,int id);
}

而今天重點關注 第3個---多個參數

GoodsInfoMapper.xml

 <!-- 多條件查詢,傳入多個參數。String name,char id -->
  <!-- 切記,標簽id要與接口方法名相同,不然報錯 -->
  <!-- 凡是查詢語句,千萬別忘記寫resultType(返回結果類型) -->
  <select id="querylist" resultType="com.chen.GoodsInfo">
  		select * from goods  where name like '#{param1}%' and id=#{id}
    </select>

select * from goods where name like '牛%' and id =10
*查詢數據庫以"牛"開頭的 ” 且id=10 *

/Mybatis02/src/test/Start2.java

package test;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import com.chen.GoodsInfo;
import com.chen.dao.GoodsDao;
import com.chen.dao.GoodsDao2;

public class Start2 {

	public static void main(String[] args) throws IOException {
		
		String resource = "mybatis-conf.xml";
		InputStream  inputStream = Resources.getResourceAsStream(resource);
		//創建SqlSessionFactory
		SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
		//true表示自動提交。否則需要使用commit方法才會提交。默認是false
		SqlSession session = sqlSessionFactory.openSession();
		
		//拿到接口的代理對象
		GoodsDao2 dao=session.getMapper(GoodsDao2.class);
		//拿到了dao這個對象接下來就可以創建sql語句了;(直接調用接口方法)
		//因為接口方法里需要傳入一個對象,所以
		GoodsInfo goods =new GoodsInfo();
		//然后給對象插屬性
		goods.setId(123);
		goods.setName("超人");
		
		//dao.insertGoods(goods);
		//dao.updateGoods(goods);
		//dao.deleteGoods("123");
		List<GoodsInfo> list =dao.querylist("牛", 10);
		System.out.println(list.size());
		
		//如果上面不設置自動提交表單,那么就需要commit方法
		session.commit();
	}

}

完成這個后,運行

關鍵來了! ,系統會報錯


什么原因呢? 從提示信息來翻譯,這個參數名並沒被找到,可以使用的參數是[0,1,param1,param2],意思是說命名要在這4個中選擇,}

原來,多參數傳遞,mybatis會做特殊處理

0是表示傳入的第一個參數,1是表示傳入的第2個參數; 或者,param1表示傳入的第一個參數,param2表示傳入的第2個參數

那么現在修改一下

 <!-- 多條件查詢,傳入多個參數。String name,char id -->
  <!-- 切記,標簽id要與接口方法名相同,不然報錯 -->
  <!-- 凡是查詢語句,千萬別忘記寫resultType(返回結果類型) -->
  <select id="querylist" resultType="com.chen.GoodsInfo">
  		select * from goods  where name like '#{param1}%' and id=#{param2}
    </select>

然后換到主入口類 運行一下

但問題又出現了,又新出現報錯

那么經過琢磨我來告訴你為什么


把# 換成$ 試試

運行一下主類

結果出來了,1代表查到了一行數據 。 記住 1 個對象 代表1行數據 。而 現在這個對象 LIst 泛型數組里 保存着。 所以,,list.size() 就是里面有多少個對象的意思。

現在說下,為什么會這樣?

那么,#{} 和${} 有什么區別?

比如說用#{},和 ${}傳參的區別,
使用#傳入參數是,sql語句解析是會加上"",比如 select * from table where name = #{name} ,傳入的name為小李,那么最后打印出來的就是
select * from table where name = ‘小李',就是會當成字符串來解析,這樣相比於$的好處是比較明顯對的吧,#{}傳參能防止sql注入,如果你傳入的參數為 單引號',那么如果使用${},這種方式 那么是會報錯的,
另外一種場景是,如果你要做動態的排序,比如 order by column,這個時候務必要用${},因為如果你使用了#{},那么打印出來的將會是
select * from table order by 'name' ,這樣是沒用,
目前來看,能用#就不要用$,
mybatis中的#和$的區別

  1. 將傳入的數據都當成一個字符串,會對自動傳入的數據加一個雙引號。如:order by #user_id#,如果傳入的值是111,那么解析成sql時的值為order by "111", 如果傳入的值是id,則解析成的sql為order by "id".

  2. $將傳入的數據直接顯示生成在sql中。如:order by $user_id$,如果傳入的值是111,那么解析成sql時的值為order by user_id, 如果傳入的值是id,則解析成的sql為order by id.
  3. 方式能夠很大程度防止sql注入。

4.$方式無法防止Sql注入。
5.$方式一般用於傳入數據庫對象,例如傳入表名. 
6.一般能用#的就別用$.
MyBatis排序時使用order by 動態參數時需要注意,用$而不是#
字符串替換
默認情況下,使用#{}格式的語法會導致MyBatis創建預處理語句屬性並以它為背景設置安全的值(比如?)。這樣做很安全,很迅速也是首選做法,有時你只是想直接在SQL語句中插入一個不改變的字符串。比如,像ORDER BY,你可以這樣來使用:
ORDER BY ${columnName}
這里MyBatis不會修改或轉義字符串。
重要:接受從用戶輸出的內容並提供給語句中不變的字符串,這樣做是不安全的。這會導致潛在的SQL注入攻擊,因此你不應該允許用戶輸入這些字段,或者通常自行轉義並檢查。
Mybatis中$和#的區別簡單小結
前不久,有人來我們公司面試,我們的經理問道了這個問題,我也是一知半解,所以就去百度了一番。
其實區別很簡單的,舉個例子大家就會明白的。寫一句SQL-例如:select * from user_role where user_code = "100";
這句話而言,需要寫成 select * from ${tableName} where user_code = #{userCode}
所以,$符是直接拼成sql的 ,#符則會以字符串的形式 與sql進行拼接。

高級補充知識點

為防止用param1 ,param2 容易 把自己都弄混。現在可以``` @param("name") 可以使用這個注解 來自定義Map封裝數據的key值。

<select id="querylist" resultType="com.chen.GoodsInfo">
     <!-- 
          #{}默認采用預處理的方式去處理SQL語句。。。
          ${}是采用非預處理模式來處理數據。。 
     -->
  		select * from goods  where name like '${sb}%' and id=#{nb}
    </select>

這樣Map的key值名字,你都能隨便設置

繼續補充額外知識點,直接傳入Map類型

結束


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM