2022-08-23
Mybatis映射文件深入
动态sql语句
概述:Mybatais的映射文件中,前面我们的SQL都是比较简单的,有时候业务逻辑复杂时,我们的sql时动态变化的,此时在其那面学习的sql就不能满足要求了
官方文档中动态sql
MyBatis 的强大特性之一便是它的动态 SQL。如果你有使用 JDBC 或其他类似框架的经验,你就能体会到根据不同条件拼接 SQL 语句有多么痛苦。拼接的时候要确保不能忘了必要的空格,还要注意省掉列名列表最后的逗号。利用动态 SQL 这一特性可以彻底摆脱这种痛苦。
通常使用动态 SQL 不可能是独立的一部分,MyBatis 当然使用一种强大的动态 SQL 语言来改进这种情形,这种语言可以被用在任意的 SQL 映射语句中。
动态 SQL 元素和使用 JSTL 或其他类似基于 XML 的文本处理器相似。在 MyBatis 之前的版本中,有很多的元素需要来了解。MyBatis 3 大大提升了它们,现在用不到原先一半的元素就可以了。MyBatis 采用功能强大的基于 OGNL 的表达式来消除其他元素。
if
choose (when, otherwise)
trim (where, set)
foreach
动态SQL之if
测试示例if
UserMapper接口下
package com_Mybatis_sql.mapper; import com_Mybatis_sql.pojo.User; import java.util.List; public interface UserMapper { public List<User> findByCondition(User user); }
UserMapper2.xml文件下
<?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_Mybatis_sql.mapper.UserMapper"> <select id="findByCondition" parameterType="user" resultType="user"> select *from user -- 用where标签保住等价于where 1=1,有条件就进入 <where> <if test="id!=0"> and id=#{id} </if> <if test="username!=null"> and username=#{username} </if> <if test="password!=null"> and password=#{password} </if> </where> </select> </mapper>
test测试下
public class MapperTest { @Test public void test1() throws IOException { InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml"); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream); SqlSession sqlSession = sqlSessionFactory.openSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); //模拟条件user User user=new User(); user.setId(1); user.setUsername("zhangsan"); user.setPassword("123"); List<User> userList = mapper.findByCondition(user); System.out.println(userList); } }
运行结果
当没有写条件时,原来的sql语句就等价于select *from user
<select id="findByIds" parameterType="list" resultType="user"> select *from user <where> <foreach collection="list" open="id in(" close=")" item="id" separator=","> #{id} </foreach> </where> </select>
这样的动态查询无论是有没有条件或者是有多个条件都能查询到
循环执行sql的拼接操作,例如::select *from user where id in(1,2,3)
UserMapper接口下
public interface UserMapper { public List<User> findByIds(List<Integer> ids); }
配置文件UserMapper2.xml配置文件下
<select id="findByIds" parameterType="list" resultType="user"> select *from user <where> <foreach collection="list" open="id in(" close=")" item="id" separator=","> #{id} </foreach> </where> </select>
MapperTest测试类下
public class MapperTest { @Test public void test2() throws IOException { InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml"); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream); SqlSession sqlSession = sqlSessionFactory.openSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); //模拟ids的数据 List<Integer> ids=new ArrayList<Integer>(); ids.add(1); ids.add(2); List<User> byIds = mapper.findByIds(ids); System.out.println(byIds); } }
运行结果
sql中可将重复的sql提取出来,使用include引用即可,最终达到sql重用的目的
<!--sql语句抽取--> <sql id="selectUser"> select *from user</sql> <select id="findByIds" parameterType="list" resultType="user"> <include refid="selectUser"></include> <where> <foreach collection="list" open="id in(" close=")" item="id" separator=","> #{id} </foreach> </where> </select>
<select>:查询
<insert>:插入
<update>:修改
<delete>:删除
<where>:where条件
<if>:if判断
<foreach>:循环
<sql>:sql片段抽取
资料摘自:https://blog.csdn.net/weixin_60719453/article/details/126450239