栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

MyBatis入门与实践全总结

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

MyBatis入门与实践全总结

MyBatis入门与实践全总结

MyBatis入门与实践全总结
  • MyBatis入门与实践全总结
  • 一、 MyBatis简介
    • 1.1 MyBatis历史
    • 1.2 什么是 `MyBatis`?
    • 1.3 MyBatis下载
    • 1.4 持久化
      • 数据持久化
      • 为什么需要持久化?
    • 1.5 持久层
    • 1.6 为什么需要Mybatis
      • 优点
    • 1.7 和其它持久化层技术对比
  • 二、搭建MyBatis
    • 开发环境
    • 2. 第一个 mybatis 程序
    • 2.1 搭建环境
      • 2.1.1 创建数据库
      • 2.1.2 新建一个普通的maven项目
      • 2.1.3 删除`src文件`: 目的是创建一个项目是父项目,以后直接创建各个模块子项目
    • 2.2 导入Maven依赖(MyBatis)
    • 2.3 编写代码
      • 2.3.1 创建一个模块 new module
      • 2.3.2 编写mybatis的核心配置文件
      • 2.3.3 编写mybatis工具类
      • 2.3.4 编写代码
        • 1. 实体类
        • 2. Mapper接口,相当于DAO
        • 3. 接口实现类
    • 2.4 测试 (junit测试)
      • 2.4.1 建立对应的包
      • 注意点:
      • 2.4.2 可能报错,需要注意:
        • 报错1:
        • 报错2:初始化异常
    • 2.5 运行
      • 2.5.1 结果显示
      • 2.5.2 文件结构
      • 2.5.3 可能遇到的问题:
  • 三、 特别注意(核心接口)
  • 四、总结流程
  • 五、 加入log4j 日志功能
    • 5.1 加入依赖 pom.xml
    • 5.2 编写`log4j.xml`配置文件,在`/src/main/resources/`下
    • 5.3 日志的级别
  • 六、 MyBatis核心配置文件
    • 6.1 `environment`
    • 6.2 `properties`
      • 6.2.1 创建`db.properties`文件
      • 6.2.2 编写`db.properties`文件
    • 6.3 `typeAliases`
    • 6.4 `mappers``
      • 6.4.1 新建一个包
      • 6.4.2 修改核心配置文件`mybatis-configxml`
    • 6.5 总结
      • 6.5.1 核心配置文件`mybatis-config.xml`
      • 6.5.2 文件结构
  • 七、MyBatis 增删改查 CRUD
    • 7. 新建项目(New Module)
    • 7.1 新建一个模块
    • 7.2 增加并配置核心配置文件
    • 7.3 新建`jdbc.properties`文件
    • 7.4 创建类
    • 7.5 创建`resources`中的`mapper`
    • 7.6 将核心配置文件作为模版`mybatis-config.xml`
    • 7.7 创建映射文件并将其作为模版`mybatis-mapper.xml`
    • 7.8 创建测试类
    • 7.9 创建工具类`Utils.java`
  • 八、 MyBatis获取参数值的两种方式(重点)
    • 8.1 单个字面量类型的参数
    • 8.2 多个字面量类型的参数
      • 8.2.1 注意点:
    • 8.3 map集合类型的参数
    • 8.4 实体类类型的参数
      • 8.4.1 注意点:
    • 8.5 使用`@Param`标识参数
      • 8.5.1 注意点:
      • 8.5.2 `@param`源码解析
    • 8.6 总结
      • 8.6.1 大致过程
  • 举例、增删改查
    • 1. 查询 Select
    • 2. 增加 insert
    • 3. 修改 update
    • 4. 删除 delete
    • 附:自动提交事物
    • 5. 分析错误
    • 6. Map
      • 6.1 修改查询 (根据id查询用户)
      • 6.2 模糊查询
    • 7. 配置解析
      • 7.1 核心配置文件
      • 7.2 环境配置(environments)
      • 7.3 属性`properties`
      • 7.4 类型别名(typeAliases)
      • 7.5 设置(setting)
      • 7.6 插件及其他
        • 7.6.1 映射器(mappers)
    • 8. 生命周期和作用域
  • 九、MyBatis的各种查询功能
    • 9.1 类型别名
    • 9.2 查询一个实体类对象
      • 9.2.1 接口
      • 9.2.2 实现类
      • 9.2.3 测试类
    • 9.3 查询一个List集合
      • 9.3.1 接口
      • 9.3.2 实现类
      • 9.3.3 测试类
    • 9.4 查询单个数据
      • 9.4.1 接口
      • 9.4.2 实现类
      • 9.4.3 测试类
    • 9.5 查询一条数据为map集合
      • 9.5.1 接口
      • 9.5.2 实现类
      • 9.5.3 测试类
    • 9.6 查询多条数据为map集合
      • 9.6.1 方法一
        • 9.6.1.2 接口
        • 9.6.1.3 实现类
      • 9.6.2 方法二
        • 9.6.2.1 接口
        • 9.6.2.2 实现类
      • 9.6.3 测试类
  • 十、 特殊SQL的执行
    • 10.1 模糊查询
      • 10.1.1 接口
      • 10.1.2 实现类
        • 10.1.2.1 第一种
        • 10.1.2.2 第二种
        • 10.1.2.3 第三种
      • 10.1.3 测试类
    • 10.2 批量删除
      • 10.2.1 接口
      • 10.2.2 实现类
      • 10.2.3 测试类
    • 10.3 动态设置表名
      • 10.3.1 接口
      • 10.3.2 实现类
      • 10.3.3 测试类
    • 10.4 添加功能获取自增主键
      • 10.4.1 接口
      • 10.4.2 实现类
      • 10.4.3 测试类
  • 十一、自定义映射resultMap
    • 11.1 建表
    • 11.2 resultMap处理字段和属性的映射关系
    • 11.3 多对一映射处理
      • 11.3.1 查询员工信息以及员工所对应的部门信息
        • 11.3.1.1 实体类
        • 11.3.1.2 接口
        • 11.3.1.3 级联方式处理映射关系
        • 11.3.1.4 使用association处理映射关系
        • 11.3.1.5 测试类
        • 11.3.1.6 分部查询
            • 11.3.1.6.1 第一步:查询员工信息
            • 11.3.1.6.2 第二步:查询部门信息
            • 11.3.1.6.3 测试类
    • 11.4 一对多映射处理
      • 11.4.1 查询员工信息以及员工所对应的部门信息
        • 11.4.1.1 实体类
        • 11.4.1.2 接口
        • 11.4.1.3 实现类
        • 11.4.1.4 测试类
      • 11.4.2 分步查询
        • 11.4.2.1 第一步:查询部门信息
          • 11.4.2.1.1 接口
          • 11.4.2.1.2 实现类
        • 11.4.2.2 第二步: 根据部门id查询部门中的所有员工
          • 11.4.2.2.1 接口
          • 11.4.2.2.2 实现类
        • 11.4.2.3 测试类
        • 11.4.2.4 测试类延迟加载
    • 11.5 延迟加载
      • 11.5.1 开启延迟加载
      • 11.5.2 开启延迟加载,配置手动设置`fetchType`
  • 十二、动态SQL
    • 12.1 if
      • 12.1.1 接口
      • 12.1.2 实现类
      • 12.1.3 测试类
    • 12.2 where
      • 12.2.1 实现类
      • 12.2.3 注意:where标签不能去掉条件后多余的and/or
    • 12.3 trim
      • 12.3.1 测试类
    • 12.4 choose、when、otherwise
      • 12.4.1 接口
      • 12.4.2 实现类
      • 12.4.3 测试类
    • 12.5 foreach
        • 12.5.1.1 批量删除 接口
        • 12.5.1.2 批量删除 实现类
          • 12.5.1.2.1 第一种写法
          • 12.5.1.2.2 第二种写法
        • 12.5.1.3 批量删除 测试类
        • 12.5.2.1 批量增加 接口
        • 12.5.2.2 批量增加 实现类
        • 12.5.2.4 批量增加 测试类
    • 12.6 SQL片段
  • 十三、MyBatis的缓存
    • 13.1 MyBatis的一级缓存 (默认开启)
    • 13.2 MyBatis的二级缓存
      • 13.2.1 二级缓存的相关配置
    • 13.3 MyBatis缓存查询的顺序 (二级缓存开启的情况下,一级缓存已经开启)
    • 13.4 整合第三方缓存EHCache代替MyBatis的二级缓存(了解)
      • 13.4.1 添加依赖
      • 13.4.2 各个jar包的功能
      • 13.4.3 创建EHCache的配置文件`ehcache.xml`
      • 13.4.4 `EHCache`配置文件说明
      • 13.4.5 设置二级缓存的类型
      • 13.4.6 加入logback日志
  • 十四、MyBatis的逆向工程 MyBatis Generator (MBG)
    • 14.1 创建逆向工程的步骤
      • 14.1.1 创建项目
      • 14.1.2 添加依赖和插件 `pom.xml`
      • 14.1.3 创建MyBatis的核心配置文件 `mybatis-config.xml`
      • 14.1.4 创建MyBatis的核心配置文件
      • 14.1.5 创建MyBatis的核心配置文件 详细版
      • 14.1.6 创建测试类 QBC查询 (Query By Criteria 根据条件查询)
      • 14.1.7 创建测试类 普通修改`updateByPrimaryKey`
      • 14.1.8 创建测试类 选择性普通修改`updateByPrimaryKeySelective`
  • 十五、分页功能
    • 15.1 分页插件使用步骤
      • 15.1.1 添加依赖
      • 15.1.2 配置分页插件
    • 15.2 分页插件的使用
      • 15.2.1 开启分页功能
      • 15.2.2 分页相关数据
        • 15.2.2.1 方法一:直接输出
        • 15.2.2.2 方法二:使用PageInfo
        • 15.2.2.3 分页数据相关属性

一、 MyBatis简介


思维导图:

1.1 MyBatis历史
  • MyBatis最初是Apache的一个开源项目iBatis, 2010年6月这个项目由Apache Software Foundation迁移到了Google Code。随着开发团队转投Google Code旗下, iBatis3.x正式更名为MyBatis。
  • 代码于2013年11月迁移到Github。
  • iBatis一词来源于“internet”和“abatis”的组合,是一个基于Java的持久层框架。 iBatis提供的持久层框架包括SQL Maps(MyBatis封装JDBC过程)和Data Access Objects(DAO)。
1.2 什么是 MyBatis?
  • MyBatis 是一款优秀的持久层框架。
  • 它支持定制化 SQL、存储过程以及高级映射。
  • MyBatis 免除了几乎所有的 JDBC 代码以及手动设置参数和手动获取结果集的工作。
  • MyBatis 可以通过简单的 XML(常用) 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通的 Java 对象)为数据库中的记录。
  • MyBatis 是一个 半自动的ORM(Object Relation Mapping,【Object:对象(实体类) ;Relation:关系(关系型数据库的数据);Mapping:映射】,将实体类对象与数据库中的数据形成映射关系)框架。(_JDBC_纯手动;MyBatis 半自动,需要自己写sql语句;Hibernate全自动)
1.3 MyBatis下载

MyBatis下载:
MyBatis下载
MyBatis下载(Maven仓库)
MyBatis官方文档网址:MyBatis官方文档网址
中文文档:中文文档
具体编程,可以详见文档!

MyBatis是Maven项目:

点击上图中的,Download Latest 下载最新版本的MyBatis:此时的最新版本是3.5.9,点击mybatis-3.5.9.zip即可下载MyBatis

mybatis-3.5.9.zip是jar包
Source code (zip)和 Source code (tar.gz)是不同格式的MyBatis源码,tar.gz是linux系统下的压缩文件格式

我们平时创建项目一般都是Maven项目,因此mybatis-3.x.x.jar包基本上不需要自己下载,官方文档倒是可以下载下来看看**。**

1.4 持久化 数据持久化
  • 持久化就是将程序的数据在持久状态和瞬时状态转化的过程
    • 瞬时状态:内存断电即失
    • 持久状态:数据库(jdbc)、IO文件持久化(相比较数据库浪费资源)
  • 生活中持久化例子:冷藏、罐头
为什么需要持久化?
  • 有一些对象,不能让它丢掉
  • 内存太贵了(外在原因)
1.5 持久层

Dao,Service, Controller层

  • 完成持久化工作的代码块 Dao层
  • 层界限十分明显
1.6 为什么需要Mybatis
  • 帮助程序员将数据存入到数据库
  • 方便
  • 传统的JDBC代码太复杂,简化、框架、自动化
  • 不用mybatis也可以,更容易上手。技术没有高低之分
优点
  1. 简单易学:本身就很小且简单。没有任何第三方依赖,最简单安装只要两个jar文件+配置几个sql映射文件。易于学习,易于使用。通过文档和源代码,可以比较完全的掌握它的设计思路和实现。
  2. 灵活:mybatis不会对应用程序或者数据库的现有设计强加任何影响。 sql写在xml里,便于统一管理和优化。通过sql语句可以满足操作数据库的所有需求。
  3. 解除sql与程序代码的耦合:通过提供DAO层,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护,更易单元测试。sql和代码的分离,提高了可维护性。
  4. 提供映射标签,支持对象与数据库的orm字段关系映射。
  5. 提供对象关系映射标签,支持对象关系组建维护。
  6. .提供xml标签,支持编写动态sql。
  7. 最重要的一点:使用的人多!

未来: mybatis => spring | spring mvc | sring boot

1.7 和其它持久化层技术对比
  • JDBC
  1. SQL 夹杂在Java代码中耦合度高,导致硬编码内伤
  2. 维护不易且实际开发需求中 SQL 有变化,频繁修改的情况多见
  3. 代码冗长,开发效率低
  • Hibernate 和 JPA
  1. 操作简便,开发效率高
  2. 程序中的长难复杂 SQL 需要绕过框架
  3. 内部自动生产的 SQL,不容易做特殊优化
  4. 基于全映射的全自动框架,大量字段的 POJO 进行部分映射时比较困难。
  5. 反射操作太多,导致数据库性能下降
  • MyBatis
  1. 轻量级,性能出色
  2. SQL 和 Java 编码分开,功能边界清晰。Java代码专注业务、SQL语句专注数据
  3. 开发效率稍逊于HIbernate,但是完全能够接受
二、搭建MyBatis 开发环境

IDE:idea 2021.3
JDK:1.8
构建工具:maven 3.6.1
MySQL版本:MySQL 8.0.3
MyBatis版本:MyBatis 3.5.9

2. 第一个 mybatis 程序

思路:搭建环境 -> 导入MyBatis -> 编写代码 -> 测试

2.1 搭建环境 2.1.1 创建数据库
CREATE DATABASE `mybatis`
USE `mybatis`

DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` int(20) NOT NULL,
`name` varchar(30) DEFAULT NULL,
`pwd` varchar(30) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `user`(`id`,`name`,`pwd`) VALUES 
(1,'张三','123456'),
(2,'李四','123456'),
(3,'王五','123890')
2.1.2 新建一个普通的maven项目


命名:

重新配置一下Maven:
Windows系统:File -> Setting -> Build,Execution,Deployment -> Build Tool -> Maven
macOS: IntelliJ IDEA -> Preferences...-> Build,Execution,Deployment -> Build Tool -> Maven
应该是自己的路径,不是Bundled(Maven 3)

2.1.3 删除src文件: 目的是创建一个项目是父项目,以后直接创建各个模块子项目 2.2 导入Maven依赖(MyBatis)
 
    
        
        
            mysql
            mysql-connector-java
            8.0.28
        
        
        
        
            org.mybatis
            mybatis
            3.5.9
        
        
        
            junit
            junit
            4.12
            test
        
    

确保依赖都导入成功:
右边Maven栏:必要时点刷新

2.3 编写代码 2.3.1 创建一个模块 new module


点击Next:

填写模块名,点击Next:

这样创建的好处是:每一个模块单独拥有自己的pom.xml文件,管理不同的依赖

2.3.2 编写mybatis的核心配置文件



连接mysql:

填写必要的信息:

选择Schemas

可能需要下载必要的文件:

连接测试:之后点击Apply,在点击OK

测试连接成功:

连接后可以显示:

显示配置项:

核心配置文件:mybatis-config.cml放到 resources文件中

 
  



  
  
    
        
                
              
                 
                
                
             
             
            
        
    

2.3.3 编写mybatis工具类

创建一些类

创建Class文件

填写Class类名

编写工具类:MybatisUtils

  • sqlSession:代表Java程序和数据库之间的会话。(HttpSession是Java程序和浏览器之间的会话)
  • SqlSessionFactory:“生产”SqlSession的“工厂”
  • 工厂模式:如果创建某一个对象,使用的过程基本固定,那么我们就可以把创建者对象的相关代码封装到一个“工厂类”中,以后都使用这个工厂类来“生产”我们需要的对象。
package com.guo.utils;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;

//sqlSessionFactory --> sqlSession   加载资源  创建对象
public class MybatisUtils {

    private static SqlSessionFactory sqlSessionFactory;
    static {
        try {
            //使用mybatis第一步获取sqlSessionFactory对象
            String resource = "mybatis-config.xml";  //初始就加载 指定配置文件加载
            //读取配置文件 字节输出流
            InputStream inputStream = Resources.getResourceAsStream(resource); 
        
        //获取 sqlSessionFactoryBuilder
        // SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        
        //获取 sqlSessionFactory 
        // sqlSessionFactoryBuilder可以传入字节输入流或者字符输入流
//相当于SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); 
        // sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
             
            //以上注释相当于下面
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); //创建流
         
        }catch (IOException e){
            e.printStackTrace();
        }
    }

    //既然有了 SqlSessionFactory,顾名思义,我们可以从中获得 SqlSession 的实例了。
    //SqlSession 提供了在数据库执行 SQL 命令所需的所有方法。你可以通过 SqlSession 实例来直接执行已映射的 SQL 语句。

    public static SqlSession getSqlSession(){
        return sqlSessionFactory.openSession();

    }

}

最终结构:

2.3.4 编写代码 1. 实体类
package com.guo.pojo;

//实体类
public class User {

    private int id;
    private String name;
    private String pwd;

    //构造函数快捷键:command + N

    public User(){

    }

    public User(int id, String name, String pwd) {
        this.id = id;
        this.name = name;
        this.pwd = pwd;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPwd() {
        return pwd;
    }

    public void setPwd(String pwd) {
        this.pwd = pwd;
    }

    @Override
    public String toString() {
        return "User{"+
                "id=" + id +
                ", name='" + name + ''' +
                ", pwd='" + pwd + ''' +
                '}';
    }
    
}
2. Mapper接口,相当于DAO
package com.guo.dao;

import com.guo.pojo.User;

import java.util.List;

public interface UserMapper {
   //获取全部用户
   List getUserList();

   
}
3. 接口实现类
  • 相关概念:ORM (Object Relations Mapping)对象关系映射。
  • 对象:Java的实体类对象
  • 关系:关系型数据库
  • 映射:二者之间的对应关系
Java概念数据库概念
类表
属性字段/列
对象记录/行
  1. 映射文件的命名
    • 表所对应的实体类的类名+Mapper.xml
    • 例如:表user,映射的实体类为User,所对应的映射文件为UserMapper.xml
    • 因此,一个映射文件对应一个实体类 ,对应一张表操作
    • Mybatis映射文件用于编写SQL,访问以及操作表中的数据。
    • Mybatis映射文件存放的位置是src/maim/mappers目录下 (mapper就是原来的dao)
  2. Mybatis中可以面向接口操作数据,要保证两个一致:
    • a. mapper接口的全类名和映射文件的命名空间(namespace)保持一致
    • b. mapper接口中方法的方法名和映射文件中编写SQL的标签的id属性保持一致
  3. 对应:表-实体类-mapper接口-映射文件





 
    
  

     
    
        
        select * from mybatis.user where name like #{value};
    

MyBatis提供了类型别名的功能,解决了问题:
mybatis-config.xml核心配置文件中引入标签



        
        
        
        
        
    

但是核心mybatis-config.xml核心配置文件中引入标签需要符合顺序!

mybatis-config.xml核心配置文件:





    
    

    
    
        
    

    
    
        
                
            
                  
                
                
                
            
        
    

6.4 `mappers``
    
    
        
    

但是每次写一个接口文件,就需要引用一个mappper标签,因此可以以包为单位改量一下:

6.4.1 新建一个包

映射文件放在resources里,这里不能直接创建包,只能创建Directory:

resources文件下是一个个目录,因此里写的是路径,创建Directory时不能写com.guo.mappers要写com/guo/mappers
最后生成的目录结构:

6.4.2 修改核心配置文件mybatis-configxml

核心配置文件mybatis-config.xml :

    
    
        
        
        
    
6.5 总结 6.5.1 核心配置文件mybatis-config.xml



    
    
  
    
        
        
        
        
        
    
    
    
        
        
            
            
            
            
                
                
                
                
                
                
                
                
            
        
    
    
    
        
        
        
    

6.5.2 文件结构

七、MyBatis 增删改查 CRUD 7. 新建项目(New Module) 7.1 新建一个模块

选中项目名右键点击New --> Module...

点击 Next

设置相应参数,设置完点击Finish

7.2 增加并配置核心配置文件

选中resources文件,右键点击New --> File

可自定义命名,但规范命名为mybatis-config.xml

7.3 新建jdbc.properties文件

选中resources文件,右键点击New --> Resource Bundle

写个名字,我这里写的是jdbc,之后里面的配置加jdbc.前缀

jdbc.driver = com.mysql.jdbc.Driver
jdbc.url =jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT
jdbc.username = 
jdbc.password = 
7.4 创建类

选中src/main/java文件,右键点击New --> Package

自定义命名包名:com.**.mappers 、com.**.pojo 等等

7.5 创建resources中的mapper

选中resources文件,右键点击New --> Directory

写路径名要和之前写过的com.**.mappers对应,只不过这里写的是路径 commappers

7.6 将核心配置文件作为模版mybatis-config.xml

点击IntelliJ IDEA --> Preferences…

或者 点击右上角齿轮 -->Preferences…

选择File and Code Templates设置

7.7 创建映射文件并将其作为模版mybatis-mapper.xml

选中resources文件,右键点击New --> File

设定名字,要与接口文件名字相同,例:ParameterMapper.xml

选择File and Code Templates设置

7.8 创建测试类

选中test/java文件,右键点击New --> Java Class

设定名字,最好要与接口文件名字相同,例:ParameterMapperTest.java

文件格式

7.9 创建工具类Utils.java

import java.io.InputStream;

public class SqlSessionUtils {

    public static SqlSession getSqlSession() {

        SqlSession sqlSession = null;

        String resource = "mybatis-config.xml";  //初始就加载
        try {
            InputStream inputStream = Resources.getResourceAsStream(resource);
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            sqlSession =  sqlSessionFactory.openSession(true); //自动提交事物

        } catch (IOException e) {
            e.printStackTrace();
        }
        return sqlSession;
    }
}
八、 MyBatis获取参数值的两种方式(重点)
  • MyBatis获取参数值的两种方式:${}和#{}
  • ${}的本质就是字符串拼接,#{}的本质就是占位符赋值(优先使用)
  • ${}使用字符串拼接的方式拼接SQL,若为字符串类型或日期类型的字段进行赋值时,需要手动加单引号;但是#{}使用占位符赋值的方式拼接SQL,此时为字符串类型或日期类型的字段进行赋值时,可以自动添加单引号。
8.1 单个字面量类型的参数
  • 若mapper接口中的方法参数为单个的字面量类型,此时可以使用${}和#{}以任意的名称(最好见名识意)获取参数的值,注意${}需要手动加单引号。
//ParameterMapper.java  接口class
    User getUserByUserName(String username);

  
	select * from mybatis.user where user.name = '${username}'  

// 测试类
    @Test
    public void testgetUserByUserName(){
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        ParameterMapper mapper = sqlSession.getMapper(ParameterMapper.class);
        User user = mapper.getUserByUserName("王五"); //需要的值
        System.out.println(user);
    }
8.2 多个字面量类型的参数
  • 若mapper接口中的方法参数为多个时,此时MyBatis会自动将这些参数放在一个map集合中
    • 以arg0,arg1…为键,以参数为值;
    • 以param1,param2…为键,以参数为值;
  • 因此只需要通过${}和#{}访问map集合的键就可以获取相对应的值,注意${}需要手动加单引号。
  • 使用arg或者param都行,要注意的是,arg是从arg0开始的,param是从param1开始的
//ParameterMapper.java  接口class
//验证和登录功能
    User checkLogin(String username,String password);


	select * from mybatis.user where user.name = '${arg0}' and user.pwd = '${arg1}';




	select * from mybatis.user where user.name = #{username} and user.pwd = #{password};

// 测试类
    @Test
    public void testCheckLoginByMap(){
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        ParameterMapper mapper = sqlSession.getMapper(ParameterMapper.class);
        Map map = new HashMap();
      //这里键username要和ParameterMapper.xml中的 #{username}的名字对应上
        map.put("username","张三"); 
      //这里值password要和ParameterMapper.xml中的#{password}的名字对应上
        map.put("password","123456");
        User user = mapper.checkLoginByMap(map);
        System.out.println(user);
    }
8.4 实体类类型的参数
  • 若mapper接口中的方法参数为实体类对象时此时可以使用${}和#{},通过访问实体类对象中的属性名获取属性值,注意${}需要手动加单引号。(使用最多的情况,浏览器传输过来的是实体类对象,通过${}和#{}以属性的方式访问属性值)
//ParameterMapper.java  接口class
//添加用户信息功能
    int insertUser(User user);


      insert into mybatis.user values (#{id},#{name},#{pwd});
	

//测试类
    @Test
    public void testinsertUser(){
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        ParameterMapper mapper = sqlSession.getMapper(ParameterMapper.class);
        int result = mapper.insertUser(new User(7,"测试2","密码"));
        //如果id为自增列,则是null
        //int result = mapper.insertUser(new User(null,"测试2","密码"));
        System.out.println(result);
    }
8.4.1 注意点:

8.5 使用@Param标识参数
  • 可以通过@Param注解标识mapper接口中的方法参数,此时,会将这些参数放在map集合中
    • 以@Param注解的value属性值为键,以参数为值;
    • 以param1,param2…为键,以参数为值;
  • 只需要通过${}和#{}访问map集合的键就可以获取相对应的值,注意${}需要手动加单引号
//ParameterMapper.java  接口class
//验证和登录功能
//键 String类型,值Object类型
//@Param("username") 相当于 @Param(value = "username")
      User checkLoginByParam(@Param("username") String username, @Param("password") String password);
      

    
        select * from mybatis.user where id = #{id}
  
  1. 测试
    UserMapperTest.java(测试类)
    @Test
    public void getUserById(){
        SqlSession sqlSession = MybatisUtils.getSqlSession(); //不变

        UserMapper mapper = sqlSession.getMapper(UserMapper.class); //获得相应接口 具体对象 
        User user = mapper.getUserById(1);
        System.out.println(user);
        sqlSession.close(); // 不变
    }

2. 增加 insert

UserMapper.java

//insert一个用户
   int addUser(User user);

UserMapper.xml

    
    
    
        insert into mybatis.user (id,name,pwd) values (#{id},#{name},#{pwd});
    

UserMapperTest.java(测试类)
增删改需要提交事物

    //增删改需要提交事物
    @Test
    public void addUser(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();//不变
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);//不变
        int res = mapper.addUser(new User(4,"赵六","121212"));
        if(res > 0){
            System.out.println("插入成功");
        }
        //提交事物
        sqlSession.commit();
        sqlSession.close(); //不变
    }
3. 修改 update

UserMapper.java

  //update修改用户
   int updateUser(User user);

UserMapper.xml

    
    
    
        update mybatis.user set name =#{name},pwd=#{pwd} where id = #{id};
    

UserMapperTest.java(测试类)
增删改需要提交事物

    @Test
    public void updateUser(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();//不变

        UserMapper mapper = sqlSession.getMapper(UserMapper.class);//不变
        mapper.updateUser(new User(4,"更改了","123123"));

        //提交事物
        sqlSession.commit();
        sqlSession.close();//不变
    }
4. 删除 delete

UserMapper.java

   //delete 删除一个用户
   int deleteUser(int id);

UserMapper.xml

    
    
    
         delete from mybatis.user where id = #{id};
    

UserMapperTest.java(测试类)
增删改需要提交事物

    @Test
    public void deleteUser(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();//不变
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);//不变
        mapper.deleteUser(4);

        //必须提交事物
        sqlSession.commit();
        sqlSession.close();//不变
    }
附:自动提交事物

修改MybatisUtils.java中sqlSessionFactory.openSession();方法可以自动提交事物,默认不自动提交事物

package com.guo.utils;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;

//sqlSessionFactory --> sqlSession   加载资源  创建对象
public class MybatisUtils {

    private static SqlSessionFactory sqlSessionFactory;
    static {
        try {
            //使用mybatis第一步获取sqlSessionFactory对象
            //加载核心配置文件
            String resource = "mybatis-config.xml";  //初始就加载
            InputStream inputStream = Resources.getResourceAsStream(resource); //读取配置文件

            //获取 sqlSessionFactoryBuilder
            SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
            //获取 sqlSessionFactory
            sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
            //相当于SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); //创建流
            //以上2句相当于 sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); //创建流

        }catch (IOException e){
            e.printStackTrace();
        }
    }

    //既然有了 SqlSessionFactory,顾名思义,我们可以从中获得 SqlSession 的实例了。
    //SqlSession 提供了在数据库执行 SQL 命令所需的所有方法。你可以通过 SqlSession 实例来直接执行已映射的 SQL 语句。

    public static SqlSession getSqlSession(){
        //获取 sqlSession
        //相当于 SqlSession sqlSession = sessionFactory.openSession();
        return sqlSessionFactory.openSession(true); //如果设置sqlSessionFactory.openSession(true);为true 可自动提交事物

    }

}
5. 分析错误
  1. 正确写法:

    错误写法:

  2. 标签不能匹配错:例如: insert 对应插入的方法

  3. mybatis-config.xml中:
    正确写法: resource是资源路径,绑定mapper需要使用路径,使用 /

   
    
        
    

错误写法:

   
    
        
    
  1. 程序数据库配置文件,必须符合规范!

  2. NullPointerException空指针异常 没有注册到资源!
    需要注意MybatisUtils.java中这两行的关系,是否能注册到资源!

   private static SqlSessionFactory sqlSessionFactory;
   sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); //创建流
  1. 输出的target文件夹中的xml文件中存在中文乱码问题!

  2. maven资源没有导出问题!
    在pom.xml中配置:

    
    
    
        
            
                src/main/resources
                
                    ***.xml
                
                true
            
            
                src/main/java
                
                    ***.xml
                
                true
            
        
    

程序报错分析:

6. Map

遇到问题:当前类字段是三个,可以写成(id,name,pwd) values (#{id},#{name},#{pwd})形式。
UserMapper.xml

    
    
        insert into mybatis.user (id,name,pwd) values (#{id},#{name},#{pwd});
    

如果实体类或者数据库表中字段过多,不太建议都写成以上这样,建议使用Map。

UserMapper.java

//万能的Map 不需要传
   int addUser2(Map map);

UserMapper.xml

    
    
        insert into mybatis.user(id,name,pwd) values (#{userid},#{userName },#{passWord});
    

UserMapperTest.java(测试类)

    @Test
    public void addUser2(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();//不变
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);//不变
        Map map = new HashMap();
        map.put("userid",5);//随意制造参数
        map.put("userName","孙七");//
        map.put("passWord","12345");
        mapper.addUser2(map);
        //必须提交事物
        sqlSession.commit();
        sqlSession.close();//不变
    }
6.1 修改查询 (根据id查询用户)

UserMapper.java

//根据ID查询用户
//User getUserById(int id); 原来的
User getUserById2(Map map);//改成

UserMapper.xml

    
        select * from mybatis.user where id = #{id}
    
6.2 模糊查询
  1. Java代码执的时候,传递通配符% %
    List userList = mapper.getUserLike("%李%");
  2. 在sql拼接中使用通配符!(容易sql注入)
    select * from mybatis.user where name like "%" #{value} "%"

UserMapper.java

//模糊查询
   List getUserLike(String value);

UserMapper.xml中 parameterType="int"可以不写了,多个参数用Map,或者注解

    
        select * from mybatis.user where name like #{value}
    

不要写成:

    
    select  * from mybatis.user where id = #{id};

9.2.3 测试类
    @Test
    public void testgetUserById(){
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        SelectMapper mapper = sqlSession.getMapper(SelectMapper.class);
        System.out.println(mapper.getUserById(1));
    }
9.3 查询一个List集合 9.3.1 接口
   

    List getAllUser();
9.3.2 实现类
    
     
    
        select count(*) from mybatis.user; 
    
9.4.3 测试类
    @Test
    public void testgetCount(){
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        SelectMapper mapper = sqlSession.getMapper(SelectMapper.class);
        System.out.println(mapper.getCount());
    }
9.5 查询一条数据为map集合 9.5.1 接口
 

    Map getUserByIdToMap(@Param("id") Integer id);
9.5.2 实现类
    
      
	select * from t_user  


9.6.2 方法二 9.6.2.1 接口
		@MapKey("id")
		Map getAllUserToMap();
9.6.2.2 实现类

    
        select * from mybatis.user where user.name like '%${username}%';
    
    
10.1.2.2 第二种
    
    
        select * from mybatis.user where user.name like "%"#{username}"%";
    
10.1.3 测试类
    @Test
    public void testGetUserByLike(){
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        SQLMapper mapper = sqlSession.getMapper(SQLMapper.class);
        List list = mapper.getUserByLike("李");
        System.out.println(list);
    }
10.2 批量删除
  • 只能使用${},如果使用#{},则解析后的sql语句为delete from t_user where id in ('1,2,3'),这样是将1,2,3看做是一个整体,只有id为1,2,3的数据会被删除。正确的语句应该是delete from t_user where id in (1,2,3),或者delete from t_user where id in ('1','2','3')
10.2.1 接口
   

    int deleteMore(@Param("ids") String ids);
10.2.2 实现类
    
    
        delete  from mybatis.user where id in (${ids});
    
10.2.3 测试类
    @Test
    public void testDeleteMore(){
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        SQLMapper mapper = sqlSession.getMapper(SQLMapper.class);
        int result = mapper.deleteMore("6,7");
        System.out.println(result);
    }
10.3 动态设置表名
  • 多张表共同存储数据
  • 只能使用${},因为表名不能加单引号
10.3.1 接口
   
    List getUserByTableName(@Param("tableName") String tableName);
10.3.2 实现类
    
    
        select * from mybatis.t_emp
    
  • 若字段名和实体类中的属性名不一致,但是字段名符合数据库的规则(使用_),实体类中的属性名符合Java的规则(使用驼峰)。此时也可通过以下两种方式处理字段名和实体类中的属性的映射关系
  1. 可以通过为字段起别名的方式,保证和实体类中的属性名保持一致
    EmpMapper.xml实现类
    
    
        select * from mybatis.t_emp
    

测试类:

    @Test
    public void testGetAllEmp(){
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
        List list = mapper.getAllEmp();
        list.forEach(emp -> System.out.println(emp));
    }
11.3 多对一映射处理 11.3.1 查询员工信息以及员工所对应的部门信息 11.3.1.1 实体类
public class Emp {

        private Integer eid;
        private String empName;
        private Integer age;
        private String sex;
        private String email;
        private Dept dept; //注意!!

    public Integer getEid() {
        return eid;
    }

    public void setEid(Integer eid) {
        this.eid = eid;
    }

    public String getEmpName() {
        return empName;
    }

    public void setEmpName(String empName) {
        this.empName = empName;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public Dept getDept() {
        return dept;
    }

    public void setDept(Dept dept) {
        this.dept = dept;
    }

    @Override
    public String toString() {
        return "Emp{" +
                "eid=" + eid +
                ", empName='" + empName + ''' +
                ", age=" + age +
                ", sex='" + sex + ''' +
                ", email='" + email + ''' +
                ", dept=" + dept +
                '}';
    }
public class Dept {
    private Integer did;
    private String deptName;

    public Dept(Integer did, String deptName) {
        this.did = did;
        this.deptName = deptName;
    }

    public Dept() {
    }

    public Integer getDid() {
        return did;
    }

    public void setDid(Integer did) {
        this.did = did;
    }

    public String getDeptName() {
        return deptName;
    }

    public void setDeptName(String deptName) {
        this.deptName = deptName;
    }

    @Override
    public String toString() {
        return "Dept{" +
                "did=" + did +
                ", deptName='" + deptName + ''' +
                '}';
    }

}
11.3.1.2 接口
   
    Emp getEmpAndDept(@Param("eid") Integer eid);
11.3.1.3 级联方式处理映射关系
   
    
        
        
        
        
        
        
        
    

    
    
        select * from mybatis.t_emp left join mybatis.t_dept on mybatis.t_emp.did = mybatis.t_dept.did where mybatis.t_emp.eid = #{eid};
    
11.3.1.5 测试类
    @Test
    public void testGetEmpAndDept(){
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
        Emp emp = mapper.getEmpAndDept(1);//自定义
        System.out.println(emp);
    }
11.3.1.6 分部查询
  1. 第一步:查询员工信息
  • select:设置分布查询的sql的唯一标识(namespace.SQLId或mapper接口的全类名.方法名)
  • column:设置分步查询的条件
  1. 第二步:查询部门信息
11.3.1.6.1 第一步:查询员工信息

EmpMapper.java接口

   
    Emp getEmpAndDeptByStepOne(@Param("eid") Integer eid);

EmpMapper.xml实现类


    
        
        
        
        
        
        
        
        
    
    
    
        select * from mybatis.t_dept where  mybatis.t_dept.did = #{did};
    
11.3.1.6.3 测试类
    @Test
    public void testGetEmpAndDeptByStep(){
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
        Emp emp = mapper.getEmpAndDeptByStepOne(1);//自定义
        System.out.println(emp);
    }

11.4 一对多映射处理 11.4.1 查询员工信息以及员工所对应的部门信息
  • collection
    • collection:用来处理一对多的映射关系
    • property: 一对多的映射关系的属性
    • ofType:表示该属性对饮的集合中存储的数据的类型
11.4.1.1 实体类
import java.util.List;

public class Dept {
    private Integer did;
    private String deptName;
    private List emps;

    public Dept(Integer did, String deptName, List emps) {
        this.did = did;
        this.deptName = deptName;
        this.emps = emps;
    }
    
    public Dept() {
    }

    public Integer getDid() {
        return did;
    }

    public void setDid(Integer did) {
        this.did = did;
    }

    public String getDeptName() {
        return deptName;
    }

    public void setDeptName(String deptName) {
        this.deptName = deptName;
    }

    public List getEmps() {
        return emps;
    }

    public void setEmps(List emps) {
        this.emps = emps;
    }

    @Override
    public String toString() {
        return "Dept{" +
                "did=" + did +
                ", deptName='" + deptName + ''' +
                ", emps=" + emps +
                '}';
    }
}
11.4.1.2 接口

DeptMapper.java

   
    Dept getDeptAndEmp(@Param("did")Integer did);
11.4.1.3 实现类

DeptMapper.xml

    
        
        
        
        
            
            
            
            
            
        
    
    
    
        select * from mybatis.t_dept where mybatis.t_dept.did = #{did};
    
11.4.2.2 第二步: 根据部门id查询部门中的所有员工 11.4.2.2.1 接口
   
    List getDeptAndEmpByStepTwo(@Param("eid") Integer eid);
11.4.2.2.2 实现类
   
    
        select * from mybatis.t_dept where mybatis.t_dept.did = #{did};
    

11.5 延迟加载
  • 分步查询的优点:可以实现延迟加载,但是必须在核心配置文件中设置全局配置信息:
    • lazyLoadingEnabled:延迟加载的全局开关。当开启时,所有关联对象都会延迟加载,默认为false(需要设置lazyLoadingEnabled: true,aggressiveLazyLoading为false)
    • aggressiveLazyLoading:当开启时,任何方法的调用都会加载该对象的所有属性。 否则,每个属性会按需加载。默认为false。
  • 此时就可以实现按需加载,获取的数据是什么,就只会执行相应的sql。此时可通过association和collection中的fetchType属性设置当前的分步查询是否使用延迟加载,fetchType=“lazy(延迟加载)|eager(立即加载)”
11.5.1 开启延迟加载
   
    
        
        
    

ResultMapTest.java测试类

   @Test
    public void testGetEmpAndDeptByStep(){
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
        Emp emp = mapper.getEmpAndDeptByStepOne(1);
        System.out.println(emp.getEmpName());
    }

未开启延迟加载前:两条SQL语句都运行了

开启延迟加载后:只运行获取emp的SQL语句

ResultMapTest.java测试类2

    @Test
    public void testGetEmpAndDeptByStep(){
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
        Emp emp = mapper.getEmpAndDeptByStepOne(1);
        System.out.println(emp.getEmpName());
        System.out.println("---------------------------");
        System.out.println(emp.getDept());
    }

未开启延迟加载前:两条SQL语句都运行了

开启延迟加载后:需要用到查询dept的时候才会调用相应的SQL语句

11.5.2 开启延迟加载,配置手动设置fetchType

fetchType:当开启了全局的延迟加载之后,可以通过该属性手动控制延迟加载的效果
fetchType=“lazy|eager”:lazy表示延迟加载,eager表示立即加载

    
        
        
        
        
        
        
    

十二、动态SQL
  • Mybatis框架的动态SQL技术是一种根据特定条件动态拼装SQL语句的功能,它存在的意义是为了解决拼接SQL语句字符串时的痛点问题
//实体类
public class Emp {

        private Integer eid;
        private String empName;
        private Integer age;
        private String sex;
        private String email;
        private Dept dept;

    public Integer getEid() {
        return eid;
    }

    public void setEid(Integer eid) {
        this.eid = eid;
    }

    public String getEmpName() {
        return empName;
    }

    public void setEmpName(String empName) {
        this.empName = empName;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public Dept getDept() {
        return dept;
    }

    public void setDept(Dept dept) {
        this.dept = dept;
    }

    @Override
    public String toString() {
        return "Emp{" +
                "eid=" + eid +
                ", empName='" + empName + ''' +
                ", age=" + age +
                ", sex='" + sex + ''' +
                ", email='" + email + ''' +
                ", dept=" + dept +
                '}';
    }

    public Emp(Integer eid, String empName, Integer age, String sex, String email, Dept dept) {
        this.eid = eid;
        this.empName = empName;
        this.age = age;
        this.sex = sex;
        this.email = email;
        this.dept = dept;
    }

    public Emp(Integer eid, String empName, Integer age, String sex, String email) {
        this.eid = eid;
        this.empName = empName;
        this.age = age;
        this.sex = sex;
        this.email = email;
    }

    public Emp() {
    }
}
12.1 if
  • if标签可通过test属性(即传递过来的数据)的表达式进行判断,若表达式的结果为true,则标签中的内容会执行;反之标签中的内容不会执行
  • 在where后面添加一个恒成立条件1=1
    • 这个恒成立条件并不会影响查询的结果
    • 这个1=1可以用来拼接and语句,例如:当empName为null时
      • 如果不加上恒成立条件,则SQL语句为select * from t_emp where and age = ? and sex = ? and email = ?,此时where会与and连用,SQL语句会报错
      • 如果加上一个恒成立条件,则SQL语句为select * from t_emp where 1= 1 and age = ? and sex = ? and email = ?,此时不报错
12.1.1 接口
  
    List getEmpByCondition(Emp emp);
12.1.2 实现类
 
    
        select * from mybatis.t_emp where 1=1
        
            and emp_name = #{empName}
        
        
            and age = #{age}
        
        
            and sex = #{sex}
        
        
            and email = #{email}
        
    
12.1.3 测试类
    @Test
    public void TestGetEmpByCondition(){
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        DynamicSQLMapper mapper = sqlSession.getMapper(DynamicSQLMapper.class);
        List list = mapper.getEmpByCondition(new Emp(null,"张三",30,"男","123@qq.com"));
        System.out.println(list);
    }
12.2 where
  • where和if一般结合使用:
    • 若where标签中的if条件都不满足,则where标签没有任何功能,即不会添加where关键字
    • 若where标签中的if条件满足,则where标签会自动添加where关键字,并将条件最前方多余的and/or去掉
12.2.1 实现类
    
    
        select * from mybatis.t_emp
        
            
                emp_name = #{empName} and 
            
            
                age = #{age} and 
            
            
                sex = #{sex} and 
            
            
                email = #{email}
            
        
    
12.3 trim
  • trim用于去掉或添加标签中的内容
  • 常用属性
  • prefix:在trim标签中的内容的前面添加指定内容
  • suffix:在trim标签中的内容的后面添加指定内容
  • prefixOverrides:在trim标签中的内容的前面去掉指定内容
  • suffixOverrides:在trim标签中的内容的后面去掉指定内容
  • 若trim中的标签都不满足条件,则trim标签没有任何效果,也就是只剩下select * from t_emp

    
        select * from mybatis.t_emp
        
            
                emp_name = #{empName} and
            
            
                age = #{age} and
            
            
                sex = #{sex} or
            
            
                email = #{email}
            
        
    
12.3.1 测试类
    @Test
    public void TestGetEmpByCondition(){
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        DynamicSQLMapper mapper = sqlSession.getMapper(DynamicSQLMapper.class);
        List list = mapper.getEmpByCondition(new Emp(null,"张三",null,"",""));
        System.out.println(list);
    }
12.4 choose、when、otherwise
  • choose、when、otherwise相当于if...else if..else
  • when至少要有一个,otherwise至多只有一个
12.4.1 接口
  
    List getEmpByChoose(Emp emp);
12.4.2 实现类
    
    
        select  from mybatis.t_emp
        
            
                emp_name = #{empName} and
            
            
                age = #{age} and
            
            
                sex = #{sex} or
            
            
                email = #{email}
            
        
    
十三、MyBatis的缓存 13.1 MyBatis的一级缓存 (默认开启)
  • 一级缓存是SqlSession级别的,通过同一个SqlSession查询的数据会被缓存,下次查询相同的数据,就会从缓存中直接获取,不会从数据库重新访问
  • 使一级缓存失效的四种情况:
    1. 不同的SqlSession对应不同的一级缓存
    2. 同一个SqlSession但是查询条件不同
    3. 同一个SqlSession两次查询期间执行了任何一次增删改操作。(增删改操作改变了数据,清空了缓存)
    4. 同一个SqlSession两次查询期间手动清空了缓存
  • 举例:
    一级缓存的范围:
//接口
Emp getEmpByEid(@Param("eid") Integer eid);

    
    
//测试类
    @Test
    public void testCache(){
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        CacheMapper mapper = sqlSession.getMapper(CacheMapper.class);
        Emp emp = mapper.getEmpByEid(1);
        System.out.println(emp);
        SqlSession sqlSession2 = SqlSessionUtils.getSqlSession();
        CacheMapper mapper1 = sqlSession2.getMapper(CacheMapper.class);
        Emp emp2 = mapper1.getEmpByEid(1);
        System.out.println(emp2);
    }


  • 一级缓存失败情况:
//接口
void insertEmp(Emp emp);
    
    
        insert into mybatis.t_emp values(null,#{empName},#{age},#{sex},#{email},null);
    
//测试类
@Test
    public void testCacheInsertEmp(){
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        CacheMapper mapper = sqlSession.getMapper(CacheMapper.class);
        Emp emp = mapper.getEmpByEid(1);
        System.out.println(emp);
        mapper.insertEmp(new Emp(null,"abc",23,"男","123@qq.com"));
        Emp emp2 = mapper.getEmpByEid(1);
        System.out.println(emp2);
    }

  • 手动清空缓存
//测试类
    @Test
    public void testCacheInsertEmp(){
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        CacheMapper mapper = sqlSession.getMapper(CacheMapper.class);
        Emp emp = mapper.getEmpByEid(1);
        System.out.println(emp);
        sqlSession.clearCache();//清空缓存
        Emp emp2 = mapper.getEmpByEid(1);
        System.out.println(emp2);
    }

13.2 MyBatis的二级缓存
  • 二级缓存是SqlSessionFactory级别,通过同一个SqlSessionFactory创建的SqlSession查询的结果会被缓存;此后若再次执行相同的查询语句,结果就会从缓存中获取

  • 二级缓存开启的条件

    1. 在核心配置文件中,设置全局配置标签中的属性cacheEnabled=“true”,默认为true,不需要设置
    2. 在映射文件(xxxMapper.xml)中设置标签,该标签里可以设置二级缓存的配置信息。
    3. 二级缓存必须在SqlSession关闭或提交之后有效
      当没有关闭或提交SqlSession时,数据会先被存储在一级缓存中,当关闭或提交SqlSession后,数据才会被保存到二级缓存中。
    4. 查询的数据所转换的实体类类型必须实现序列化的接口
      public class Emp implements Serializable{}
  • 使二级缓存失效的情况:两次查询之间执行了任意的增删改,会使一级和二级缓存同时失效。

  • 手动清空缓存:因为是sqlSession.clearCache();//清空缓存是Sqlsession级别所以是一级缓存。

  • 测试:

//测试类
   
    @Test
    public void testTwoCache(){
        //工具类不可用,只能重新写
        try{
            InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);

            SqlSession sqlSession1 = sqlSessionFactory.openSession(true);
            CacheMapper mapper1 = sqlSession1.getMapper(CacheMapper.class);
            System.out.println(mapper1.getEmpByEid(1));

            SqlSession sqlSession2 = sqlSessionFactory.openSession(true);
            CacheMapper mapper2 = sqlSession2.getMapper(CacheMapper.class);
            System.out.println(mapper2.getEmpByEid(1));
        } catch (IOException e){
            e.printStackTrace();
        }
    }

//测试类
   
@Test
    public void testTwoCache(){
        //工具类不可用,只能重新写
        try{
            InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
            SqlSession sqlSession1 = sqlSessionFactory.openSession(true);
            CacheMapper mapper1 = sqlSession1.getMapper(CacheMapper.class);
            System.out.println(mapper1.getEmpByEid(1));
            sqlSession1.close();
            SqlSession sqlSession2 = sqlSessionFactory.openSession(true);
            CacheMapper mapper2 = sqlSession2.getMapper(CacheMapper.class);
            System.out.println(mapper2.getEmpByEid(1));
            sqlSession2.close();
        } catch (IOException e){
            e.printStackTrace();
        }
    }

13.2.1 二级缓存的相关配置
  • 在mapper配置文件中添加的标签可以设置一些属性
  • eviction属性:缓存回收策略
    • LRU(Least Recently Used) – 最近最少使用的:移除最长时间不被使用的对象。
    • FIFO(First in First out) – 先进先出:按对象进入缓存的顺序来移除它们。
    • SOFT – 软引用:移除基于垃圾回收器状态和软引用规则的对象。
    • WEAK – 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。
    • 默认的是 LRU
  • flushInterval属性:刷新间隔,单位毫秒
    • 默认情况是不设置,也就是没有刷新间隔,缓存仅仅**调用语句(增删改)**时刷新
  • size属性:引用数目,正整数
    • 代表缓存最多可以存储多少个对象,太大容易导致内存溢出
  • readOnly属性:只读,true/false
    • true:只读缓存;会给所有调用者返回缓存对象的相同实例。因此这些对象不能被修改。这提供了很重要的性能优势。例子:查询出来的信息保存在二级缓存中,这些信息不能被改,否则与数据库不相同了!
    • false:读写缓存;会返回缓存对象的拷贝(通过序列化)。这会慢一些,但是安全,因此默认是false。
13.3 MyBatis缓存查询的顺序 (二级缓存开启的情况下,一级缓存已经开启)
  • 一级缓存只对应一个SqlSession,二级缓存对应多个SqlSession因此:
  • 先查询二级缓存,因为二级缓存中可能会有其他程序已经查出来的数据,可以拿来直接使用
  • 如果二级缓存没有命中,再查询一级缓存
  • 如果一级缓存也没有命中,则查询数据库
  • SqlSession关闭之后,一级缓存中的数据会写入二级缓存
13.4 整合第三方缓存EHCache代替MyBatis的二级缓存(了解) 13.4.1 添加依赖


	org.mybatis.caches
	mybatis-ehcache
	1.2.1



	ch.qos.logback
	logback-classic
	1.2.3

13.4.2 各个jar包的功能
jar包名称作用
mybatis-ehcacheMybatis和EHCache的整合包
ehcacheEHCache核心包
slf4j-apiSLF4J日志门面包
logback-classic支持SLF4J门面接口的一个具体实现,里面放实现类
13.4.3 创建EHCache的配置文件ehcache.xml
  • 名字必须叫ehcache.xml


    
    
    
    

13.4.4 EHCache配置文件说明
属性名是否必须作用
maxElementsInMemory是在内存中缓存的element的最大数目
maxElementsOnDisk是在磁盘上缓存的element的最大数目,若是0表示无穷大
eternal是设定缓存的elements是否永远不过期。 如果为true,则缓存的数据始终有效, 如果为false那么还要根据timeToIdleSeconds、timeToLiveSeconds判断
overflowToDisk是设定当内存缓存溢出的时候是否将过期的element缓存到磁盘上
timeToIdleSeconds否当缓存在EhCache中的数据前后两次访问的时间超过timeToIdleSeconds的属性取值时, 这些数据便会删除,默认值是0,也就是可闲置时间无穷大
timeToLiveSeconds否缓存element的有效生命期,默认是0.,也就是element存活时间无穷大
diskSpoolBufferSizeMB否DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区
diskPersistent否在VM重启的时候是否启用磁盘保存EhCache中的数据,默认是false
diskExpiryThreadIntervalSeconds否磁盘缓存的清理线程运行间隔,默认是120秒。每个120s, 相应的线程会进行一次EhCache中数据的清理工作
memoryStoreEvictionPolicy否当内存缓存达到最大,有新的element加入的时候, 移除缓存中element的策略。 默认是LRU(最近最少使用),可选的有LFU(最不常使用)和FIFO(先进先出
13.4.5 设置二级缓存的类型
  • 在xxxMapper.xml文件中设置二级缓存类型
13.4.6 加入logback日志
  • 存在SLF4J时,作为简易日志的log4j将失效,此时我们需要借助SLF4J的具体实现logback来打印日志。创建logback的配置文件logback.xml,名字固定,不可改变!


    
    
        
            
            
            [%d{HH:mm:ss.SSS}] [%-5level] [%thread] [%logger] [%msg]%n
        
    
    
    
    
        
        
    
    
    

此时可以重新运行一下测试类,输出的日志相比MyBatis的日志肯定会多一些,个人感觉会有点乱!

十四、MyBatis的逆向工程 MyBatis Generator (MBG)
  • 正向工程:先创建Java实体类,由框架负责根据实体类生成数据库表。Hibernate是支持正向工程的
  • 逆向工程:先创建数据库表,由框架负责根据数据库表,反向生成如下资源:
    • Java实体类
    • Mapper接口
    • Mapper映射文件
14.1 创建逆向工程的步骤 14.1.1 创建项目


14.1.2 添加依赖和插件 pom.xml


    
        Mybatis_Study
        com.mybatis
        1.0-SNAPSHOT
    
    4.0.0

    com.guo.mybatis
    mybatis-MBG
    jar

    
        8
        8
    

    
        
        
            org.mybatis
            mybatis
            3.5.9
        
        
        
            junit
            junit
            4.12
            test
        
        
        
            mysql
            mysql-connector-java
            8.0.28
        
        
        
            log4j
            log4j
            1.2.17
        
    
    
    
        
        
            
            
                org.mybatis.generator
                mybatis-generator-maven-plugin
                1.3.0
                
                
                    
                    
                        org.mybatis.generator
                        mybatis-generator-core
                        1.3.2
                    
                    
                    
                        com.mchange
                        c3p0
                        0.9.2
                    
                    
                    
                        mysql
                        mysql-connector-java
                        8.0.28
                    
                
            
        
    


14.1.3 创建MyBatis的核心配置文件 mybatis-config.xml



    

    
        
    

    
        
            
            
                
                
                
                
            
        
    

    
        
    

14.1.4 创建MyBatis的核心配置文件

文件名必须是:generatorConfig.xml

macOS系统路径是:./src/main/java

windows系统应该是:.srcmainjava




    
    
        
        
        
        
        
            
            
            
        
        
        
            
        
        
        
            
        
        
        
        
        
  • 如果出现报错:Exception getting JDBC Driver,可能是pom.xml中,数据库驱动配置错误
  • dependency中的驱动
  • 两者的驱动版本应该相同
        
        
            mysql
            mysql-connector-java
            8.0.28
        
  • mybatis-generator-maven-plugin插件中的驱动

    
        
        
            
            
                org.mybatis.generator
                mybatis-generator-maven-plugin
                1.3.0
                
                
                    
                    
                        org.mybatis.generator
                        mybatis-generator-core
                        1.3.2
                    
                    
                    
                        com.mchange
                        c3p0
                        0.9.2
                    
                    
                    
                        mysql
                        mysql-connector-java
                        8.0.28
                    
                
            
        
    

运行插件前:

运行插件后

注意新生成实体类中:没有有参构造方法,没有午餐构造方法,以及toString()方法,需要手动生成
自动生成驼峰结构的属性:

精简版只生成5个方法:

14.1.5 创建MyBatis的核心配置文件 详细版
  • 将上述MyBatis的核心配置文件设置修改:

    注意新生成实体类中:没有有参构造方法,没有午餐构造方法,以及toString()方法,需要手动生成

普通添加和选择性添加,结果上相同,但方法有所不同:

普通更新操作和选择性更新操作有很大不同,需要特别注意!

14.1.6 创建测试类 QBC查询 (Query By Criteria 根据条件查询)
  • selectByExample:按条件查询,需要传入一个example对象或者null;如果传入一个null,则表示没有条件,也就是查询所有数据
  • example.createCriteria().xxx:创建条件对象,通过andXXX方法为SQL添加查询添加,每个条件之间是and关系
  • example.or().xxx:将之前添加的条件通过or拼接其他条件
    @Test
    public void testMBG(){
        try{
            InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
            SqlSession sqlSession = sqlSessionFactory.openSession(true);
            EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);

           //查询所有数据
           List list =  mapper.selectByExample(null);
           list.forEach(emp -> System.out.println(emp));

        }catch (IOException e){
            e.printStackTrace();
        }
    }


加上条件查询

  @Test
    public void testMBG(){
        try{
            InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
            SqlSession sqlSession = sqlSessionFactory.openSession(true);
            EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);

            //根据条件查询 QBC Query By Criteria 根据条件查询
            EmpExample example = new EmpExample();
            example.createCriteria().andEmpNameEqualTo("张三");
            List list =  mapper.selectByExample(example);
            list.forEach(emp -> System.out.println(emp));
        }catch (IOException e){
            e.printStackTrace();
        }
    }


可以继续叠加方法:

    @Test
    public void testMBG(){
        try{
            InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
            SqlSession sqlSession = sqlSessionFactory.openSession(true);
            EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);

            //根据条件查询 QBC Query By Criteria 根据条件查询
            EmpExample example = new EmpExample();
            example.createCriteria().andEmpNameEqualTo("张三").andAgeGreaterThanOrEqualTo(20);
            List list =  mapper.selectByExample(example);
            list.forEach(emp -> System.out.println(emp));
        }catch (IOException e){
            e.printStackTrace();
        }
    }


加上or

    @Test
    public void testMBG(){
        try{
            InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
            SqlSession sqlSession = sqlSessionFactory.openSession(true);
            EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);

            //根据条件查询 QBC Query By Criteria 根据条件查询
            EmpExample example = new EmpExample();
            example.createCriteria().andEmpNameEqualTo("张三").andAgeGreaterThanOrEqualTo(20);//名字是:张三年龄大于等于20
            example.or().andDidIsNotNull();//or设置  did值不为空
            List list =  mapper.selectByExample(example);
            list.forEach(emp -> System.out.println(emp));
        }catch (IOException e){
            e.printStackTrace();
        }
    }

14.1.7 创建测试类 普通修改updateByPrimaryKey

原表

    @Test
    public void testMBGUpdate(){
        try{
            InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
            SqlSession sqlSession = sqlSessionFactory.openSession(true);
            EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
            mapper.updateByPrimaryKey(new Emp(12,"abc改",22,null,"456@qq.com",3));
        }catch (IOException e){
            e.printStackTrace();
        }
    }

运行后:

性别变成了:null

14.1.8 创建测试类 选择性普通修改updateByPrimaryKeySelective

原表

    @Test
    public void testMBGUpdateSelect(){
        try{
            InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
            SqlSession sqlSession = sqlSessionFactory.openSession(true);
            EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
            mapper.updateByPrimaryKeySelective(new Emp(12,"abc改",22,null,"456@qq.com",3));
        }catch (IOException e){
            e.printStackTrace();
        }
    }

运行后:

表中性别没有变:

十五、分页功能 15.1 分页插件使用步骤 15.1.1 添加依赖
    
        
            com.github.pagehelper
            pagehelper
            5.2.0
        
15.1.2 配置分页插件
  • 在MyBatis的核心配置文件mybatis-config.xml中配置插件plugins
  • 核心配置文件中的标签必须按照固定的顺序(有的标签可以不写,但顺序一定不能乱):
    properties、settings、typeAliases、typeHandlers、objectFactory、objectWrapperFactory、reflectorFactory、plugins、environments、databaseIdProvider、mappers

	
	

15.2 分页插件的使用 15.2.1 开启分页功能
  • 在查询功能之前使用PageHelper.startPage(int pageNum, int pageSize)开启分页功能
    • pageNum:当前页的页码
    • pageSize:每页显示的条数
    @Test
    public void testPageHelper() throws IOException {
        try{
            InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
            SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
            SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is);
            SqlSession sqlSession = sqlSessionFactory.openSession(true);
            EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
            //访问第一页,每页四条数据
            PageHelper.startPage(2,4);//pageNum = 1,pageSize = 4
            List list = mapper.selectByExample(null);//查询所有数据
            list.forEach(emp -> System.out.println(emp));
        }catch (IOException  e){
            e.printStackTrace();
        }

    }

15.2.2 分页相关数据 15.2.2.1 方法一:直接输出

PageHelper其实是一个Page类型

@Test
    public void testPageHelper() throws IOException {
        try{
            InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
            SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
            SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is);
            SqlSession sqlSession = sqlSessionFactory.openSession(true);
            EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
            //访问第一页,每页四条数据
            Page page = PageHelper.startPage(2,4);//pageNum = 1,pageSize = 4
            List list = mapper.selectByExample(null);//查询所有数据
            //list.forEach(emp -> System.out.println(emp));
            System.out.println(page);
        }catch (IOException  e){
            e.printStackTrace();
        }
 

输出结果:

Page{count=true, pageNum=2, pageSize=4, startRow=4, endRow=8, total=9, pages=3, reasonable=false, pageSizeZero=false}[Emp{eid=5, empName='田七', age=23, sex='男', email='123@qq.com', did=2}, Emp{eid=6, empName='a', age=1, sex='男', email='123@321.com', did=null}, Emp{eid=7, empName='b', age=2, sex='男', email='123@321.com', did=null}, Emp{eid=8, empName='c', age=3, sex='男', email='123@321.com', did=null}]

count=true, pageNum=2: 当前页页码
pageSize=4:每页显示条数
startRow=4:从那行开始
endRow=8: 到底几行结束
total=9 :一共多少条数据
pages=3: 一共多少页

数据:

[Emp{eid=5, empName='田七', age=23, sex='男', email='123@qq.com', did=2}, Emp{eid=6, empName='a', age=1, sex='男', email='123@321.com', did=null}, Emp{eid=7, empName='b', age=2, sex='男', email='123@321.com', did=null}, Emp{eid=8, empName='c', age=3, sex='男', email='123@321.com', did=null}]
15.2.2.2 方法二:使用PageInfo
  • 在查询获取list集合之后,使用PageInfo pageInfo = new PageInfo<>(List list, intnavigatePages)获取分页相关数据
    • list:分页之后的数据
    • navigatePages:导航分页的页码数
    @Test
    public void testPageHelper() throws IOException {
        try{
            InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
            SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
            SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is);
            SqlSession sqlSession = sqlSessionFactory.openSession(true);
            EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
            //访问第一页,每页四条数据
            PageHelper.startPage(2,4);
            List list = mapper.selectByExample(null);//查询所有数据
            //获取分页数据,设置导航分页时用    不建议写偶数,一般为基数
            PageInfo page = new PageInfo<>(list,3);
            System.out.println(page);
        }catch (IOException  e){
            e.printStackTrace();
        }
PageInfo{
# pageNum=2:页码 ,pageSize=4:每页有多少条数据,size=4:当前页码真实的数量(最后一页不一定是满的),startRow=5:从第几行开始,endRow=8:从第几行结束, total=9:总条数,pages=3:页数
pageNum=2, pageSize=4, size=4, startRow=5, endRow=8, total=9, pages=3, 

# 分页相关数据
list=Page{count=true, pageNum=2, pageSize=4, startRow=4, endRow=8, total=9, pages=3, reasonable=false, pageSizeZero=false}[Emp{eid=5, empName='田七', age=23, sex='男', email='123@qq.com', did=2}, Emp{eid=6, empName='a', age=1, sex='男', email='123@321.com', did=null}, Emp{eid=7, empName='b', age=2, sex='男', email='123@321.com', did=null}, Emp{eid=8, empName='c', age=3, sex='男', email='123@321.com', did=null}], 

# prePage=1:上一页页码,nextPage=3:下一页页码,isFirstPage=false:是否是第一页,isLastPage=false:是否是最后一页,hasPreviousPage=true:是否有上一页,hasNextPage=true:是否有下一页,navigatePages=3:方法设置的3( PageInfo page = new PageInfo<>(list,3);),navigatepageNums=[1, 2, 3]:导航分页页码,navigateFirstPage=1:导航分页从第几页开始,navigateLastPage=3:导航分页从第几页结束
prePage=1, nextPage=3, isFirstPage=false, isLastPage=false, hasPreviousPage=true, hasNextPage=true, navigatePages=3, navigateFirstPage=1, navigateLastPage=3, navigatepageNums=[1, 2, 3]}
  • 在页面中配置导航栏超链接时,可以通过访问PageInfo预对象。当isFirstPage=false或hasPreviousPage=true才需要配置首页和上一页,即:不是第一页或有上一页时才显示首页和上一页。当isLastPage=false或hasNextPage=true才需要配置尾页和下一页,即:不是尾页或有下一页时才显示尾页和下一页。设置导航分页,将navigatepageNums数组进行循环,设置超链接进行跳转。
15.2.2.3 分页数据相关属性
  • pageNum:当前页的页码
  • pageSize:每页显示的条数
  • size:当前页显示的真实条数
  • total:总记录数
  • pages:总页数
  • prePage:上一页的页码
  • nextPage:下一页的页码
  • isFirstPage/isLastPage:是否为第一页/最后一页
  • hasPreviousPage/hasNextPage:是否存在上一页/下一页
  • navigatePages:导航分页的页码数
  • navigatepageNums:导航分页的页码,[1,2,3,4,5]
转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号