什么是Mybatis-Puls
MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
MyBatis-Puls与Mybatis 是最好的搭档的关系。
Mybatis-Puls的特性
-
无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
-
损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作,BaseMapper
-
强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求,以后简单的CRUD操作,不用自己编写了 !
-
支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
-
支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 – Sequence),可自由配置,完美解决主键问题
-
支持 ActiveRecord 模式:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作
-
支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )
-
内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用(自动帮你生成代码)
-
内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询
-
分页插件支持多种数据库:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多种数据库
-
内置性能分析插件:可输出 Sql 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询
-
内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作
Mybatis 与Mpuls的异同
这里的Mpuls是指Mybatis-puls
相同点
-
对底层JDBC进行高度封装:Mybatis与Mybatis-puls 都是简化我们连接数据库开发,尽可能地减少使用JDBC操作封装
不同点
-
降低代码解耦性:Mybatis 使用接口与xml进行配置绑定,解除强耦合,Mybatis-Puls实现BaseMapper
接口 直接调用封装好的底层增删改查语句 实现方法不同:Mybatis还是使用xml实现sql语句增删改查, Mybatis-Puls 使用BaseMapper
进行sql语句的继承调用 自动生成代码器不同:Mybatis 是使用mybatis逆向工程生成pojo,接口 已经模板代码 Mybatis-Puls 是使用代码生成器自动生成代码
Mybatis-Puls增删改查
-
简单增删改查–单一表 – 使用继承BaseMapper接口
封装好的增删改查方法 复杂增删改查 -多表或复杂语句操作 — 使用条件构造器语法实现
Mybatis-Puls 快速入门
快速入门Mybatis-puls步骤
环境准备
-
1.创建数据库
-
2.导入maven依赖
-
3.配置数据源连接信息
增删改查准备
-
4.创建pojo类
-
5.创建mapper接口 继承基本的接口BaseMapper接口
-
6.启动类 添加扫描mapper注解
开始使用Mybatis-puls
创建数据库和表
-- 创建user表
CREATE TABLE user
(
id BIGINT(20) NOT NULL COMMENT '主键ID',
name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',
age INT(11) NULL DEFAULT NULL COMMENT '年龄',
email VARCHAR(50) NULL DEFAULT NULL COMMENT '邮箱',
PRIMARY KEY (id)
);
INSERT INTO USER (id, NAME, age, email) VALUES
(1, 'Jone', 18, 'test1@baomidou.com'),
(2, 'Jack', 20, 'test2@baomidou.com'),
(3, 'Tom', 28, 'test3@baomidou.com'),
(4, 'Sandy', 21, 'test4@baomidou.com'),
(5, 'Billie', 24, 'test5@baomidou.com');
-- 真实开发中,version(乐观锁)、delete(逻辑删除)、gmt_create、gmt_modified
创建springboot项目
引入maven依赖
在springboot项目依赖基础上 映入相关依赖
<!-- 数据库驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!-- mybatis-plus -->
<!-- mybatis-plus 是自己开发,并非官方的! -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.0</version>
</dependency>
配置数据源连接信息
# mysql 5 驱动不同 com.mysql.jdbc.Driver
# mysql 8 驱动不同com.mysql.cj.jdbc.Driver、需要增加时区的配置 serverTimezone=GMT%2B8
spring.datasource.url=jdbc:mysql://localhost:3306/mybatis-plus? useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=123456
增删改查准备
创建pojo封装类
@Data //get set 方法
@AllArgsConstructor //有参构造
@NoArgsConstructor //无参构造
public class User {
private Long id;
private String name;
private Integer age;
private String email;
}
Mapper接口
继承基本的接口BaseMapper接口,调用BaseMapper提前封装好的sql语句,实现自动增删改查
@Mapper
//在对应的Mapper 上面继承基本类BaseMapper
//将数据库封装对象的参数,传递到BaseMapper这个泛型类中,作为参数 就可以激活BaseMapper这个类 使用泛型先封装好的增删改查方法
public interface UserMapper extends BaseMapper<User> {
//直接可以使用mybatis-puls 的增删改查方法
//所有的CRUD操作都已经编写完成了
//你不需要像以前的配置一大堆文件了
/**
* 原理
* 将数据库封装对象作为参数,传递到BaseMapper这个泛型类中,
* 就可以激活BaseMapper这个类 使用泛型先封装好的增删改查方法
*/
}
mapper接口省去简单增删改查方法的创建的原因
实现BaseMapper这个接口
-
接口里面使用泛型,已经提前构造好了简单的增删改查方法 传递参数对象 给泛型接收即可
-
将数据库封装对象的参数,传递到BaseMapper这个泛型类中,作为参数 就可以激活BaseMapper这个类 使用泛型先封装好的增删改查方法
以下是BaseMapper源码
(这是mapper省略增删改查的原因 ,不用出现在项目中)
//传进去的对象 将由泛型接收 变成使用的增删改查方法
/**
* Mapper 继承该接口后,无需编写 mapper.xml 文件,即可获得CRUD功能
* 这个 Mapper 支持 id 泛型*/
public interface BaseMapper<T> {
/**
* 插入一条记录
* @param var1(对象)
* 实体对象
* @return int
*/
//插入一条记录 传入是一个对象
int insert(T var1);
/**
* 根据 ID 删除
* @param id
* 主键ID
* @return int
*/
//根据Id删除记录 传入是一个id
int deleteById(Serializable var1);
/**
* 根据 columnMap 条件,删除记录 var1对象
* @param columnMap
* 表字段 map 对象
* @return int
*/
//根据对象参数,删除含参数的map对象
int deleteByMap(@Param("cm") Map<String, Object> var1);
/**
* 根据 entity(对象) 条件,删除记录 var1 对象
* @param wrapper
* 实体对象封装操作类(可以为 null)
* @return int
*/
//根据对象条件,删除表记录
int delete(@Param("ew") Wrapper<T> var1);
/**
* 删除(根据ID 批量删除)
* @param idList
* 主键ID列表
* @return int
*/
//根据主键id删除表记录
int deleteBatchIds(@Param("coll") Collection<? extends Serializable> var1);
/**
* 根据 ID 修改
* @param var1
* 实体对象
* @return int
*/
//根据Id 更新修改表记录
int updateById(@Param("et") T var1);
/**
* 根据 whereEntity 条件,更新记录
* @param entity
* 实体对象
* @param wrapper
* 实体对象封装操作类(可以为 null)
* @return
*/
//根据对象 更新表记录
int update(@Param("et") T var1, @Param("ew") Wrapper<T> var2);
/**
* 根据 ID 查询
* @param id
* 主键ID
* @return T
*/
//根据主键Id查询表记录
T selectById(Serializable var1);
/**
* 查询(根据ID 批量查询)
* @param idList
* 主键ID列表
* @return List<T>
*/
//根据主键id 进行记录批量查询
List<T> selectBatchIds(@Param("coll") Collection<? extends Serializable> var1);
/**
* 查询(根据 columnMap 条件)
* @param columnMap
* 表字段 map 对象
* @return List<T>
*/
//根据对象条件 ,查询整个表的map集合记录
List<T> selectByMap(@Param("cm") Map<String, Object> var1);
/**
* 根据 entity 条件,查询一条记录
* @param entity
* 实体对象
* @return T
*/
//根据对象条件 ,查询记录
T selectOne(@Param("ew") Wrapper<T> var1);
/**
* 根据 Wrapper 条件,查询总记录数
* @param wrapper
* 实体对象
* @return int
*/
Integer selectCount(@Param("ew") Wrapper<T> var1);
/**
* 根据 entity 条件,查询全部记录
* @param wrapper
* 实体对象封装操作类(可以为 null)
* @return List<T>
*/
List<T> selectList(@Param("ew") Wrapper<T> var1);
/**
* 根据 Wrapper 条件,查询全部记录
* @param wrapper
* 实体对象封装操作类(可以为 null)
* @return List<T>
*/
List<Map<String, Object>> selectMaps(@Param("ew") Wrapper<T> var1);
/**
* 根据 Wrapper 条件,查询全部记录
* @param wrapper
* 实体对象封装操作类(可以为 null)
* @return List<Object>
*/
List<Object> selectObjs(@Param("ew") Wrapper<T> var1);
/**
* 用法:(new RowBounds(offset, limit), ew);
* 根据 entity 条件,查询全部记录(并翻页)
* @param rowBounds
* 分页查询条件(可以为 RowBounds.DEFAULT)
* @param wrapper
* 实体对象封装操作类(可以为 null)
* @return List<T>
*/
//分页查询
IPage<T> selectPage(IPage<T> var1, @Param("ew") Wrapper<T> var2);
/** -- 不常用,
* 根据 Wrapper 条件,查询全部记录(并翻页)
* @param rowBounds
* 分页查询条件(可以为 RowBounds.DEFAULT)
* @param wrapper
* 实体对象封装操作类
* @return List<Map<String, Object>>
*/
IPage<Map<String, Object>> selectMapsPage(IPage<T> var1, @Param("ew") Wrapper<T> var2);
}
启动类
启动类添加mapper扫描注解 使用加载mapper使用
package com.lhw.mybatispuls;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan(basePackages = "com.lhw.mybatispuls.dao.UserMapper")
public class MybatisPulsApplication {
public static void main(String[] args) {
SpringApplication.run(MybatisPulsApplication.class, args);
}
}
调用增删改查
前面的mapper接口已经封装了具体的增删改查方法
这里我们可以直接调用传值进去,进行简单的增删改查就可以直接使用
一般使用的范围模块
-
测试模块使用 — 测试检查,传值并直接调用增删改查的方法
-
业务层使用 –实现业务,传值并直接调用增删改查的方法
测试类调用增删改查
调用封装好的增删改查的方法
使用注入的接口调用其继承父类的增删改查方法,我们只需要传入相应查询的值即可
@SpringBootTest
class MybatisPulsApplicationTests {
//继承了BaseMapper 所有的方法都来着父类
//我们也可以编写自己的扩展方法
@Autowired //注入doa层接口即可
private UserMapper userMapper;
@Test
void contextLoads() {
//参数是一个Wrapper 是一个条件构造器 启用就使用条件查询 ,不启用就null 不使用条件查询
//如何调用继承的增删改查的方法:使用注入的接口调用其继承父类的方法,我们只需要传值即可
List<User> users = userMapper.selectList(null);
//打印结果值
users.forEach(System.out::println);
}
}
配置日志
将sql可视化
配置mybatis-puls或mybatis配置
#配置日志
#使用默认控制台输出
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
简单增删改查操作
mybatis-puls的增删改查都交由mybatis-puls的特殊接口 BaseMapper
插入数据
基本插入数据操作
@Test
public void testInsert(){
User user = new User();
user.setName("张三");
user.setAge(23);
user.setEmail("123456789@qq.com");
//插入数据
int insert = userMapper1.insert(user); //帮我们自动生成id
//打印插入数据结果
System.out.println(insert); //受影响行数
System.out.println(user); //发现 id会自动回填 主键生成策略
}
这里了解一下什么是主键生成策略
主键生成策略
数据库插入的id默认值为:生成全局唯一id
雪花算法
生成全局唯一id
snowflake是Twitter开源的分布式ID生成算法,结果是一个long型的ID。其核心思想是:使用41bit作为毫秒数,10bit作为机器的ID(5个bit是数据中心,5个bit的机器ID),12bit作为毫秒内的流水号(意味着每个节点在每毫秒可以产生 4096 个 ID),最后还有一个符号位,永远是0。可以保证几乎全球唯一!
想要生成的id自增
-
pojo实体类字段上@TableId(type = IdType.AUTO)
-
数据库设置主键自增
查看注解源码
public enum IdType {
AUTO(0), //数据库id自增
NONE(1), //未设置主键
INPUT(2), //手动输入
ASSIGN_ID(3), //默认的全局唯一id
ASSIGN_UUID(4), //全局唯一id UUID
ID_WORKER_STR(5); //ID_WORKER 字符串表示法
}
例如
在实体类声明id自增
@Data //get set 方法
@AllArgsConstructor //有参构造
@NoArgsConstructor //无参构造
public class User {
//在实体类 声明id全局自增
@TableId(type = IdType.AUTO) //声明id自增
private Long id;
private String name;
private Integer age;
private String email;
}
删除数据
基本删除操作
//测试删除
@Test
public void testDeleteById(){
userMapper.deleteById(1L);
}
//通过id批量删除
@Test
public void testDeleteBatchId(){
userMapper.deleteBatchIds(Arrays.asList(2, 3, 4));
}
//通过map删除
@Test
public void testDeleteMap(){
HashMap<String, Object> map = new HashMap<>();
map.put("name", "陈伟");
userMapper.deleteByMap(map);
}
逻辑删除
-
物理删除:从数据库中直接移除
-
逻辑删除:在数据库中没有移除,而是通过一个变量让他失效,deleted = 0 变成 deleted=1
使用步骤
-
在数据库中增加一个deleted字段
-
在实体类中增加属性
-
配置逻辑删除变量
-
调用逻辑删除
在数据库中增加一个deleted字段
在实体类中增加属性
@TableLogic //逻辑删除
private Integer deleted;
配置逻辑删除变量
在配置文件里 添加两个逻辑删除变量
#配置逻辑删除
#delete-value=1 是启用逻辑删除
mybatis-plus.global-config.db-config.logic-delete-value=1
#not-delete-value=0 是关闭逻辑删除
mybatis-plus.global-config.db-config.logic-not-delete-value=0
调用逻辑删除
//测试删除
@Test
public void testDeleteById(){
userMapper.deleteById(1L);
}
更新数据
更新数据
//测试更新
@Test
public void testUpdate(){
User user = new User();
//通过条件自动拼接动态SQL
user.setId(5L);
user.setName("陈伟");
user.setAge(20);
user.setEmail("1277077741@qq.com");
//注意:updateById 参数是一个对象!
int i = userMapper.updateById(user);
System.out.println(i);
}
自动插入
需要自动更新的东西,比如字段插入时间
创建时间、修改时间!这些个操作都是自动化完成的,我们不希望手动更新!
阿里巴巴开发手册:所有的数据库表:gmt_create、gmr_modified、几乎所有的表都要配置上!而且需要自动化
代码级别实现
实体类的字段属性上需要增加注解
@Data //get set 方法
@AllArgsConstructor //有参构造
@NoArgsConstructor //无参构造
public class User {
private Long id;
private String name;
private Integer age;
private String email;
//字段添加自动填充内容 例如时间戳
//创建时间时,自动填写一个插入时间戳操作
@TableField(fill = FieldFill.INSERT)
private Date createTime;
//更新时间时,自动填写一个更新时间戳操作
@TableField(fill = FieldFill.UPDATE)
private Date updateTime;
}
创建一个自动插入处理器
编写处理器处理注解即可!
@Component //一定不要忘记把处理器加到IOC容器中
@Slf4j //打印一下日志之类的
public class MyMetaObjectHandler implements MetaObjectHandler {
//插入时候的填充策略
@Override
public void insertFill(MetaObject metaObject) {
log.info("start insert fill ......");
//default MetaObjectHandler
//setFieldValByName(String fieldName, Object fieldVal, MetaObject metaObject)
//自动插入时间
//将需要处理的字段 以参数的形式放入处理器
this.setFieldValByName("createTime", new Date(), metaObject);
this.setFieldValByName("updateTime", new Date(), metaObject);
}
//更新时候的填充策略
@Override
public void updateFill(MetaObject metaObject) {
log.info("start update fill ......");
//自动更新时间
//将需要处理的字段 以参数的形式放入处理器
this.setUpdateFieldValByName("updateTime", new Date(), metaObject);
}
}
4、测试插入
5、测试更新、观察时间即可!
乐观锁
乐观锁的作用:在多线程下,插队操作是否会被拦截
原子引用!
乐观锁:顾名思义十分乐观,他总是认为不会出现问题,无论干什么不去上锁!如果出现了问题,再次更新值测试!
悲观锁:顾名思义十分悲观,他总是任务总是出现问题,无论干什么都会上锁!再去操作!
我们这里主要讲解,乐观锁机制!
乐观锁实现方式:
-
取出记录,获取当前version
-
更新时,带上这个version
-
执行更新时,set version = new version where version = oldversion
-
如果version不对,就更新失败
乐观锁:1、先查询,获得版本号 version = 1
— A
update user set name = “ChanV”, version = version + 1
where id = 2 and version = 1— B 线程抢先完成,这个时候 version = 2,会导致 A 修改失败!
update user set name = “ChanV”, version = version + 1
where id = 2 and version = 1
乐观锁的实现
-
在数据库添加version字段
-
在实体类中添加对应version字段和注解
-
注册乐观锁拦截器
1、给数据库中增加version字段!
2、我们实体类加对应的字段和乐观锁注解
@Data //get set 方法
@AllArgsConstructor //有参构造
@NoArgsConstructor //无参构造
public class User {
private Long id;
private String name;
private Integer age;
private String email;
//在实体类添加对应字段 和乐观锁注解
@Version //乐观锁version注解
private Integer version;
}
注册乐观锁拦截器
实现一个配置类 将需要配置的乐观锁拦截器配置进去
//扫描我们的mapper文件夹
@MapperScan("com.lhw.mapper")
@EnableTransactionManagement
@Configuration //配置类
public class MyBatisPlusConfig {
//注册乐观锁插件
//配置乐观锁的插件 形成一个乐观锁的拦截器 当版本不对时,更新失败
@Bean
public OptimisticLockerInnerInterceptor optimisticLockerInnerInterceptor(){
return new OptimisticLockerInnerInterceptor();
}
}
测试乐观锁的使用
在多线程下,插队操作是否会被拦截
//测试乐观锁成功!执行成功就会执行更新操作
@Test
public void testOptimisticLocker(){
//1、查询用户信息
User user = userMapper.selectById(1330080433207046145L);
//2、修改用户信息
user.setName("ChanV");
user.setEmail("1277077741@qq.com");
//3、执行更新操作 执行成功就会执行更新操作
userMapper.updateById(user);
}
//测试乐观锁失败!多线程下 就不会执行更新操作 拦截上锁
@Test
public void testOptimisticLocker2(){
//线程1
User user = userMapper.selectById(5L);
user.setName("ChanV111");
user.setEmail("1277077741@qq.com");
//模拟另一个线程执行了插队操作
User user2 = userMapper.selectById(5L);
user2.setName("ChanV222");
user2.setEmail("1277077741@qq.com");
userMapper.updateById(user2);
//自旋锁多次尝试提交
userMapper.updateById(user); //如果没有乐观锁就会覆盖队线程的值
}
}
查询数据
基本查询
//查询测试
@Test
public void testSelectById(){
User user = userMapper.selectById(1L);
System.out.println(user);
}
//批量查询
@Test
public void testSelectByBatchId(){
//批量查询方法selectBatchIds()接收一个对象
List<User> users = userMapper.selectBatchIds(Arrays.asList(1, 2, 3));
users.forEach(System.out::println);
}
//条件查询 map
@Test
public void testSelectByBatchIds(){
//使用map 存储键值对
HashMap<String, Object> map = new HashMap<>();
//自定义要查询
map.put("name", "张三");
map.put("age",3);
//查询结果使用list集合接收结果
List<User> users = userMapper.selectByMap(map);
//打印结果
users.forEach(System.out::println);
}
分页查询
分页在网站使用的十分之多!
-
1、原始的 limit 进行分页
-
2、pageHelper 第三方插件
-
3、MP其实也内置了分页插件
Mybatis-Puls内置分页插件的使用
1、配置拦截器组件即可
//分页插件
@Bean
public PaginationInterceptor paginationInterceptor() {
PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
return paginationInterceptor;
}
2、直接使用Page对象即可!
//测试分页查询
@Test
public void testPage(){
//参数一:当前页
//参数二:页面大小
//使用了分页插件之后,所有的分页操作也变得简单了!
Page<User> page = new Page<>(2, 5);
userMapper.selectPage(page, null);
page.getRecords().forEach(System.out::println);
System.out.println(page.getTotal());
}
}
条件构造器
十分重要:Wapper(条件构造器)
我们写复杂的SQL语句时,可以使用条件构造器的语法代替来进行替换
条件构造器语法
条件判断
allEq:所有条件全等于
allEq({id:1,name:"老王",age:null})--->id = 1 and name = '老王' and age is null
allEq({id:1,name:"老王",age:null}, false)--->id = 1 and name = '老王'
eq: 等于 =
eq("name", "老王")--->name = '老王'
ne:不等于 < >
ne("name", "老王")--->name <> '老王'
gt: 大于 >
gt("age", 18)--->age > 18
ge:大于等于 >=
ge("age", 18)--->age >= 18
le:小于等于 < =
le("age", 18)`--->`age <= 18
It:小于 <
lt("age", 18)--->age < 18
区间
between:介于什么之间
between("age", 18, 30)`--->`age between 18 and 30
like:LIKE ‘%值%
左右都包含
like("name", "王")--->name like '%王% //左右都能匹配到'王' 字
likeLeft:LIKE ‘%王’
左包含 只能向左匹配
likeLeft("name", "王")--->name like '%王'
likeRight :LIKE ‘王%’
右包含 只能向右匹配
likeRight("name", "王")`--->`name like '王%'
notlike:NOT LIKE ‘%值%
左右都不包含
notLike("name", "王")`--->`name not like '%王%'
in:在范围内
in("age",{1,2,3})`--->`age in (1,2,3) //对象的值不在这个范围内
notIn:不在范围内
notIn("age",{1,2,3})`--->`age not in (1,2,3) //对象的值 不在这个范围
非空
isNull
空值
isNull("name")--->name is null //是空值
isNotNull
非空
isNotNull("name")--->name is not null //不为空 非空
排序
orderByAsc
排序:ORDER BY 字段, … ASC //字段升序
orderByAsc("id", "name")--->order by id ASC,name ASC
orderByDesc
排序:ORDER BY 字段, … DESC //字段降序
orderByDesc("id", "name")`--->`order by id DESC,name DESC //降序
orderBy
排序:ORDER BY 字段, … //默认排序
orderBy(true, true, "id", "name")`--->`order by id ASC,name ASC
条件查询实例
不为空查询
@Test
public void QueryWrapper(){
//查询name不为空的用户,并且邮箱不为空的用户,年龄大于等于12岁
QueryWrapper<User> wrapper = new QueryWrapper<>(); //查询条件构造器
//调用查询构造器的查询方法
wrapper.
isNotNull("name") //不为空
.isNotNull("email") //条件不为空
.ge("age",12); //对象大于等于
userMapper.selectList(wrapper).forEach(System.out::println); //调用条件构造器进行查询 并打印
}
相等查询
@Test
public void Test2(){
//查询名字是否相等
QueryWrapper<User> wrapper = new QueryWrapper<>(); //获取条件构造器对象
wrapper.eq("name","张三"); //查询数据库是否
User user = userMapper.selectOne(wrapper); //查询一个数据,出现过多结果使用list 或Map集合
System.out.println(user);
}
区间查询
@Test
public void Test3(){
//查询在年龄在20~30之间的用户
QueryWrapper<User> wrapper = new QueryWrapper<>(); //获取条件构造器对象
wrapper.between("age",20,30); //区级查询
Integer count = userMapper.selectCount(wrapper); //查询结果
System.out.println(count);
}
模糊查询
//模糊查询
@Test
void test4(){
//查询年龄在19到30岁之间的用户
QueryWrapper<User> wrapper = new QueryWrapper<>();
//左和右
wrapper.notLike("name", "b") //在name 字段中不包含 b
.likeRight("email", "t"); //在email字段 中 向右包含t
List<Map<String, Object>> maps = userMapper.selectMaps(wrapper);
maps.forEach(System.out::println);
}
子查询
@Test
void test5(){
QueryWrapper<User> wrapper = new QueryWrapper<>();
//id 在子查询中查出来
wrapper.inSql("id", "select id from user where id < 3");
List<Object> objects = userMapper.selectObjs(wrapper);
objects.forEach(System.out::println);
}
排序查询
@Test
void test6(){
QueryWrapper<User> wrapper = new QueryWrapper<>();
//通过id进行排序
wrapper.orderByDesc("id"); //通过id 进行降序排序
//wrapper.orderByASC("id"); //通过id 进行升序排序
List<User> users = userMapper.selectList(wrapper);
users.forEach(System.out::println);
}
代码自动生成器
创建使用代码生成器模板类
public class Code {
public static void main(String[] args) {
//需要构建一个 代码自动生成器 对象
// 代码生成器
AutoGenerator mpg = new AutoGenerator();
//配置策略
//1、全局配置
GlobalConfig gc = new GlobalConfig();
String projectPath = System.getProperty("user.dir"); //获取用户目录
gc.setOutputDir(projectPath + "/src/main/java"); //保存路径
gc.setAuthor("ChanV"); //声明作者名称
gc.setOpen(false); //是否打开资源浏览器
gc.setFileOverride(false); //是否覆盖
gc.setServiceName("%sService"); //去Service的I前缀
gc.setIdType(IdType.ID_WORKER);
gc.setDateType(DateType.ONLY_DATE);
gc.setSwagger2(true); //是否生成
mpg.setGlobalConfig(gc);
//2、设置数据源
DataSourceConfig dsc = new DataSourceConfig();
dsc.setUrl("jdbc:mysql://localhost:3306/mybatis-plus?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8"); //设置连接URL
dsc.setDriverName("com.mysql.cj.jdbc.Driver"); //设置数据源名称
dsc.setUsername("root"); //设置数据库用户名
dsc.setPassword("root"); //设置数据库密码
dsc.setDbType(DbType.MYSQL); //设置连接的数据库类型
mpg.setDataSource(dsc); //连接数据源
//3、包的配置
PackageConfig pc = new PackageConfig(); //获取包配置对象
pc.setModuleName("blog"); //设置模块名
pc.setParent("com.chanv"); //设置包路径
pc.setEntity("pojo"); //设置实体类名
pc.setMapper("mapper"); //设置Mapper名
pc.setService("service"); //设置Service名
pc.setController("controller"); //设置controller名
mpg.setPackageInfo(pc); //设置包信息对象
//4、策略配置
StrategyConfig strategy = new StrategyConfig();
//strategy.setInclude("user"); //设置要映射的表名 生成其他的表 只需要改这个
strategy.setInclude("user","student","teacher"); //引入多个参数,直接上传多张表
strategy.setNaming(NamingStrategy.underline_to_camel); //设置包名命名规则
strategy.setColumnNaming(NamingStrategy.underline_to_camel); //设置数据库字段命名规则
strategy.setEntityLombokModel(true); //自动lombok
strategy.setLogicDeleteFieldName("deleted"); //设置逻辑删除
//自动填充配置
TableFill createTime = new TableFill("create_time", FieldFill.INSERT);
TableFill updateTime = new TableFill("update_time", FieldFill.UPDATE);
ArrayList<TableFill> tableFills = new ArrayList<>();
tableFills.add(createTime); //创建时间 自动填充字段
tableFills.add(updateTime); //更新时间 自动填充字段
strategy.setTableFillList(tableFills);
//乐观锁
strategy.setVersionFieldName("version");
strategy.setRestControllerStyle(true);
strategy.setControllerMappingHyphenStyle(true); //控制层映射地址 localhost:8080/hello_id_2
mpg.setStrategy(strategy);
mpg.execute(); //执行代码构造器
}
}
原文始发于微信公众号(理想Talk):Mybatis-Plus ! 这篇足以!!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/27841.html