动态SQL
动态 SQL,主要用于解决查询条件不确定的情况:在程序运行期间,根据用户提交的查询条件进行查询。提交的查询条件不同,执行的 SQL 语句不同。若将每种可能的情况均逐一列出,对所有条件进行排列组合,将会出现大量的 SQL 语句。此时,可使用动态 SQL 来解决这样的问题。
动态 SQL,即通过 MyBatis 提供的各种标签对条件作出判断以实现动态拼接 SQL 语句。这里的条件判断使用的表达式为 OGNL 表达式。 常用的动态 SQL 标签有<if/>、 <where/>、<choose/>、<foreach/>等。
MyBatis 的动态 SQL 语句,与 JSTL 中的语句非常相似。
项目实例
(1) 定义数据库表
(2) 定义实体
public class Student {
private Integer id;
private String name;
private int age;
private double score;
}
(3) 创建工具类
public class MyBatisUtils {
private static SqlSessionFactory sqlSessionFactory;
public static SqlSession getSqlSession() {
try {
InputStream is = Resources.getResourceAsStream("mybatis.xml");
if (sqlSessionFactory == null) {
sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
}
return sqlSessionFactory.openSession();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
(4)定义测试类
定义 @Before 与 @After 方法
public class MyTest {
private IStudentDao dao;
private SqlSession sqlSession;
@Before
public void setUp() {
sqlSession = MyBatisUtils.getSqlSession();
dao = sqlSession.getMapper(IStudentDao.class);
}
@After
public void tearDown() {
if (sqlSession != null) {
sqlSession.close();
}
}
}
注意:
在 mapper 的动态 SQL 中若出现大于号(>)、小于号(<)、大于等于号(>=),小于等于号(<=)等符号,最好将其转换为实体符号。否则, XML 可能会出现解析出错问题。特别是对于小于号(<),在 XML 中是绝对不能出现的。否则,一定出错。
<if/>标签
对于该标签的执行,当 test 的值为 true 时,会将其包含的 SQL 片断拼接到其所在的 SQL语句中。这引发的问题是,查询条件不确定,查询条件依赖于用户提交的内容。此时,就可使用动态 SQL 语句,根据用户提交内容对将要执行的 SQL 进行拼接。
(1)定义 Dao 接口
public interface IStudentDao {
List<Student> selectStudentsByIf(Student student);
}
(2)定义映射文件
为了解决两个条件均未做设定的情况,在 where 后添加了一个“1=1”的条件。这样就不至于两个条件均未设定而出现只剩下一个 where,而没有任何可拼接的条件的不完整 SQL 语句。
<!-- if标签 -->
<select id="selectStudentsByIf" resultType="Student">
select id,name,age,score
from student
where 1 = 1
<if test="name != null and name != ''">
and name like '%' #{name} '%'
</if>
<if test="age > 0">
and age > #{age}
</if