mybatis

文章目录

  • Mybatis
    • 核心配置文件
    • 搭建框架
    • 实现方法插入语句
    • 优化
      • 1、自动提交
      • 2、封装得到会话对象
    • 关于如何增删改查
      • 映射关系
      • 返回的是一个对象
      • 返回所有对象
    • 核心配置文件
      • 1、environment
      • 2、datasource
      • 3、typeAliases类型别名
      • 4、mappers
    • mybatis获取参数值的两种方式
      • 第一种
      • 第二种
      • 第三种 传map
      • 第四种 访问User类中的属性值
      • 第五种 使用注解@Param("")
    • mybatis的各种查询功能
      • 如果查询出来的结果没用实体类怎么办
      • 模糊查询
      • 批量删除
      • 动态设置表名
      • 获取自增的主键
      • ResultMap
      • 多对一
        • 处理多对一映射关系
        • 使用分步查询处理多对一
      • 延迟(懒)加载
      • 一对多
        • collection处理一对多级联关系
        • 使用分步处理一对多
      • 动态Sql
      • 一级缓存和二级缓存
      • 分页插件
      • 动态Sql
      • 一级缓存和二级缓存
      • 分页插件

Mybatis

核心配置文件


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.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/ssm?serverTimezone=UTC"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            dataSource>
        environment>
    environments>

    <mappers>
        <mapper resource="org/mybatis/example/BlogMapper.xml"/>
    mappers>
configuration>

搭建框架

0、整体架构

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dJINrjp5-1661318876021)(C:\Users\28908\AppData\Roaming\Typora\typora-user-images\image-20220802103604973.png)]

1、写一个mapper

//类似于以前的dao
public interface UserMapper {
    int insertUser();
}

2、写一个xml映射文件


DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="mapper.UserMapper">



    <insert id="insertUser">
        insert into user values (null,'admin',0)
    insert>
mapper>

这里有三个对应问题

  • 该映射文件名称和mapper接口类名相同

  • namespace要和mapper类的全路径名保持一致

  • id和mapper类里对应的方法名保持一致

3、将该映射文件配置到该项目的配置文件里

mybatis-config.xml


<mappers>
    <mapper resource="mappers/UserMapper.xml"/>
mappers>

实现方法插入语句

测试类

import mapper.UserMapper;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;
import org.apache.ibatis.io.Resources;

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

public class MybatisTest {
    @Test
    public void testInsert() throws IOException {
//        获取核心配置文件的输入流
        InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
//        获取sqlSessionFactoryBuilder对象
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
//        获取sqlSessionFactoryBuilder
        SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is);
//        获取sql的会话对象sqlSession,是mybatis提供的操作数据库的对象
        SqlSession sqlSession = sqlSessionFactory.openSession();
//        获取userMapper的代理实现类对象
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
//        调用接口里的方法,他会调用这个方法然后自动执行sql语句
        int result = mapper.insertUser();
//        提交事务
        sqlSession.commit();
        System.out.println(result);
//        关闭sqlSession
        sqlSession.close();
    }

    }

优化

1、自动提交

//        获取sql的会话对象sqlSession(不会自动提交事务),是mybatis提供的操作数据库的对象
//        SqlSession sqlSession = sqlSessionFactory.openSession();
//        获取sql的会话对象sqlSession(会自动提交事务),是mybatis提供的操作数据库的对象
        SqlSession sqlSession = sqlSessionFactory.openSession(true);

2、封装得到会话对象

package util;

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;

public class SqlSessionUtils {
//    封装会话对象
    public static SqlSession getSqlSession(){

        SqlSession sqlSession = null;
        try {
            //        获取核心配置文件的输入流
            InputStream is  = Resources.getResourceAsStream("mybatis-config.xml");
            //        获取sqlSessionFactoryBuilder对象
            SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
//        获取sqlSessionFactoryBuilder
            SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is);
//        获取sql的会话对象sqlSession(不会自动提交事务),是mybatis提供的操作数据库的对象
//        SqlSession sqlSession = sqlSessionFactory.openSession();
//        获取sql的会话对象sqlSession(会自动提交事务),是mybatis提供的操作数据库的对象
             sqlSession = sqlSessionFactory.openSession(true);

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

此时测试方法:

    @Test
    public void testInsert() throws IOException {
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
//        获取userMapper的代理实现类对象
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        mapper.updateUser();
//        关闭sqlSession
        sqlSession.close();
    }

关于如何增删改查

映射关系

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-w72BbV0I-1661318876022)(C:\Users\28908\AppData\Roaming\Typora\typora-user-images\image-20220802152224259.png)]

返回的是一个对象

1、首先要写一个实体类与数据库表格对应

User类

package entity;

public class User {
    private int id;
    private String name;
    private int sex;

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

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

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

    public int getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public int getSex() {
        return sex;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", sex=" + sex +
                '}';
    }
}

2、定义接口方法

//    查询信息UserMapper类
User getUser();

3、写sql语句


<select id="getUser" resultType="entity.User">
    select * from user where id = 1
select>

4、测试

@Test
public void getUserTest(){
    SqlSession sqlSession = SqlSessionUtils.getSqlSession();
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    User user = mapper.getUser();
    System.out.println(user);

}

5、结果

User{id=1, name=‘aaaa’, sex=0}

返回所有对象

1、定义方法

//    查询所有用户信息
List<User> getAllUser();

2、写sql语句

<select id="getAllUser" resultType="entity.User">
    select * from user
select>

3、测试类

@Test
public void getAllUserTest(){
    SqlSession sqlSession = SqlSessionUtils.getSqlSession();
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    List<User> allUser = mapper.getAllUser();
    allUser.forEach(System.out::println);
}

4、结果

User{id=1, name=‘aaaa’, sex=0}
User{id=2, name=‘lucy’, sex=1}
User{id=3, name=‘jack’, sex=0}

核心配置文件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9GntnAwH-1661318876023)(C:\Users\28908\AppData\Roaming\Typora\typora-user-images\image-20220802160523799.png)]

1、environment

image-20220802155610466 image-20220802155633639

2、datasource

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2sH6Qjbr-1661318876024)(C:\Users\28908\AppData\Roaming\Typora\typora-user-images\image-20220802160059208.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-R7Ur4mdx-1661318876024)(C:\Users\28908\AppData\Roaming\Typora\typora-user-images\image-20220802160208639.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kxWkyXbO-1661318876024)(C:\Users\28908\AppData\Roaming\Typora\typora-user-images\image-20220802160234881.png)]

3、typeAliases类型别名

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7kII5oWc-1661318876025)(C:\Users\28908\AppData\Roaming\Typora\typora-user-images\image-20220802160832869.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FCEnJARX-1661318876025)(C:\Users\28908\AppData\Roaming\Typora\typora-user-images\image-20220802160913865.png)]

若不设置别名,那当前的类型拥有默认的别名即类型且不区分大小写

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MJLx9LTu-1661318876026)(C:\Users\28908\AppData\Roaming\Typora\typora-user-images\image-20220802161126596.png)]

4、mappers

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EgLhjouj-1661318876026)(C:\Users\28908\AppData\Roaming\Typora\typora-user-images\image-20220802161938011.png)]

mybatis获取参数值的两种方式

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AxJaGpfs-1661318876027)(C:\Users\28908\AppData\Roaming\Typora\typora-user-images\image-20220802165617043.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NyioasGg-1661318876027)(C:\Users\28908\AppData\Roaming\Typora\typora-user-images\image-20220802170707110.png)]

第一种

  • #{}本质是一个占位符--“?”,所以用这个不用加单引号

  • ${}他不是占位符,如果不加单引号那就是=admin这种会报错,所以加上单引号username=‘admin’,但是这种不能写数字,他会直接运算出来

第二种

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kw6m8Ltu-1661318876027)(C:\Users\28908\AppData\Roaming\Typora\typora-user-images\image-20220802172212892.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9f54ksrn-1661318876028)(C:\Users\28908\AppData\Roaming\Typora\typora-user-images\image-20220802172329073.png)]

第三种 传map

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-m49yTTuy-1661318876028)(C:\Users\28908\AppData\Roaming\Typora\typora-user-images\image-20220802173542600.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HD8M5OD0-1661318876029)(C:\Users\28908\AppData\Roaming\Typora\typora-user-images\image-20220802173556991.png)]

第四种 访问User类中的属性值

这种就可直接通过属性名访问属性值

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YshwdgoC-1661318876029)(C:\Users\28908\AppData\Roaming\Typora\typora-user-images\image-20220803093917082.png)]

前提要有getset方法

第五种 使用注解@Param(“”)

在mapper接口的参数上使用param注解.

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VEJGmXsU-1661318876030)(C:\Users\28908\AppData\Roaming\Typora\typora-user-images\image-20220803094459776.png)]

他还会把这两个参数放到map集合里,自动生成键值,就是param里的参数

他会以两种方式进行存储1.param的value为键值

2.以param1,param2为键,以参数为值

mybatis的各种查询功能

查询的结果是什么类型resultType就写什么类型

resultType里用的是别名,所以里面用大写小写都可以

如果查询出来的结果没用实体类怎么办

1、查询单条数据放map里

那就把resultType=“map”

方法返回值为Map

如果里面某个属性值为null,那这个字段是不会放到map集合里的

2、查询多条数据放到map里

resultType=“map”

方法返回值为List>

3、当查询多条数据,也可以使用第一种的返回值,加上注解@MapKey(设置map集合的键,查询出来的字段)

如果是@MapKey(“id”)

把查询出来的所有对象放到一个map里,键值为0 1 2 3.。

{0={},1={},2={}…}

模糊查询

不能直接使用#{}

这样写是错误的!!

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-550NkNX3-1661318876030)(C:\Users\28908\AppData\Roaming\Typora\typora-user-images\image-20220803134007877.png)]

3种正确写法:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Z84kNurj-1661318876030)(C:\Users\28908\AppData\Roaming\Typora\typora-user-images\image-20220803134838475.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mNyl7Rem-1661318876031)(C:\Users\28908\AppData\Roaming\Typora\typora-user-images\image-20220803135020920.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PthoYviG-1661318876031)(C:\Users\28908\AppData\Roaming\Typora\typora-user-images\image-20220803140327981.png)]

批量删除

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NFDMEtd3-1661318876031)(C:\Users\28908\AppData\Roaming\Typora\typora-user-images\image-20220803141320618.png)]

动态设置表名

表名不能加单引号所以只能用${}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-x38OHO8p-1661318876031)(C:\Users\28908\AppData\Roaming\Typora\typora-user-images\image-20220803141729994.png)]

获取自增的主键

//    插入使用自增主键
    void inserUser(User user);



    <insert id="inserUser" useGeneratedKeys="true" keyProperty="id">
        insert into user  values (null ,#{name},#{sex})
    insert>
@Test
public void insertUser(){
    SqlSession sqlSession = SqlSessionUtils.getSqlSession();
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    User user = new User("jjj",1);
    mapper.inserUser(user);
    System.out.println(user);
}

ResultMap

通过改名创建对应关系

<resultMap id="BaseResultMap" type="com.ufgov.ur.common.entity.FaReportField">
    <id column="SET_YEAR" jdbcType="VARCHAR" property="setYear"/>
resultMap>
<select id="getFaReportFieldList" resultMap="BaseResultMap">
    select
    <include refid="Base_Column_List"/>
    from FA_REPORT_FIELD
    <where>
        SET_YEAR = #{setYear,jdbcType=VARCHAR}
    where>
    order by REPORT_CODE, FIELD_CODE
select>

第二种是写setting配置

mapUnderscoreToCamelCase 是否开启驼峰命名自动映射,即从经典数据库列名 A_COLUMN 映射到经典 Java 属性名 aColumn。 true \false False
<settings>
    <setting name="mapUnderscoreToCamelCase" value="true"/>
settings>

多对一

处理多对一映射关系

级联关联:

第一种方法:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SlL5RMTy-1661318876032)(C:\Users\28908\AppData\Roaming\Typora\typora-user-images\image-20220803173255901.png)]

第二种方法:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2SRvWatk-1661318876032)(C:\Users\28908\AppData\Roaming\Typora\typora-user-images\image-20220803173746962.png)]

association:处理多对一映射关系(处理实体类类型的属性)

property:实体类里关联的另外一个实体类的属性名

javaType:所关联的实体属于的实体类的类名

实例:

Emp类:

package entity;

public class Emp {
    private int id;
    private String name;
    private Dept dept;

    @Override
    public String toString() {
        return "Emp{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", dept=" + dept +
                '}';
    }
}

Dept类:

package entity;

public class Dept {
    private int deptId;
    private String deptName;

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

接口里的方法:

Emp getEmpAndDeptByStep(@Param("empId") Integer id);

xml配置文件


    <resultMap id="empAndDept" type="entity.Emp">
        <id column="id" property="id">id>
        <result column="name" property="name">result>
        <association property="dept" javaType="entity.Dept">
            <id column="dept_id" property="deptId">id>
            <result column="dept_name" property="deptName">result>
        association>
    resultMap>
    <select id="getEmpAndDeptByStep" resultMap="empAndDept">
        select id,name,dept_id,dept_name from emp left join dept on emp.id=dept.dept_id where id=#{empId}
    select>

测试类:

@Test
public void getEmpAndDeptById() {
    SqlSession sqlSession = SqlSessionUtils.getSqlSession();
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    Emp emp = mapper.getEmpAndDeptByStep(1);
    System.out.println(emp);
}

结果:

Emp{id=1, name='事业部', dept=Dept{deptId=1, deptName='啊啊啊'}}

使用分步查询处理多对一

延迟(懒)加载

分步查询可以实现延迟加载.但是必须在核心配置文件中设置全局配置信息.

lazyLoadingEnabled:为true时开启懒加载

aggressiveLazyLoading:为false(默认)时按需加载

<settings>

    <setting name="lazyLoadingEnabled" value="true"/>
    
        <setting name="aggressiveLazyLoading" value="false"/>
settings>

fetchType:在开启了延迟加载的环境中,通过该属性设置当前的分步查询是否使用延迟加载

fetchType=“lazy(懒加载)|eager(立即加载)”

<association property="dept"
             fetchType="lazy"
             select="mapper.UserMapper.getDept"
             column="dept_id">
</association>

一对多

collection处理一对多级联关系

方法:

B getBAndA(@Param("id") Integer id);

xml

<resultMap id="aAndb" type="entity.B">
    <id column="id" property="id">id>
    <result column="dept_id" property="deptId">result>
    <result column="dept_name" property="deptName">result>
    <collection property="as" ofType="entity.A">
       

        <result column="name" property="name">result>
        <result column="dept_id" property="deptId">result>
    collection>
resultMap>

<select id="getBAndA" resultMap="aAndb">
    select * from b left join a on b.dept_id=a.dept_id where b.id=#{id}
select>

测试

@Test
public void getAandB2() {
    SqlSession sqlSession = SqlSessionUtils.getSqlSession();
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    B bAndA = mapper.getBAndA(1);
    System.out.println(bAndA);
}

结果

B{id=1, deptId=1, deptName='第一', as=[A{id=0, name='lucy', deptId=1}, A{id=0, name='li', deptId=1}]}

使用分步处理一对多

数据库:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Q3cqINXU-1661318876033)(C:\Users\28908\AppData\Roaming\Typora\typora-user-images\image-20220804162924475.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-a3JRvxNE-1661318876033)(C:\Users\28908\AppData\Roaming\Typora\typora-user-images\image-20220804162941031.png)]

A类

package entity;

public class A {
    private int id;
    private String name;
    private int deptId;

    public int getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public int getDeptId() {
        return deptId;
    }

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

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

    public void setDeptId(int deptId) {
        this.deptId = deptId;
    }

    @Override
    public String toString() {
        return "A{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", deptId=" + deptId +
                '}';
    }
}

B类:

package entity;

import java.util.List;

public class B {
    private int id;
    private int deptId;
    private String deptName;
    private List<A> as;

    public void setAs(List<A> as) {
        this.as = as;
    }

    public List<A> getAs() {
        return as;
    }

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

    public void setDeptId(int deptId) {
        this.deptId = deptId;
    }

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

    public int getId() {
        return id;
    }

    public int getDeptId() {
        return deptId;
    }

    public String getDeptName() {
        return deptName;
    }

    @Override
    public String toString() {
        return "B{" +
                "id=" + id +
                ", deptId=" + deptId +
                ", deptName='" + deptName + '\'' +
                ", as=" + as +
                '}';
    }
}

接口方法:

B getBAndAByOne(@Param("id") Integer id);
List<A> getBAndAByTwo(@Param("deptId") Integer deptId);

xml文件:

<resultMap id="AandBByOne" type="entity.B">
        <id property="id" column="id">id>
        <result column="dept_id" property="deptId">result>
        <result column="dept_name" property="deptName">result>
        <association property="as"
                    select="mapper.UserMapper.getBAndAByTwo"
                    column="dept_id">
        association>
    resultMap>
    <select id="getBAndAByTwo" resultType="entity.A">
        select * from a where a.dept_id=#{deptId}
    select>

    <select id="getBAndAByOne" resultMap="AandBByOne">
        select * from b where b.id=#{id}
    select>

test

@Test
public void getAandBByStep() {
    SqlSession sqlSession = SqlSessionUtils.getSqlSession();
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    B bAndAByOne = mapper.getBAndAByOne(1);
    System.out.println(bAndAByOne);
}

结果

B{id=1, deptId=1, deptName='第一', as=[A{id=0, name='lucy', deptId=1}, A{id=4, name='li', deptId=1}]}

动态Sql

https://mybatis.net.cn/dynamic-sql.html

一级缓存和二级缓存

https://www.baidu.com/link?url=l_ZB_1Bk47HUOuBzLDex4IsfAUF61ocbcLWq7yOVloQGBakTcjaZB8RO7VD8pG8hJrd4yngk7dXAKO6JnK-o8FBBVkGe3LWAlCJr-PqZXUe&wd=&eqid=8352787e00003a970000000262eb755e

分页插件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aAhOZvah-1661318876033)(C:\Users\28908\AppData\Roaming\Typora\typora-user-images\image-20220804154917095.png)]

https://zhuanlan.zhihu.com/p/425922768

ltMap=“AandBByOne”>
select * from b where b.id=#{id}


test

```java
@Test
public void getAandBByStep() {
    SqlSession sqlSession = SqlSessionUtils.getSqlSession();
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    B bAndAByOne = mapper.getBAndAByOne(1);
    System.out.println(bAndAByOne);
}

结果

B{id=1, deptId=1, deptName='第一', as=[A{id=0, name='lucy', deptId=1}, A{id=4, name='li', deptId=1}]}

动态Sql

https://mybatis.net.cn/dynamic-sql.html

一级缓存和二级缓存

https://www.baidu.com/link?url=l_ZB_1Bk47HUOuBzLDex4IsfAUF61ocbcLWq7yOVloQGBakTcjaZB8RO7VD8pG8hJrd4yngk7dXAKO6JnK-o8FBBVkGe3LWAlCJr-PqZXUe&wd=&eqid=8352787e00003a970000000262eb755e

分页插件

[外链图片转存中…(img-aAhOZvah-1661318876033)]

https://zhuanlan.zhihu.com/p/425922768

你可能感兴趣的:(mybatis,java,mysql)