mybatis中大于、小于、不等于
mybatis中可以直接使用>和<,但是不能直接使用>=和<=,通常在mybatis中的运算符这样写:
<(小于)、>(大于)、<=(小于等于)、<=(大于等于)、<>(不等于<>)
或者使用<![CDATA[ ]]>包裹
<![CDATA[ >= ]]>(大于等于)、<![CDATA[ != ]]>/<![CDATA[ <> ]]>(不等于<>)
${}和#{}的区别
- #将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号。如:order by #{user_id}如果传的值是12将被解析为order by “12”
- $将传入的数据直接显示生成在sql中。如:order by u s e r i d 如果传的值是 12 将被解析为 o r d e r b y 12 ; 如果传的值是 i d ,将被解析为 o r d e r b y i d 。所以 {user_id}如果传的值是12将被解析为order by 12;如果传的值是id,将被解析为order by id。所以 userid如果传的值是12将被解析为orderby12;如果传的值是id,将被解析为orderbyid。所以{}有sql注入风险。
- #{} 的参数替换是发生在 DBMS(数据库管理系统) 中,而 ${} 则发生在动态解析过程中。
Mapper接口传单参数使用默认变量名为_parameter
List<Person> queryByParam(String pname);
xml中获取参数时,如果是要进行非null的判断,则不可在if后直接那变量名进行判空,因为mybatis会默认变量名为_parameter,否则会报no getter/setter错误。
<select id="queryByParam" resultType="com.example.springbootmybatis.bean.Person" parameterType="string">
select * from t_person
<where>
<if test="pname != null and pname != ''">
pname = #{pname}
</if>
</where>
</select>
以上写法会报错:org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.reflection.ReflectionException: There is no getter for property named ‘pname’ in ‘class java.lang.String’
需要这样写:
<if test="_parameter != null and _parameter != ''">pname = #{pname}</if>
如果不想使用默认参数,需要通过@Param注解指定。
@Param注解
作用是给参数命名,参数命名后就能根据名字得到参数值。
如果在方法上一个参数@Param("aaaa") String name,xml中可以通过#{aaaa}取值
如果参数是对象,@Param(value = "st")student student,xml中通过#{st.属性名}取值
xml中if判断各类型参数是否为空
在sql中如果拿传入的时间类型参数与空字符串进行比较,会出异常,if判断中只需要写 即可,枚举类型的也只判null,包装类如Boolean,Integer等也都不判’’ 另外list判断:temp != null and temp.size() >0
布尔类型处理
- 保存布尔类型时要使用Boolean,不要使用boolean,否则使用@Data的时候boolean会生成is**方法,而没有get方法
- 保存布尔类型时在xml中if判断的时候只判null,不要判’',否则保存false的时候值保存不上,为空值不是我们想要的0
- 数据库会保存1(true)、0(false)
- 查询时传true/false或者字符串的"true"/"false"都可以
foreach标签
常见属性:
item表示集合中每一个元素进行迭代时的别名,即指map或list的value(值)
index指 定一个名字,用于表示在迭代过程中,每次迭代到的位置,在数组集合里这个单词就是指下标,在map中指map的key
open表示该语句以什么开始,
separator表示在每次进行迭代之间以什么符号作为分隔符,
close表示以什么结束。
collection接收传来的数据
collection取值
-
如果传入的是单参数且参数类型是一个List的时候,collection属性值为list。
-
如果传入的是单参数且参数类型是一个array数组的时候,collection的属性值为array。
-
MAP中有list或array时,foreach中的collection必须是具体list或array的变量名。比如这里MAP含有一个名为idList的list,所以MAP中用idList取值。
map.put("idList",ids); map.put("address",goodsAddress);
<if test="idList != null and idList.size >0 "> id in <foreach collection="idList" item="item" open="(" close=")" separator=","> #{item} </foreach> </if>
-
JAVA对象中有list或array时,foreach中的collection必须是具体list或array的变量名。比如查询对象中含有一个名为addressList的list,取值如下。
private List<String> addressList;
<if test="addressList != null and addressList.size > 0 "> goods_address in <foreach collection="addressList" item="item" open="(" close=")" separator=","> #{item} </foreach> </if>
MyBatis参数条件查询传入的值为0时的判断
<if test="randomVal!=null and randomVal!=''>
limit #{randomVal},1
</if>
当randomVal为0时,以上这种是不行的,MyBatis解析的所有sqlNode节点,针对if节点会交给IfSqlNode来处理,经过层层处理,最终都会调用OgnlOps.class类的doubleValue(Object value)方法,0和""都调用该方法返回的double值都为0.0,再进行比较。可以使用如下写法:
<if test="randomVal!=null and randomVal!='' or 0 == randomVal">
limit #{randomVal},1
</if>
或者
<if test="testValue!=null">
limit #{randomVal},1
</if>
parameterType
将会传入这条语句的参数的类全限定名或别名。这个属性是可选的,因为 MyBatis 可以通过类型处理器(TypeHandler)推断出具体传入语句的参数,默认值为未设置(unset)。
resultType
期望从这条语句中返回结果的类全限定名或别名。 注意,如果返回的是集合,那应该设置为集合包含的类型,而不是集合本身的类型。 resultType 和 resultMap 之间只能同时使用一个。