10、MyBatis的自动生成代码、PageHelper分页插件

2023-11-07

代码生成

方式一:官方jar

为了简化MyBatis的编写,官方推出了一个工具"mybatis-generator",Java编写的,通过这个工具可以生成数据库表对应的实体类、Mapper接口以及Mapper映射文件。

官网:

http://mybatis.org/generator/

快速入门指南:

http://mybatis.org/generator/quickstart.html

我们这里就是使用从命令提示符运行MyBatis Generator。

您必须创建XML配置文件才能从命令行运行MBG。如果文件名为“ generatorConfig.xml”,则以下任何命令行将运行MBG:

java -jar mybatis-generator-core-xxxjar -configfile generatorConfig.xml
java -jar mybatis-generator-core-xxxjar -configfile generatorConfig.xml -overwrite
参数 解释
-configfile 文件名 (必需) 指定配置文件的名称。
-overwrite(可选) 如果指定,则如果发现现有Java文件的名称与生成的文件的名称相同,则现有Java文件将被覆盖。如果未指定,并且已经存在与生成文件同名的Java文件,则MBG会将新生成的Java文件以唯一名称(例如MyClass.java.1,MyClass.java.2,等等。)。

jar包是一系列class和资源文件的组合包,jar包如果配置了main函数所在的执行类,jar包是可以直接运行在虚拟机上的。

但是通过上面的方式,自动创建的pojo、mapper.java、mapper.xml没有在IDEA环境中,需要将生成的文件拷贝到项目中,不是特别方便。

上面的方式,具有通用的优点,任何IDE开发工具都可以使用。

方式二:IDEA

如果是IDEA,那么Easy Code插件可以解决这个问题。

在这里插入图片描述

首先需要在IDEA中连接数据库,下面是IDEA中连接MySQL数据库的驱动

在这里插入图片描述

1、使用Easy Code:

在这里插入图片描述

效果:如左侧所示。

2、使用mybatis-generate tool;

在这里插入图片描述

使用第二种的效果:

在这里插入图片描述

测试成功。

插件及其应用(PageHelper)

查询数据的时候,会遇到分页的问题(分页就是将满足条件的数据,按照每一页多少条这样的数据限定要求进行显示,程序中的查询大部分都需要使用到分页)。

分页我们分为

前端

前端需要分页的 数据(总条数,总页数,当前第几页[计算有没有上一页,有无下一页...],当前页码的数据[list])
显示分页操作条【栏】
挺麻烦的【前端可以使用分页插件】

后台

后台要编写两条sql
一条是查询全部数据【需要总条数】
一条sql查询当前页码的数据
service 或者 工具类中,计算,通过总条数以及每页条数,计算共有多少页....

数据库

数据库要有分页的sql语句,
mysql limit关键词【最简单的】
oracle rownum伪劣【最麻烦】
sqlserver top【子查询】

通过mybatis的分页插件,大大简化分页的sql以及分页的逻辑封装部分。

类似于Java Web中的过滤器【过滤器就是一个筛子,也就是说客户端请求服务器端资源,比如请求xxxservlet,过滤器就是在访问xxxservlet之前,会拦截客户端请求。相应地,之前servlet中返回数据,到客户端,现在返回数据之后,还要经过过滤器,才会到客户端】;

MyBatis中有一个接口,叫做拦截器Interceptor,允许我们定制更加灵活的程序,比如通过拦截器,可以拦截mybatis执行过程中一些重要的组件和方法。

比如通过编写拦截器,就可以得到程序运行过程中给的sql语句,并且我们可以修改sql语句。mybatis开放了这样的功能。

pageHelper就是利用了mybatis中提供的这个拦截器功能,可以对分页进行大大的简化。

官网:https://pagehelper.github.io/

如果你也在用 MyBatis,建议尝试该分页插件,这一定是最方便使用的分页插件。分页插件支持任何复杂的单表、多表分页。

使用方式:https://pagehelper.github.io/docs/howtouse/

1、引入分页插件

<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper</artifactId>
    <version>5.2.0</version>
</dependency>

2、配置拦截器插件

特别注意,新版拦截器是 com.github.pagehelper.PageInterceptorcom.github.pagehelper.PageHelper 现在是一个特殊的 dialect 实现类,是分页插件的默认实现类,提供了和以前相同的用法。

2.1、在MyBatis配置文件中配置拦截器

<!--
    plugins在配置文件中的位置必须符合要求,否则会报错,顺序如下:
    properties?, settings?,
    typeAliases?, typeHandlers?,
    objectFactory?,objectWrapperFactory?,
    plugins?,
    environments?, databaseIdProvider?, mappers?
-->
<plugins>
    <!-- com.github.pagehelper为PageHelper类所在包名 -->
    <plugin interceptor="com.github.pagehelper.PageInterceptor">
        <!-- 使用下面的方式配置参数,后面会有所有的参数介绍 -->
        <property name="param1" value="value1"/>
    </plugin>
</plugins>

3、使用

为分页查询新建一张表page,自动生成model、mapper.java、mapper.xml文件,然后添加100条数据。

@Data
public class Page implements Serializable {
    private Integer pid;

    private String pname;

    private Integer pcount;

    private Double pprice;

    private static final long serialVersionUID = 1L;
}

为表中初始化100条数据

@Test
public void initData() {
    try (SqlSession sqlSession = factory.openSession()) {
        PageMapper mapper = sqlSession.getMapper(PageMapper.class);
        for (int i = 1; i <= 100; i++) {
            Page page = new Page();
            page.setPname("java" + i);
            page.setPcount(i);
            page.setPprice(i + 0.1);
            mapper.insertSelective(page);
        }
        sqlSession.commit();
    }
}

全查测试:

//带查询条件的分页的查询方法
List<Page> select(Page page);
<resultMap id="BaseResultMap" type="org.westos.model.Page">
    <id column="pid" jdbcType="INTEGER" property="pid"/>
    <result column="pname" jdbcType="VARCHAR" property="pname"/>
    <result column="pcount" jdbcType="INTEGER" property="pcount"/>
    <result column="pprice" jdbcType="FLOAT" property="pprice"/>
</resultMap>

<sql id="Base_Column_List">
    pid, pname, pcount, pprice
</sql>

<select id="select" resultMap="BaseResultMap">
    select
    <include refid="Base_Column_List"/>
    from page
    <where>
        <if test="pid != null">
            and pid = #{pid}
        </if>
        <if test="pname != null">
            and pname like concat('%', #{pname}, '%')
        </if>
        <if test="pcount != null">
            and pcount = #{pcount}
        </if>
        <if test="pprice != null">
            and pprice = #{pprice}
        </if>
    </where>
</select>
//全查测试
@Test
public void select1() {
    try (SqlSession sqlSession = factory.openSession()) {
        PageMapper mapper = sqlSession.getMapper(PageMapper.class);
        List<Page> select = mapper.select(null);
        System.out.println(JSON.toJSONString(select, true));
    }
}

带参数的全查测试:

//全查测试,带参数
@Test
public void select2() {
    try (SqlSession sqlSession = factory.openSession()) {
        PageMapper mapper = sqlSession.getMapper(PageMapper.class);
        Page page = new Page();
        page.setPname("java2");
        List<Page> select = mapper.select(page);
        System.out.println(select.size());
        //11
    }
}

全查测试,带分页:

//全查测试,带分页
@Test
public void select3() {
    try (SqlSession sqlSession = factory.openSession()) {
        PageMapper mapper = sqlSession.getMapper(PageMapper.class);
        //配置分页,需要两个参数:1、pageNum第几页 2、pageSize页的大小
        PageHelper.startPage(2, 10);
        //第二页,查10条
        //limit (pageNum-1)*size, size
        //limit 0,10
        //limit 10,10
        //limit 20,10
        List<Page> select = mapper.select(null);
        System.out.println(select.size());
    }
}
==>  Preparing: SELECT count(0) FROM page 
==> Parameters: 
<==    Columns: count(0)
<==        Row: 100
<==      Total: 1
==>  Preparing: select pid, pname, pcount, pprice from page LIMIT ?, ? 
==> Parameters: 10(Long), 10(Integer)
<==    Columns: pid, pname, pcount, pprice
<==        Row: 11, java11, 11, 11.1
<==        Row: 12, java12, 12, 12.1
<==        Row: 13, java13, 13, 13.1
<==        Row: 14, java14, 14, 14.1
<==        Row: 15, java15, 15, 15.1
<==        Row: 16, java16, 16, 16.1
<==        Row: 17, java17, 17, 17.1
<==        Row: 18, java18, 18, 18.1
<==        Row: 19, java19, 19, 19.1
<==        Row: 20, java20, 20, 20.1
<==      Total: 10
10

全查测试,带条件,带分页

//全查测试,带条件,带分页
@Test
public void select4() {
    try (SqlSession sqlSession = factory.openSession()) {
        PageMapper mapper = sqlSession.getMapper(PageMapper.class);
        PageHelper.startPage(1, 5);
        Page page = new Page();
        page.setPname("java1");
        List<Page> select = mapper.select(page);
        System.out.println(JSON.toJSONString(select, true));

        PageHelper.startPage(2, 5);
        select = mapper.select(page);
        System.out.println(JSON.toJSONString(select, true));
    }
}
==>  Preparing: SELECT count(0) FROM page WHERE pname LIKE concat('%', ?, '%') 
==> Parameters: java1(String)
<==    Columns: count(0)
<==        Row: 12
<==      Total: 1
==>  Preparing: select pid, pname, pcount, pprice from page WHERE pname like concat('%', ?, '%') LIMIT ? 
==> Parameters: java1(String), 5(Integer)
<==    Columns: pid, pname, pcount, pprice
<==        Row: 1, java1, 1, 1.1
<==        Row: 10, java10, 10, 10.1
<==        Row: 11, java11, 11, 11.1
<==        Row: 12, java12, 12, 12.1
<==        Row: 13, java13, 13, 13.1
<==      Total: 5
[
	{
		"pcount":1,
		"pid":1,
		"pname":"java1",
		"pprice":1.1
	},
	{
		"pcount":10,
		"pid":10,
		"pname":"java10",
		"pprice":10.1
	},
	{
		"pcount":11,
		"pid":11,
		"pname":"java11",
		"pprice":11.1
	},
	{
		"pcount":12,
		"pid":12,
		"pname":"java12",
		"pprice":12.1
	},
	{
		"pcount":13,
		"pid":13,
		"pname":"java13",
		"pprice":13.1
	}
]
==>  Preparing: select pid, pname, pcount, pprice from page WHERE pname like concat('%', ?, '%') LIMIT ?, ? 
==> Parameters: java1(String), 5(Long), 5(Integer)
<==    Columns: pid, pname, pcount, pprice
<==        Row: 14, java14, 14, 14.1
<==        Row: 15, java15, 15, 15.1
<==        Row: 16, java16, 16, 16.1
<==        Row: 17, java17, 17, 17.1
<==        Row: 18, java18, 18, 18.1
<==      Total: 5
[
	{
		"pcount":14,
		"pid":14,
		"pname":"java14",
		"pprice":14.1
	},
	{
		"pcount":15,
		"pid":15,
		"pname":"java15",
		"pprice":15.1
	},
	{
		"pcount":16,
		"pid":16,
		"pname":"java16",
		"pprice":16.1
	},
	{
		"pcount":17,
		"pid":17,
		"pname":"java17",
		"pprice":17.1
	},
	{
		"pcount":18,
		"pid":18,
		"pname":"java18",
		"pprice":18.1
	}
]

全查测试,带分页,带分页数据的封装功能

//全查测试,带分页,带分页数据的封装功能
@Test
public void select5() {
    try (SqlSession sqlSession = factory.openSession()) {
        PageMapper mapper = sqlSession.getMapper(PageMapper.class);
        //在查询之前
        PageHelper.startPage(1, 10);
        List<Page> select = mapper.select(null);
        //分页信息封装类,通常写在查询之后
        PageInfo<Page> pageInfo = new PageInfo<>(select);
        System.out.println(JSON.toJSONString(pageInfo, true));
    }
}
{
	"endRow":10, 
	"hasNextPage":true,
	"hasPreviousPage":false,
	"isFirstPage":true,
	"isLastPage":false,
	"list":[
		{
			"pcount":1,
			"pid":1,
			"pname":"java1",
			"pprice":1.1
		},
		{
			"pcount":2,
			"pid":2,
			"pname":"java2",
			"pprice":2.1
		},
		{
			"pcount":3,
			"pid":3,
			"pname":"java3",
			"pprice":3.1
		},
		{
			"pcount":4,
			"pid":4,
			"pname":"java4",
			"pprice":4.1
		},
		{
			"pcount":5,
			"pid":5,
			"pname":"java5",
			"pprice":5.1
		},
		{
			"pcount":6,
			"pid":6,
			"pname":"java6",
			"pprice":6.1
		},
		{
			"pcount":7,
			"pid":7,
			"pname":"java7",
			"pprice":7.1
		},
		{
			"pcount":8,
			"pid":8,
			"pname":"java8",
			"pprice":8.1
		},
		{
			"pcount":9,
			"pid":9,
			"pname":"java9",
			"pprice":9.1
		},
		{
			"pcount":10,
			"pid":10,
			"pname":"java10",
			"pprice":10.1
		}
	],
	"navigateFirstPage":1,
	"navigateLastPage":8,
	"navigatePages":8,
	"navigatepageNums":[1,2,3,4,5,6,7,8],
	"nextPage":2,
	"pageNum":1,
	"pageSize":10,
	"pages":10,
	"prePage":0,
	"size":10,
	"startRow":1,
	"total":100
}

在说详细的原理:

如何自定义mybatis的拦截器【了解,mybatis提供插件这样的功能是为了更加灵活的执行一些操作,允许程序员查看或者操控mybatis运行的细节】

第一步:实现Interceptor接口

public interface Interceptor {    
    //拦截之后需要执行的方法  
    Object intercept(Invocation invocation) throws Throwable;    
    //返回代理对象  
    Object plugin(Object target);    
    //设置拦截器 运行的一些参数  
    void setProperties(Properties properties); 
}
package org.westos.util;

import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;

import java.sql.Connection;
import java.util.Properties;

/**
 * @author lwj
 * @date 2020/9/20 9:17
 */
@Intercepts({
        @Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})
})
public class MyBatisInterceptor implements Interceptor {
    /*
    * MyBatis允许拦截
    * 1、Executor执行器(SqlSession持有执行器)
    * 2、SQL语句执行 StatementHandler 拦截sql语句
    * 3、参数
    * 4、结果
    * (1)需要用@Intercepts注解来指定
    * (2)将该拦截器注册到mybatis-config.xml
    * */
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        StatementHandler sh = (StatementHandler) invocation.getTarget();
        MetaObject mo = SystemMetaObject.forObject(sh);
        //获得了运算后的sql
        Object value = mo.getValue("delegate.boundSql.sql");
        System.out.println("MyBatisInterceptor-->>" + value);
        return invocation.proceed();
    }

    @Override
    public Object plugin(Object o) {
        return Plugin.wrap(o,this);
    }

    @Override
    public void setProperties(Properties properties) {

    }
}

第二步:配置拦截器

<plugins>
    <!-- com.github.pagehelper为PageHelper类所在包名 -->
    <!--<plugin interceptor="com.github.pagehelper.PageInterceptor">
        </plugin>-->
    <plugin interceptor="org.westos.util.MyBatisInterceptor"/>
</plugins>

测试,随意测试Mapper中的方法,在控制台中均可以查看到 mybatis运行过程中的sql语句

@Test
public void testSelectByPrimaryKey() {
    try (SqlSession sqlSession = factory.openSession()) {
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        User user = mapper.selectByPrimaryKey(1);
        System.out.println(JSON.toJSONString(user,true));
    }
}
MyBatisInterceptor-->>select
         
        uid, uname, upassword, u_nickname
     
        from user
        where `uid` = ?
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

10、MyBatis的自动生成代码、PageHelper分页插件 的相关文章

  • set()函数 c++用法

    SET 是一种包含已排序对象的关联容器 set集合容器实现了红黑树 Red Black Tree 的平衡二叉检索树的数据结构 在插入元素时 它会自动调整二叉树的排列 把元素放到适当的位置 它不会插入相同键值的元素 而采取忽略处理 平衡二叉树

随机推荐

  • SIM卡工作原理

    1 如何检测卡的插入 参考文献 1 https blog csdn net LUOHUATINGYUSHENG article details 96473340 2 如何判断SIM卡的工作电压 包括1 8V 3V 5V 判断逻辑 模块先给s
  • Linux安装nginx/tenginx

    tenginx为例 Tengine2 3 3点击下载 先安装依赖库 Ubuntu为例 PCRE库支持正则表达式 sudo apt get install libpcre3 libpcre3 dev zlib库用于对HTTP包的内容做gzip
  • 1.basic_something

    1 基础必须 4个 op session graph run 矩阵乘法 tf matmul import tensorflow as tf m1 tf constant 3 3 定义1行2列的矩阵常量op 1 op m2 tf consta
  • UE4_c++ 设置Actor BeginPlay的顺序

    在项目开发中 涉及到数据初始化 一个类可能需要依赖另一个类的初始化 因此在某些时候 需要把一个类的初始化的优先级提高 针对不同Actor的BeginPlay在运行时的执行顺序 有兴趣的可以自行去测试 意义不大 下面提供一种方法 使一个Act
  • Python图像锐化及边缘检测(Roberts、Prewitt、Sobel、Lapllacian、Canny、LOG)

    目录 图像锐化概述 算法方法介绍 代码实现 效果展示 图像锐化概述 图像锐化 image sharpening 是补偿图像的轮廓 增强图像的边缘及灰度跳变的部分 使图像变得清晰 分为空间域处理和频域处理两类 图像锐化是为了突出图像上地物的边
  • 睿智的目标检测51——Tensorflow2搭建yolo3目标检测平台

    睿智的目标检测51 Tensorflow2搭建yolo3目标检测平台 学习前言 源码下载 YoloV3实现思路 一 整体结构解析 二 网络结构解析 1 主干网络Darknet53介绍 2 构建FPN特征金字塔进行加强特征提取 3 利用Yol
  • java try的用法_Java中try、catch的使用方法

    Java中有两种处理异常的方式 分别是用throws抛出异常 用try catch捕获异常 try catch 在Java try catch语句的语法格式 try 代码块 catch Exception1 e 抛出异常后所要进行的操作 当
  • ElasticSearch最佳入门实践(五十八)搜索相关参数梳理以及bouncing results问题解决方案

    1 preference 决定了哪些shard会被用来执行搜索操作 primary primary first local only node xyz prefer node xyz shards 2 3 bouncing results问
  • 如何在SQL查询中文列

    背景介绍 需求背景 第三方提供视图 查询该视图信息 列名采取中文形式 例如 视图名V Test 姓名 性别 工作年限 年 张三 男 4 李四 女 1 复现步骤 Navicat配置Sql Server 因为未接触过中文列名 所以简单查了下 可
  • 如何向icloud上传文件_怎么把文件放进苹果icloud

    展开全部 将文件放入苹果62616964757a686964616fe58685e5aeb931333365653932iCloud的方法很多 介绍以下三种方法供参考 方法一 手机 通过苹果手机直接存储到iCloud 1 在苹果应用商店 A
  • kali 远程登陆提示 拒绝访问(access denied)

    1 今天配置kali远程登陆 配置好后登陆发现输入密码对的 但是还是拒绝访问 access denied 2 后来发现是配置在 etc ssh sshd config 时候 配错了 把 PermitRootLogin without pas
  • ⛳ Class.forName()方法

    目录 Class forName 方法 特点 举例 Class forName 方法 Class forName 是Java中的一个反射方法 用于根据类的完整限定名 fully qualified name 加载类并返回对应的Class对象
  • 调整数组顺序使奇数位于偶数前面(java)

    一 问题描述 输入一个整数数组 实现一个函数来调整该数组中数字的顺序 使得所有的奇数位于数组的前半部分 所有的偶数位于位于数组的后半部分 并保证奇数和奇数 偶数和偶数之间的相对位置不变 二 算法分析 给定一个数组array 目标 调整数组中
  • java 枚举类使用反射

    目录 前言 一 枚举类 二 反射获取枚举 三 反射调用枚举方法 前言 跟普通类使用反射基本一样 一 枚举类 public enum OperateType add 添加 0 delete 删除 1 select 查询 2 update 修改
  • Python Pandas 对列/行 Column/Row 进行选择,增加,删除操作

    Pandas 的列 行操作 一 列操作 1 1 选择列 1 2 增加列 1 3 删除列 del 和 pop 函数 二 行操作 2 1 选择行 2 1 1 通过 label 选择行 loc 函数 2 1 2 通过序号选择行 iloc 函数 2
  • 华为云Classroom赋能--面向高校学生的Toolkit系列实践培训

    Classroom培训课程系列 ToolKit的专题培训 Classroom包含实验系列 Toolkit语音合成实验 Toolkit系列培训课程简介 什么是Toolkit Huawei Cloud Toolkit中文名是华为云开发者插件 是
  • 针对-128到127之间的数据,做了一个数据缓冲池

    package test import java util HashMap import java util HashSet import java util Map import java util Set import org apac
  • 模板类中友元函数的声明与定义

    cpp 全部在Test h这个头文件中 ifndef TEST H define TEST H template
  • 数据如何赋能?

    该问题已同步到小程序 全栈面试题 问题 大家经常动不动就提到数据赋能 那么数据是如何为业务赋能的呢 就此问题 各位大佬们展开了激烈的讨论 讨论 congrats 对于中大型企业 数据已经成为了业务展开工作的基本构成部分了 比如每天运营 产品
  • 10、MyBatis的自动生成代码、PageHelper分页插件

    文章目录 代码生成 方式一 官方jar 方式二 IDEA 插件及其应用 PageHelper 代码生成 方式一 官方jar 为了简化MyBatis的编写 官方推出了一个工具 mybatis generator Java编写的 通过这个工具可