![cover](https://img-blog.csdnimg.cn/e2f0765f95bb408cb678b91aeccfd844.png#pic_center)
Mybatis-Plus入门(新版3.5.2)
良心!新版代码自动生成器详解,基本CRUD使用,条件构造器使用,分页插件等!
Mybatis-Plus入门(新版3.5.2)
目录
环境:
jdk:1.8
mybatis-plus:3.5.2
springboot:2.7.1
PostgreSQL:14.4
mybatis-plus官网
文档说明:本文的会直接从代码生成开始,用最短的时间,最少的弯路学会使用mybatis-plus,提高开发效率,但是需要一定的基础。
一、概述
不多说生涩的理论,我的感受是:
- 不用再写简单的SQL语句,单表CRUD直接就有了。
- 自带分页插件,好用的一批。
- 代码生成器,开发效率无敌。
虽然复杂的SQL还是要手写,但是,都这样了还要啥自行车?
二、代码生成
-
新建springboot项目,添加依赖
<!--数据库驱动--> <dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <!--数据库连接池--> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.2.11</version> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.5.2</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <!--代码生成器--> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-generator</artifactId> <version>3.5.2</version> </dependency> <!--自动代码生成到时候需要配置开启swagger注解,所以导入swagger--> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.9.2</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>2.9.2</version> </dependency> <!--模板引擎,规定必须设置--> <dependency> <groupId>org.apache.velocity</groupId> <artifactId>velocity-engine-core</artifactId> <version>2.3</version> </dependency>
-
配置数据源
代码生成是根据数据库生成相应的实体,服务等,所以我们要先建一张表:
/* Navicat Premium Data Transfer Source Server : localhost_5432 Source Server Type : PostgreSQL Source Server Version : 140004 Source Host : localhost:5432 Source Catalog : db_ds_ss Source Schema : test Target Server Type : PostgreSQL Target Server Version : 140004 File Encoding : 65001 Date: 01/07/2022 11:39:21 */ -- ---------------------------- -- Table structure for ds_user -- ---------------------------- DROP TABLE IF EXISTS "test"."ds_user"; CREATE TABLE "test"."ds_user" ( "ds_user_name" varchar(255) COLLATE "pg_catalog"."default" NOT NULL, "ds_user_password" varchar(255) COLLATE "pg_catalog"."default" NOT NULL, "ds_user_email" varchar(255) COLLATE "pg_catalog"."default", "ds_user_tel" varchar(255) COLLATE "pg_catalog"."default", "ds_user_role" int2 NOT NULL, "create_time" timestamp(0) DEFAULT now(), "modify_time" timestamp(0) DEFAULT now(), "deleted" int2 NOT NULL DEFAULT 0, "ds_user_id" serial4 NOT NULL ) ; COMMENT ON COLUMN "test"."ds_user"."ds_user_name" IS '用户名 '; COMMENT ON COLUMN "test"."ds_user"."ds_user_password" IS '密码'; COMMENT ON COLUMN "test"."ds_user"."ds_user_email" IS '邮箱'; COMMENT ON COLUMN "test"."ds_user"."ds_user_tel" IS '手机'; COMMENT ON COLUMN "test"."ds_user"."ds_user_role" IS '用户权限:如果为0则为普通用户,1则为管理员 '; COMMENT ON COLUMN "test"."ds_user"."create_time" IS '创建时间 '; COMMENT ON COLUMN "test"."ds_user"."modify_time" IS '修改时间 '; COMMENT ON COLUMN "test"."ds_user"."deleted" IS '删除标志 ,逻辑删除,0表示未删除,1表示删除'; COMMENT ON COLUMN "test"."ds_user"."ds_user_id" IS 'id ,自增'; -- ---------------------------- -- Uniques structure for table ds_user -- ---------------------------- ALTER TABLE "test"."ds_user" ADD CONSTRAINT "ds_user_ds_user_id_key" UNIQUE ("ds_user_name"); -- ---------------------------- -- Primary Key structure for table ds_user -- ---------------------------- ALTER TABLE "test"."ds_user" ADD CONSTRAINT "ds_user_pk" PRIMARY KEY ("ds_user_id");
阿里的开发手册规定:id, gmt_create, gmt_modified必须要有。(创建、修改时间自动插入实现见下文)
另外,逻辑删除也可以加上,也就是用一个表示判断数据是否被删除了,而不是真正的移除这一条数据,删除的sql也从delete变成了
update xxx set delete=1 where xxx
。yml中配置数据源:
spring: datasource: druid: driver-class-name: org.postgresql.Driver url: jdbc:postgresql://localhost:5432/db_ds_ss?currentSchema=test username: postgres password: 123456 initial-size: 5 max-active: 20 min-idle: 5 max-wait: 60000 mybatis-plus: configuration: #日志输出 log-impl: org.apache.ibatis.logging.stdout.StdOutImpl global-config: db-config: #逻辑删除 logic-delete-value: 1 logic-not-delete-value: 0
-
写代码
搞个测试就可以了,方便
@Test void autocode() { // 最开始是配置数据源,postgresql还得指定架构,这里我就指定了用test架构 FastAutoGenerator.create(new DataSourceConfig.Builder("jdbc:postgresql://localhost:5432/db_ds_ss?currentSchema=test", "postgres", "123456").schema("test")) // 全局配置 .globalConfig(builder -> { builder.author("yangsf") // 设置作者 .enableSwagger() // 开启 swagger 模式(根据数据库的注释等生成swagger的注解,真的牛) .fileOverride() // 覆盖已生成文件 .outputDir(System.getProperty("user.dir") + "/src/main/java") // 指定输出目录 .disableOpenDir() // 生成后不打开资源管理器 .dateType(DateType.ONLY_DATE) // 时间类型 .commentDate("yyyy-MM-dd hh:mm:ss"); // 时间格式 }) // 包配置,也就是生成哪些文件夹 .packageConfig(builder -> { builder.parent("com.yangsf") // 设置父包名 也就是生成在输出目录的 com/yangsf下 .moduleName("mybatisplus") // 设置父包模块名 也就是代码放在com/yangsf/mybatisplus下 .pathInfo(Collections.singletonMap(OutputFile.xml, System.getProperty("user.dir")+"/src/main/resources/mapper")) // 设置mapperXml生成路径 .service("service") // 接下来的几个都是包名,也就是对应的代码的存放目录 .entity("entity") .mapper("mapper") .controller("controller") .xml("mapper") .other("utils"); }) // 策略配置 .strategyConfig(builder -> { builder.addInclude("ds_user") // 这里填数据库表名,可以填多个,用’,‘隔开 .addTablePrefix("ds_") // 忽略前缀 // mapper(dao)层的配置 .mapperBuilder() .formatMapperFileName("%sMapper") // 生成的文件名都叫xxxmapper(根据表名) .enableMapperAnnotation() //开启@mapper注解 .superClass(BaseMapper.class) // 继承BaseMapper类 .formatXmlFileName("%sMapper") // 生成对应的xml都叫xxxmapper // service层配置 .serviceBuilder() .formatServiceFileName("%sService") .formatServiceImplFileName("%sServiceImpl") // 实体类配置 .entityBuilder() .idType(IdType.AUTO) // 主键的策略,我选的是自增 .enableLombok() //开启 Lombok .disableSerialVersionUID() //不实现 Serializable 接口,不生产 SerialVersionUID .logicDeleteColumnName("deleted") //逻辑删除字段名 .naming(NamingStrategy.underline_to_camel) //数据库表映射到实体的命名策略:下划线转驼峰命 .columnNaming(NamingStrategy.underline_to_camel) //数据库表字段映射到实体的命名策略:下划线转驼峰命 .addTableFills( new Column("create_time", FieldFill.INSERT), new Column("modify_time", FieldFill.INSERT_UPDATE) ) //添加表字段填充,"create_time"字段自动填充为插入时间,"modify_time"字段自动填充为插入修改时间,到时候需要编写具体的代码实现 .enableTableFieldAnnotation() // 开启生成字段注解 // controller层配置 .controllerBuilder() .formatFileName("%sController") //格式化 Controller 类文件名称,%s进行匹配表名,如 UserController .enableRestStyle(); //开启生成 @RestController 控制器 }) // 模板引擎配置 ,默认是Velocity .templateEngine(new FreemarkerTemplateEngine()) .execute(); // 执行 }
运行后,就会发现:
直接爽。
三、CRUD
代码生成了,怎么用?直接调方法就完事。
3.1 增加(Create)
也就是插入。
这里要注意的是,插入时间也就是creat_time字段,自己每次手动写插入时间是很low比的行为,我们直接统一解决,让他自己插入。
顺便把修改时间一起搞了。
首先,要有一个注解@TableField,因我我们生成代码的时候配置了这个注解,所以自己就有了:
CTRL+鼠标左键可以点进FieldFill查看其中的枚举的解释。
我们需要一个策略来填充这两个字段,新建一个handler包,新建一个MyMetaObjectHandler类实现MetaObjectHandler接口:
@Slf4j
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
log.info("start insert fill ....");
this.setFieldValByName("createTime", new Date(), metaObject);
}
@Override
public void updateFill(MetaObject metaObject) {
log.info("start update fill ....");
this.setFieldValByName("modifyTime", new Date(), metaObject);
}
}
我们之后就不用手动输入这两个时间了。
测试:
@Autowired
UserService userService;
@Test
void contextLoads() {
// 保存一个
User user = new User();
user.setDsUserName("root");
user.setDsUserPassword("123456");
user.setDsUserRole(1);
userService.save(user);
// 保存多个
User user1 = new User();
user1.setDsUserName("admin");
user1.setDsUserPassword("123456");
user1.setDsUserRole(1);
User user2 = new User();
user2.setDsUserName("xiaoming");
user2.setDsUserPassword("123456");
user2.setDsUserRole(1);
ArrayList<User> users = new ArrayList<>();
users.add(user1);
users.add(user2);
userService.saveBatch(users);
}
数据库中果然增加了,并且插入时间也自动填充上了。
3.2 读取查询(Retrieve)
先来个简单的查询所有,为了方便我们去实体类中加一个toString方法,然后就可以直接开始查询刚刚插入的数据了:
@Test
void selectTest() {
// 查询所有
userService.list().forEach(System.out::println);
}
日志输出和结果都在这里,注意看标红的地方,这就是利用逻辑删除标志来判断记录是否已被删除。
如果要条件查询,就需要学习Wapper,mybatis-plus的条件构造器,不过我们在这里先不慌学,在之后专门一章来说Wrrapper。
3.3 更新(Update)
先来个根据id修改:
@Test
void updateTest() {
User user = new User();
user.setDsUserId(9);
user.setDsUserName("yangsf");r
userService.updateById(user);
}
这里将id为9的记录的ds_user_name字段修改为了“yangsf”,并且自动填充了修改时间,复杂的修改需要使用Wrapper(见下文)。
3.4 和删除(Delete)
删除如果配置了逻辑删除,那就是逻辑删除(修改删除标志的值),如果没有配置,就是普通删除(删除记录)。
看个简单的,根据id删除:
@Test
void deleteTest() {
User user = new User();
user.setDsUserId(9);
userService.removeById(user);
}
这里将id为9的记录逻辑删除了,来看看sql:
实际上只是更改了一个值,并不是物理删除。
四、Wrapper
条件构造器,生成sql里where后面的东西,一般分两种wrapper,查询wrapper和更新wrapper(它们俩的父wrapper是AbstractWrapper),能构造的条件很多,不用记,需要的时候去官网看即可,这里说一下用法
举两个例子,一个查一个改,主要是学会怎么看官方文档。
例1:
查询权限为1且名为root且id大于3的用户的创建时间
第一步:查看官方文档构造条件相等的方法
第二步:查看条件构造大于的方法
第三步:查看只查询某字段的方法
于是找到eq,gt和select
然后看示例,例如eq:
即可写出下面的代码:
@Test
void wrapperOne() {
// 查询权限为1且名为root且id大于3的用户的创建时间
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("ds_user_role", 1)
.eq("ds_user_name", "root")
.gt("ds_user_id", 3)
.select("create_time");
userService.list(wrapper).forEach(System.out::println);
}
生成了这样一个sql:
例2:
修改名为admin且tel为空的字段的权限为0
第一步:依然是查看条件构造的方法
第二部:查看修改的方法
条件构造不必在说
于是找到set:
即可写出如下代码:
@Test
void wrapperTow() {
// 修改名为admin且tel为空的字段的权限为0
UpdateWrapper<User> wrapper = new UpdateWrapper<>();
wrapper.eq("ds_user_name", "admin")
.isNull("ds_user_tel")
.set("ds_user_role", 0);
userService.update(wrapper);
}
生成的sql:
五、插件
内置了多个插件
这里只说分页,分页是真的爽。
不用分页插件分页,用limit的话,还要需要计算一下是从多少条开始,使用分页插件就再也不用计算了。
首先添加配置类:
@Configuration
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.POSTGRE_SQL));
return interceptor;
}
}
然后就能直接用了:
@Test
void pageTest01() {
// new 一个Page对象即可,第一个参数是页码,第二个参数是页面大小,比如第二页就是2,5
Page<User> userPage = new Page<>(1, 2);
// 还可以传个wrapper进去
userService.page(userPage, null);
// 输出查询结果
userPage.getRecords().forEach(System.out::println);
// 总共的记录数
System.out.println(userPage.getTotal());
// 总共的页数
System.out.println(userPage.getPages());
}
总结:一个字,爽!
更多推荐
所有评论(0)