Mybatis整理系列(01)————传入参数方式以及#{}与${}的区别
1、如果传入的parameterType是Map/Object,在Map/Object中定义的属性在where条件中可以直接使用,不管是精准搜索(=)还是模糊搜索(LIKE)
<select id="countByRole" parameterType="java.util.Map" resultType="java.lang.Integer">
select count(*)
FROM t_enterprise_invest_detail T JOIN t_enterprise_base_info B ON T.ENTERPRISE_USCC = B.ENTERPRISE_USCC
<where>
T.status=101001
<if test="investDetailId!=null">
AND T.INVEST_DETAIL_ID = #{investDetailId, jdbcType=VARCHAR}
</if>
<if test="enterpriseName!=null">
AND T.ENTERPRISE_NAME LIKE '%' #{enterpriseName,jdbcType=VARCHAR} '%'
</if>
<if test="enterpriseUscc!=null">
AND T.ENTERPRISE_USCC = #{enterpriseUscc,jdbcType=VARCHAR}
</if>
<if test="enterpriseId!=null">
AND T.ENTERPRISE_ID = #{enterpriseId,jdbcType=VARCHAR}
</if>
<if test="investDetailDes != null">
AND INVEST_DETAIL_DES LIKE '%' #{investDetailDes, jdbcType=VARCHAR} '%'
</if>
</where>
</select>
2、如果传入的parameterType是java.lang.Integer/java.lang.String,传入的参数可以进行精准搜索(=),不可以模糊搜索(LIKE)。刚开始以为是因为id设置的定义与其他字段不同,其实应该和这个没关系。
<resultMap id="BaseResultMap" type="com.jsptpd.gayg.common.model.DicType">
<id column="TYPE_ID" jdbcType="INTEGER" property="typeId" />
<result column="TYPE_NAME" jdbcType="VARCHAR" property="typeName" />
<result column="P_TYPE_ID" jdbcType="INTEGER" property="pTypeId" />
<result column="STATUS" jdbcType="INTEGER" property="status" />
<result column="ORDER_NO" jdbcType="INTEGER" property="orderNo" />
<result column="KEY_VALUE" jdbcType="VARCHAR" property="keyValue" />
<result column="OPERATOR" jdbcType="VARCHAR" property="operator" />
<result column="OPERATE_TIME" jdbcType="TIMESTAMP" property="operateTime" />
</resultMap>
如果传入的parameterType是java.lang.Integer/java.lang.String条件下正确的
<select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from t_dic_type
where TYPE_ID = #{typeId,jdbcType=INTEGER}
</select>
如果传入的parameterType是java.lang.Integer/java.lang.String条件下错误的。报错如下:nested exception is org.apache.ibatis.binding.BindingException: Parameter ‘INTEGER’ not found. Available parameters are [pTypeId, param1]。得出:parameterType是Integer/String时,不可以进行模糊搜索。
<select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from t_dic_type
where TYPE_ID LIKE '%'#{typeId,jdbcType=INTEGER}'%'
</select>
不管是改dao中指定属性名@Param("typeId")还是修改xxMapper.xml中where后的搜索条件都不行
DicType selectByPrimaryKey(@Param("typeId")Integer typeId);
P_TYPE_ID LIKE '%' ${pTypeId} '%'
P_TYPE_ID LIKE '%' ${pTypeId,jdbcType=INTEGER} '%'
P_TYPE_ID LIKE '%' #{pTypeId,jdbcType=INTEGER} '%'
精准搜索(=):不管是新的参数名还是数据库中表对应的Object中的参数
① #{参数名},传入一个参数
DAO方法:
public List<User> selectUserByOrgId(String orgId);
Mapper.xml:
<select id="selectUserByOrgId" parameterType="java.lang.String" resultType="user">
select * from user where org_id = #{orgId}
</select>
service:
List<User> users = userDao.selectUserByOrgId("1");
② #{0}、#{1}……索引方式,传入多个参数
DAO方法:
public User selectUserByNameAndAge(String name,int age);
Mapper.xml:
<select id="selectUserByNameAndAge" resultType="user">
select * from user where name = #{0} and age = #{1}
</select>
service:
User user = userDao.selectUserByNameAndAge("lucy",18);
③ #{参数名},传入多个参数,并且参数用@param注解
DAO方法:
public User selectUserByNameAndAge(@param("name")String name,@param("age")int age);
Mapper.xml:
<select id="selectUserByNameAndAge" resultType="user">
select * from user where name = #{name} and age = #{age}
</select>
service:
User user = userDao.selectUserByNameAndAge("lucy",18);
模糊搜索(LIKE):
① 当传入的字段类型是Integer
DAO方法:
List<DataList> selectByPTypeId(Integer pTypeId);
Mapper.xml:不使用CONCAT(错误的示例)
<select id="selectByPTypeId" resultMap="DataListMap">
select TYPE_ID, TYPE_NAME, P_TYPE_ID,KEY_VALUE
from t_dic_type
where P_TYPE_ID LIKE CONCAT('%', #{pTypeId,jdbcType=INTEGER}, '%')
</select>
如果传入的是Integer型参数,虽然是#{pTypeId,jdbcType=INTEGER}
(区别$)但是Mapper.xml在处理的时候不会对这个参数加上引号,实际的sql语句是:
select TYPE_ID, TYPE_NAME, P_TYPE_ID,KEY_VALUE from t_dic_type where P_TYPE_ID LIKE '%' ? '%'
Mapper.xml:使用CONCAT(正确误的示例)
<select id="selectByPTypeId" resultMap="DataListMap">
select TYPE_ID, TYPE_NAME, P_TYPE_ID,KEY_VALUE
from t_dic_type
<!-- where P_TYPE_ID LIKE '%' #{pTypeId,jdbcType=INTEGER} '%'-->
where P_TYPE_ID LIKE CONCAT('%', #{pTypeId,jdbcType=INTEGER}, '%')
</select>
但是如果使用CONCAT的话,虽然也不会加引号,但是实际的sql是可以查询到数据的,sql语句是:
select TYPE_ID, TYPE_NAME, P_TYPE_ID,KEY_VALUE from t_dic_type where P_TYPE_ID LIKE CONCAT('%', ?, '%')
② 当传入的字段类型是String
不管加没加CONCAT都可以查询到数据,可能是因为Mapper.xml在处理的时候会自动加上引号。
DAO方法:
List<DataList> selectByPTypeId(String pTypeId);
Mapper.xml:
<select id="selectByPTypeId" resultMap="DataListMap">
select TYPE_ID, TYPE_NAME, P_TYPE_ID,KEY_VALUE
from t_dic_type
<!-- where P_TYPE_ID LIKE '%' #{pTypeId,jdbcType=VARCHAR} '%'-->
where P_TYPE_ID LIKE CONCAT('%', #{pTypeId,jdbcType=VARCHAR}, '%')
</select>
所以综上所述,模糊搜索时
parameterType为Integer时
不可以使用 where P_TYPE_ID LIKE '%' #{pTypeId,jdbcType=INTEGER} '%'
但是可以使用 where P_TYPE_ID LIKE CONCAT('%', #{pTypeId,jdbcType=INTEGER}, '%')
parameterType为String时
可以使用 where P_TYPE_ID LIKE '%' #{pTypeId,jdbcType=VARCHAR} '%'
也可以使用 where P_TYPE_ID LIKE CONCAT('%', #{pTypeId,jdbcType=VARCHAR}, '%')
因此,使用模糊搜索时我们尽量使用带CONCAT这种方法。