mybatis中映射文件的SQL深入:动态SQL标签、标签、标签

1.1 概述 

  • mybatis的映射文件中,前面我们的SQL都是比较简单的,有些业务逻辑复杂的时候,我们的SQL是动态变化的。

mybatis中映射文件的SQL深入:动态SQL标签、标签、标签

mybatis中映射文件的SQL深入:动态SQL标签、标签、标签

 1.2 动态SQL之<if>标签

  • 我们根据实体类的不同取值,使用不同的SQL语句来进行查询。比如在id如果不为空时可以根据id查询,如果username不同空时还要加入用户名作为条件。这种情况我们在多条件组合查询中经常会使用到。

1.需求:根据id或者名称查询。 

2.dao 查询方法

public interface IUserDao {

   
/**
     *
查询全部
     */
   
List<User> findAll();

   
/**
     *
条件查询,根据idusername查询
     */
   
List<User> findByCondition(User user);
}

3.接口映射: IUserDao.xml 

   <!-- 动态SQL
        <if> 
条件判断标签
            test 属性,用来判断的表达式,返回boolean类型
                 test="id != 0"  这里的id就是parameterTypeUser对象的id属性。
                                 这里的id也是获取对象的id属性值。
-->

<select id="findByCondition" parameterType="user" resultType="user">
    select * from user where 1=1
   
<!-- 判断 -->
   
<if test="id != 0">
        and id=#{id}
    </
if>
    <if test="username != null">
        and username=#{username}
    </
if>
</select>

4.测试

public class UserDaoTest {

    private InputStream in;
    private SqlSession session;
    private IUserDao userDao;

    // 每次再执行junit测试方法之前执行
    @Before
   
public void before() throws IOException {
        in = Resources.getResourceAsStream("SqlMapConfig.xml");
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        SqlSessionFactory factory = builder.build(in);
        session = factory.openSession();
        userDao = session.getMapper(IUserDao.class);
    }

    @After
   
public void close() throws IOException {
        //关闭
        session.commit();
        session.close();
        in.close();
    }

    @Test
   
public void find() throws IOException {
        User user = new User();
        user.setId(46);
        user.setUsername("马云");
        //执行方法
        List<User> list = userDao.findByCondition(user);
        System.out.println(list);
    }
}

 

1.3 动态SQL之<where>标签

  • 通过<where>标签拼接where条件,简化where写法。 

<select id="findByCondition" parameterType="user" resultType="user">
    select * from user
    <where>
        <!-- 判断 -->
        <if test="id != 0">
            and id=#{id}
        </if>
        <if test="username != null">
            and username=#{username}
        </if>
    </where>

 </select>

 1.4 动态标签之<foreach>标签

  1. 作用:遍历参数值
  2. 查询需求:根据多个id查询

    SELECT * FROM USER WHERE id=41 OR id=42

    SELECT * FROM USER WHERE id IN (41,42)
  3. 定义查询扩展对象,封装多个id值

 /** 当前QueryVo支持User对象的所有属性查询以及扩展属性
 */
public class QueryVo extends User {

    // 条件:多个id
    private List<Integer> ids;

    public List<Integer> getIds() {
        return ids;
    }

    public void setIds(List<Integer> ids) {
        this.ids = ids;
    }
}

dao接口、映射 

mybatis中映射文件的SQL深入:动态SQL标签、标签、标签

!--多个id查询-->
<!--SELECT * FROM USER WHERE 1=1 and id IN (41,42)-->
<!--
    foreach
        collection
遍历的集合
        open       sql语句中最先拼接的部分。遍历的开始
        close      sql语句后最后拼接的部分。遍历的结束
        separator  每一次遍历中,拼接sql语句时候以指定的分割符分割(逗号)
        item       存储每一次遍历的结果
        index      当前遍历元素的索引
-->

<select id="findByCondition2" parameterType="queryvo" resultType="user">
    SELECT * FROM USER WHERE 1=1
    <
if test="ids != null and ids.size()>0">
        <foreach collection="ids" open="and id IN (" separator="," close=")" item="id">
            #{id}
        </
foreach>
    </if>
</select> 

 测试:

@Test
public void find2() throws IOException {
    // 条件
    QueryVo queryVo = new QueryVo();
    List<Integer> ids = new ArrayList<>();
    ids.add(46);
    ids.add(48);
    ids.add(41);
    // 设置条件
    queryVo.setIds(ids);

    //执行方法
    List<User> list = userDao.findByCondition2(queryVo);
    System.out.println(list);
}

1.5 mybatis中简化的SQL片段

  • Sql 中可将重复的 sql 提取出来,使用时用 include 引用即可,最终达到 sql 重用的目的。我们先到 UserDao.xml 文件中使用<sql>标签,定义出公共部分。
  • <!--
        sql
    标签:定义SQL片段,抽取公用的SQL部分
        include标签: 用来引用sql片段
    -->

    <sql id="selectUser">
        SELECT * FROM USER WHERE 1=1
    </
    sql>
    <select id="findByCondition2" parameterType="queryvo" resultType="user">
        <!--引用SQL片段-->
       
    <include refid="selectUser"></include>
        <if test="ids != null and ids.size()>0">
            <foreach collection="ids" open="and id IN (" separator="," close=")" item="id">
                #{id}
            </
    foreach>
        </if>
    </select>
  • 再通过<include>标签的 refid 属性的值就是<sql> 标签定义 id 的取值。
    注意:如果引用其它 mapper.xml 的 sql 片段,则在引用时需要加上 namespace,如下:
    <include refid="namespace.sql 片段”/>