mybatisplus查询今天的数据_Mybatis Plus 学习笔记

注解

@TableName

表名注解,当数据库中的表名和实体类名之间不能完全匹配时,需要使用这个注解进行绑定。

如:数据库表中的数据库表名为 t_student,而实体类的类名为: Student,则需要在该类上增加注解:

@TableName(value = "t_student")

public class Student {

private Long stuId;

}

全局设置数据库表前缀

当数据库表中的所有表名前有前缀时,需要每次指定 @TableName注解,很麻烦,需要使用全局配置:

mybatis-plus:

global-config:

db-config:

table-prefix: "t_"

@TableId

主键注解,当数据库中的主键和实体类中主键属性不同时,使用这个注解进行绑定。 如:数据库表中的主键是 id,而实体类中的属性值是 stuId,那么就在实体类主键属性上加上注解

public class Student {

@TableId(value = "id")

private Long stuId;

}

IdType

@TableId注解还有一个属性配置是主键的主键类型,具体可选值如下,默认值为:IdType.NONE

描述
AUTO 数据库自增
INPUT 自行输入
ID_WORKER 分布式全局唯一ID 长整型类型
UUID 32位UUID字符串
NONE 无状态(默认)
IDWORKERSTR 分布式全局唯一ID 字符串类型

全局设置设置注解策略

设置主键策略,默认值:ID_WORKER

mybatis-plus:

global-config:

db-config:

id-type: AUTO

全局设置驼峰功能

mybatisPlus 有一个全局的配置策略,可以实现数据库表中的列名字段是下划线分割,自动对应实体类中驼峰名:

如:数据库中的 stu_address字段与实体类中的 stuAddress属性字段相对应。

mybatis-plus:

global-config:

db-config:

table-underline: true

# 表名、是否使用下划线命名(默认 true:默认数据库表下划线命名)

在 Springboot 中,可以通过设置 map-underscore-to-camel-case属性为 true 来开启驼峰功能。因此 mybatisPlus 也继承了这种配置,默认为 true

mybatis-plus:

configuration:

map-underscore-to-camel-case: true

@TableField

value

当显示配置的时候,则按设置的值为准。

exist

标识该字段是数据库表字段,当实体类中有属性字段不在数据库表中的时候,就需要在数据库操作时忽略这些字段,因此可以配置 exist=false属性配置,如果不配置,默认为:true

BaseMapper

BaseMapper 接口是专门用来进行通用增删改查的接口,通过指定泛型可以对数据实体对象进行通用的CIUD操作,大致可以分为四类:

Insert

intinsert(T entity)

insert 方法会将实体对象中的非空属性值映射到数据库,进行插入操作,也就是说有多少非空属性,执行的SQL语句中才插入多少,和 mybatis 中的 insertSeletive 一样,有值才操作。

亮点

插入成功默认返回主键,mybatis Plus 插入数据之后,实体类中的主键会返回给实体类,相比 mybatis 原生的默认不返回要很多繁琐的配置:

id="insert" useGeneratedKeys="true" keyProperty="stuId" parameterType="org.woodwhales.king.Student">

insert into student(userName, password, comment)

values(#{userName}, #{password}, #{comment})

其中: keyProperty中配置的是实体类中的属性字段,用来接收数据库表返回的主键值。

Update

根据主键更新

intupdateById(T entity)

带条件的更新

intupdate(T entity,WrapperupdateWrapper)

如:更新姓名为 Tom且年龄为 28 的学生数据:

LambdaQueryWrapper lambdaQueryWrapper = new QueryWrapper().lambda()

.eq(Student::getName, "Tom")

.eq(Student::getAge, 28);

Student student = Student.builder()

.name("woodwhales")

.age(20)

.email("[email protected]").build();

int row = studentMapper.update(student, lambdaQueryWrapper);

SQL脚本执行日志

==> Preparing: UPDATE student SET name=?, age=?, email=? WHERE name = ? AND age = ?

==> Parameters: woodwhales(String), 20(Integer), [email protected](String), Tom(String), 28(Integer)

<== Updates: 1

Select

Delete

条件构造器

EntityWapper

注意:条件构造器中使用的是数据列名,而不是实体类对象属性。

分页查询(带条件)

对于条件构造器的编写,可以使用最原始写法:

QueryWrapper queryWrapper = new QueryWrapper();

queryWrapper.eq(“stu_name”, "Tom");

queryWrapper.like("email", "woodwhale");

也可以使用 QueryWrapper().lambda()这样类似于 JDK1.8 的 lambda表达式编写条件构造器,下文中均采用此写法。

例:查询数据库中 student 表( Student 实体类)中的所有姓名为 Tom且年龄在10-20 岁之间的分页数据,当前页为 1,每页显示数为 2

IPage pager = studentMapper.selectPage(new Page(1, 2),

new QueryWrapper().lambda()

.eq(Student::getName, "Tom")

.between(Student::getAge, 10, 20));

List studentList = pager.getRecords();

studentList.forEach(System.out::println);

System.out.println("total: " + pager.getTotal());

System.out.println("pages: " + pager.getPages());

System.out.println("size: " + pager.getSize());

SQL脚本执行日志

==> Preparing: SELECT id,name,age,email FROM student WHERE name = ? AND age BETWEEN ? AND ? LIMIT ?,?

==> Parameters: Tom(String), 10(Integer), 20(Integer), 0(Long), 1(Long)

注意:上面代码查询出来的对象 pager中的 total和 pages总是为 0 ,解决办法:编写一个配置类,自定义一个分页插件 PaginationInterceptor配置到 spring 中即可:

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import com.baomidou.mybatisplus.annotation.DbType;

import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;

@Configuration

public class AppConfig {

@Bean

public PaginationInterceptor paginationInterceptor() {

PaginationInterceptor page = new PaginationInterceptor();

page.setDialectType(DbType.MYSQL.getDb()); // 设置数据库方言

return page;

}

}

上述代码中:只需要返回 newPaginationInterceptor()即可使得 selectPage返回对象中有数据总记录数。

带条件的查询-并且

查询数据库中 student 表( Student 实体类)中的所有邮箱名字含有 woodwhale且年龄在10-20 岁之间的所有数据:

List studentList = studentMapper.selectList(new QueryWrapper()

.lambda()

.like(Student::getEmail, "woodwhale")

.between(Student::getAge, 10, 20));

SQL脚本执行日志

==> Preparing: SELECT id,name,age,email FROM student WHERE email LIKE ? AND age BETWEEN ? AND ?

==> Parameters: %woodwhale%(String), 10(Integer), 20(Integer)

带条件的查询-或者

IPage pager = studentMapper.selectPage(new Page(1, 2),

new QueryWrapper().lambda()

.eq(Student::getName, "Tom")

.between(Student::getAge, 10, 20)

.or()

.like(Student::getEmail, "woodwhale"));

注意: or()中可以传参一个布尔表达式,当条件为 false时,或者作用失效,后面的条件会与前面的条件形成并且的关系。引用官方的解释:

主动调用 or表示紧接着下一个方法不是用 and连接!(不调用 or则默认为使用 and连接)

SQL脚本执行日志

==> Preparing: SELECT COUNT(1) FROM student WHERE name = ? AND age BETWEEN ? AND ? OR email LIKE ?

==> Parameters: Tom(String), 10(Integer), 20(Integer), %woodwhale%(String)

==> Preparing: SELECT id,name,age,email FROM student WHERE name = ? AND age BETWEEN ? AND ? OR email LIKE ? limit ?

==> Parameters: Tom(String), 10(Integer), 20(Integer), %woodwhale%(String), 1(Long)

查询结果排序

orderBy(booleancondition,booleanisAsc,R...columns)

对查询的结果进行降序排列( isAsc 设置成了 false)

List studentList = userMapper.selectList(Wrappers.query().orderBy(true, false, "age"));

studentList.forEach(System.out::println);

SQL 脚本执行日志

==> Preparing: SELECT id,name,age,email FROM student ORDER BY age DESC

==> Parameters:

<== Total: 8

mybatis Plus 提供了更加便捷的方法:

降序排序

orderByDesc(R column)

orderByDesc(R...columns)

orderByDesc(booleancondition,R...columns)

升序排序

orderByAsc(R column)

orderByAsc(R...columns)

orderByAsc(booleancondition,R...columns)

领域模式

ActiveRecord

必须存在对应的 原始mapper并继承 baseMapper并且可以使用的前提下,才能使用此 AR 模式。

使用方法

实体类对象继承 Model抽象类即可。

@Data

@Builder

public class Student extends Model{

@TableId(type=IdType.AUTO)

private Long id;

private String name;

private Integer age;

private String email;

}

对数据的增删改查操作,直接操作自己即可。

Student student = Student.builder().id(null).name("adc").age(20).email("[email protected]").build();

boolean insert = student.insert();

条件查询

领域模式下查询主键的方法,有参数传入时以传入为准,无参数时以对象为准。当对象没有主键时,会报 com.baomidou.mybatisplus.core.exceptions.MybatisPlusException:selectById primaryKeyisnull.异常,删除主键的方法同理,另外删除逻辑上不存在的数据也是返回成功。

Student student = Student.builder().id(5L).build();

Student result = student.selectById(6L);

SQL脚本执行日志

==> Preparing: SELECT id,name,age,email FROM student WHERE id=?

==> Parameters: 6(Long)

<== Total: 1

分页查询

分页返回的数据对象是 IPage,从 IPage可以获取相应的总记录数,记录,当前页,每页数。

IPage selectPage(IPage page, Wrapper queryWrapper)

代码生成器

AutoGenerator 是 MyBatis-Plus 的代码生成器,MyBatis-Plus 的代码生成器比 Mybatis 原生的代码生成器强大的地方在于,能够快速生成通过 AutoGenerator 可以快速生成 Entity、Mapper、Mapper XML、Service、Controller 等各个模块的代码,极大的提升了开发效率。

以下代码生成器中开启了 lombok, sprigboot-web, swagger2, freemarker,因此需要添加依赖:

mysql

mysql-connector-java

runtime

org.springframework.boot

spring-boot-starter-test

test

org.projectlombok

lombok

true

org.springframework.boot

spring-boot-starter-web

com.baomidou

mybatis-plus-boot-starter

3.1.0

com.alibaba

druid

1.1.10

com.baomidou

mybatis-plus-generator

3.1.0

org.springframework.boot

spring-boot-starter-freemarker

io.springfox

springfox-swagger2

2.7.0

io.springfox

springfox-swagger-ui

2.7.0

最佳实践

import java.util.ArrayList;

import java.util.List;

import com.baomidou.mybatisplus.annotation.DbType;

import com.baomidou.mybatisplus.annotation.IdType;

import com.baomidou.mybatisplus.core.toolkit.StringPool;

import com.baomidou.mybatisplus.generator.AutoGenerator;

import com.baomidou.mybatisplus.generator.InjectionConfig;

import com.baomidou.mybatisplus.generator.config.DataSourceConfig;

import com.baomidou.mybatisplus.generator.config.FileOutConfig;

import com.baomidou.mybatisplus.generator.config.GlobalConfig;

import com.baomidou.mybatisplus.generator.config.PackageConfig;

import com.baomidou.mybatisplus.generator.config.StrategyConfig;

import com.baomidou.mybatisplus.generator.config.TemplateConfig;

import com.baomidou.mybatisplus.generator.config.po.TableInfo;

import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;

import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;

public class Generator {

public static void main(String[] args) {

// 代码生成器

AutoGenerator mpg = new AutoGenerator();

// 全局配置

GlobalConfig gc = new GlobalConfig();

String projectPath = System.getProperty("user.dir");

gc.setActiveRecord(true); // 开启领域模式

gc.setIdType(IdType.AUTO);

gc.setServiceName("%sService"); // 各层文件名称方式,例如: %sAction 生成 UserAction

gc.setOutputDir(projectPath + "/src/main/java"); // 生成文件的输出目录【默认 D 盘根目录】

gc.setAuthor("woodwhales"); // [开发者]

gc.setFileOverride(true); // 开启文件覆盖

gc.setOpen(false); // 是否打开输出目录

gc.setSwagger2(true); // 开启 swagger2 模式

gc.setBaseResultMap(true); // 开启 BaseResultMap

gc.setBaseColumnList(true); // 开启 baseColumnList

mpg.setGlobalConfig(gc);

// 数据源配置

DataSourceConfig dsc = new DataSourceConfig();

dsc.setUrl("jdbc:mysql://localhost:3306/mytest?useUnicode=true&useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC");

dsc.setDriverName("com.mysql.cj.jdbc.Driver"); // 注意:mysql 5.7 之后的驱动是com.mysql.cj.jdbc.Driver

dsc.setDbType(DbType.MYSQL);

dsc.setUsername("root");

dsc.setPassword("root");

mpg.setDataSource(dsc);

// 包配置

PackageConfig pc = new PackageConfig();

pc.setParent("org.woodwahles"); // [实体类所在模块的父模块名]

pc.setModuleName("king"); // [实体类所在模块名]

pc.setXml("mapper"); // 默认包名:mapper.xml

mpg.setPackageInfo(pc);

// 自定义配置

InjectionConfig cfg = new InjectionConfig() {

@Override

public void initMap() {

// to do nothing

}

};

List focList = new ArrayList<>();

focList.add(new FileOutConfig("/templates/mapper.xml.ftl") {

@Override

public String outputFile(TableInfo tableInfo) {

// 自定义mapper文件名称

return projectPath + "/src/main/resources/mapper/" + pc.getModuleName() + "/"

+ tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;

}

});

cfg.setFileOutConfigList(focList);

mpg.setCfg(cfg);

mpg.setTemplate(new TemplateConfig().setXml(null));

// 策略配置

StrategyConfig strategy = new StrategyConfig();

strategy.setNaming(NamingStrategy.underline_to_camel); // 下划线转驼峰命名

strategy.setColumnNaming(NamingStrategy.underline_to_camel);

strategy.setEntityLombokModel(true);

strategy.setInclude("student"); // [表名]

strategy.setSuperEntityColumns("id");

strategy.setControllerMappingHyphenStyle(true);

// strategy.setTablePrefix(pc.getModuleName() + "_"); // 数据库表名前缀

mpg.setStrategy(strategy);

// 选择 freemarker 引擎需要指定如下加,注意 pom 依赖必须有!

mpg.setTemplateEngine(new FreemarkerTemplateEngine());

mpg.execute();

}

}

生成的项目结构如下:

mybatisplus查询今天的数据_Mybatis Plus 学习笔记_第1张图片

插件

攻击 SQL 阻断解析器

作用!阻止恶意的全表更新删除

@Configuration

public class AppConfig {

/**

* 分页插件

*/

@Bean

public PaginationInterceptor paginationInterceptor() {

PaginationInterceptor page = new PaginationInterceptor();

page.setDialectType(DbType.MYSQL.getDb()); // 设置数据库方言

List sqlParserList = new ArrayList<>();

// 攻击 SQL 阻断解析器、加入解析链

sqlParserList.add(new BlockAttackSqlParser());

page.setSqlParserList(sqlParserList);

return page;

}

}

性能分析插件

该插件只用于开发环境,不建议生产环境使用。

@Configuration

public class AppConfig {

/**

* 性能分析插件

*/

@Bean

@Profile({"dev","test"}) // 设置 dev test 环境开启

public PerformanceInterceptor performanceInterceptor() {

PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();

// maxTime 指的是 SQL 执行最大时长,超过自动停止运行,有助于发现问题。

performanceInterceptor.setMaxTime(100);

// SQL 是否格式化

performanceInterceptor.setFormat(true);

return performanceInterceptor;

}

}

乐观锁插件

目的:当要更新一条记录的时候,希望这条记录没有被别人更新

乐观锁的实现思路:

  • 取出记录时,获取当前 version

  • 更新时,带上这个 version

  • 执行更新时, set version = newVersion where version = oldVersion

  • 如果 version不对,就更新失败

插件使用步骤:

1. 将插件注入spring 框架:

@Configuration

public class AppConfig {

@Bean

public OptimisticLockerInterceptor optimisticLockerInterceptor() {

return new OptimisticLockerInterceptor();

}

}

2. 使用注解 @Version注解实体字段(必要步骤)

@Version

private Integer version;

特别说明

  • 支持的数据类型只有: int, Integer, long, Long, Date, Timestamp, LocalDateTime

  • 整数类型下 newVersion=oldVersion+1

  • newVersion 会回写到 entity 中

  • 仅支持 updateById(id) 与 update(entity,wrapper) 方法

  • 在 update(entity,wrapper)方法下, wrapper不能复用!

逻辑删除插件

首先指定逻辑删除字段在数据库表中的取值:

mybatis-plus:

global-config:

db-config:

logic-delete-value: 1 # 逻辑已删除值(默认为 1)

logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)

将插件注入spring中:

import com.baomidou.mybatisplus.core.injector.ISqlInjector;

import com.baomidou.mybatisplus.extension.injector.LogicSqlInjector;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

@Configuration

public class MyBatisPlusConfiguration {

@Bean

public ISqlInjector sqlInjector() {

return new LogicSqlInjector();

}

}

实体类字段上加上 @TableLogic注解

@TableLogic

private Integer deleted;

使用 Mybatis-Plus 自带方法删除和查找都会附带逻辑删除功能(自己写的 xml不会)

MybatisX插件(IDEA插件)

MybatisX 是一款基于 IDEA 的快速开发插件,为效率而生。

安装方法:打开 IDEA,进入 File -> Settings -> Plugins -> Browse Repositories,输入 mybatisx 搜索并安装。

插件功能:Java 与 XML 调回跳转,Mapper 方法自动生成 XML。

插件源码:https://gitee.com/baomidou/MybatisX。

-END-

技术改变生活,
菜鸟程序员的成长之路。
欢迎关注: 木鲸鱼

你可能感兴趣的:(mybatisplus查询今天的数据_Mybatis Plus 学习笔记)