#动态SQL 拼接
可以根据具体的参数条件,来对SQL语句进行动态拼接
#xml方式实现
数据库添加两个字段age 和phone和对应的数据,age为int 类型,phone为varchar类型
定义一个接口UserDao3
package com.mu.dao;
import com.mu.pojo.User;
import java.util.Map;
import java.util.List;
public interface UserDao3 {
//使用Map方式可以传递多个参数
//if标签
List<User> iftest(Map map);
//where标签
List<User> ifwhere(Map map);
//choose标签
List<User> ifchoose(Map map);
//set标签
void ifset(Map map);
//foreach标签
void ifforeach1(List list);
List<User> ifforeach2(Map map);
//include标签(SQL片段引用)
List<User> ifinclude();
}
编写接口的UserMapper3文件
<?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.mu.dao.UserDao3">
<!--这里添加各示例SQL-->
</mapper>
全局配置文件mybatis-config中加载UserMapper3.xml
新增一个测试类
package com.mu;
import com.mu.dao.UserDao3;
import com.mu.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.Before;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class MyTest2 {
private SqlSessionFactory sqlSessionFactory;
@Before
public void init() throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("mybatis-config.xml");
sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
//下一步在这里添加各示例测试
}
##if
if 标签通常用于 WHERE 语句、UPDATE 语句、INSERT 语句中,通过判断参数值来决定是否使用某个查询条件、判断是否更新某一个字段、判断是否插入某个字段的值。
当满足test条件时,才会将标签内的SQL语句拼接上去
mapper3文件中加入
<!-- if示例
需求:根据年龄和电话号码查询id大于3的用户,如果年龄不为空按年龄查询,电话号码不为空按电话号码查询,如果两者都不为空则组合查询
-->
<select id="iftest" resultType="com.mu.pojo.User" parameterType="map">
SELECT * FROM user WHERE id>3
<if test="age!= null ">
AND age = #{age}
</if>
<if test="phone!= null and phone !='' ">
AND phone = #{phone}
</if>
</select>
添加测试
//在这里添加各示例测试
@Test
public void Test() {
SqlSession sqlSession = sqlSessionFactory.openSession();
UserDao3 mapper = sqlSession.getMapper(UserDao3.class);
HashMap<String, String> map = new HashMap<String, String>();
System.out.println("---根据age查询--->>");
map.put("age", "30");
List<User> userList = mapper.iftest(map);
//这里使用lambda表达式遍历
userList.forEach(System.out::println);
//清空map和userlist
System.out.println("---根据phone查询--->>");
map.clear();
userList.clear();
map.put("phone", "08610021");
userList = mapper.iftest(map);
userList.forEach(System.out::println);
System.out.println("---age和phone联合查询---->>");
map.clear();
userList.clear();
map.put("age", "30");
map.put("phone", "08610021");
userList = mapper.iftest(map);
userList.forEach(System.out::println);
sqlSession.close();
}
测试结果
##where
where标签只会在至少有一个子元素返回了SQL语句时,才会向SQL语句中添加WHERE,并且如果WHERE之后是以AND或OR开头,会自动将其删掉
mapper3文件中加入
<!-- where示例
需求:同上,区别在于WHERE之后如果是以AND或OR开头,会自动将其删掉
-->
<select id="ifwhere" resultType="com.mu.pojo.User" parameterType="map">
SELECT * FROM user
<where>
<if test="age!= null ">
AND age = #{age}
</if>
<if test="phone!= null and phone !='' ">
AND phone = #{phone}
</if>
</where>
</select>
添加测试
@Test
public void Test3(){
SqlSession sqlSession3 = sqlSessionFactory.openSession();
UserDao3 mapper3 = sqlSession3.getMapper(UserDao3.class);
HashMap<String, String> map3 = new HashMap<String, String>();
System.out.println("---根据age查询---");
map3.put("age", "10");
List<User> userList = mapper3.ifwhere(map3);
userList.forEach(System.out::println);
System.out.println("---根据phone查询---");
map3.clear();
userList.clear();
map3.put("phone", "08610000");
userList = mapper3.ifwhere(map3);
userList.forEach(System.out::println);
System.out.println("---age和phone联合查询---->>");
map3.clear();
userList.clear();
map3.put("age", "10");
map3.put("phone", "08610000");
userList = mapper3.ifwhere(map3);
userList.forEach(System.out::println);
sqlSession3.close();
测试结果
在打开Mapper文件看,发现map集合中age不为空的时候,确实是自动删除了之后是AND
##choose
choose 和 when , otherwise 是配套标签 ,类似于java中的switch,只会选中满足条件的一个
mapper3文件中加入
<!-- choose示例
需求:根据年龄或电话号码查询用户,如果年龄不为空按年龄查询,电话号码不为空按电话号码查询,都不满足则按名字或id查询
都满足则按传入参数第一个条件查询
类似java中的switch,只会选中满足条件的一个,otherwise类似 defatul-->
<select id="ifchoose" resultType="com.mu.pojo.User" parameterType="map">
SELECT * FROM user
<where>
<choose>
<when test="age!= null ">
age = #{age}
</when>
<when test="phone!= null and phone !='' ">
phone = #{phone}
</when>
<otherwise>
name = #{name} OR id = #{id}
</otherwise>
</choose>
</where>
</select>
添加测试
@Test
public void Test4(){
SqlSession sqlSession4 = sqlSessionFactory.openSession();
UserDao3 mapper4 = sqlSession4.getMapper(UserDao3.class);
HashMap<String, String> map4 = new HashMap<String, String>();
System.out.println("---根据age查询---");
map4.put("age", "20");
List<User> userList = mapper4.ifchoose(map4);
userList.forEach(System.out::println);
System.out.println("---根据phone查询");
map4.clear();
userList.clear();
map4.put("phone","08610086");
userList = mapper4.ifchoose(map4);
userList.forEach(System.out::println);
System.out.println("----按名字或id查询-------");
map4.clear();
userList.clear();
map4.put("id","20");
userList = mapper4.ifchoose(map4);
userList.forEach(System.out::println);
sqlSession4.close();
##set
set标签至少有一个子元素返回了SQL语句时,才会向SQL语句中添加SET,并且如果SET之后是以,开头的话,会自动将其删掉
mapper3文件中加入
<!-- set示例
需求:根据名字更新年龄和电话号码,如果年龄不为空则更新年龄,电话号码不为空则更新电话号码
并且如果SET之后是以,开头的话,会自动将其删掉
-->
<update id="ifset" parameterType="map">
update user
<set>
<if test="age != null ">
age = #{age},
</if>
<if test="phone!= null and phone !='' ">
phone =#{phone}
</if>
</set>
where name =#{name}
</update>
添加测试
@Test
public void Test5(){
SqlSession sqlSession5 = sqlSessionFactory.openSession();
UserDao3 mapper5 = sqlSession5.getMapper(UserDao3.class);
HashMap<String, String> map5 = new HashMap<String, String>();
System.out.println("---更改前---");
List<User> userList= mapper5.ifinclude();
userList.forEach(System.out::println);
System.out.println("--更改朱八的age和phone--");
map5.put("name","朱八");
map5.put("age","25");
map5.put("phone","08610099");
mapper5.ifset(map5);
sqlSession5.commit();
map5.clear();
System.out.println("--更改杜十的age为50--");
map5.put("name","杜十");
map5.put("age","50");
mapper5.ifset(map5);
sqlSession5.commit();
System.out.println("---更改后---");
userList.clear();
userList= mapper5.ifinclude();
userList.forEach(System.out::println);
sqlSession5.close();
}
测试结果
在打开Mapper文件看,发现map集合中只有age不为空的时候,set标签自动删除了sql语句后的“ ,”号
##foreach
foreach标签用来做迭代拼接的,通常会与SQL语句中的IN查询条件结合使用
需求1:把id=1,4,10,20的用户年龄都修改为22
原生sql语句:update user set age = 22 where id in (1,4,10,20)
需求2:查询id=1,4,10,20且phone != '08610001’用户的全部信息
示例2原生sql 语句:select * from user where phone != ‘08610001’ and(id=1 or id=4 or id =10 or id=20)
mapper3文件中加入
<!-- foreach示例
collection:指定输入对象中的集合属性
item:每次遍历生成的对象
open:开始遍历时的拼接字符串
close:结束时拼接的字符串
separator:遍历对象之间需要拼接的字符串
示例1:update user set age = 22 where id in (1,4,10,20)
示例2:select * from user where phone != '08610001' and(id=1 or id=4 or id =10 or id=20)
-->
<update id="ifforeach1" parameterType="list">
update user set age = 22 where id in
<foreach collection="list" item="item" open="(" close=")" separator=",">
#{item}
</foreach>
</update>
<select id="ifforeach2" resultType="com.mu.pojo.User" parameterType="map" >
select * from user where phone != '08610001' and
<foreach collection="list" item="id" open="(" close=")" separator="or">
id=#{id}
</foreach>
</select>
添加测试
@Test
public void Test6(){
SqlSession sqlSession6 = sqlSessionFactory.openSession();
UserDao3 mapper6 = sqlSession6.getMapper(UserDao3.class);
List list = new ArrayList();
list.add(1);
list.add(4);
list.add(10);
list.add(20);
HashMap map6 = new HashMap();
map6.put("list",list);
System.out.println("-----示例2--------");
List<User> userList= mapper6.ifforeach2(map6);
userList.forEach(System.out::println);
System.out.println("-----示例1--------");
mapper6.ifforeach1(list);
sqlSession6.commit();
System.out.println("-----更改后的示例2--------");
userList.clear();
userList= mapper6.ifforeach2(map6);
userList.forEach(System.out::println);
}
@Test
测试结果
##SQL片段
可将重复的SQL片段提取出来,然后在需要的地方,使用标签进行引用,增加代码的重用性
mapper3文件中加入
<!-- include 标签sql片段引用示例 -->
<sql id="find">
select * from user
</sql>
<select id="ifinclude" resultType="com.mu.pojo.User" >
<include refid="find"></include>
</select>
添加测试
@Test
public void Test7(){
SqlSession sqlSession7 = sqlSessionFactory.openSession();
UserDao3 mapper7 = sqlSession7.getMapper(UserDao3.class);
List<User> userList= mapper7.ifinclude();
userList.forEach(System.out::println);
}
共有条评论 网友评论