一.MyBatis中的动态SQL
动态SQL是MyBatis中一个非常有用的功能,可以根据不同的条件来动态生成SQL语句,以实现更灵活的数据操作。在MyBatis中,动态SQL可以通过使用if、choose、when、otherwise等标签来实现。这些标签可以根据条件判断来决定是否包含某部分SQL语句
MyBatis提供了几种方式来实现动态SQL:
1. 使用基于XML的动态SQL:在映射文件(mapper.xml)中使用if、choose、when、otherwise等标签来实现条件判断和SQL片段的动态拼接。例如:
<select id="findUser" parameterType="map" resultType="User"> SELECT * FROM user WHERE 1=1 <if test="id != null"> AND id = #{id} </if> <if test="name != null"> AND name = #{name} </if> </select>
在上面的例子中,根据传入的参数map中的id和name是否为空,动态拼接了不同的SQL片段。
2. 使用基于注解的动态SQL:通过在Java方法上使用@SelectProvider、@UpdateProvider等注解,并在对应的Provider类中编写动态SQL逻辑。Provider类可以根据传入参数动态生成SQL语句。例如:
@SelectProvider(type = UserProvider.class, method = "findUser") User findUser(Map<String, Object> params); public class UserProvider { public String findUser(Map<String, Object> params) { StringBuilder sql = new StringBuilder("SELECT * FROM user WHERE 1=1"); if (params.get("id") != null) { sql.append(" AND id = #{id}"); } if (params.get("name") != null) { sql.append(" AND name = #{name}"); } return sql.toString(); } }
上面的例子中,根据传入的参数params中的id和name是否为空,动态拼接了不同的SQL语句。
使用动态SQL能够根据不同的条件生成不同的SQL语句,提高了查询的灵活性和代码的可维护性。在实际开发中,可以根据具体需求选择适合的动态SQL实现方式。
二.MyBatis中的模糊查询
1. # 符号:这种方式是使用预编译的方式处理参数,即将参数值转义后拼接到SQL语句中。在SQL语句执行前,会使用PreparedStatement进行参数绑定。这种方式可以一定程度上防止SQL注入攻击,因为参数值会被转义处理。
例如:
输出结果:
在上面的例子中,#{bname}会将传入的bname值进行预编译转义处理,然后再拼接到SQL语句中。
2. $ 符号:这种方式是直接将参数值按照原样拼接到SQL语句中。在SQL语句执行前,不会进行预编译处理。这种方式适用于处理列名、表名等无法通过预编译处理的情况。然而,这种方式存在SQL注入的风险,因为参数值是直接拼接到SQL语句中,没有经过转义处理。
例如:
输出结果:
在上面的例子中,${bname}会将传入的bname值直接拼接到SQL语句中。
---问题
---所以大家知道 # 和 $ 在MyBatis中的模糊查询中的区别了嘛???
- 使用 # 可以有效防止SQL注入攻击,因为参数值会进行预编译处理。但是,这样会导致SQL语句无法被缓存,因为每次参数值不同,都会生成一个新的预编译SQL语句。使用的时候不需要带引号
- 使用 $ 符号可以处理那些不能被预编译处理的部分,使用符号可以处理那些不能被预编译处理的部分,但是存在SQL注入的风险。此外,使用符号会将参数值直接拼接到SQL语句中,有一定的性能提升,因为SQL语句可以被缓存和重用。在使用的时候需要带引号。并且 $ 可以用来做动态列,完成动态开发
因此,在使用#和$时需要根据具体场景和需求来选择合适的方式。一般来说,推荐使用#符号,并根据需要在SQL语句中使用动态SQL来处理特殊情况下的参数拼接。
MyBatis的模糊查询有三种查询方式,上面已经介绍了两种,还有最后一种
它输出的方式和 # 的是一样的,在企业中一般采用这种方式
三.MyBatis 中的结果映射
在MyBatis的结果映射中,resultType和resultMap是两种不同的方式来指定结果映射规则。
1. resultType:
resultType是一种简单的结果映射方式,用于指定查询结果应该映射到的Java对 象的类型。可以直接指定Java对象的类名或别名。
例如:
<select id="getUserById" resultType="User"> SELECT * FROM user WHERE id = #{id} </select>
在上面的例子中,resultType="User"指定了查询结果应该映射到User对象。
2. resultMap:
resultMap是一种更灵活和复杂的结果映射方式,用于定义详细的结果映射规则。通过 在映射文件(mapper.xml)或注解中定义<resultMap>标签或@Results注解来指定结 映 射规则。可以通过<id>、<result>和<association>等标签或注解来指定如何将查询结果映 射到Java对象的属性。
例如:
<resultMap id="userResultMap" type="User"> <id property="id" column="id"/> <result property="name" column="name"/> <result property="age" column="age"/> <association property="department" javaType="Department"> <id property="id" column="dept_id"/> <result property="name" column="dept_name"/> </association> </resultMap>
在上面的例子中,定义了一个名为userResultMap的结果映射,详细指定了查询结果的字段与Java对象的属性之间的映射关系。
---问题
---所以大家知道 resultType 和 resultMap 在MyBatis中的映射中的区别了嘛???
区别和使用场景:
- resultType适用于简单的结果映射,当查询结果只涉及一个Java对象时,可以使用resultType来指定映射的Java对象类型。这种方式简单明了,适用于简单的查询场景。
- resultMap适用于复杂的结果映射,当查询结果涉及多个Java对象、关联对象或需要自定义映射规则时,可以使用resultMap来定义详细的结果映射规则。这种方式更灵活,适用于复杂的查询场景。