MyBatis参数处理

参数处理

单个参数

通过#{参数名}取出参数值

接口定义如下

public User getUserByUserName(String userName);

接口对应的 Mapper.xml 定义如下所示

<select id="getUserByUserName"
        parameterType="String"
        resultType="com.example.mybatis.entity.User">
    select
    id, username, user_email userEmail, user_city userCity, age
    from user
    where username = #{username}
</select>

多个参数

MyBatis会做特殊处理,会将你的多个参数封装成一个Map,keyparam1, param2,..., paramN,value为 value1,value2,...valueN,可以通过#{param1}来获取value1的值,#{paramN}来获取valueN的值。value1,value2,...valueN就是我们通过方法传递过来的值。

接口定义如下

public User getUserByIdAndUserName(Integer id, String username);

接口对应的 Mapper.xml 定义如下所示。 两个参数分别是 Integer 类型和 String 类型,类型不一致,此时 parameterType 可以省略 。

<select id="getUserByIdAndUserName"
        resultType="com.example.mybatis.entity.User">
    select
    id, username, user_email userEmail, user_city userCity, age
    from user
    where id = #{param1}
    and username = #{param2}
</select>

这里需要注意的是通过 #{param1} 和 #{param2} 来映射两个参数,以此类推,如果有第 3 个参数,则使用 #{param3} 来映射。

命名参数

MyBatis封装参数时由用户来指定Map的key.

接口定义如下

public User getUserByIdAndUserName(@Param("id")Integer id, @Param("username")String username);

接口对应的 Mapper.xml 定义如下所示

<select id="getUserByIdAndUserName"
        resultType="com.example.mybatis.entity.User">
    select
    id, username, user_email userEmail, user_city userCity, age
    from user
    where id = #{id}
    and username = #{username}
</select>

POJO

多个参数一个个写太麻烦了,这时候我们可以将参数列表进行封装,将封装对象作为 parameterType 的值。

接口定义如下

public User getUserByIdAndUserName(User user);

接口对应的 Mapper.xml 定义如下所示

命名参数:封装参数时指定Map的key,

<select id="getUserByIdAndUserName"
        parameterType="com.example.mybatis.entity.User"
        resultType="com.example.mybatis.entity.User">
    select
    id, username, user_email userEmail, user_city userCity, age
    from user
    where id = #{id}
    and username = #{username}
</select>

与多个参数的不同之处在于,这里是通过 #{属性名} 来映射参数对象的具体属性值的。

有时候为了方便,也可以直接使用Map来传递数据,但是使用Map会使得代码的可读性很差,一般不推荐使用这种方式。

特殊情况

如果参数类型是Collection(List,Set)类型或者是数组,MyBatis也会特殊处理

如果为Collection类型的,key为collection;如果为List类型的,key为list

public int addUserList(List<User> userList);

接口对应的 Mapper.xml 定义如下所示

<insert id="addUserList"
        parameterType="com.example.mybatis.entity.User"
        useGeneratedKeys="true"
        keyProperty="id">
    insert into user
    (username, user_email, user_city, age)
    values
    <foreach item="item"  collection="collection" separator=",">
        (#{item.username}, #{item.userEmail}, #{item.userCity}, #{item.age})
    </foreach>
</insert>

如果是数组类型,key为array

接口定义如下

public int addUserList(User[] userList);

接口对应的 Mapper.xml 定义如下所示

<insert id="addUserList"
        parameterType="com.example.mybatis.entity.User"
        useGeneratedKeys="true"
        keyProperty="id">
    insert into user
    (username, user_email, user_city, age)
    values
    <foreach item="item"  collection="array" separator=",">
        (#{item.username}, #{item.userEmail}, #{item.userCity}, #{item.age})
    </foreach>
</insert>

#{}与${}取值区别

#{}是以预编译的形式将参数设置到sql语句中,防止SQL注入,${}取出的值直接拼装在SQL语句中,会有安全问题。

不过有时你就是想直接在 SQL 语句中插入一个不转义的字符串。 比如,像 ORDER BY,你可以这样来使用

ORDER BY ${columnName}

这里 MyBatis 不会修改或转义字符串。

当 SQL 语句中的元数据(如表名或列名)是动态生成的时候,字符串替换将会非常有用。 举个例子,如果你想通过任何一列从表中 select 数据时,不需要像下面这样写:

@Select("select * from user where id = #{id}")
User findById(@Param("id") long id);

@Select("select * from user where name = #{name}")
User findByName(@Param("name") String name);

@Select("select * from user where email = #{email}")
User findByEmail(@Param("email") String email);

可以只写这样一个方法:

@Select("select * from user where ${column} = #{value}")
User findByColumn(@Param("column") String column, @Param("value") String value);

其中 ${column} 会被直接替换,而 #{value} 会被使用 ? 预处理。因此你就可以像下面这样来达到上述功能:

User userOfId1 = userMapper.findByColumn("id", 1L);
User userOfNameKid = userMapper.findByColumn("name", "kid");
User userOfEmail = userMapper.findByColumn("email", "noone@nowhere.com");

这个方法也同样适用于用来替换表名的情况。

#{}指定 jdbcType

只需要在可能执行插入、更新和删除的且允许空值的列上指定 JDBC 类型。这是 JDBC 的要求而非 MyBatis 的要求。

为了以后可能的使用场景,MyBatis 通过内置的 jdbcType 枚举类型支持下面的 JDBC 类型。

BITFLOATCHARTIMESTAMPOTHERUNDEFINED
TINYINTREALVARCHARBINARYBLOBNVARCHAR
SMALLINTDOUBLELONGVARCHARVARBINARYCLOBNCHAR
INTEGERNUMERICDATELONGVARBINARYBOOLEANNCLOB
BIGINTDECIMALTIMENULLCURSORARRAY

在我们数据为null的时候,有些数据库可能不能识别MyBatis对null的默认处理。比如Oracle,MyBatis对所有的null都映射成原生JDBC的OTHER类型,Oracle不能正确处理,但是MySQL却能处理。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值