Mybatis参数处理

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的属性值。

<insert id="insertUser" parameterType="User">
  insert into users (id, username, password)
  values (#{id}, #{username}, #{password})
</insert>

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}

//如果是Collection(List、Set)类型或者数组,也会特殊处理。也是把传入的list或者数组封装在map中
key:Collection(collection),如果是List还可以使用这个key(list)
public Employee getEmpById(List<Integer> ids);
取值:取出第一个id的值:#{ids[0]}

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注入。
  • $方式一般用于传入数据库对象,例如传入表名.
  • 一般能用#的就别用$.

 

 
 
 
 

转载于:https://my.oschina.net/lin546/blog/1620856

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值