动态SQL
3.1 <if>
元素
是常用的判断语句,主要用于实现某些简单的条件选择。
示例3-1
- 创建项目
- 复制MyBatis Day1的项目src。
- 将配置文件中的数据库信息修改为外部引用。
创建db.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/db_mybatis?serverTimezone=UTC
jdbc.username=root
jdbc.password=root
在MyBatis配置文件中配置properties属性,修改数据库连接信息。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<properties resource="db.properties"/>
<!-- 1.配置环境,默认的环境id为mysql-->
<environments default="mysql">
<!-- 1.2 配置id为mysql的数据库环境-->
<environment id="mysql">
<!-- 使用JDBC事务管理-->
<transactionManager type="JDBC"></transactionManager>
<!-- 数据库连接池-->
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<!-- 2.配置mapper位置-->
<mappers>
<mapper resource="com/ssm/mapper/UserMapper.xml"/>
</mappers>
</configuration>
- 创建一个com.ssm.util包,创建工具类MyBatisUtil,定义获取SqlSession的方法。
package com.ssm.util;
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 javax.annotation.Resource;
import java.io.IOException;
import java.io.InputStream;
public class MyBatisUtil {
private static SqlSessionFactory sqlSessionFactory=null;
static {
try {
String resource = "mybatis-config.xml";
InputStream inputStream= Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
//获取SqlSession
public static SqlSession getSession(){
return sqlSessionFactory.openSession();
}
}
- 修改映射文件,使用
<if>
编写动态SQL
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ssm.mapper.UserMapper">
<!-- 使用if-->
<select id="findUserByNameAndJobs" parameterType="com.ssm.po.User" resultType="com.ssm.po.User">
select * from t_user where 1=1
<if test="username !=null and username !=''">
and username like concat ('%',#{username},'%')
</if>
<if test="jobs !=null and jobs !=''">
and jobs=#{jobs}
</if>
</select>
</mapper>
使用test属性分别进行非空判断,如果传入条件非空,就进行动态SQL组装。
- 创建测试类
package com.ssm.test;
import com.ssm.po.User;
import com.ssm.util.MyBatisUtil;
import org.apache.ibatis.session.SqlSession;
import java.util.List;
public class findUserByNameAndJobsTest {
public static void main(String[] args){
// 通过工具类生成SqlSession对象;
SqlSession sqlSession= MyBatisUtil.getSession();
// 创建user;
User user=new User();
user.setUsername("zhangsan");
user.setJobs("teacher");
// 执行
List<User> users= sqlSession.selectList("com.ssm.mapper.UserMapper.findUserByNameAndJobs",user);
for (User u:users){
System.out.println(u.toString());
}
sqlSession.close();
}
}
首先通过MyBatisUtil工具类获取SqlSession对象,
然后User封装查询条件
通过SqlSession执行查询
关闭SqlSession
运行结果
- 注释掉查询条件,查询所有结果
3.2 <choose>
、<when>
和<otherwise>
元素
类似于Java中的
switch
case
default
示例3-2
- 在映射文件中使用元素执行动态SQL
<!-- 使用choose when otherwise-->
<select id="findUserByNameOrJobs" parameterType="com.ssm.po.User" resultType="com.ssm.po.User">
select * from t_user where 1=1
<choose>
<when test="username !=null and username !=''">
and username like concat('%',#{username},'%')
</when>
<when test="jobs !=null and jobs !=''">
and jobs=#{jobs}
</when>
<otherwise>
and phone is not null
</otherwise>
</choose>
</select>
若第一个when为真则只组装第一个,否则向下判断第二个when;
若都不为真,则执行otherwise。
- 创建测试类
package com.ssm.test;
import com.ssm.po.User;
import com.ssm.util.MyBatisUtil;
import org.apache.ibatis.session.SqlSession;
import java.util.List;
public class findUserByNameOrJobsTest {
public static void main(String[] args){
SqlSession sqlSession= MyBatisUtil.getSession();
User user=new User();
user.setUsername("zhangsan");
user.setJobs("teacher");
List<User> users=sqlSession.selectList("com.ssm.mapper.UserMapper.findUserByNameOrJobs");
for (User u:users){
System.out.println(u.toString());
}
sqlSession.close();
}
}
结果相同。
3.3 <where>
<trim>
元素
where 1=1 为了保证当条件不成立时不会报错。
示例3-3
将where1=1替换。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ssm.mapper.UserMapper">
<!-- 使用if-->
<select id="findUserByNameAndJobs" parameterType="com.ssm.po.User" resultType="com.ssm.po.User">
select * from t_user
<where>
<if test="username !=null and username !=''">
and username like concat ('%',#{username},'%')
</if>
<if test="jobs !=null and jobs !=''">
and jobs=#{jobs}
</if>
</where>
</select>
<!-- 使用choose when otherwise-->
<select id="findUserByNameOrJobs" parameterType="com.ssm.po.User" resultType="com.ssm.po.User">
select * from t_user where 1=1
<choose>
<when test="username !=null and username !=''">
and username like concat('%',#{username},'%')
</when>
<when test="jobs !=null and jobs !=''">
and jobs=#{jobs}
</when>
<otherwise>
and phone is not null
</otherwise>
</choose>
</select>
</mapper>
3.4 <set>
元素
用于更新操作,在动态包含的SQL语句前输出一个set关键词,并将SQL语句中最后一个多余的逗号去除。
示例3-4
<!-- 使用set-->
<update id="updateUser" parameterType="com.ssm.po.User">
update current_user
<set>
<if test="username !=null and username !=''">
username=#{username}
</if>
<if test="jobs !=null and jobs !=''">
jobs=#{jobs}
</if>
<if test="phone !=null and phone !=''">
phone=#{phone}
</if>
</set>
where id=#{id}
</update>
3.5 <foreach>
元素
通常在构建IN条件语句时使用。
示例 3-5
编写映射
<!-- 使用foreach-->
<select id="findUserByIds" parameterType="List" resultType="com.ssm.po.User">
select * from t_user where id in
<foreach collection="list" index="index" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</select>
编写测试类
package com.ssm.test;
import com.ssm.po.User;
import com.ssm.util.MyBatisUtil;
import org.apache.ibatis.session.SqlSession;
import java.util.ArrayList;
import java.util.List;
public class findUserByIdsTest {
public static void main(String[] args){
SqlSession sqlSession= MyBatisUtil.getSession();
// 创建list集合 封闭查询id
List ids=new ArrayList();
ids.add(1);
ids.add(2);
List<User> users=sqlSession.selectList("com.ssm.mapper.UserMapper.findUserByIds",ids);
for(User user:users){
System.out.println(user.toString());
}
sqlSession.close();
}
}
输出结果集
3.6 <bind>
元素
不必使用数据库语言,只要使用MyBatis语言即可与所需参数连接。
<!-- 使用bind-->
<select id="findUserByName2" parameterType="com.ssm.po.User" resultType="com.ssm.po.User">
<bind name="p_username" value="'%'+_parameter.getUsername()+'%'"/>
select * from t_user where username like #{p_username}
</select>
示例3-6
编写测试类
package com.ssm.test;
import com.ssm.po.User;
import com.ssm.util.MyBatisUtil;
import org.apache.ibatis.session.SqlSession;
import java.util.List;
public class findUserByName2 {
public static void main(String[] args){
SqlSession sqlSession=MyBatisUtil.getSession();
User user = new User();
user.setUsername("s");
List<User> users=sqlSession.selectList("com.ssm.mapper.UserMapper.findUserByName2",user);
for (User u:users){
System.out.println(u.toString());
}
sqlSession.close();
}
}