先總結一下,后面再一個個解釋:
單個參數:直接使用#{參數名}進行取值,mybatis沒做特殊處理,參數名可以隨便寫。
多個參數:使用#{param1},#{param2}取值
命名參數:通過@param("key")明確指定封裝map中的key,就可以通過#{key}取出參數值了
POJO:如果多個參數正好是業務模型,這時候就可以傳入業務模型,通過#{屬性名}就可以取值了
Map:如果多個參數不是業務模型,而且不經常使用,可以自定義Map傳入
TO:如果多個參數不是業務模型,而且經常使用,可以自定義一個TO來傳輸對象
1、單個參數
在配置sql映射文件中,sql語句傳入一個參數時,應該怎么傳呢
前面我們試驗過mybatis不做特殊處理,只需要用 #{參數名} 取出參數值就可以了。
<?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="com.pjf.mybatis.dao.HotelMapper"> <!-- public Hotel getHotel(Integer i); --> <select id="getHotel" resultType="com.pjf.mybatis.po.Hotel"> select id,hotel_name as hotelName, hotel_address as hotelAddress, price from hotel where <!-- 這里#{id}可以寫成任何值如 #{abc}--> id=#{id} </select> </mapper>
注:事實上這里#{id},參數名id可以寫任何值,因為只有傳了一個參數。。
2、多個參數
首先舉個例子,理所當然,很容易認為是這樣去取參數值,直接寫#{id}和#{price}
<?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="com.pjf.mybatis.dao.HotelMapper"> <!-- public Hotel getHotel(Integer i,Integer j); --> <select id="getHotel" resultType="com.pjf.mybatis.po.Hotel"> select id,hotel_name as hotelName, hotel_address as hotelAddress, price from hotel where id=#{id} and price =#{price} </select> </mapper>
這樣是不對的,運行之后發現報錯了
Caused by: org.apache.ibatis.binding.BindingException:
Parameter 'id' not found.
Available parameters are [arg1, arg0, param1, param2]
事實上,多個參數時,mybatis會做特殊處理,多個參數會被封裝成map
key是param1, param2.....或者0、1、2索引值
value是參數值
下面可以再實驗下,將參數名改為#{param1},#{ param2}
<?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="com.pjf.mybatis.dao.HotelMapper"> <!-- public Hotel getHotel(Integer i,Integer j); --> <select id="getHotel" resultType="com.pjf.mybatis.po.Hotel"> select id,hotel_name as hotelName, hotel_address as hotelAddress, price from hotel where id=#{param1} and price =#{param2} </select> </mapper>
可以發現這時候結果就對了
3、命名參數
事實上,人們還是習慣使用#{id}和#{price}而不是#{param1}和#{param2},當然mybatis也提供了解決辦法
通過@param("key")明確指定封裝map中的key,就可以通過#{key}取出參數值了
@param("key")寫在hotelMapper接口上
package com.pjf.mybatis.dao; import org.apache.ibatis.annotations.Param; import com.pjf.mybatis.po.Hotel; public interface HotelMapper { public Hotel getHotel(@Param("id")Integer i,@Param("price")Integer j); }
hotelMapper.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="com.pjf.mybatis.dao.HotelMapper"> <!-- public Hotel getHotel(@Param("id")Integer i,@Param("price")Integer j); --> <select id="getHotel" resultType="com.pjf.mybatis.po.Hotel"> select id,hotel_name as hotelName, hotel_address as hotelAddress, price from hotel where id=#{id} and price =#{price} </select> </mapper>
這時候就可以通過#{id}和#{price}取出參數值了。
4、map
上面是@param("key")指定一個key,那么我們當然也可以自己傳入一個Map。
實例:
hotelMapper接口
package com.pjf.mybatis.dao; import java.util.Map; import org.apache.ibatis.annotations.Param; import com.pjf.mybatis.po.Hotel; public interface HotelMapper { public Hotel getHotel(Map<String,Integer> map); }
hotelMapper.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="com.pjf.mybatis.dao.HotelMapper"> <!-- public Hotel getHotel(@Param("id")Integer i,@Param("price")Integer j); --> <select id="getHotel" resultType="com.pjf.mybatis.po.Hotel"> select id,hotel_name as hotelName, hotel_address as hotelAddress, price from hotel where id=#{id} and price =#{price} </select> </mapper>
測試類
package com.pjf.mybatis; import java.io.IOException; import java.io.InputStream; import java.util.HashMap; import java.util.Map; 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 org.junit.Test; import com.pjf.mybatis.dao.HotelMapper; import com.pjf.mybatis.po.Hotel; public class TestHotel { public SqlSessionFactory sqlSessionFactory() throws IOException { // mybatis的配置文件 String resource = "mybatis_config.xml"; // 使用類加載器加載mybatis的配置文件(它也加載關聯的映射文件)TestHotel.class.getClassLoader() InputStream is = Resources.getResourceAsStream(resource); // 構建sqlSession的工廠 SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(is); return sessionFactory; } // 查 @Test public void getHotel() throws IOException { SqlSessionFactory sessionFactory = sqlSessionFactory(); SqlSession session = sessionFactory.openSession(); HotelMapper hotelMapper = session.getMapper(HotelMapper.class); System.out.println(hotelMapper.getClass()); //手動封裝一個map傳入 Map map =new HashMap<>(); map.put("id", 1001); map.put("price", 997); Hotel hotel = hotelMapper.getHotel(map); System.out.println(hotel); session.close(); } }
5、對象參數(POJO)
如果多個參數正好是業務模型,這時候就可以直接傳如對象,通過#{屬性值}就可以取到對象的屬性值了
hotelMapper接口
package com.pjf.mybatis.dao; import java.util.Map; import org.apache.ibatis.annotations.Param; import com.pjf.mybatis.po.Hotel; public interface HotelMapper { public Hotel getHotel(Map<String,Integer> map);
//直接傳入hotel業務模型 public void insertHotel(Hotel hotel); }
6、對象參數(TO)
如果多個參數不是業務模型,但是有用的比較頻繁時,這時候我們可以編寫一個TO對象專門用來傳遞參數
package com.pjf.mybatis.po; public class HotelTo { private int id; private int price; public int getId() { return id; } public void setId(int id) { this.id = id; } public int getPrice() { return price; } public void setPrice(int price) { this.price = price; } }
這時候接口就可以修改為
package com.pjf.mybatis.dao; import java.util.Map; import org.apache.ibatis.annotations.Param; import com.pjf.mybatis.po.Hotel; public interface HotelMapper { public Hotel getHotel(Map<String,Integer> map); //傳入HotelTo 模型 public void insertHotel(HotelTo hotelTo); }
思考:
public void insertHotel(Integer id,Hotel hotel);對於這個id應該sql怎么取值呢,是不是可以使用#{param1},那么的Hotel對象的price應該怎么取值呢?