您的位置:首页 > 其它

MyBatis中parameterType参数传递与获取,#{}和${}区别,LIKE查询

2019-07-01 23:03 381 查看

Mybatis传入参数类型

在MyBatis的select、insert、update、delete这些元素中都提到了parameterType这个属性。MyBatis现在可以使用的parameterType传入以下类型的参数,拼接sql语句。

  1. 基本类型:int,String,long,Date;
  2. 集合类型:数组,List,Map
  3. 对象类型:POJO对象

一、传入基本类型

  1. 通过#{参数名},只能传入一个参数;(如果只有一个参数,参数名可以随便写)
  2. 通过#{arg0}、#{arg1}…或者#{param1},#{param2}…索引方式,可以传入多个参数;
  3. 如果通过#{参数名}传多个值,又不想使用索引方式,可以使用@param()注解。

通过#{参数名}: 获取参数中的值
dao中的方法:

public User selectUserByOrgId(long userId);

mapper.xml:

<sql id="Base_Column_List" >
userId,name,age,gender,phone
</sql>

<select id="selectUserByOrgId" parameterType="java.lang.Long"
resultType="Base_Column_List">
select
<include refid="Base_Column_List" />
from user where org_id = #{userId}
</select>

通过#{0}、#{1}……索引方式,传入多个参数
dao中的方法:

public User selectUser(String username,String password);

mapper.xml:

<select id="selectUser" resultType="Base_Column_List">
select
<include refid="Base_Column_List" />
from user where username= #{0} and password= #{1}
</select>

#{参数名},传入多个参数,并且参数用@param注解 (推荐)
dao中的方法:

public User selectUser(@Param("username") String username,
@Param("password") String password);

mapper.xml:

<select id="selectUser" resultType="Base_Column_List">
select
<include refid="Base_Column_List" />
from user where username= #{username} and password= #{password}
</select>

注意:

在sql动态语句中经常会有根据数据库某个字段状态进行判断的,但在Mybatis中如果用了if判断那么传进来的参数时,不能直接单独传入,要封装到Map或对象中。例如下边代码会出错:

<select id="selectUserById" parameterType="int"
resultType="Base_Column_List">
select
<include refid="Base_Column_List" />
from user
<if test="userId!=0">
where userId= #{userId}
</if>
</select>

因为java的int类型默认值为0,导致0与null的判定无法识别
Mybatis默认采用ONGL解析参数,所以会自动采用对象树的形式取Integer.userId。Integer对象没有userId属性。如果不用if标签判断,直接传入不会报错。

解决办法1:参数名全部改为_parameter

<select id="sel_campusinfo" parameterType="int" resultType="Campusinfo">
select
<include refid="Base_Column_List" />
from user
<if test="_parameter!=0">
where userId= #{userId}
</if>
</select>

解决办法2
dao中的方法设置为:

User seleteUserById(@Param("id") int id);

mapper.xml:

<select id="seleteUserById" parameterType="int" resultMap="BaseResultMap">
select
<include refid="Base_Column_List"/>
from user
<if test="id!=0">
where id = #{id}
</if>
</select>

二、传入集合类型

  1. 传入数组类型
    dao中的方法:
//goodsIdArray = {1,2,3,4,5}
List<Goods> queryGoodsArray(long[] goodsIdArray);

mapper.xml:

<sql id="Base_Column_List">
id, userId, userName, goodsId, goodsName, goodsPic, goodsStyle, goodsPrice, goodsNum,
storeId, storeName, addTime
</sql>

<!-- 查询满足goodsId等于goodsIdArray中的值 -->
<select id="queryGoodsArray" resultMap="Base_goods_List">
select * from t_goods
where goodsId in
<foreach collection="array" open="(" separator="," close=")" item="goodsId">
#{goodsId}
</foreach>
</select>

注意:

  1. 用到foreach循环遍历数组,foreach标签中的属性有,collection,open,separator,close,item
  2. collection:单独传入list时,当传入的类型是List集合时,它的值为list;单独传入数组时,当传入的类型为数组时,它的值为array。
  3. open:是以某字符开头,separator:字符串之间分隔符,close:是以某字符结束
  4. item:遍历的当前对象
  5. 以上完成的sql语句为:
select * from t_goods where goodsId in (1,2,3,4,5)
  1. 传入List类型
    当涉及到批量操作数据时,可能会涉及到传入参数为list。
    dao中的方法:
int addUsers(List<User> users);

mapper.xml:

<sql id="addUser">
username, password, name, age, sex, phone
</sql>

<insert id="addUsers" parameterType="java.util.List">
insert into user
(  <include refid="addUser" />  )
values
<foreach collection="list" item="user" separator=",">
(
#{user.username},
#{user.password},
#{user.name},
#{user.age},
#{user.sex},
#{user.phone}
)
</foreach>
</insert>

注意:

  1. parameterType的类型为java.util.List,但是不写也不会错误
  2. collection属性为list
  3. item为当前对象
  4. separator:必须有,不写会出现错误
  5. 以上完成的sql语句为:
insert into user ( username, password, name, age, sex, phone )
values (?,?,?,?,?,?) , (?,?,?,?,?,?) , (?,?,?,?,?,?)

(?,?,?,?,?,?) 为插入的数据条数

  1. 传入map类型
    (1)如果map中只封装了简单类型,例如:
Map<String,Object> map=new HasMap<String,Object>();
map.put("name","张三");
map.put("age",23);

通过 #{map中的键} 取值。
dao中的方法:

User queryUser(Map map);
<select id="queryUser" parameterType="java.util.Map" resultType="BaseResultMap">
select * from user where name = #{name} and age = #{age}
</select>

(2) 如果Map中有list或array时,foreach中的collection必须是具体list或array的变量名。比如这里Map含有一个名为intList的list,所以Map中用intList取值,这点和单独传list或array时不太一样。例如:

Map<String, Object> map= new HashMap<String, Object>();
List<Integer> intList= new ArrayList<>();
intList.add(1);
intList.add(2);
intList.add(3);
map.put("userId", 123);
map.put("intList", intList);

dao中的方法:

List<User> queryUsers(Map map);

mapper.xml:

<select id="queryUsers" resultMap="BaseResultMap" parameterType="java.util.Map">
select * from user
where 1=1 and intListin
<foreach item="item" index="index" collection="intList"
open="(" separator="," close=")">
#{item}
</foreach>
</select>

(3)如果Map中封装的是实体类,则通过#{key.attributeName}取值,例如:

User user= new User("张三",18);
Map<String,Object> map=new HasMap<String,Object>();
map.put("user",user);

dao中的方法:

User queryUsers(Map map);

mapper.xml:

<select id="selectUserByNameAndAge" parameterType="Map"
resultType="BaseResultMap">
select * from user
where name = #{user.name} and age = #{user.age}
</select>

三、传入对象类型

直接传入实体参数,通过#{属性名}取值,但Java对象中有list或array时,foreach中的collection必须是具体list或array的变量名。
mapper.xml:

<update id="updateByPrimaryKeySelective" parameterType="com.boot.demo.model.User">
update user
<set>
<if test="username != null">
username = #{username,jdbcType=VARCHAR},
</if>
<if test="password != null">
password = #{password,jdbcType=VARCHAR},
</if>
<if test="name != null">
name = #{name,jdbcType=VARCHAR},
</if>
<if test="age != null">
age = #{age,jdbcType=INTEGER},
</if>
<if test="sex != null">
sex = #{sex,jdbcType=VARCHAR},
</if>
<if test="phone != null">
phone = #{phone,jdbcType=VARCHAR},
</if>
</set>
where id = #{id,jdbcType=INTEGER}
</update>

property:属性名,即代码传入的变量名。
javaType:该字段在JAVA中的类型,比如int。
jdbcType:该字段在JDBC中的类型,比如NUMERIC。
column:数据库中字段名
resultMap:结果,可以自行指定
resultType:结果,现成的对象类
namespace:对数据库操作的方法->mapper文件所在的包名

四、#{}和${}的区别

简单概括就是:

  1. #{}拿到值之后,拼装sql,会自动对值添加单引号"
  2. ${}则把拿到的值直接拼装进sql,如果需要加单引号",必须手动添加,一般用于动态传入表名或字段名使用,同时需要添加属性statementType=”STATEMENT”,使用非预编译模式。

statementType属性:
STATEMENT(非预编译):使用Statement查询sql语句,
PREPARED(预编译):使用PreparedStatement 查询sql语句,可防止sql注入

举例:根据用户选择对查询的数据排序

List<User> selectUsers(@Param("str") String str);
<select id="selectUsers" parameterType="String" resultMap="BaseResultMap" statementType="STATEMENT">
select
<include refid="Base_Column_List" />
from user
order by ${str} desc
</select>

这样完成的sql语句为:
当str="age"时

select id, username, password, name, age, sex, phone
from user order by age desc

当str="name"时

select id, username, password, name, age, sex, phone
from user order by name desc

四、LIKE查询

使用like查询可以通过#{},${}和CONCAT()函数连接参数形式三种查询方式,但是#{}和 ${}都有明显的弊端,所以推荐使用CONCAT()函数查询。

使用CONCAT()函数连接参数形式

dao中方法:

List<User> selectUsers(@Param("name") String name);

mapper.xml:

<select id="selectUsers" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from user
where name like CONCAT('%',#{name},'%')
</select>

以上完成的sql语句为:

select * from user where name like CONCAT('%',?,'%')
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: