MyBatis中parameterType参数传递与获取,#{}和${}区别,LIKE查询
Mybatis传入参数类型
在MyBatis的select、insert、update、delete这些元素中都提到了parameterType这个属性。MyBatis现在可以使用的parameterType传入以下类型的参数,拼接sql语句。
- 基本类型:int,String,long,Date;
- 集合类型:数组,List,Map
- 对象类型:POJO对象
一、传入基本类型
- 通过#{参数名},只能传入一个参数;(如果只有一个参数,参数名可以随便写)
- 通过#{arg0}、#{arg1}…或者#{param1},#{param2}…索引方式,可以传入多个参数;
- 如果通过#{参数名}传多个值,又不想使用索引方式,可以使用@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>
二、传入集合类型
- 传入数组类型
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>
注意:
- 用到foreach循环遍历数组,foreach标签中的属性有,collection,open,separator,close,item
- collection:单独传入list时,当传入的类型是List集合时,它的值为list;单独传入数组时,当传入的类型为数组时,它的值为array。
- open:是以某字符开头,separator:字符串之间分隔符,close:是以某字符结束
- item:遍历的当前对象
- 以上完成的sql语句为:
select * from t_goods where goodsId in (1,2,3,4,5)
- 传入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>
注意:
- parameterType的类型为java.util.List,但是不写也不会错误
- collection属性为list
- item为当前对象
- separator:必须有,不写会出现错误
- 以上完成的sql语句为:
insert into user ( username, password, name, age, sex, phone ) values (?,?,?,?,?,?) , (?,?,?,?,?,?) , (?,?,?,?,?,?)(?,?,?,?,?,?) 为插入的数据条数
- 传入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文件所在的包名
四、#{}和${}的区别
简单概括就是:
- #{}拿到值之后,拼装sql,会自动对值添加单引号"
- ${}则把拿到的值直接拼装进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('%',?,'%')
- mybatis parameterType 传递多个参数
- 关于向Mybatis传递多个参数进行SQL查询的用法
- Mybatis 参数无法获取Parameter not found
- mybatis参数传递与拦截获取
- Mybatis中模糊查询时相关的参数传递及xml配置
- Mybatis传递单个参数(string)时,获取参数失败
- MyBatis学习总结(13)——Mybatis查询之resultMap和resultType区别
- Mybatis参数获取时$与#的区别
- mybatis 传递多个参数 --解决mybatis查询使用多个参数方法--javabean传统方法和map方法
- Mybatis 传递参数和模糊查询
- 12、Mybatis中用#{}和${}获取输入参数的区别
- MyBatis输入类型parameterType#{}与${}的区别
- MyBatis 之parameterType属性—传入参数
- SpringMVC中使用Ajax POST请求以json格式传递参数服务端通过request.getParameter("name")无法获取参数值问题分析
- mybatis常见问题处理:批量操作,传递多个参数,like语句写法等等
- MyBatis 传入参数之parameterType
- mybatis中的#和$的区别以及mybatis like查询
- MyBatis的传入参数parameterType类型
- MyBatis的传入参数parameterType类型
- MyBatis传入参数与parameterType