在 MyBatis 中,有几种方式可以根据变量动态执行 SQL 语句:
MyBatis 提供了一系列动态 SQL 标签:
<select id="findUsers" parameterType="map" resultType="User">
SELECT * FROM users
<where>
<if test="name != null">
AND name = #{name}
</if>
<if test="age != null">
AND age = #{age}
</if>
<choose>
<when test="orderBy == 'name'">
ORDER BY name
</when>
<when test="orderBy == 'age'">
ORDER BY age
</when>
<otherwise>
ORDER BY id
</otherwise>
</choose>
</where>
</select>
<script>
标签执行动态 SQL可以在 Mapper 接口中使用 @Select
注解结合 <script>
标签:
@Select({"<script>",
"SELECT * FROM users",
"<where>",
" <if test='name != null'> AND name = #{name}</if>",
" <if test='age != null'> AND age = #{age}</if>",
"</where>",
"</script>"})
List<User> findUsers(Map<String, Object> params);
创建 SQL 提供者类:
public class UserSqlProvider {
public String findUsers(Map<String, Object> params) {
return new SQL() {{
SELECT("*");
FROM("users");
if (params.get("name") != null) {
WHERE("name = #{name}");
}
if (params.get("age") != null) {
WHERE("age = #{age}");
}
}}.toString();
}
}
然后在 Mapper 接口中使用:
@SelectProvider(type = UserSqlProvider.class, method = "findUsers")
List<User> findUsers(Map<String, Object> params);
@Select
注解结合条件判断@Select("SELECT * FROM users WHERE " +
"#{name} IS NULL OR name = #{name} AND " +
"#{age} IS NULL OR age = #{age}")
List<User> findUsers(@Param("name") String name, @Param("age") Integer age);
如果你使用 MyBatis-Plus,可以使用其条件构造器:
public List<User> findUsers(String name, Integer age) {
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
if (name != null) {
queryWrapper.eq("name", name);
}
if (age != null) {
queryWrapper.eq("age", age);
}
return userMapper.selectList(queryWrapper);
}
选择哪种方法取决于你的具体需求和项目架构。对于简单的条件查询,动态 SQL 标签通常是最方便的;对于复杂的逻辑,SQL 提供者可能更合适。