当前位置: 首页 > news >正文

mybatis笔记(下)

动态语句简介

什么是mybatis动态语句?

是指在sql映射文件中,根据动态生成的sql语句的功能。通过使用mybatis提供的动态的sql元素,可以根据不同条件生成不同的sql语句避免在代码中拼接字符串。

动态语句的标签

注意使用标签前先将不用标签将正常desql语句写一遍,在用标签将其拆分

whereif标签:

<!--List<Employee> query(@Param("name") String name, @Param("salary") Double salary);

    要求:两个属性可传,可不传

         如果传入属性,就判断相等,如果不传入,就不加对应条件

         where

         if   判断传入的参数,最终是否添加语句

            <if test=""> sql语句 </if>

            test属性 内部作比较运算 ,最终 true将标签内的sql语句进行拼接 false不拼接标签内部语句

            判断语句:"key 比较符号 值 and|or key 比较符号 值"

            注意:可以直接取传入的值

                 大于和小于 不推荐直接写符号 >==&gt;  <==&lt;

        直接使用<if标签可能会出现的问题

        假如两个都满足: where emp_name=#{name} and emp_salary=#{salary}

        假如第一个满足第二个不满足:where emp_name=#{name}

        假如第二个满足第一个不满足:where and emp_salary=#{salary} 错误

        假如两个都不满足:where   错误

        如和解决这一问题呢?

        使用<where标签将所有的<if标签包裹起来

        <where 标签的作用;

           ①自动添加where关键字 where内部有任何一个if满足,自动添加where关键字

           ②自动去掉多余的and|or关键字

     综上所述:<if 与 <where 要一起使用

-->

    <select id="query" resultType="employee">

        select * from t_emp

        <where>

            <if test="name != null">

                emp_name=#{name}

            </if>

            <if test="salary != null and salary &gt; 100">

                and emp_salary=#{salary}

            </if>

        </where>

    </select>

set标签(用在update标签中)

    <!--

        //更具员工id更新员工数据,要求传入的name和salary不为null的才更新

                int update(Employee employee);

                参数可传,可不传

                全部满足:没问题

                第一个满足:多了个","  错误

                第二个满足: 没问题

                都不满足:语法错误

            如何解决呢?

            将set变为<set标签将<if标签包裹

            <set标签的作用:

                 ①自动去掉多余的逗号

                 ②自动添加set关键字

             注意:如果if中的条件都不满足还是会报错的,所以至少有一个要满足

    -->

    <insert id="update">

        update t_emp

        <set>

            <if test="empName != null">

                emp_name=#{empName},

            </if>

            <if test="empSalary != null">

                emp_salary=#{empSalary}

            </if>

        </set>

          where emp_id=#{empId}

    </insert>

trim标签

使用trim标签控制条件部分两端是否包含某些字符

- prefix属性:指定要动态添加的前缀

- suffix属性:指定要动态添加的后缀

- prefixOverrides属性:指定要动态去掉的前缀,使用“|”分隔有可能的多个值

- suffixOverrides属性:指定要动态去掉的后缀,使用“|”分隔有可能的多个值

<!--

    方法:

    List<Employee> queryTrim(@Param("name") String name, @Param("salary") Double salary);

    int updateTrim(Employee employee);

    Trim标签可以替代where标签和set标签

-->

    <select id="queryTrim" resultType="employee">

        select * from t_emp

        <trim prefix="where" prefixOverrides="and|or">

            <if test="name != null">

                emp_name=#{name}

            </if>

            <if test="salary != null and salary &gt; 100">

                and emp_salary=#{salary}

            </if>

        </trim>

    </select>

    <insert id="updateTrim">

        update t_emp

        <trim prefix="set" suffixOverrides=",">

            <if test="empName != null">

                emp_name=#{empName},

            </if>

            <if test="empSalary != null">

                emp_salary=#{empSalary}

            </if>

        </trim>

        where emp_id=#{empId}

    </insert>

Choose/when/otherwise标签

在多个分支条件中,仅执行一个。

- 从上到下依次执行条件判断

- 遇到的第一个满足条件的分支会被采纳

- 被采纳分支后面的分支都将不被考虑

- 如果所有的when分支都不满足,那么就执行otherwise分支

    <!--

        //根据两个条件查询,如果姓名不为null使用姓名查询,如果姓名为null,薪水不为null使用薪水查询!都为null查询全部

         List<Employee> queryChoose(@Param("name") String name, @Param("salary") Double salary);

    -->

    <select id="queryTrim" resultType="employee">

        select * from t_emp where

        <choose>

            <when test="name != null">

                emp_name=#{name}

            </when>

            <when test="salary != null">

                 emp_salary=#{salary}

            </when>

            <otherwise>1=1</otherwise>

        </choose>

    </select>

总结:对比if的不同点

if可以有多个同时满足,而choose只能有一个满足

foreach标签

    <!--foreach

    //根据id的批量查询(传入一个listint类型的集合)

    List<Employee> queryBatch(@Param("ids") List<Integer> ids);

    [1,2,3]

    mysql中的写法

    select * from t_emp where emp_id(1,2,3)#查询id123的员工们的信息

    -->

    <select id="queryTrim" resultType="employee">

        select * from t_emp

                         where emp_id in

                         <!--

                         <foreach标签(遍历传入的集合)

                         collection ="形参集合的标识(@Param|arg0...|list" 指定要遍历的集合

                         open  在遍历之前要追加的字符串

                         close 在遍历之后要追加的字符串

                         separator  每次遍历的分割符号,如果是最后一次,不会追加

                         item="id"  获取每个遍历项(将每次遍历的值放在id变量中)——————<foreachsql语句中会被引用

                         -->

                         <foreach collection="ids" open="(" separator="," close=")" item="id">

                             <!-- 遍历的内容,#{遍历项 item指定的key} -->

                             #{id}

                         </foreach>

    </select>

    <!--

        //根据id的批量增删改

    int deleteBatch(@Param("ids") List<Integer> ids);

    int insertBatch(@Param("list") List<Employee> employeeList);

    int updateBatch(@Param("list") List<Employee> employeeList);

    -->

    <delete id="deleteBatch">

        delete from t_emp where emp_id in

                           <foreach collection="ids" open="(" separator="," close=")" item="id">

                               #{id}

                           </foreach>

    </delete>

    <insert id="insertBatch">

        insert into t_emp(emp_name,emp_salary)

                    values

        <foreach collection="list" separator="," item="employee">

            (#{employee.empName},#{empSalary})

        </foreach>

    </insert>

    <!--

    当找不到那块有遍历规律时,直接将整个sql语句遍历 (相当于一个标签设置多个语句)

    如果一个标签设计多个sql语句,需要设置允许指定多语句:

    此时需要在数据库连接信息的URL地址中设置:atguigu.dev.url=jdbc:mysql:///mybatis-example?allowMultiQueries=true

    -->

    <update id="updateBatch">

        <foreach collection="list" item="employee">

            update t_emp set emp_name=#{employee.empName},emp_salary=#{employee.empSalary}

                                                                 where emp_id=#{employee.empId}

        </foreach>

    </update>

sql片段提取

使用sql标签抽取重复的sql片段

    <!--

    使用sql标签抽取重复片段:

    ①使用<sql标签抽取 id属性是代表此片段的标识

    ②使用<include标签来引用重复片段  refid属性填写要引用的重复sql片段的标识

    -->

    <sql id="selectSql">

        select * from t_emp

    </sql>

    <select id="query" resultType="employee">

        <include refid="selectSql"></include>

        <where>

            <if test="name != null">

                emp_name=#{name}

            </if>

            <if test="salary != null and salary &gt; 100">

                and emp_salary=#{salary}

            </if>

        </where>

    </select>

mapper按包批量扫描

1. 需求

    Mapper 配置文件很多时,在全局配置文件中一个一个注册太麻烦,希望有一个办法能够一劳永逸。

2.配置方式

Mybatis 允许在指定 Mapper 映射文件时,只指定其所在的包:

<mappers>

    <package name="com.atguigu.mapper"/>

</mappers>

此时这个包下的所有 Mapper 配置文件将被自动加载、注册,比较方便。

资源创建要求

- Mapper 接口和 Mapper 配置文件名称一致

    - Mapper 接口:EmployeeMapper.java

    - Mapper 配置文件:EmployeeMapper.xml

在mybatis-config文件中:

    <mappers>

<!--  单个文件映射  <mapper resource="mappers/EmployeeMapper.xml"/>-->

        <!-- 批量处理mapper指令

             1 要求mapperxml文件和mapper接口的命名必须相同

             2 最终打包后的位置要一致 都是指定的包地址下

                如何实现:

                  方案一:将xml文件也加入到接口所在的包(不推荐)

                  方案二:resource文件夹创建对应的(与mapper接口文件夹结构一致)文件夹结构即可

          注意:resource下直接创建多层文件夹 使用/分割,如果使用的是.那么就只会创建一个文件夹       

        -->

        <package name="org.example.mapper"/>

    </mappers>

 分页插件

如何使用分页插件:

①引入依赖

<dependency>

    <groupId>com.github.pagehelper</groupId>

    <artifactId>pagehelper</artifactId>

    <version>5.1.11</version>

</dependency>

②在 MyBatis 的配置文件mybatis-config中添加 PageHelper 的插件:

<plugins>

    <plugin interceptor="com.github.pagehelper.PageInterceptor">

        <property name="helperDialect" value="mysql"/>

    </plugin>

</plugins>

③使用

public class MyBatisTest {

    private SqlSession sqlSession;



    @BeforeEach//每次执行测试方法前,先走初始化方法

    public void start() throws IOException {

        InputStream ips = Resources.getResourceAsStream("mybatis-config.xml");

        SqlSessionFactory build = new SqlSessionFactoryBuilder().build(ips);

        sqlSession = build.openSession();

    }



    @AfterEach//每次执行测试方法后,先走此方法

    public void end(){

        sqlSession.close();

    }



    @Test

    public void test1(){

        /**

         * 使用步骤:

         * ①设置查看的页数和页容量

         *       通过PageHelper调用startPage()函数,传入pageNum与PageSize

         * ②正常执行函数调用查询语句

         * ③创建pageInfo对象

         *       通过PageInfo构造器,传入查询结果

         * ④通过PageInfo对象调用getList()得到当前页的数据

         */

        EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);

        //调用之前,设置分页数据(当前是第几页,每页显示多少个)

        PageHelper.startPage(1,2);

        //注意:不能将两条查询装到一个分页区(startPage与PageInfo之间)

        List<Employee> list = mapper.queryList();

        //将查询数据封装到一个PageInfo的分页实体类(通过该对象可以查看一共有多少页,一共有多少条

        PageInfo<Employee> pageInfo = new PageInfo<>(list);

        //pageInfo获取分页的数据

        //当前页的数据

        List<Employee> list1 = pageInfo.getList();

        //获取总页数

        int pages = pageInfo.getPages();

        //获取总条数

        long total = pageInfo.getTotal();

        //获取当前是第几页

        int pageNum = pageInfo.getPageNum();

        //获取页容量

        int pageSize = pageInfo.getPageSize();

        //查看是否有下一页

        boolean hasNextPage = pageInfo.isHasNextPage();

        System.out.println(list1);

    }

}

相关文章:

  • 每日一题之杨辉三角
  • scss基础用法
  • AI×数据治理|百分点科技BD-OS重构数据工程的“基石能力”
  • Linux系统 | 线程的同步与互斥
  • 蓝桥杯 合并数列
  • AI Agent 开发与传统后端开发区别?
  • 项目-苍穹外卖(十六) Apache ECharts+数据统计
  • SpringSecurity OAuth2:授权服务器与资源服务器配置
  • 基于Spring Boot的服装定制系统的设计与实现(LW+源码+讲解)
  • FAST-LIVO2 Fast, Direct LiDAR-Inertial-Visual Odometry论文阅读
  • 硬件基础--16_公式梳理
  • “头”里有什么——HTML 元信息
  • Stable Virtual Camera 重新定义3D内容生成,解锁图像新维度;BatteryLife助力更精准预测电池寿命
  • gogs私服搭建
  • Django自带的Admin后台中如何获取当前登录用户
  • 概率与决策理论
  • 【AI】10卡的GPU服务器,Docker 配置 docker-compose.yml 限制指定使用最后两块GPU 序号8,9
  • 欧几里得距离(Euclidean Distance)公式
  • ue材质学习感想总结笔记
  • leetcode230.二叉搜索树中第k小的元素
  • 美凯龙:董事兼总经理车建兴被立案调查并留置
  • 梅花奖在上海丨陈丽俐“婺剧折戏专场”:文戏武做,武戏文唱
  • 盖茨说对中国技术封锁起到反作用
  • 珠峰窗口期5月开启 普通人登一次有多烧钱?
  • 上海下周最高气温在30℃附近徘徊,夏天越来越近
  • 黄土是他们的气质:打破宁夏当代油画创作的沉寂