Mybatis参数处理


声明:本文转载自https://my.oschina.net/GL24568/blog/1620856,转载目的在于传递更多信息,仅供学习交流之用。如有侵权行为,请联系我,我会及时删除。

1、单个参数

 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 * from hotel         where      <!-- 这里#{id}可以写成任何值如 #{abc}-->         id=#{id}      </select> </mapper>

注:事实上这里#{id},参数名id可以写任何值,因为只有传了一个参数。

2、多个参数

     mybatis会做特殊处理。 多个参数会被封装成 一个map。需要用  #{key} 取出参数值, key是param1, param2.....或者0、1、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 * 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} 取出参数值, key是param1, param2.....或者0、1、2索引值 。

改成下面这样就正确了。

<?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 * from hotel         where         id=#{param1} and price =#{param2}     </select> </mapper>

3、命名参数

事实上,人们还是习惯使用#{id}和#{price}而不是#{param1}和#{param2},当然mybatis也提供了解决办法,通过@param("key")明确指定封装map中的key,就可以通过#{key}取出参数值了,@param("key")写在hotelMapper接口上。

 public interface HotelMapper {      public Hotel getHotel(@Param("id")Integer i,@Param("price")Integer j);  }

这时候就可以通过#{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(@Param("id")Integer i,@Param("price")Integer j); -->     <select id="getHotel" resultType="com.pjf.mybatis.po.Hotel">         select* from hotel         where         id=#{id} and price =#{price}     </select> </mapper>

4、POJO

如果多个参数正好是我们业务逻辑的数据模型,我们就可以直接传入pojo;#{属性名}:取出传入的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 {      //直接传入hotel业务模型     public void insertHotel(Hotel hotel); }

5、map

如果多个参数不是业务模型中的数据,没有对应的pojo,不经常使用,为了方便,我们也可以传入map。  #{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 * from hotel         where         id=#{id} and price =#{price}     </select> </mapper>

测试类

public class TestHotel {      public SqlSessionFactory sqlSessionFactory() throws IOException {          String resource = "mybatis_config.xml";         InputStream is = Resources.getResourceAsStream(resource);         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();     } }

6、对象参数

如果多个参数不是业务模型,但是有用的比较频繁时,这时候我们可以编写一个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 {      //传入HotelTo 模型     public void insertHotel(HotelTo hotelTo); }

7、例子

public Employee getEmp(@Param("id")Integer id,String lastName); 取值:id==>#{id/param1}   lastName==>#{param2}
public Employee getEmp(Integer id,@Param("e")Employee emp); 取值:id==>#{param1}    lastName===>#{param2.lastName/e.lastName}

8、${} 与 #{} 的区别

举例说明

1 select * from user where name = "dato";  2  3 select * from user where name = #{name};  4  5 select * from user where name = ${name};

一般情况下,我们都不会注意到这里面有什么不一样的地方。因为这些sql都可以达到我们的目的,去查询名字叫dato的用户。

区别

动态 SQL 是 mybatis 的强大特性之一,也是它优于其他 ORM 框架的一个重要原因。mybatis 在对 sql 语句进行预编译之前,会对 sql 进行动态解析,解析为一个 BoundSql 对象,也是在此处对动态 SQL 进行处理的。在动态 SQL 解析阶段, #{ } 和 ${ } 会有不同的表现

select * from user where name = #{name};

#{} 在动态解析的时候, 会解析成一个参数标记符。就是解析之后的语句是:

select * from user where name = ?;

那么我们使用 ${}的时候

select * from user where name = ${name};

${}在动态解析的时候,会将我们传入的参数当做String字符串填充到我们的语句中,就会变成下面的语句

select * from user where name = "dato";

预编译之前的 SQL 语句已经不包含变量了,完全已经是常量数据了。相当于我们普通没有变量的sql了。

综上所得, ${ } 变量的替换阶段是在动态 SQL 解析阶段,而 #{ }变量的替换是在 DBMS 中。

这是 #{} 和 ${} 我们能看到的主要的区别,除此之外,还有以下区别:

  • #方式能够很大程度防止sql注入。
  • $方式无法防止Sql注入。
  • $方式一般用于传入数据库对象,例如传入表名.
  • 一般能用#的就别用$.

 

 

 

本文发表于2018年02月10日 16:31
(c)注:本文转载自https://my.oschina.net/GL24568/blog/1620856,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如有侵权行为,请联系我们,我们会及时删除.

阅读 1700 讨论 0 喜欢 0

抢先体验

扫码体验
趣味小程序
文字表情生成器

闪念胶囊

你要过得好哇,这样我才能恨你啊,你要是过得不好,我都不知道该恨你还是拥抱你啊。

直抵黄龙府,与诸君痛饮尔。

那时陪伴我的人啊,你们如今在何方。

不出意外的话,我们再也不会见了,祝你前程似锦。

这世界真好,吃野东西也要留出这条命来看看

快捷链接
网站地图
提交友链
Copyright © 2016 - 2021 Cion.
All Rights Reserved.
京ICP备2021004668号-1