动态SQL
什么是动态SQL?
MyBatis的官方文档中是这样介绍的?
动态 SQL 是 MyBatis 的强大特性之一。如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL,可以彻底摆脱这种痛苦。
使用动态 SQL 并非一件易事,但借助可用于任何 SQL 映射语句中的强大的动态 SQL 语言,MyBatis 显著地提升了这一特性的易用性。
如果你之前用过 JSTL 或任何基于类 XML 语言的文本处理器,你对动态 SQL 元素可能会感觉似曾相识。在 MyBatis 之前的版本中,需要花时间了解大量的元素。借助功能强大的基于 OGNL 的表达式,MyBatis 3 替换了之前的大部分元素,大大精简了元素种类,现在要学习的元素种类比原来的一半还要少。
换句话说,我们可以根据传入参数的不同,来执行不同的查询条件。
IF标签:
如何使用?
我们首先创建一个Mapper接口,起名为:UserMapper ,并增加一个方法
public interface UserMapper {
public List
<User> findByCondition(User user
);
}
同时创建一个xml文件,起名为UserMapper.xml 然后编写SQL
<mapper namespace
=“com.dxh.dao.UserMapper”>
<select id
=“findByCondition” parameterType
=“com.dxh.pojo.User” resultType
=“com.dxh.pojo.User”>
SELECT * FROM user where 1
=1
<if test
=“id != null”>
and
id = #{id}
</if
>
<if test
=“username != null”>
and username
= #{username}
</if
>
</select
>
</mapper
>
这个SQL的意思是:
当id不为null的时候执行的SQL是:SELECT * FROM user where id = #{id}
当id为null的时候执行的SQL是 SELECT * FROM user where 1=1
很明显我们可以看到where 1=1 是多余的,因此我们可以这样写:
<select id
=“findByCondition” parameterType
=“com.dxh.pojo.User” resultType
=“com.dxh.pojo.User”>
SELECT
* FROM user
<where>
<if test
=“id != null”>
and id
= #
{id
}
</if>
<if test
=“username != null”>
and username
= #
{username
}
</if>
</where
>
</select
>
测试:
编写一个测试类:
package com
.dxh
.test
;
import com
.dxh
.dao
.UserMapper
;
import com
.dxh
.pojo
.User
;
import org
.apache
.ibatis
.io
.Resources
;
import org
.apache
.ibatis
.session
.SqlSession
;
import org
.apache
.ibatis
.session
.SqlSessionFactory
;
import org
.apache
.ibatis
.session
.SqlSessionFactoryBuilder
;
import org
.junit
.Test
;
import java
.io
.IOException
;
import java
.io
.InputStream
;
import java
.util
.List
;
public class TestMain {
@Test
public void test1() throws IOException
{
InputStream resourceAsStream
= Resources
.getResourceAsStream(“sqlMapConfig.xml”);
SqlSessionFactory build
= new SqlSessionFactoryBuilder().build(resourceAsStream
);
SqlSession sqlSession
= build
.openSession();
UserMapper mapper
= sqlSession
.getMapper(UserMapper
.class);
User user
= new User();
user
.setId(1);
List
<User> byCondition
= mapper
.findByCondition(user
);
for (User user1
: byCondition
) {
System
.out
.println(user1
);
}
System
.out
.println(“======”);
User user2
= new User();
List
<User> byCondition2
= mapper
.findByCondition(user2
);
for (User user3
: byCondition2
) {
System
.out
.println(user3
);
}
}
}
我们执行两次mapper.findByCondition() ,分别传入user和user2,一个的id有被赋值,一个没有,最后的结果为:
User{id=1, username=lucy}
======
User{id=1, username=lucy}
User{id=2, username=李四}
User{id=3, username=zhaowu}
foreach标签:
当我们需要查询出 id为1、2、3时应该怎么做? SQL应该这样写:SELECT * FROM user where id in (1,2,3)。那么使用mybatis的foreach标签应该如何使用?
如何使用?
在UserMapper接口中增加一个方法:List<User> findByIds(int[] arr);
public List
<User> findByIds(int[] arr
);
在UserMapper.xml 中编写:
<select id
=“findByIds” parameterType
=“list” resultType
=“com.dxh.pojo.User”>
SELECT
* FROM user
<where>
<foreach collection
=“array” open
=“id in (“ close
=“)” item
=“id” separator
=“,”>
#
{id
}
</foreach
>
</where
>
</select
>
我们可以看到,foreach中我们使用到了5个值:
collection 这里就是写我们传入的类型,如果是数组就是array ,如果是集合就是list
open 我们之前说到SELECT * FROM user where id in (1,2,3)正确的SQL应该这样写,那么open就是填写我们需要拼接的前半部分
close 填写我们需要拼接的后半部分
item 我们需要遍历的值是id,所以就填写id
separator ……where id in (1,2,3) 1,2,3之间用,分割。
测试:
@Test
public void test2() throws IOException
{
InputStream resourceAsStream
= Resources
.getResourceAsStream(“sqlMapConfig.xml”);
SqlSessionFactory build
= new SqlSessionFactoryBuilder().build(resourceAsStream
);
SqlSession sqlSession
= build
.openSession();
UserMapper mapper
= sqlSession
.getMapper(UserMapper
.class);
int[] arr
={1,3};
List
<User> byCondition
= mapper
.findByIds(arr
);
for (User user1
: byCondition
) {
System
.out
.println(user1
);
}
}
输出结果:
User{id=1, username=lucy}
User{id=3, username=zhaowu}
正确~
最后
这里只是介绍了两个经常使用的标签,mybatis中还有很多标签,比如choose、when、otherwise、trim、set等等
值得一说的是Mybatis的官方网站中已经支持中文了,母语看着更舒服~
https://mybatis.org/mybatis-3/zh/
到此这篇关于Mybatis动态SQL的文章就介绍到这了。