MyBatis-Plus 详解

news2024/11/16 11:46:43

文章目录

  • MyBatisPlus
  • 一、入门案例
    • 1.1 准备表结构和数据
    • 1.2 添加依赖
    • 1.3 yml 配置
    • 1.4 添加 Factor 实体
    • 1.5 创建Mapper接口
    • 1.6 创建Mapper.xml 文件
    • 1.7 测试操作
    • 1.8 日志输出
  • 二、CRUD操作
    • 2.1 插入因子
    • 2.2 更新因子
    • 2.3 删除因子
      • ① 根据id删除
      • ② 批量删除
      • ③ 通过Map删除
    • 2.4 查询操作
      • ① 根据id查询
      • ② 根据id批量查询
      • ③ 通过Map查询
      • ④ 查询是否存在某条件数据
      • ⑤ 查询所有数据
  • 三、CRUD接口
    • 3.1 Service的使用
    • 3.2 查询操作
    • 3.3 批量插入
  • 四、常用注解
    • 4.1 @TableName
    • 4.2 @TableId
    • 4.3 @TableField
    • 4.4 @TableLogic
  • 五、条件构造器
    • 5.1 Wrapper接口
    • 5.2 QueryWrapper
      • ① 查询条件
      • ② 排序条件
      • ③ 删除条件
      • ④ 组合条件
      • ⑤ 查询特定的字段
      • ⑥ 实现子查询
    • 5.3 UpdateWrapper
    • 5.4 参数校验
    • 5.5 LambdaQueryWrapper
    • 5.6 LambdaUpdateWrapper
  • 六、复杂查询 Mapper.xml
    • 6.1 Mapper 接口
    • 6.2 Mapper.xml
    • 6.3 测试
  • 七、分页插件
  • 八、代码生成器


提示:以下是本篇文章正文内容,Java 系列学习将会持续更新

MyBatisPlus

image.png

MyBatis-Plus (opens new window)(简称 MP)是一个 MyBatis (opens new window) 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。

官网地址:https://baomidou.com/

一、入门案例

1.1 准备表结构和数据

准备如下的表结构和相关数据

DROP TABLE IF EXISTS `factor`;
CREATE TABLE `factor`  (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `factor_name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
  `unit` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
  `factor_precision` double NOT NULL,
  `type` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 14 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;

插入对应的相关数据

INSERT INTO `factor` VALUES (1, '浑浊度', 'NTU', 0.01, '物理因子');
INSERT INTO `factor` VALUES (2, '溶解氧', 'DO', 0.04, '化学因子');
INSERT INTO `factor` VALUES (3, '耗氧量', 'COD', 0.03, '物理因子');
INSERT INTO `factor` VALUES (4, '有机碳含量', 'TOC', 0.01, '化学因子');
INSERT INTO `factor` VALUES (5, '无机盐含量', 'HTB', 0.04, '化学因子');
INSERT INTO `factor` VALUES (6, '透明度', 'DF', 0.01, '物理因子');
INSERT INTO `factor` VALUES (7, '悬浮物含量', 'mg/L', 0.02, '物理因子');
INSERT INTO `factor` VALUES (8, '氰化物', 'QHW', 0.01, '化学因子');
INSERT INTO `factor` VALUES (9, '重金属', 'ZJS', 0.03, '物理因子');
INSERT INTO `factor` VALUES (10, '硝酸盐', 'XSY', 0.04, '化学因子');
INSERT INTO `factor` VALUES (11, '透光度', 'TGD', 0.02, '物理因子');
INSERT INTO `factor` VALUES (12, '折射度', 'ZSD', 0.01, '物理因子');
INSERT INTO `factor` VALUES (13, '含铅量', 'Pt/L', 0.03, '物理因子');

1.2 添加依赖

<!-- 引入MyBatisPlus的依赖 -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.5.1</version>
</dependency>
<!-- 数据库使用MySQL数据库 -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>

1.3 yml 配置

spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/water_monitoring?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
    username: root
    password: 123456
    driver-class-name: com.mysql.jdbc.Driver

mybatis-plus:
  mapper-locations: classpath:mapper/**.xml
  type-aliases-package: com.wangshaoyu.mybatisplusstudy.pojo

1.4 添加 Factor 实体

  • 当实体类名称和表名称一致时,且类属性和表字段一致时,可以不添加字段注解,也可以不在 mapper.xml 中配置。
  • 如果实体类名称或属性与表中不一致时,需要注解或 xml 中配置。
@Data
public class Factor {
    private Integer id;
    private String factorName;
    private String unit;
    private Double factorPrecision;
    private String type;
}

1.5 创建Mapper接口

/**
 * MyBatisPlus中的Mapper接口继承自BaseMapper
 */
@Repository
@Mapper
public interface FactorMapper extends BaseMapper<Factor> {
}

1.6 创建Mapper.xml 文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.wangshaoyu.mybatisplusstudy.mapper.FactorMapper"> <!-- 对应的Mapper接口 -->

    <!--   id = 自定义结果集命名    type = 对应的实体类 -->
    <resultMap id="FactorResult" type="com.wangshaoyu.mybatisplusstudy.pojo.Factor">
        <id     property="id"               column="id"               />
        <result property="factorName"       column="factor_name"      />
        <result property="unit"             column="unit"             />
        <result property="factorPrecision"  column="factor_precision" />
        <result property="type"             column="type"             />
    </resultMap>
</mapper>

当实体类中存在表中没有的字段,且该属性为与另一张表相关联的 List 列表时,例如 List<Device> devices; 。此时我们可以在 xml 中添加这样的对应关系,<collection property="device" javaType="list" resultMap="deviceResult" />

1.7 测试操作

@SpringBootTest
class MpDemo01ApplicationTests {

    @Autowired
    private FactorMapper factorMapper;

    @Test
    void queryUser() {
        List<Factor> factors = factorMapper.selectList(null);
        factors.forEach(System.out::println);
    }
}

1.8 日志输出

为了便于学习我们可以指定日志的实现 StdOutImpl 来处理,然后操作数据库的时候就可以看到对应的日志信息了。

# 指定日志输出
mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

在这里插入图片描述

回到目录…

二、CRUD操作

2.1 插入因子

@Test
void test11() {
    Factor factor = new Factor("xxx", "KL", 0.04, "哲学因子");
    int insert = factorMapper.insert(factor);
}

注意:在MyBatisPlus中插入数据的时候,如果id为空,默认会通过雪花算法来生成 id。也可以通过 @TableId 的类型设置自增。

2.2 更新因子

@Test
void test12() {
    Factor factor = new Factor(14, "yyy", "KL", 0.04, "哲学因子");
    int update = factorMapper.updateById(factor);
}

2.3 删除因子

① 根据id删除

@Test
void test13() {
    // 方式一
    int delete = factorMapper.deleteById(14);
    // 方式二
    Factor factor = new Factor();
    factor.setId(15);
    int delete2 = factorMapper.deleteById(factor);
}

② 批量删除

@Test
void test14() {
    int delete3 = factorMapper.deleteBatchIds(Arrays.asList(1, 2, 3, 4));
}

③ 通过Map删除

@Test
void test15() {
    Map<String,Object> map = new HashMap<>();
    map.put("factor_name","氰化物");
    map.put("type","化学因子");
    int i = userMapper.deleteByMap(map);
}

2.4 查询操作

① 根据id查询

@Test
void test16() {
    Factor factor = factorMapper.selectById(1);
}

② 根据id批量查询

@Test
void test17() {
    List<Factor> factors = factorMapper.selectBatchIds(Arrays.asList(1, 2, 3));
}

③ 通过Map查询

@Test
void test15() {
    Map<String,Object> map = new HashMap<>();
    map.put("factor_name","氰化物");
    map.put("type","化学因子");
    List<Factor> factors = factorMapper.selectByMap(map);
}

④ 查询是否存在某条件数据

也可以通过 exists() 方法查询是否存在符合某条件的数据,将查询条件封装到一个QueryWrapper中

@Test
void querySite() {
    QueryWrapper<Site> wrapper = new QueryWrapper<>();
    wrapper.eq("site_name", "太原一站");
    System.out.println(siteMapper.exists(wrapper));
}

⑤ 查询所有数据

@Test
void test16() {
	List<Factor> factors = factorMapper.selectList(null);
    factors.forEach(System.out::println);
}

当然在selectList中需要我们传递进去一个Wrapper对象,这个是一个条件构造器,这个在后面会详细的讲解。

回到目录…

三、CRUD接口

官网地址:https://baomidou.com/pages/49cc81/#service-crud-%E6%8E%A5%E5%8F%A3

官网说明

  • 通用 Service CRUD 封装IService(opens new window)接口,进一步封装 CRUD 采用 get 查询单行 remove 删除 list 查询集合 page 分页 前缀命名方式区分 Mapper 层避免混淆,
  • 泛型 T 为任意实体对象
  • 建议如果存在自定义通用 Service 方法的可能,请创建自己的 IBaseService 继承 Mybatis-Plus 提供的基类
  • 对象 Wrapper 为 条件构造器

在MyBatis-Plus中有一个接口 IService和其实现类 ServiceImpl,封装了常见的业务层逻辑

3.1 Service的使用

要使用 CRUD 的接口,那么我们自定义的 Service 接口需要继承 IService 接口。

/**
 * Factor对应的Service接口
 * 要使用MyBatisPlus的Service完成CRUD操作,得继承IService
 */
public interface IFactorService extends IService<Factor> {
}

对应的 Servic e实现得继承 ServiceImpl 同时指定 mapper 和实体对象。

/**
 * Service的实现类
 * 必须继承 ServiceImpl 并且在泛型中指定 对应的Mapper和实体对象
 */
@Service
public class FactorServiceImpl extends ServiceImpl<FactorMapper, Factor> implements IFactorService {
}

3.2 查询操作

通过 Service 中提供的 count 方法可以查询总的记录数、get 方法,List 方法等。

@Resource
private IFactorService factorService;

@Test
void test1() {
    long count = factorService.count();
    System.out.println("count = " + count);
    
    Factor factor = factorService.getById(2);
    System.out.println("factor = " + factor);
}

3.3 批量插入

在 service 中给我们提供了批量插入的方法。

@Test
void test2() {
    Factor factor1 = new Factor("xxx", "KL", 0.02, "哲学因子");
    Factor factor2 = new Factor("yyy", "KL", 0.04, "化学因子");
    Factor factor3 = new Factor("zzz", "KL", 0.03, "物理因子");
    boolean insert = factorService.saveBatch(Arrays.asList(factor1, factor2, factor3));
}

还有 saveOrUpdate 等方法,可自行应用。

回到目录…

四、常用注解

4.1 @TableName

如果表名和我们的实体类的名称不一致的话,在执行相关操作的时候会抛出对应的异常,这时我们就可以通过@TableName来解决这个问题。

@Data
@TableName("factor")
public class Factor {
    private Integer id;
    private String factorName;
    private String unit;
    private Double factorPrecision;
    private String type;
}

在开发的过程中,我们经常遇到以上的问题,即实体类所对应的表都有固定的前缀,例如t_或tbl_ 此时,可以使用 MyBatis-Plus 提供的全局配置,为实体类所对应的表名设置默认的前缀,那么就不需要在每个实体类上通过 @TableName 标识实体类对应的表.

# 配置MyBatis-Plus操作表的默认前缀
mybatis-plus:
  global-config:
    db-config:
      table-prefix: t_

4.2 @TableId

我们可以通过 @TableId 注解来显示的指定哪个属性为主键对应的属性,@TableId 中的 value 值在实体类中的字段和表结构的字段一致的情况下我们不用添加,但如果不一致,@TableId 中的 value 我们需要设置表结构中的主键字段。

@TableId 中还有一个比较重要的属性是 Type。Type 是用来定义主键的生成策略的。以下是官网截图
image.png

这个可以在 @TableId 中配置,也可以在配置文件中统一配置全局的生成策略。

image.png

4.3 @TableField

  @TableField注解的作用是当实体类中的属性和表结构中的字段名称不一致的情况下来设置对应关系的,当然,在MyBatis-Plus中针对实体中是userName而表结构中是user_name这种情况会自动帮助我们完成驼峰命名法的转换。

@Data
@TableName("factor")
public class Factor {
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;
    @TableField("factor_name")
    private String factorName;
    @TableField("unit")
    private String unit;
    @TableField("factor_precision")
    private Double factorPrecision;
    @TableField("type")
    private String type;
    @TableField(exist = false)// 数据库表中不存在的数据
    private List<Device> devices;
}

4.4 @TableLogic

@TableLogic 是用来完成 逻辑删除 操作的。

删除类型描述
逻辑删除假删除,将对应数据中代表是否被删除字段的状态修改为“被删除状态”,之后在数据库中仍旧能看到此条数据记录
物理删除真实删除,将对应数据从数据库中删除,之后查询不到此条被删除的数据

效果演示:先在表中创建一个 is_deleted 字段。

image.png
对应的在实体类中添加一个 isDeleted 属性。
image.png

然后我们调用删除功能。
image.png
可以看到我们调用了 deleteById 方法,但是真实执行的是 Update 方法,实现了逻辑删除的场景。

当然也可以在属性文件中配置全局的

# 配置逻辑删除
mybatis-plus:
  global-config:
    db-config:
      logic-delete-field: is_deleted
	  logic-delete-value: 1
      logic-not-delete-value: 0

回到目录…

五、条件构造器

当我们需要对单表的CURD做复杂条件处理的时候我们就需要借助Wrapper接口来处理,也就是通过条件构造器来处理。

5.1 Wrapper接口

Wrapper接口是条件构造的抽象类,是最顶级的类。
image.png

5.2 QueryWrapper

首先来看看 QueryWrapper 的使用,针对where后的条件封装。

① 查询条件

/**
 * 查询因子名称中带"度"的、精确度小于0.02,且类型为物理的因子
 */
@Test
void test1() {
    QueryWrapper<Factor> wrapper = new QueryWrapper<>();
    wrapper.like("factor_name", "度").lt("factor_precision", 0.02).eq("type", "物理因子");
    List<Factor> factors = factorMapper.selectList(wrapper);
}

② 排序条件

/**
 * 根据精确度降序然后根据id升序
 */
@Test
void test2() {
    QueryWrapper<Factor> wrapper = new QueryWrapper<>();
    wrapper.orderByDesc("factor_precision").orderByAsc("id");
    List<Factor> factors = factorMapper.selectList(wrapper);
}

③ 删除条件

/**
 * 删除所有精确度小于0.03的因子
 */
@Test
void test3() {
    QueryWrapper<Factor> wrapper = new QueryWrapper<>();
    wrapper.le("factor_precision", 0.03);
    int delete = factorMapper.delete(wrapper);
}

④ 组合条件

在封装条件的时候我们可以同时有多个条件组合,类似于 and 和 or 的操作,这时 QueryWrapper 也能很轻松的处理。

/**
 * 查询出精确度大于0.02并且名称中包含的有'度' 或者 类型为“化学因子”的因子
 */
@Test
void test4() {
    QueryWrapper<Factor> wrapper = new QueryWrapper<>();
    wrapper.gt("factor_precision", 0.02)
    	.like("factor_name", "度")
        .or() // 默认是通过and连接 显示加上 or()方法表示or连接
        .eq("type", "化学因子");
    List<Factor> factors = factorMapper.selectList(wrapper);
}

@Test
void test5() {
    QueryWrapper<Factor> wrapper = new QueryWrapper<>();
    wrapper.and((i)->{
        i.gt("factor_precision", 0.02).like("factor_name", "度");
    }).or((i)->{
        i.eq("type", "化学因子");
    });
    List<Factor> factors = factorMapper.selectList(wrapper);
}

⑤ 查询特定的字段

特殊情况我们需要查询特定的字段,这时可以通过 select 方法来处理。

/**
 * 查询出年龄大于20并且姓名中包含的有'o'或者邮箱地址为空的记录
 */
@Test
void test6() {
	QueryWrapper<Factor> wrapper = new QueryWrapper<>();
    wrapper.gt("factor_precision", 0.02)
        .like("factor_name", "度")
        .or() // 默认是通过and连接 显示加上 or()方法表示or连接
        .eq("type", "化学因子")
        .select("uid","name","age"); // 指定特定的字段
    // selectMaps()返回Map集合列表,通常配合select()使用,避免Factor对象中没有被查询到的列值为null
    List<Map<String, Object>> maps = userMapper.selectMaps(wrapper);
    maps.forEach(System.out::println);
}

⑥ 实现子查询

单表查询中对子查询的需求也是有的,我们来看看如何实现。

/**
 * 子查询: 查询具备绑定关系的因子(名称和类型)
 * SELECT * from FROM factor WHERE id IN (SELECT d);
 */
@Test
void test7() {
    QueryWrapper<User> wrapper = new QueryWrapper<>();
    wrapper.inSql("id","SELECT device_id FROM relation").select("factor_name", "type");
    List<Map<String, Object>> maps = factorMapper.selectMaps(wrapper);
    maps.forEach(System.out::println);
}

5.3 UpdateWrapper

当我们需要组装更新的字段数据的时候,可以通过 UpdateWrapper 来实现。

/**
 * 更新因子的精确度和单位
 * UPDATE factor SET factor_precision=?, unit=? WHERE factor_name = ?;
 */
@Test
void test7() {
    UpdateWrapper<Factor> wrapper = new UpdateWrapper<>();
    wrapper.set("factor_precision", 0.05)
        	.set("unit", "KHJ")
        	.eq("factor_name", "折射度");
    int update = factorMapper.update(null, wrapper);
}

5.4 参数校验

实际开发中,用户的查询条件都是动态的,我们需要根据不同的输入条件来动态的生成对应的SQL语句,这时我们来看看在MyBatisPlus中是如何处理的。

@Test
void test8() {
    String name = "重金属";
    double precision = 0.03;
    QueryWrapper<Factor> wrapper = new QueryWrapper<>();
    if(StringUtils.isNotBlank(name)) {
        wrapper.eq("factor_name", name);
    }
    if(precision > 0) {
        wrapper.eq("factor_precision", precision);
    }
    List<Factor> factors = factorMapper.selectList(wrapper);
}

我们可以用这个参数来实现对应的动态SQL处理

@Test
void test8() {
    String name = "重金属";
    double precision = 0.03;
    QueryWrapper<Factor> wrapper = new QueryWrapper<>();
    wrapper.eq(StringUtils.isNotBlank(name), "factor_name", name)
           .eq(precision > 0, "factor_precision", precision);
    List<Factor> factors = factorMapper.selectList(wrapper);
}

5.5 LambdaQueryWrapper

LambdaQueryWrapper<实体类> lambda= Wrappers.lambdaQuery(实体类.class);
lambda.eq(实体类::get实体类字段, 入参)
	.orderByAsc(实体类::get实体类字段)
	.select(实体类::get实体类字段, 实体类::get实体类字段);
@Test
void test1() {
    Site site = new Site(12, "西安二站", "陕西省", "西安市", "标准站", "陕西省西安市高新区", "小白");
    // 查看同一城市是否存在同名的站点
    boolean exists = siteMapper.exists(new LambdaQueryWrapper<Site>()
    	.eq(Site::getSiteName, site.getSiteName())
        .eq(ObjectUtil.isNotNull(site.getCity()), Site::getCity, site.getCity()));
}

5.6 LambdaUpdateWrapper

LambdaUpdateWrapper<实体类> lambda = Wrappers.lambdaUpdate(实体类.class);
lambda.set(实体类::getName, "张三").eq(实体类::getId, id);
baseMapper.update(lambda); //提交
@Test
void test2() {
	LambdaUpdateWrapper<Site> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
	lambdaUpdateWrapper.set(Site::getDirector, "小酒").eq(Site::getSiteName, "西安二站");
	int update = siteMapper.update(null, lambdaUpdateWrapper);
}

回到目录…

六、复杂查询 Mapper.xml

6.1 Mapper 接口

如果需要联表查询等这种复杂的查询,则需要在 Mapper 接口中自定义方法。

@Repository
@Mapper
public interface FactorMapper extends BaseMapper<Factor> {
    // 根据设备id查询因子
    // select f.id, f.factor_name, f.unit, f.factor_precision, f.type from factor f 
    // left join relation r 
    // on f.id = r.factor_id 
    // where r.device_id = 5;
    List<Factor> selectFactorsByDeviceId(@Param(Constants.WRAPPER) Wrapper<Factor> queryWrapper);
    
    // 根据名称和类型查询(尝试传递包装类参数)
    List<Factor> selectFactorByNameAndType(@Param("name")String name, @Param("type")String type);
}

6.2 Mapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.wangshaoyu.mybatisplusstudy.mapper.FactorMapper"> <!-- 对应的Mapper接口 -->

    <!--   id = 自定义结果集命名    type = 对应的实体类 -->
    <resultMap id="FactorResult" type="com.wangshaoyu.mybatisplusstudy.pojo.Factor">
        <id     property="id"               column="id"               />
        <result property="factorName"       column="factor_name"      />
        <result property="unit"             column="unit"             />
        <result property="factorPrecision"  column="factor_precision" />
        <result property="type"             column="type"             />
    </resultMap>
    
    <!-- 自定义sql语句名称 -->
    <sql id="selectFactorVo">
        select f.id, f.factor_name, f.unit, f.factor_precision, f.type
        from factor f
        left join relation r on f.id = r.factor_id
        ${ew.getCustomSqlSegment}
    </sql>
    <!-- id = Mapper接口中对应的方法名      resultMap = 接收结果集 -->
    <select id="selectFactorsByDeviceId" resultMap="FactorResult">
        <include refid="selectFactorVo"/> <!-- 指定执行的sql语句 -->
    </select>
    
    <select id="selectFactorByNameAndType" resultMap="FactorResult">
        select * from factor where factor_name = #{name} and type = #{type};
    </select>
</mapper>

注意${ew.getCustomSqlSegment} 会直接在前面添加 where,条件就是在 Wrapper 中取。

6.3 测试

@Test
void test() {
    QueryWrapper<Factor> wrapper = new QueryWrapper<>();
    wrapper.eq("r.device_id", 5);
    List<Factor> factors = factorMapper.selectFactorsByDeviceId(wrapper);
    factors.forEach(System.out::println);
    
    List<Factor> factors2 = factorMapper.selectFactorByNameAndType("溶解氧", "化学因子");
    factors2.forEach(System.out::println);
}

回到目录…

七、分页插件

在MyBatisPlus中集成了分页插件,我们不需要单独的引入,只需要添加对应的配置类

@Configuration
@MapperScan("com.bobo.mpdemo01.mapper")
public class MyBatisPlusConfig {

    /**
     * 新的分页插件,一缓和二缓遵循mybatis的规则,
     * 需要设置 MybatisConfiguration#useDeprecatedExecutor = false 避免缓存出现问题(该属性会在旧插件移除后一同移除)
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }

}

然后就可以测试操作了。

@Test
void queryPage() {
    Page<Factor> page = new Page<>(1, 3);
    Page<Factor> factorPage = factorMapper.selectPage(page, null);
    System.out.println("factorPage.getCurrent() = " + factorPage.getCurrent()); // 当前页码
    System.out.println("factorPage.getSize() = " + factorPage.getSize()); // 当前页的内容数量
    System.out.println("factorPage.getTotal() = " + factorPage.getTotal()); // 内容总量
    System.out.println("factorPage.getPages() = " + factorPage.getPages()); // 总分页数
    System.out.println("factorPage.hasPrevious() = " + factorPage.hasPrevious()); // 是否有前一页
    System.out.println("factorPage.hasNext() = " + factorPage.hasNext()); // 是否有后一页
    System.out.println("factorPage.getRecords() = " + factorPage.getRecords()); // 分页内容
}

回到目录…

八、代码生成器

①添加依赖:

<dependency>
	<groupId>com.baomidou</groupId>
	<artifactId>mybatis-plus-generator</artifactId>
	<version>3.5.2</version>
</dependency>

<dependency>
	<groupId>org.freemarker</groupId>
	<artifactId>freemarker</artifactId>
</dependency>

②快速生成:

/**
 * 代码生成器
 */
public class MyFastAutoGenerator {
    public static void main(String[] args) {

        FastAutoGenerator.create("jdbc:mysql://localhost:3306/mp?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true"
                , "root", "123456")
                .globalConfig(builder -> {
                    builder.author("boge") // 设置作者
                            //.enableSwagger() // 开启 swagger 模式
                            .fileOverride() // 覆盖已生成文件
                            .outputDir("D://MyBatisPlus"); // 指定输出目录
                })
                .packageConfig(builder -> {
                    builder.parent("com.bobo.mp") // 设置父包名
                            .moduleName("system") // 设置父包模块名
                            .pathInfo(Collections.singletonMap(OutputFile.xml, "D://")); // 设置mapperXml生成路径
                })
                .strategyConfig(builder -> {
                    builder.addInclude("t_user") // 设置需要生成的表名
                            .addTablePrefix("t_", "c_"); // 设置过滤表前缀
                })
                .templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板,默认的是Velocity引擎模板
                .execute();

    }
}

回到目录…


总结:
提示:这里对文章进行总结:
本文是对Mybatis-Plus的学习,是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。之后的学习内容将持续更新!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/906994.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

系统架构合理性的思考 | 京东云技术团队

最近牵头在梳理部门的系统架构合理性&#xff0c;开始工作之前&#xff0c;我首先想到的是如何定义架构合理性&#xff1f; 从研发的角度来看如果系统上下文清晰、应用架构设计简单、应用拆分合理应该称之为架构合理。 基于以上的定义可以从以下三个方面来梳理评估&#xff1…

标签准备——labelIMG工具使用

当我们已经准备了大量用于图片标注所需的图片后,便需要使用labelIMG工具进行打标签的操作了。 1、标签规划 在我们开始打标签之前,首先需要注意的是,打标签是我们开展训练、识别工作的基础,我们需要准确最好标签的规划,明确都有哪些标签,并在venv/Lib/site-packages/la…

怎么压缩视频?一分钟学会视频压缩技巧

现在拍摄的视频文件体积都比较大&#xff0c;如果再加上后期的剪辑处理&#xff0c;动不动就是几个GB起步&#xff0c;这样一来不仅占用空间&#xff0c;还不方便传输&#xff0c;今天就围绕这个问题给大家分享几个压缩视频的方法&#xff0c;需要的朋友可以参考下。 方法一&am…

如何拥有观影氛围感?极米投影仪H6为你打造美好之夜

当前人们对于家庭舒适度的要求越来越高&#xff0c;“仪式感”也被越来越多的人关注起来&#xff0c;对于喜欢看电影的年轻人来说&#xff0c;在家里的观影氛围感当然也不能少。今天&#xff0c;笔者就为大家带来了一款打造观影氛围感好物极米H6。 作为极米H系列首款4K分辨率的…

Docker基本操作命令(一)

Docker基本操作命令 1、搜索镜像 docker search命令搜索存放在 Docker Hub中的镜像,此命令默认Docker会在Docker Hub中搜索镜像&#xff0c;可以配置了其他镜像仓库 [rootzch01 ~]# docker search centos NAME:镜像仓库名称DESCRIPTION:镜像仓库描述STARS&#xff1a;镜像仓…

探索聊天型AI进阶:从ChatGPT到提示工程入门

&#x1f482; 个人网站:【工具大全】【游戏大全】【神级源码资源网】&#x1f91f; 前端学习课程&#xff1a;&#x1f449;【28个案例趣学前端】【400个JS面试题】&#x1f485; 寻找学习交流、摸鱼划水的小伙伴&#xff0c;请点击【摸鱼学习交流群】 导言 近年来&#xff0…

滑动验证组件---设置movable-view组件的x属性在微信小程序端失效的问题

场景 采用uniapp的movable-view组件实现滑动验证组件。 流程 滑块未滑到最右端时&#xff0c;回弹到原点滑块滑到最右端时&#xff0c;则显示滑动结束&#xff0c;不可再滑动 问题 频繁设置uniapp的movable-view组件的x属性&#xff0c;在H5端正常&#xff0c;但在微信小程…

实时操作系统与非实时操作系统

一、实时操作系统 实时操作系统&#xff08;RTOS&#xff09;是指当外界事件或数据产生时&#xff0c;能够接受并以足够快的速度予以处理&#xff0c;其处理的结果又能在规定的时间之内来控制生产过程或对处理系统做出快速响应&#xff0c;调度一切可利用的资源完成实时任务&am…

win10 版本21H2 + vs2022 + Windows 11 版本 22H2 WDK

打开VS&#xff0c;工具–>获取工具和功能–>单个组件。在里面搜索SDK Windows 11 SDK(10.0.22621.0) Windows 11 版本 21H2 WDK 不支持 Visual Studio 2022。 若要使用 Visual Studio 2022 开发和测试驱动程序&#xff0c;请下载 Windows 11 版本 22H2 WDK。 #include…

自定义目录高亮的锚点计算位移

如果可以实现记得给个星星&#xff0c;谢谢老铁&#xff5e; 一、问题的描述 一个支持目录树形结构&#xff0c;自定义目录高亮的锚点计算位移,且支持选中该目录后锚点对应的内容。这里只提供左边的组件思路&#xff0c;右边展示对应的内容最好自己自定义组件控制更为灵活&am…

MyBatis(一)执行流程概述

目录 一、简介二、MyBatis执行流程1.读取核心配置文件 mybatis-config.xml2.构建会话工厂 SqlSessionFactory3.创建会话 SqlSession4.Executor 执行器5.MappedStatement 对象6.输入参数处理&#xff08;map,list,String,Integer,pojo&#xff09;7.操作数据库8.输出结果处理&am…

[C语言]分支语句和循环语句

[C语言]分支语句和循环语句 文章目录 [C语言]分支语句和循环语句C语言语句分类分支语句if语法结构else的匹配规则switch语句switch语句中的breakswitch语句中default 循环语句while循环while循环中的break和continuefor循环for循环中的break和continuefor循环的变种do while循环…

ARM汇编【1】:数据类型

与高级语言类似&#xff0c;ARM支持对不同数据类型的操作。我们可以加载或存储的数据类型可以是有符号和无符号字、半字或字节。这些数据类型的扩展名是&#xff1a;-h或-sh表示半字&#xff0c;-b或-sb表示字节&#xff0c;不表示字的扩展名。有符号数据类型或无符号数据类型之…

二重积分小技巧---交换积分

又一个奇技淫巧。 【例1】 ∫ 0 1 d y ∫ y 1 x 3 1 d x ? \int _0 ^1 dy \int _{\sqrt y} ^ 1 \sqrt{x^3 1} dx ? ∫01​dy∫y ​1​x31 ​dx? 解析&#xff1a; 不说话&#xff0c;看下图&#xff1a; ∫ 0 1 d y ∫ y 1 x 3 1 d x ∫ 0 1 d x ∫ 0 x 2 x 3 1 d…

照亮虚拟网络流量“盲区”:超融合网络流量可视化功能解读

云计算时代下&#xff0c;网络虚拟化使网络管理更加集中、灵活和便捷&#xff0c;但同时也让云内的网络变得更加复杂。传统网络流量诊断方法和工具&#xff0c;难以对云内虚拟网络的“东-西向流量”进行可视化呈现和分析&#xff0c;形成了网络运维管理的盲区&#xff0c;提升了…

Shopify独立站也会被封店?告诉你这背后深藏的玄机!

很多人觉得做独立站就完全自由了&#xff0c;不被平台监管&#xff0c;也不会被封店。但事实真的是这样吗&#xff1f;其实独立站只是相对自由&#xff0c;受到的监管相对较少&#xff0c;封店的风险较小&#xff0c;但并不是完全高枕无忧。想知道什么情况下会被封店&#xff1…

无涯教程-PHP - 全局变量函数

全局变量 与局部变量相反,可以在程序的任何部分访问全局变量。通过将关键字 GLOBAL 放置在应被识别为全局变量的前面,可以很方便地实现这一目标。 <?php$somevar15;function addit() {GLOBAL $somevar;$somevar;print "Somevar is $somevar";}addit(); ?> …

MyBatis快速入门以及环境搭建和CRUD的实现

目录 前言 一、MyBatis简介 1.MyBatis是什么 2.MyBatis的特点 3.mybatis的作用 4.MyBatis的应用场景 5.MyBatis优缺点 二、相关概念 1.ORM概述 2.常见的ORM框架 3.什么是持久层框架 三、MyBatis的工作原理 1.框架交互 2.工作原理 ​编辑 四、MyBatis环境搭建 1…

SQL - 开窗(窗口)函数

什么是开窗函数&#xff1f; 开窗函数对一组值进行操作&#xff0c;它不像普通聚合函数那样需要使用GROUP BY子句对数据进行分组&#xff0c;能够在同一行中同时返回基础行的列和聚合列 开窗函数的语法形式为&#xff1a;函数 over(partition by <分组用列> order by …

Vue2到3 Day7 全套学习内容,众多案例上手(内付源码)

简介&#xff1a; Vue2到3 Day1-3 全套学习内容&#xff0c;众多案例上手&#xff08;内付源码&#xff09;_星辰大海1412的博客-CSDN博客本文是一篇入门级的Vue.js介绍文章&#xff0c;旨在帮助读者了解Vue.js框架的基本概念和核心功能。Vue.js是一款流行的JavaScript前端框架…