ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Mybatis-入门

2022-08-22 16:02:29  阅读:161  来源: 互联网

标签:缓存 入门 dept SQL Mybatis id name


第一章 初识Mybatis框架

1.1 框架概念

  • 前辈们已经写好的成熟的解决方案
  • 程序中框架【代码半成品】
  • 生活中“框架”
    • 手抓饼
    • 买毛坯房
  • SSM【Spring+SpringMVC+Mybatis】
    • Mybatis:JDBC【dao层】半成品
    • SpringMVC:Servlet【表示层、表述层、控制层、表现层】半成品
    • Spring:大管家

1.2 Mybatis框架简介

  • Mybatis前身Ibatis

  • Mybatis是一个半自动化的持久化层ORM框架

    • ORM:Object Relational Mapping【对象关系映射】
      • 理解:将对象中属性与表中字段进行关联映射
      • 优势:操作对象中属性,就可以影响表中字段数据

    image-20220507101305212

  • Mybatis与Hibernate对比

    • Hibernate全自动化持久层ORM框架
      • 不需要手写sql【不方便优化SQL】
    • Mybatis半自动化持久层ORM框架
      • 需要手写sql【方便优化SQL】
  • POJO(Plain Ordinary Java Object,普通的Java对象)

    • POJO作用等同于JavaBean

1.3 Mybatis官方网址

第二章 搭建Mybatis框架

2.1 搭建框架思路

  • 导入框架所需jar包【坐标】
  • 编写配置文件【不同框架配置文件不同】
  • 使用框架核心类库【不同框架核心类库不同】

2.2 搭建Mybatis框架步骤

  1. 准备

    • 建库建表建约束
    • 准备maven工程
  2. 导入mybatis所需jar包

    <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.26</version>
    </dependency>
    <!--导入MyBatis的jar包-->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.6</version>
    </dependency>
    <!--junit-->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>
    
  3. 编写mybatis-config.xml核心配置文件

    • 名称:没有具体要求,建议使用mybatis-config.xml

    • 位置:src/main/resources

    • 作用:设置mybatis基本行为

    • 示例代码

      <?xml version="1.0" encoding="UTF-8" ?>
      <!DOCTYPE configuration
              PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
              "http://mybatis.org/dtd/mybatis-3-config.dtd">
      
      <configuration>
          <!--设置数据库连接环境-->
          <environments default="development">
              <environment id="development">
                  <!-- 设置事务管理器 -->
                  <transactionManager type="JDBC"/>
                  <!--设置数据源-->
                  <dataSource type="POOLED">
                      <property name="driver" value="com.mysql.jdbc.Driver"/>
                      <property name="url" value="jdbc:mysql://localhost:3306/db220227"/>
                      <property name="username" value="root"/>
                      <property name="password" value="root"/>
                  </dataSource>
              </environment>
          </environments>
          <!--    设置映射文件路径-->
          <mappers>
              <mapper resource="mapper/EmployeeMapper.xml"/>
          </mappers>
      </configuration>
      
  4. 编写POJO及对应接口【CRUD】

    package com.atguigu.mapper;
    import com.atguigu.pojo.Employee;
    /**
     * @author Chunsheng Zhang 尚硅谷
     * @create 2022/5/7 10:53
     */
    public interface EmployeeMapper {
        /**
         * 通过员工id获取员工信息
         */
        public Employee selectEmpById(int empId);
    }
    
  5. 编写映射文件【xxxMapper.xml】

    • 名称:要求与接口名称一致

    • 位置:src/main/resouces/mapper/

    • 主要作用:为接口中的方法定义SQL语句【三点一致】

      • 映射文件名称与接口名称一致
      • 映射文件中mapper标签的namespace属性,与接口的全类名一致
      • 映射文件中sql语句的id属性值,与接口中方法名一致
    • 示例代码

      <?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.atguigu.mapper.EmployeeMapper">
          <!--定义查询sql语句
              resultType:设置结果集类型全类名
          -->
        <select id="selectEmpById" resultType="com.atguigu.pojo.Employee">
              SELECT
                  id,
                  last_name lastName,
                  email,
                  salary
              FROM
                  tbl_employee
              WHERE
                  id = #{empId}
        </select>
      </mapper>
      
  6. 使用核心类库进行测试

    • 核心类库:SqlSession

    • 先获取SqlSessionFactory,再获取SqlSession,最后通过SqlSession获取接口的代理对象,进行测试

    • 示例代码

      @Test
      public void testHw() throws Exception{
      
          //定义mybatis核心配置文件路径
          String resource = "mybatis-config.xml";
          //使用IO流,读取配置文件
          InputStream inputStream = Resources.getResourceAsStream(resource);
          //通过SqlSessionFactoryBuilder构建SqlSessionFactory对象
          SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
      
          //通过sqlSessionFactory获取SqlSession对象
          SqlSession sqlSession = sqlSessionFactory.openSession();
          //最后通过SqlSession获取接口的代理对象,进行测试
          //旧版本玩法:sqlSession.select();
          EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);
          //测试
          Employee employee = employeeMapper.selectEmpById(1);
          System.out.println("employee = " + employee);
      
      }
      

2.3 搭建Mybatis框架常见问题

image-20220507113607046

image-20220507113618641

第三章 日志框架【log4j】

3.1 log4j作用

  • 为相应框架添加日志功能【可以看到框架内部执行细节】

3.2 log4j使用步骤

  • 导入log4j的jar包

    <!--log4j-->
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.17</version>
    </dependency>
    
  • 编写配置文件

    • 名称:log4j.xml

    • 位置:src/main/resources

    • 示例代码

      <?xml version="1.0" encoding="UTF-8" ?>
      <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
      <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
      
          <appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
              <param name="Encoding" value="UTF-8" />
              <layout class="org.apache.log4j.PatternLayout">
                  <param name="ConversionPattern" value="%-5p %d{MM-dd HH:mm:ss,SSS} %m  (%F:%L) \n" />
              </layout>
          </appender>
          <logger name="java.sql">
              <level value="debug" />
          </logger>
          <logger name="org.apache.ibatis">
              <level value="info" />
          </logger>
          <root>
              <level value="debug" />
              <appender-ref ref="STDOUT" />
          </root>
      </log4j:configuration>
      

第四章 Mybatis核心配置文件详解

4.1 配置文件概述

  • MyBatis 的配置文件包含了会深深影响 MyBatis 行为的设置和属性信息。
  • 配置文件中包含一个根标签【configuration】,九个子标签【需要掌握其中6个子标签】

4.2 Mybatis核心配置文件中标签的作用

  • 根标签:configuration,主要作用就是包含子标签

  • 子标签

    image-20220507141937174

    • properties子标签

      • 语法:<properties resource="基于类路径引入外部属性文件">

      • 作用:定义property属性,也可以引入外部属性文件

      • 示例代码

        <!--    定义属性文件-->
        <!--    <properties>-->
        <!--        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>-->
        <!--    </properties>-->
        
        <!--    引入外部属性文件-->
        <properties resource="db.properties"></properties>
        
    • settings子标签

      • 语法:

      • 作用:这是 MyBatis 中极为重要的调整设置,它们会改变 MyBatis 的运行时行为

      • 常用属性

        • mapUnderscoreToCamelCase:是否开启驼峰命名自动映射,即从经典数据库列名 A_COLUMN 映射到经典 Java 属性名 aColumn。【注意字母必须全部相同才可以自动映射
          • false:默认值
          • true:开启驼峰式命名自动映射
        • cacheEnabled
        • lazyLoadingEnabled
        • useGeneratedKeys
      • 示例代码

        <settings>
            <setting name="mapUnderscoreToCamelCase" value="true"/>
        </settings>
        
    • typeAliases子标签

      • 语法:

      • 作用:定义类型别名【类型别名可为 Java 类型(POJO)设置一个缩写名字。】

      • 示例代码

        <!-- 方式一:为POJO定义类型别名-->
           <typeAliases>
                <typeAlias type="com.atguigu.pojo.Employee" alias="employee"></typeAlias>
            </typeAliases>
        <!--方式二-->
            <typeAliases>
                <!--为当前包下所有的POJO定义别名【默认:将类名字母作为别名,不区分大小写,建议使用小写字母】-->
                <package name="com.atguigu.pojo"/>
            </typeAliases>
        
      • Mybatis内建的类型别名

        image-20220509141552583

        image-20220509141611087

    • environments子标签

      • 作用:设置数据库环境【多个】,最终会使用Spring管理数据源&事务管理器

      • 示例代码

        <!--设置数据库连接环境-->
            <environments default="development">
        
                <environment id="development">
                    <!-- 设置事务管理器 -->
                    <transactionManager type="JDBC"/>
                    <!--设置数据源-->
                    <dataSource type="POOLED">
        <!--                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>-->
        <!--                <property name="url" value="jdbc:mysql://localhost:3306/db220227?serverTimezone=UTC"/>-->
                        <property name="driver" value="${db.driverClassName}"/>
                        <property name="url" value="${db.url}"/>
                        <property name="username" value="${db.username}"/>
                        <property name="password" value="${db.password}"/>
                    </dataSource>
                </environment>
            </environments>
        
    • mappers子标签

      • 作用:设置映射文件路径【加载映射文件】

      • 示例代码

        <!--    设置映射文件路径-->
            <mappers>
                <mapper resource="mapper/EmployeeMapper.xml"/>
                <!--
                       * 设置加载映射文件的包名【加载当前包下的所有映射文件】
                       * 注意:要求映射文件的包名与接口的包名必须一致
                -->
        <!--        <package name="com.atguigu.mapper"/>-->
            </mappers>
        
  • 总结Mybatis核心配置文件【mybatis-config.xml】

    • 子标签有顺序要求的,参考顺序详情见官网
    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE configuration
            PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-config.dtd">
    
    <configuration>
    
        <!--    定义属性文件-->
        <!--    <properties>-->
        <!--        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>-->
        <!--    </properties>-->
    
        <!--    引入外部属性文件-->
        <properties resource="db.properties"></properties>
    
        <settings>
            <setting name="mapUnderscoreToCamelCase" value="true"/>
        </settings>
    
    <!--    为POJO定义类型别名-->
    <!--    <typeAliases>-->
    <!--        <typeAlias type="com.atguigu.pojo.Employee" alias="employee"></typeAlias>-->
    <!--    </typeAliases>-->
    
        <typeAliases>
            <!--为当前包下所有的POJO定义别名【默认:将类名字母作为别名,不区分大小写,建议使用小写字母】-->
            <package name="com.atguigu.pojo"/>
        </typeAliases>
    
    
        <!--设置数据库连接环境-->
        <environments default="development">
    
            <environment id="development">
                <!-- 设置事务管理器 -->
                <transactionManager type="JDBC"/>
                <!--设置数据源-->
                <dataSource type="POOLED">
    <!--                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>-->
    <!--                <property name="url" value="jdbc:mysql://localhost:3306/db220227?serverTimezone=UTC"/>-->
                    <property name="driver" value="${db.driverClassName}"/>
                    <property name="url" value="${db.url}"/>
                    <property name="username" value="${db.username}"/>
                    <property name="password" value="${db.password}"/>
                </dataSource>
            </environment>
        </environments>
        <!--    设置映射文件路径-->
        <mappers>
            <mapper resource="mapper/EmployeeMapper.xml"/>
            <!--
                   * 设置加载映射文件的包名【加载当前包下的所有映射文件】
                   * 注意:要求映射文件的包名与接口的包名必须一致
            -->
    <!--        <package name="com.atguigu.mapper"/>-->
        </mappers>
    </configuration>
    

第五章 Mybatis映射文件详解

5.1 映射文件概述

  • MyBatis 的真正强大在于它的语句映射,这是它的魔力所在。由于它的异常强大,映射器的 XML 文件就显得相对简单。
  • 如果拿它跟具有相同功能的 JDBC 代码进行对比,你会立即发现省掉了将近 95% 的代码
  • MyBatis 致力于减少使用成本,让程序员能更专注于 SQL 代码。

5.2 映射文件的详解

  • 根标签【一个】

    • 语法:

      <mapper namespace="com.atguigu.mapper.EmployeeMapper"></mapper>
      
    • 作用:定义当前映射文件的namespace【设置目标接口】

  • 子标签【共有9个,需要掌握8个】

    • insert:定义添加SQL语句

    • delete:定义删除SQL语句

    • update:定义修改SQL语句

    • select:定义查询SQL语句

      • 注意:查询语句必须定义resultType或resultMap,否则报如下错

        Caused by: org.apache.ibatis.executor.ExecutorException: A query was run and no Result Maps were found for the Mapped Statement 'com.atguigu.mapper.EmployeeMapper.selectAllEmp'. It's likely that neither a Result Type nor a Result Map was specified.

    • sql:定义SQL片段

    • resultMap标签:自定义映射,resultType解决不了的问题,交个resultMap

    • cache:定义当前名称空间的缓存配置

    • cache-ref:定义当前名称空间的缓存引用

5.3 子标签中常用的属性

  • id属性:为SQL语句定义唯一标识

  • resultType属性:定义结果集预期返回的类型【全类名(类的全限定名)或别名】

    • 注意
      • 如果返回的是集合,那应该设置为集合包含的类型,而不是集合本身的类型。
      • resultType 和 resultMap 之间只能同时使用一个。

第六章 获取主键自增&数据库受影响行数

6.1 获取主键自增数值

  • 语法:在insert标签中添加两个属性即可

    • useGeneratedKeys=true
    • keyProperty="对象id"
  • 示例代码

    <insert id="insertEmployee" useGeneratedKeys="true" keyProperty="id">
        INSERT INTO
            tbl_employee (last_name,email,salary)
        VALUES
            (#{lastName},#{email},#{salary})
    </insert>
    

6.2 获取数据库受影响行数

  • 语法:将接口的返回值设置int或boolean即可

  • 示例代码

      /**
         * 删除员工信息
         * @param empId
         */
        public int deleteEmpById(int empId);
        public boolean deleteEmpById(int empId);
    

第七章 Mybatis中参数传递问题【重点】

参数传递概念:Mybatis中参数传递指的是,将接口中方法的参数,传递到映射文件的SQL语句中。

7.1 单个普通类型参数

  • 普通参数:包括基本类型及其包装类型+String等
  • 语法规定:单个普通参数可以任意入参【任意参数名&任意参数类型】

7.2 多个普通参数

  • Mybatis底层会将多个参数封装Map中,Map的key是param1、param2、...或【arg0、arg1、...】

  • 注意:获取多个普通参数值,通过Map的key获取。否则报如下错误

    Caused by: org.apache.ibatis.binding.BindingException: Parameter 'id' not found. Available parameters are [arg1, arg0, param1, param2]

7.3 POJO参数【常用】

  • Mybatis中支持POJO入参的,使用POJO的属性作为参数key
  • 使用POJO参数时,应该使用POJO的属性获取参数值
  • 适用场景:支持POJO就用POJO入参

7.4 命名参数【常用】

  • 语法:@Param注解,Mybatis中使用该注解为参数命名【定义名称】

    • @Param注解位置:参数前面
    • @Param注解属性:value属性【定义参数名称】
      • 注意:所有注解如只使用一个value属性时,value关键字可省略的
  • 概述:命名参数底层封装Map【ParamMap继承HashMap】

  • 命名参数,支持两种参数

    • 自己定义名称【id、lastName、...】
    • param1、param2、...
  • 适用场景:不支持POJO&少量参数【参数<=2】

  • 源码解析命名参数

    image-20220509111550636

    image-20220509112806797

7.5 Map参数【常用】

  • Mybatis中支持Map参数,map的key就是参数key
  • Map参数中:使用Map的key获取参数值
  • 适用场景:不支持POJO&大量参数【参数>=3】

7.6 其他参数【List|Array|Collection等】

  • 会被MyBatis封装成一个map传入, Collection对应的key是collection,Array对应的key是array. 如果确定是List集合,key还可以是list。

第八章 Mybatis中#{}与${}区别【面试题】

8.1 回顾Statement&PreparedStatement对象

  • Statement:执行SQL语句命令对象,入参使用字符串拼接的方式,没有解决SQL注入安全隐患,相对不安全。
  • PreparedStatement:执行SQL语句命令对象,入参使用预编译SQL方式【占位符】,解决SQL注入安全隐患,相对安全。

8.2 #{}与$()区别

  • {}底层使用PreparedStatement对象,执行SQL语句命令对象,入参使用预编译SQL方式【占位符】,解决SQL注入安全隐患,相对安全。

  • ${}底层使用Statement对象,执行SQL语句命令对象,入参使用字符串拼接的方式,没有解决SQL注入安全隐患,相对不安全。

8.3 #{}和${}使用场景

  • 回顾单条完整SQL语句,其中【?】就是占位符

    SELECT 
    	col,col2,... 
    FROM 
    	tableName 
    WHERE opr1=? 
    AND opr2=? 
    GROUP BY ? 
    ORDER BY ? 
    LIMIT ?,?
    
  • {}使用场景:原生SQL的【?】位置,在Mybatis中就可以使用【#{}】

    • {} == ?

  • ${}使用场景:原生SQL的【?】解决不了问题,如需要参数时,使用${}

    • 最常用场景:动态查询表名时使用${}

      image-20220509114837835

    • 示例代码

      /**
       * 测试【$使用场景】
       * 动态查询表名
       */
      public List<Employee> selectAllEmp(@Param("tableName") String tableName);
      
      <!--    测试动态表【$使用场景】-->
      <select id="selectAllEmp" resultType="employee">
          select
          	id,
          	last_name,
          	email,
          	salary
          from
          	${tableName}
      </select>
      

第九章 Mybatis中返回值四种结果

9.1 查询单行数据返回单个对象

public Employee selectEmpByEmpIdAndLastName(int id,String lastName);
<!--    通过员工id及员工lastName获取员工信息-->
    <select id="selectEmpByEmpIdAndLastName" resultType="employee">
        select
            id,
            last_name,
            email,
            salary
        from
            tbl_employee
        where
            id = #{arg0}
        and
            last_name = #{arg1}
    </select>
  • resultType设置对象全类名或别名即可

9.2 查询多行数据返回对象的集合

/**
 * 测试【$使用场景】
 * 动态查询表名
 */
public List<Employee> selectAllEmp(@Param("tableName") String tableName);
<!--    测试动态表【$使用场景】-->
    <select id="selectAllEmp" resultType="employee">
        select
            id,
            last_name,
            email,
            salary
        from
            ${tableName}
    </select>
  • resultType设置集合包含的类型

9.3 查询单行数据返回Map

  • 为什么返回Map?

    • 查询结果不支持对象,返回Map

      /**
       * 查询单行数据,返回Map
       */
      public Map<String,Object> selectOneObjectReturnMap(int empId);
      
      <!--    查询单行数据,返回Map-->
      <select id="selectOneObjectReturnMap" resultType="map">
          select
              id,
              last_name,
              email,
              salary
          from
         	 	tbl_employee
          where
         	 	id = #{empId}
      </select>
      
    • 查询结果不期望返回对象,期望Map

      /**
       * 查询结果不期望返回对象,期望Map
       * 查询单行数据,返回Map
       */
      public Map<String,Employee> selectOneObjectReturnMap2(int empId);
      
      <!--    查询单行数据,返回Map-->
          <select id="selectOneObjectReturnMap2" resultType="map">
              select
                  id,
                  last_name,
                  email,
                  salary
              from
                  tbl_employee
              where
                  id = #{empId}
          </select>
      
  • 总结:查询单行数据返回Map,字段作为Map的key,查询结果作为Map的value

9.4 查询多行数据返回Map

  • 查询多行数据支持List但期望返回Map<Integer,Employee>
/**
 * 查询多行数据返回Map
 *      key:id
 *      value:employee
 * @return
 */
@MapKey("id")
public Map<Integer,Employee> selectAllEmpReturnMap();
<!-- 查询多行数据返回Map-->
<select id="selectAllEmpReturnMap" resultType="map">
    select
        id,
        last_name,
        email,
        salary
    from
        tbl_employee
</select>
  • 注意:查询多行数据返回Map<Integer,Employee>,必须使用@MapKey注解标识key的属性名

第十章 Mybatis中自动映射与自定义映射【重难点】

回顾多表连接查询几种情况

-- employee 多 dept 一
-- 在【多】的表中,添加【一】的id

  1. 等值连接查询

    SELECT
    e.id,e.last_name,e.email,e.salary,
    d.dept_id,d.dept_name
    FROM
    tbl_employee e,tbl_dept d
    WHERE
    e.dept_id=d.dept_id

  2. 内连接查询

    SELECT
    e.id,e.last_name,e.email,e.salary,
    d.dept_id,d.dept_name
    FROM
    tbl_employee e
    INNER JOIN
    tbl_dept d
    ON
    e.dept_id=d.dept_id

  3. 外连接查询

    • 左外连接

      SELECT
      e.id,e.last_name,e.email,e.salary,
      d.dept_id,d.dept_name
      FROM
      tbl_employee e LEFT JOIN tbl_dept d
      ON
      e.dept_id=d.dept_id

    • 右外连接

      SELECT
      e.id,e.last_name,e.email,e.salary,
      d.dept_id,d.dept_name
      FROM
      tbl_employee e RIGHT JOIN tbl_dept d
      ON
      e.dept_id=d.dept_id

10.1 自动映射【resultType】与自定义映射【resultMap】概述

  • 自动映射【resultType】:指的是将表中的字段类中的属性自动建立映射关系

    • 注意:

      • 要求字段名与属性名一致,才可以自动映射。

      • 如属性名与字段名不一致,可以定义字段别名解决问题。

      • 如需将字段a_bc与aBc属性自动映射,开启驼峰式命名映射即可

        <settings>
            <setting name="mapUnderscoreToCamelCase" value="true"/>
        </settings>
        
    • 自动映射解决不了问题

      • 不期望定义别名&不支持驼峰式命名映射,自动映射解决不了
      • 多表连接查询时,结果集中返回多张表的数据,此时resultType解决不了
  • 自定义映射【resultMap】

    • 指定是程序员自己定义表中的字段类中的属性关联关系
  • 注意:resultType与resultMap只能同时使用一个

    • 使用心得:优先使用resultType解决,resultType解决不了,使用resultMap

10.2 自定义映射【级联映射(一对一)】

建立对象与对象之间关联关系

/**
 * 自定义映射【级联映射】
 *      通过员工id获取员工信息,及员工所属的部门信息
 */
public Employee selectEmpAndDeptByEmpId(int empId);
<!--    自定义映射-级联映射-->
<resultMap id="empAndDeptRm" type="employee">
    <id property="id" column="id"></id>
    <result property="lastName" column="last_name"></result>
    <result property="email" column="email"></result>
    <result property="salary" column="salary"></result>
    <!--        级联映射-->
    <result property="dept.deptId" column="dept_id"></result>
    <result property="dept.deptName" column="dept_name"></result>
</resultMap>
<select id="selectEmpAndDeptByEmpId" resultMap="empAndDeptRm">
    SELECT
        e.`id`,
        e.`last_name`,
        e.`email`,
        e.`salary`,
        d.`dept_id`,
        d.`dept_name`
    FROM
        tbl_employee e,
        tbl_dept d
    WHERE
    	e.`dept_id` = d.`dept_id`
    AND
    	e.id = #{empId}
</select>

10.3 自定义映射【association(一对一)】

/**
 * 自定义映射【association】
 *      通过员工id获取员工信息,及员工所属的部门信息
 */
public Employee selectEmpAndDeptByEmpIdAssociation(int empId);
<!--    association映射-->
    <resultMap id="empAndDeptAssociationRm" type="employee">
        <!--        定义主键映射关系-->
        <id property="id" column="id"></id>
        <!--        定义非主键映射关系-->
        <result property="lastName" column="last_name"></result>
        <result property="email" column="email"></result>
        <result property="salary" column="salary"></result>
        <!--        association映射-->
        <association property="dept"
                     javaType="com.atguigu.pojo.Dept">
            <id property="deptId" column="dept_id"></id>
            <result property="deptName" column="dept_name"></result>
        </association>
    </resultMap>
    <select id="selectEmpAndDeptByEmpIdAssociation" resultMap="empAndDeptAssociationRm">
         SELECT
            e.`id`,
            e.`last_name`,
            e.`email`,
            e.`salary`,
            d.`dept_id`,
            d.`dept_name`
        FROM
            tbl_employee e,
            tbl_dept d
        WHERE
            e.`dept_id` = d.`dept_id`
        AND
            e.id = #{empId}
    </select>
  • association分步查询

    • 概述:将多表【一步】连接查询,拆分成单表的多步查询

    • 优势:提高查询效率,降低服务器压力

    • 语法&示例代码

      /**
       *  测试分步查询association
       *  通过员工id获取员工信息,及员工所属的部门信息
       *      1. 通过员工id,获取员工信息【包含部门id】
       *      2. 通过员工id获取部门id,从而通过部门id,获取部门信息
       */
      public Employee selectEmpAndDeptByEmpIdAssociationStep(int empId);
      
      <!--    day04-->
          <resultMap id="empAndDeptAssociationStepRm" type="employee">
              <id property="id" column="id"></id>
              <result property="lastName" column="last_name"></result>
              <result property="email" column="email"></result>
              <result property="salary" column="salary"></result>
              <!--        association分步查询-->
              <association property="dept"
                     select="com.atguigu.mapper.DeptMapper.selectDeptByDeptId"
                          column="dept_id">
              </association>
          </resultMap>
          <select id="selectEmpAndDeptByEmpIdAssociationStep" resultMap="empAndDeptAssociationStepRm">
              select
                  id,
                  last_name,
                  email,
                  salary,
                  dept_id
              from
                  tbl_employee
              where
                  id = #{empId}
          </select>
      
      /**
       * 通过部门id获取部门信息
       */
      public Dept selectDeptByDeptId(int deptId);
      
      <select id="selectDeptByDeptId" resultType="dept">
          select
              dept_id,
              dept_name
          from
              tbl_dept
          where
              dept_id=#{deptId}
      </select>
      
  • association延迟加载

10.4 自定义映射【collection(一对多)】

  • 基本语法

    /**
     * 通过部门id获取部门信息,及部门对应的员工信息
     */
    public Dept selectDeptAndEmpByDeptId(int deptId);
    
    <!--    通过部门id获取部门信息,及部门对应的员工信息-->
        <resultMap id="deptAndEmpRm" type="dept">
            <id property="deptId" column="dept_id"></id>
            <result property="deptName" column="dept_name"></result>
            <!-- collection解决一对多问题-->
            <collection property="empList"
                        ofType="com.atguigu.pojo.Employee">
                <id property="id" column="id"></id>
                <result property="lastName" column="last_name"></result>
                <result property="email" column="email"></result>
                <result property="salary" column="salary"></result>
            </collection>
        </resultMap>
        <select id="selectDeptAndEmpByDeptId" resultMap="deptAndEmpRm">
            SELECT
                e.`id`,
                e.`last_name`,
                e.`email`,
                e.`salary`,
                d.`dept_id`,
                d.`dept_name`
            FROM
                tbl_employee e,
                tbl_dept d
            WHERE
                e.`dept_id` = d.`dept_id`
            AND
                d.dept_id = #{deptId}
        </select>
    
  • collection分步查询

    /**
     * collection分步查询
     *      通过部门id获取部门信息,及部门对应的员工信息
                1. 通过部门id获取部门信息【tbl_dept】
                2. 通过部门id获取员工信息【tbl_employee】
     */
    public Dept selectDeptAndEmpByDeptIdStep(int deptId);
    
    <!--    collection分步查询-->
        <resultMap id="deptAndEmpStepRm" type="dept">
            <id property="deptId" column="dept_id"></id>
            <result property="deptName" column="dept_name"></result>
            <collection property="empList"
                        select="com.atguigu.mapper.EmployeeMapper.selectEmpByDeptId"
                        column="dept_id"
                        fetchType="lazy">
    
            </collection>
        </resultMap>
        <select id="selectDeptAndEmpByDeptIdStep" resultMap="deptAndEmpStepRm">
            select
                dept_id,
                dept_name
            from
                tbl_dept
            where
                dept_id = #{deptId}
        </select>
    
    /**
     * 通过部门id获取员工信息
     */
    public List<Employee> selectEmpByDeptId(int deptId);
    
    <!--    通过部门id获取员工信息-->
    <select id="selectEmpByDeptId" resultType="employee">
        select
            id,
            last_name,
            email,
            salary,
            dept_id
        from
            tbl_employee
        where
            dept_id = #{deptId}
    </select>
    

10.5 resultMap标签详解

  • 属性

    • id属性:定义resultMap唯一标识
    • type属性:定义resultMap类型【类似与resultType作用】
  • 子标签

    • id子标签:自定义主键字段与属性关联关系
      • property属性:设置属性名称【对象中】
      • column属性:设置字段名称【表中】
    • result子标签:自定义非主键字段与属性关联关系
      • property属性:设置属性名称【对象中】
      • column属性:设置字段名称【表中】
    • association子标签:自定义一对一关联关系
      • 属性
        • property属性:设置【关联】属性名称
        • javaType属性:设置属性Java类型【全类名或别名】
        • select属性:定义分步查询SQL的ID
        • column属性:定义分步查询SQID的参数
        • fetchType属性:定义局部延迟加载
      • 子标签
        • id子标签:自定义主键字段与属性关联关系
        • result子标签:自定义非主键字段与属性关联关系
    • collection子标签:自定义一对多关联关系
      • 属性
        • property属性:设置【关联】属性名称
        • ofType属性:设置集合属性的泛型类型【全类名或别名】
        • select属性:定义分步查询SQL的ID
        • column属性:定义分步查询SQID的参数
        • fetchType属性:定义局部延迟加载
      • 子标签
        • id子标签:自定义主键字段与属性关联关系
        • result子标签:自定义非主键字段与属性关联关系

第十一章 Mybatis中延迟加载【懒加载】

11.1 延迟加载使用场景

  • 前提:在分步查询的基础上实现延迟加载
  • 概述:使用当前数据时加载,不使用当前数据时,暂不加载

11.2 延迟加载语法

  • 全局设置【settings中】

    <!--  开启延迟加载【默认值:false】-->
    <setting name="lazyLoadingEnabled" value="true"/>
    <!--  开启时,任一方法的调用都会加载该对象的所有延迟加载属性。
                    否则,每个延迟加载属性会按需加载
                    默认值:false【在 3.4.1 及之前的版本中默认为 true】
                -->
    <setting name="aggressiveLazyLoading" value="false"/>
    
  • 局部设置【分步查询association或collection添加fetchType属性】

    • fetchType属性
      • lazy:开启局部懒加载
      • eager:关闭局部懒加载
    <association property="dept"
                select="com.atguigu.mapper.DeptMapper.selectDeptByDeptId"
                column="dept_id"
                fetchType="eager">
    </association>
    <collection property="empList"
                    select="com.atguigu.mapper.EmployeeMapper.selectEmpByDeptId"
                        column="dept_id"
                        fetchType="lazy">
            </collection>
    

11.3 延迟加载扩展

  • 如分步查询时,接口中需要多个参数时怎么办?

    • 将多个参数封装Map结构即可
    • 语法:{k1=v1,k2=v2,...}
  • 示例代码

    <resultMap id="deptAndEmpStepRm" type="dept">
        <id property="deptId" column="dept_id"></id>
        <result property="deptName" column="dept_name"></result>
        <collection property="empList"
                    select="com.atguigu.mapper.EmployeeMapper.selectEmpByDeptId"
                    column="{dId=dept_id}"
                    fetchType="lazy">
    
        </collection>
    </resultMap>
    <select id="selectDeptAndEmpByDeptIdStep" resultMap="deptAndEmpStepRm">
        select
            dept_id,
            dept_name
        from
            tbl_dept
        where
            dept_id = #{deptId}
    </select>
    
    <select id="selectEmpByDeptId" resultType="employee">
        select
            id,
            last_name,
            email,
            salary,
            dept_id
        from
            tbl_employee
        where
            dept_id = #{dId}
    </select>
    

第十二章 Mybatis中动态SQL【重要】

12.1 动态SQL概述

  • 动态SQL:指定是SQL语句可动态变化
    • 类似页面
      • 静态页面:html【thymeleaf动态渲染数据】
      • 动态页面:jsp
  • Mybatis中特点
    • Mybatis的接口中【不支持】方法重载
      • 因为:接口中方法名与SQL的id一致,而SQL的id不能重复
    • Mybatis映射文件中注释
      • xml注释【推荐使用】:
      • SQL注释【不推荐使用】:-- 注释内容
    • Mybatis动态SQL中支持:OGNL表达式语言
      • OGNL( Object Graph Navigation Language )对象图导航语言
      • 这是一种强大的表达式语言,通过它可以非常方便的来操作对象属性。

12.2 动态SQL常用标签

  • if标签:应用于SQL中的基本if判断

  • where标签:解决where关键字及条件中多出的前面第一个and或or关键字问题

    <!--    测试动态SQL-->
    <select id="selectEmpByDynamicOpr" resultType="employee">
        select
            id,
            last_name,
            email,
            salary,
            dept_id
        from
         tbl_employee
        <where>
            <if test="id != null">
                 id = #{id}
            </if>
            <if test="lastName != null">
                and last_name = #{lastName}
            </if>
            <if test="email != null">
                and email = #{email}
            </if>
            <if test="salary != null">
                and salary = #{salary}
            </if>
        </where>
    </select>
    
  • trim标签:可以在条件判断完的SQL语句前后添加或者去掉指定的字符

    • prefix: 添加前缀
    • prefixOverrides: 去掉前缀
    • suffix: 添加后缀
    • suffixOverrides: 去掉后缀
    <!--    测试trim-->
        <select id="selectEmpByDynamicTrim" resultType="employee">
            select
                id,
                last_name,
                email,
                salary,
                dept_id
            from
                tbl_employee
            <trim prefix="where" suffixOverrides="and|or">
                <if test="id != null">
                    id = #{id} and
                </if>
                <if test="lastName != null">
                    last_name = #{lastName} and
                </if>
                <if test="email != null">
                    email = #{email} and
                </if>
                <if test="salary!=null">
                    salary = #{salary}
                </if>
            </trim>
        </select>
    
  • choose 主要是用于分支判断,类似于java中的switch case,只会满足所有分支中的一个

    <!--    测试choose-->
        <select id="selectEmpByDynamicChoose" resultType="employee">
            select
                id,
                last_name,
                email,
                salary,
                dept_id
            from
                tbl_employee
            <where>
                <choose>
                    <when test="id!=null">
                        id = #{id}
                    </when>
                    <when test="lastName!=null">
                        last_name = #{lastName}
                    </when>
                    <when test="email!=null">
                        email = #{email}
                    </when>
                    <when test="salary!=null">
                        salary = #{salary}
                    </when>
                    <otherwise>
                        1=1
                    </otherwise>
                </choose>
            </where>
        </select>
    
  • set标签:主要是用于解决修改操作中SQL语句中可能多出一个逗号的问题

    <!--    修改员工信息-->
        <update id="updateEmp">
            update
                tbl_employee
            <set>
                <if test="lastName!=null">
                    last_name = #{lastName},
                </if>
                <if test="email">
                    email = #{email},
                </if>
                <if test="salary!=null">
                    salary = #{salary}
                </if>
            </set>
            where
                id = #{id}
        </update>
    
  • foreach标签:

    <!--    测试foreach标签-->
        <select id="selectEmpByIds" resultType="employee">
            select
                id,
                last_name,
                email,
                salary
            from
                tbl_employee
            where
                id in
                    <foreach open="(" close=")" collection="ids" item="id" separator=",">
                        #{id}
                    </foreach>
        </select>
    
  • sql标签:定义SQL语句片段

    • 语法

      • sql标签定义SQL片段
      • 使用include标签引入SQL片段
    • 示例代码

      <!--    定义SQL片段【员工表,主信息】-->
          <sql id="sql_column_employee">
              id,
              last_name,
              email,
              salary
          </sql>
          
      <!--    定义SQL片段【查询员工表】-->
          <sql id="sql_from_employee">
              select
                  id,
                  last_name,
                  email,
                  salary,
                  dept_id
              from
                  tbl_employee
          </sql>
          <!--    测试动态SQL-->
          <select id="selectEmpByDynamicOpr" resultType="employee">
              <include refid="sql_from_employee"></include>
              <where>
                  <if test="id != null">
                       id = #{id}
                  </if>
                  <if test="lastName != null">
                      and last_name = #{lastName}
                  </if>
                  <if test="email != null">
                      and email = #{email}
                  </if>
                  <if test="salary != null">
                      and salary = #{salary}
                  </if>
              </where>
          </select>
      <!--    测试foreach标签-->
          <select id="selectEmpByIds" resultType="employee">
              select
                  <include refid="sql_column_employee"></include>
              from
                  tbl_employee
              where
                  id in
                      <foreach open="(" close=")" collection="ids" item="id" separator=",">
                          #{id}
                      </foreach>
          </select>
      

第十三章 Mybatis中缓存机制

13.1 缓存概述

  • 生活中缓存
    • 缓存音频、视频
    • 优势:节约数据流量、提高效率
  • Mybatis程序中缓存【提高程序性能,降低服务器压力】
    • 一级缓存:本地缓存【SqlSession级别缓存】
    • 二级缓存:second level cache【全局作用域缓存(SqlSessionFactory级别缓存)】
    • 第三方缓存:EhChach缓存框架

13.2 Mybatis中一级缓存

  • 概述:一级缓存也叫本地缓存,作用域:SqlSession【sqlSession级别缓存】

  • 特点:

    • 一级缓存默认开启,不能被关闭
    • 一级缓存可以清空
  • 缓存原理

    • 第一次获取数据时,先从数据中获取数据,并将数据缓存至一级缓存中
      • 一级缓存机制:底层就是一个Map,Map的key:【 hashCode+查询的SqlId+编写的sql查询语句+参数】
    • 以后再次获取相同数据时,先从一级缓存中获取,如在一级缓存中未获取到所需数据,再从数据库中获取。
  • 一级缓存五种失效情况

    1. 不同的SqlSession对应不同的一级缓存

    2. 同一个SqlSession但是查询条件不同

    3. 同一个SqlSession两次查询期间执行了任何一次增删改操作

    • 执行增删改操作,会默认情况缓存
    1. 同一个SqlSession两次查询期间手动清空了缓存
    • sqlSession.clearCache();
    1. 同一个SqlSession两次查询期间提交了事务
    • sqlSession.commit();

13.3 Mybatis中二级缓存

  • 二级缓存概述

    • second level cache【全局作用域缓存(sqlSessionFactory)】
    • 作用域:sqlSessionFactory
  • 二级缓存特点

    • 二级缓存默认关闭的,需要手动开启才可以使用
    • 二级缓存需要提交sqlSession或关闭sqlSession时,才会缓存数据
  • 二级缓存使用步骤

    ① 全局配置文件中开启二级缓存

    ② 需要使用二级缓存的映射文件处使用cache配置缓存

    ③ 注意:POJO需要实现Serializable接口

    ④ 关闭sqlSession或提交sqlSession时,将数据缓存到二级缓存

  • 二级缓存,缓存机制

    • 第一次获取数据时,从数据库获取数据,将数据缓存至一级缓存,当提交sqlSession或关闭sqlSession时,将数据缓存至二级缓存。
    • 以后再次获取相同数据时,先从一级缓存中获取数据,如一级缓存中未获取到数据,再从二级缓存中获取,如二级缓存也未获取到数据,需要去数据库中获取数据。
  • 二级缓存相关属性

    • eviction:设置缓存回收策略
      • LRU:最近最少使用的,先移除
      • FIFO:先进先出,按照对象进入顺序,去移除对象
    • flushInternal:设置刷新间隔,单位毫秒
    • size:设置缓存数量
    • readOnly:设置缓存是否为只读缓存【设置只读,就不能进行增删改操作】
  • 二级缓存失效情况

    • 两次查询期间,执行任意一次增删改操作
    • 执行sqlSession.clearCache()只清空一级缓存,不会清空二级缓存

13.4 Mybatis中第三方缓存【EhCache】

  • EhCache概述

    • EhCache是缓存插件
    • EhCache 是一个纯Java的进程内缓存框架,具有快速、精干等特点,是Hibernate中默认的CacheProvider
  • EhCache使用步骤

    1. 导入jar包

    2. 编写配置文件

      • 名称:ehcache.xml
      • 位置:src/main/resources
    3. 在映射文件中,加载第三方缓存插件

      <cache type="org.mybatis.caches.ehcache.EhcacheCache"></cache>
      
  • EhCache注意事项

    • EhCache需要开启二级缓存,才能使用【EhCache需要在二级缓存基础上使用】
    • 设置二级缓存失效,第三方EhCache缓存也会失效

第十四章 Mybatis逆向工程

14.1 逆向工程概述

  • 正向工程:通过应用程序【java代码】,影响数据库表中的数据【java->表】
  • 逆向工程:通过表结构,影响【生成】应用程序

14.2 逆向工程-MBG

  • MBG全称:Mybatis Generator就是代码生成器
  • 可以快速通过表结构,生成对应代码【POJO&PojoMapper&PojoMapper.xml】
  • 但是表连接、存储过程等这些复杂sql的定义需要我们手工编写
  • MBG支持两种风格CURD
    • 普通CRUD
    • QBC风格CRUD
  • 文档地址:http://www.mybatis.org/generator/

14.3 MBG基本使用

  • 导入jar包

    <!-- mybatis-generator-core -->
    <dependency>
        <groupId>org.mybatis.generator</groupId>
        <artifactId>mybatis-generator-core</artifactId>
        <version>1.3.6</version>
    </dependency>
    <!-- mysql-connector-java -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.37</version>
        <!--            <version>8.0.26</version>-->
    </dependency>
    <!--导入MyBatis的jar包-->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.6</version>
    </dependency>
    <!--junit-->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>
    
    <!--log4j-->
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.17</version>
    </dependency>
    
  • 编写配置文件

    • 名称:mbg.xml

    • 位置:src/main/resources

    • 示例代码

      <!DOCTYPE generatorConfiguration PUBLIC
              "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
              "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
      <generatorConfiguration>
          <!--
             id属性:设置一个唯一标识
             targetRuntime属性值说明:
               MyBatis3Simple:基本的增删改查
               MyBatis3:带条件查询的增删改查
          -->
          <context id="simple" targetRuntime="MyBatis3Simple">
              <!--设置连接数据库的相关信息-->
              <jdbcConnection driverClass="com.mysql.jdbc.Driver"
                              connectionURL="jdbc:mysql://localhost:3306/mybatis"
                              userId="root"
                              password="root"/>
      
              <!--设置JavaBean的生成策略-->
              <javaModelGenerator targetPackage="com.atguigu.mybatis.mbg.beans" targetProject="src/main/java"/>
      
              <!--设置SQL映射文件的生成策略-->
              <sqlMapGenerator targetPackage="com.atguigu.mybatis.mbg.mapper" targetProject="src/main/resources"/>
      
              <!--设置Mapper接口的生成策略-->
              <javaClientGenerator type="XMLMAPPER" targetPackage="com.atguigu.mybatis.mbg.mapper" targetProject="src/main/java"/>
      
              <!--逆向分析的表-->
              <table tableName="employees" domainObjectName="Employee"/>
              <table tableName="departments" domainObjectName="Department"/>
          </context>
      </generatorConfiguration>
      
  • 执行代码生成器,生成相关代码

    @Test
    public void testMBG() throws IOException, XMLParserException, InvalidConfigurationException, SQLException, InterruptedException {
        List<String> warnings = new ArrayList<String>();
        boolean overwrite = true;
        File configFile = new File("src/main/resources/mbg.xml");
        ConfigurationParser cp = new ConfigurationParser(warnings);
        Configuration config = cp.parseConfiguration(configFile);
        DefaultShellCallback callback = new DefaultShellCallback(overwrite);
        MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
        myBatisGenerator.generate(null);
    }
    

第十五章 Mybatis分页插件【PageHelper】

15.1 分页功能基本概述

  • 为什么需要分页

    • 提高用户体验度
    • 降低服务器压力
  • 设计分页Page类

    image-20220511115006632

    • 属性:
      • pageNum:当前页码【用户行为】
      • pages:总页数【计算:总页数=总数据数量/每页显示数量】
      • total:总数据数量【查询数据库获取】
      • pageSize:每页显示数量
      • List:当前页显示数据集合【查询数据库获取】
    • 使用业务层【service】实现分页功能
    • 使用业务bean实现分页功能

15.2 PageHelper概述

15.3 PageHelper应用

  • 使用步骤

    1. 导入jar包

      <!-- pagehelper -->
      <dependency>
          <groupId>com.github.pagehelper</groupId>
          <artifactId>pagehelper</artifactId>
          <version>5.0.0</version>
      </dependency>
      
    2. 在mybatis-config.xml配置文件中添加插件

      <plugins>
          <!--配置PageHelper分页插件-->
          <plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
      </plugins>
      
    3. 使用

      • 在查询之前,开启分页功能

        • PageHelper.startPage(int pageNum,int pageSize)
          • pageNum:当前页码
          • pageSize:每页显示数据数量
      • 在查询之后,将结果封装PageInfo中

        • PageInfo pageInfo = new PageInfo(list,index)

          • index:设置页码逻辑
          /*
              假设:页码=8【index=5】
                  [1] 2 3 4 5
                  1 [2] 3 4 5
                  1 2 [3] 4 5
          
                  2 3 [4] 5 6
                  3 4 [5] 6 7
                  4 5 [6] 7 8
          
                  4 5 6 [7] 8
                  4 5 6 7 [8]
          * */
          

15.4 Page与PageInfo

  • Page业务bean

     //开启分页
    Page<Employee> page = PageHelper.startPage(2, 3);
    //执行查询语句
    List<Employee> employees = mapper.selectByExample(ee);
    // - pageNum:当前页码【用户行为】
    int pageNum = page.getPageNum();
    System.out.println("pageNum = " + pageNum);
    // - pages:总页数【计算:总页数=总数据数量/每页显示数量】
    int pages = page.getPages();
    System.out.println("pages = " + pages);
    // - total:总数据数量【查询数据库获取】
    long total = page.getTotal();
    System.out.println("total = " + total);
    //- pageSize:每页显示数量
    int pageSize = page.getPageSize();
    System.out.println("pageSize = " + pageSize);
    // - List<T>:当前页显示数据集合【查询数据库获取】
    List<Employee> result = page.getResult();
    
    for (Employee employee : page.getResult()) {
        System.out.println("employee = " + employee);
    }
    
  • PageInfo业务bean

    //开启分页
    Page<Employee> page = PageHelper.startPage(1, 5);
    //执行查询语句
    List<Employee> employees = mapper.selectByExample(ee);
    //测试PageInfo
    PageInfo<Employee> pageInfo = new PageInfo<>(employees,5);
    //当前页码【用户行为】
    int pageNum = pageInfo.getPageNum();
    System.out.println("pageNum = " + pageNum);
    //总页数【计算:总页数=总数据数量/每页显示数量】
    int pages = pageInfo.getPages();
    System.out.println("pages = " + pages);
    //总数据数量【查询数据库获取】
    long total = pageInfo.getTotal();
    System.out.println("total = " + total);
    //每页显示数量
    int pageSize = pageInfo.getPageSize();
    System.out.println("pageSize = " + pageSize);
    //当前页显示数据集合【查询数据库获取】
    for (Employee employee : pageInfo.getList()) {
        System.out.println("employee = " + employee);
    }
    
    System.out.println("总记录数是:"+pageInfo.getTotal());
    System.out.println("是否有上一页:"+pageInfo.isHasPreviousPage());
    System.out.println("上一页是:"+pageInfo.getPrePage());
    System.out.println("是否有下一页:"+pageInfo.isHasNextPage());
    System.out.println("下一页是:"+pageInfo.getNextPage());
    System.out.println("是否是第一页:"+pageInfo.isIsFirstPage());
    System.out.println("是否是最后一页:"+pageInfo.isIsLastPage());
    
    System.out.println("页码信息:");
    int[] navigatepageNums = pageInfo.getNavigatepageNums();
    for (int navigatepageNum : navigatepageNums) {
        System.out.print(navigatepageNum+"  ");
    }
    

标签:缓存,入门,dept,SQL,Mybatis,id,name
来源: https://www.cnblogs.com/tianzhuo/p/16613072.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有