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

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('%',?,'%') 
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值