Mybatis-动态SQL、分页插件

动态SQL

介绍

之前存在的问题 

动态 SQL 之

介绍

语法

动态 SQL 之

介绍

语法

SQL片段抽取

介绍

语法

分页插件

什么是分页?

Mybatis中的分页插件

分页插件的使用

开发步骤

分页插件的参数

PageInfo()

核心方法

详细使用


动态SQL

介绍

Mybatis 的映射文件中,前面我们的 SQL 都是比较简单的,有些时候业务逻辑复杂时,我们的 SQL是动态变化的,此时在前面的学习中我们的 SQL 就不能满足要求了。

关于动态SQL参考的官方文档,描述如下:

之前存在的问题 

多条件查询样例:

这个时候我们的SQL语法要怎么写呢?

如果还是使用之前的方法,则就要写两条SQL语句 ,如果再多的话,代码量就会变的越来越大!

所以我们就要用到动态SQL

我们只要学其中的 if foreach 就好。

动态 SQL 之<if>

介绍

<where>:条件标签。如果有动态条件,则使用该标签代替where关键字

<if>:条件判断标签

语法

<if test = "条件判断">

        查询条件拼接

</if>

例如上述案例:

我们只要将StudentMapper.xml,按如下写法即可!!!

注意:是#{},表示${}!!!刚刚不小心写错了,找bug找了好久!!!

<select id="selectCondition" resultType="student" parameterType="student">
    SELECT * FROM student
    <where>
        <if test="id != null">
            id = #{id}
        </if>
        <if test="name != null">
            AND name = #{name}
        </if>
        <if test="age != null">
            AND age = #{age}
        </if>
    </where>
</select>

动态 SQL 之<foreach>

介绍

<foreach>:循环遍历标签。适用于多个参数”或者“的关系

语法

collection:参数容器类型,(list - 集合,array - 数组)

open:开始的SQL语句

close:结束的SQL语句

item:参数的变量名

separator:分隔符

<foreach collection=“”open=“”close=“”item=“”separator=“”>
        获取参数
</foreach>

循环执行sql的拼接操作,例如:SELECT * FROM student WHERE id IN (1,2,5)

<select id="selectByIds" resultType="student" parameterType="list">
    <!-- SELECT * FROM student WHERE id IN (1,2,5) -->
    SELECT * FROM student
    <where>
        <foreach collection="list" open="id IN (" close=")" item="id" separator=",">
            #{id}
        </foreach>
    </where>
</select>

这里的parameterTypelist,表示传进来的参数是一个集合类型;itemid,表示使用名为id的变量去接收list中的每一个元素。

对于SQL语句:SELECT * FROM student WHERE id IN (1,2,5)来说,上述的xml就不会吧SQL写“死”!list传几个id过来,“()”中就有几个值!

SQL片段抽取

介绍

SQL中可将重复的 SQL 提取出来,使用时用 include 引用即可,最终达到 SQL重用的目的。

<sql>:抽取 SQL 语句标签。 
<include>:引入 SQL 片段标签。 

语法

<sql id=“片段唯一标识”>抽取的 SQL 语句</sql>

<include refid=“片段唯一标识”/>

例如在StudentMapper.xmlSELECT * FROM student 语句较多!我们可以对它们进行抽取

StudentMapper.xml文件中的<mapper>根标签下写入:

<sql id="select">SELECT * FROM student</sql>

 再在使用到该语句的地方用<include>标签进行替换

<select id="selectAll" resultType="student">
    <include refid="select"/>
</select>

修改后的完整的StudentMapper.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属性:名称空间
-->

<mapper namespace="com.itheima.mapper.StudentMapper">

    <sql id="select">SELECT * FROM student</sql>

    <!--
    select:查询功能的标签
    id属性:唯一标识
    resultType属性:指定结果映射对象类型
    parameterType属性:指定参数映射对象类型
    -->
    <select id="selectAll" resultType="student">
        <include refid="select"/>
    </select>
    
    <select id="selectById" resultType="student" parameterType="int">
        <include refid="select"/> WHERE id = #{id}
    </select>

    <!--
        返回的是一个int类型的行数!所以可以省略resultType
        但是,SQL语句的参数id、name、age是从学生对象中来所以,要有parameterType
    -->
    <insert id="insert" parameterType="student">
        INSERT INTO student VALUES (#{id},#{name},#{age})
    </insert>

    <update id="update" parameterType="student">
        UPDATE student SET name = #{name},age = #{age} WHERE id = #{id}
    </update>

    <!-- java.lang.Integer -> int-->
    <delete id="delete" parameterType="int">
        DELETE FROM student WHERE id = #{id}
    </delete>

    <select id="selectCondition" resultType="student" parameterType="student">
        <include refid="select"/>
        <where>
            <if test="id != null">
                id = #{id}
            </if>
            <if test="name != null">
                AND name = #{name}
            </if>
            <if test="age != null">
                AND age = #{age}
            </if>
        </where>
    </select>

    <select id="selectByIds" resultType="student" parameterType="list">
        <include refid="select"/>
        <where>
            <foreach collection="list" open="id IN (" close=")" item="id" separator=",">
                #{id}
            </foreach>
        </where>
    </select>
</mapper>

分页插件

什么是分页?

  • 分页可以将很多条结果进行分页显示。

  • 如果当前在第一页,则没有上一页。如果当前在最后一页,则没有下一页。

  • 需要明确当前是第几页,这一页中显示多少条结果。

Mybatis中的分页插件

  1. 在企业级开发中,分页也是一种常见的技术。而目前使用的 MyBatis 不带分页功能的,如果想实现分页的 功能,需要我们手动编写 LIMIT 语句。但是不同的数据库实现分页的 SQL 语句也是不同的,所以手写分页 成本较高。这个时候就可以借助分页插件来帮助我们实现分页功能。

  2. PageHelper:第三方分页助手。将复杂的分页操作进行封装,从而让分页功能变得非常简单。

分页插件的使用

MyBatis可以使用第三方的插件来对功能进行扩展,分页助手PageHelper是将分页的复杂操作进行封装,使用简单的方式即可获得分页的相关数据

开发步骤

①导入与PageHelper的jar包

②在mybatis核心配置文件中配置PageHelper插件

在idea中要导入这两个架包 

 在MyBatisConfig.xml

<!-- 注意:分页助手的插件  配置在通用mapper之前 -->
<plugin interceptor="com.github.pagehelper.PageHelper"></plugin>
public class pagingTest {

    @Test
    public void selectPaging() throws IOException {
        InputStream is = Resources.getResourceAsStream("MyBatisConfig.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
        SqlSession sqlSession = sqlSessionFactory.openSession(true);
        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);

        //分页助手
        PageHelper.startPage(3,2);

        List<Student> list = mapper.selectAll();

        for (Student student : list) {
            System.out.println(student);
        }

        sqlSession.close();
        is.close();
    }
}

注:

PageHelper有一个静态方法startPage() ,有两个参数第一个参数是pageNum表示当前页,第二个是pageSize表示每一页数据的条数。

分页插件的参数

PageInfo()

封装分页相关参数的功能类

核心方法

详细使用

我们本身db1数据库student表中的数据如下,一共8条数据。

代码如下:

public class pagingTest {

    @Test
    public void selectPaging() throws IOException {
        InputStream is = Resources.getResourceAsStream("MyBatisConfig.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
        SqlSession sqlSession = sqlSessionFactory.openSession(true);
        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);

        // 先分页,再在每一页中去获取list对象
        PageHelper.startPage(3,3);

        List<Student> list = mapper.selectAll();

        //创建获取分页相关参数的功能类
        PageInfo<Student> info = new PageInfo<>(list);
        System.out.println("总条数:" + info.getTotal());
        System.out.println("总页数:" + info.getPages());
        System.out.println("当前页:" + info.getPageNum());
        System.out.println("每页显示条数:" + info.getPageSize());
        System.out.println("上一页:" + info.getPrePage());
        System.out.println("下一页:" + info.getNextPage());
        System.out.println("是否是第一页:" + info.isIsFirstPage());
        System.out.println("是否是最后一页:" + info.isIsLastPage());

        sqlSession.close();
        is.close();
    }
}

运行结果

posted @ 2022-02-27 04:23  金鳞踏雨  阅读(34)  评论(0编辑  收藏  举报  来源