spring boot(二)整合mybatis plus+ 分页插件 + 代码生成
spring boot(二)整合mybatis plus+ 分页插件 + 代码生成
先创建spring boot项目,不知道怎么创建项目的 可以看我上一篇文章
用到的环境 JDK8 、maven、lombok、mysql 5.7
swagger 是为了方便接口测试
一、Spring boot 集成mybatis plus
mysql数据库准备
建议创建一个新的数据库测试
执行下面初始化SQL:
-- 创建测试用户表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');
1、添加 maven依赖
<!--mybatis-plus start--> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.4.3.1</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.0.29</version> </dependency> <!-- 提供mysql驱动 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.38</version> </dependency> <!--mybatis-plus end-->
2、application.yml配置
server: port: 9999spring: datasource: type: com.alibaba.druid.pool.DruidDataSource # 使用druid数据源 driver-class-name: com.mysql.jdbc.Driver url: jdbc:mysql://127.0.0.1:3308/test?useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&serverTimezone=Asia/Shanghai&useSSL=false username: root password: 999999999
3、在 Spring Boot 启动类中添加 @MapperScan 注解,扫描 Mapper 文件夹:
import org.mybatis.spring.annotation.MapperScan;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;@MapperScan("com.example.springbootmybatisplus.dao")@SpringBootApplicationpublic class SpringbootMybatisPlusApplication { public static void main(String[] args) { SpringApplication.run(SpringbootMybatisPlusApplication.class, args); } }
4、编码,写例子测试
4.1、 编写实体类 User.java
@Datapublic class User { private Long id; private String name; private Integer age; private String email; }
4.2、 编写Mapper类 UserMapper.java
package com.example.springbootmybatisplus.dao;import com.baomidou.mybatisplus.core.mapper.BaseMapper;import com.example.springbootmybatisplus.entity.User;public interface UserMapper extends BaseMapper<User> { }
4.3、 编写TestController接口进行测试
import cn.hutool.core.collection.CollUtil;import com.baomidou.mybatisplus.core.metadata.IPage;import com.baomidou.mybatisplus.extension.plugins.pagination.Page;import com.example.springbootmybatisplus.dao.UserMapper;import com.example.springbootmybatisplus.entity.User;import lombok.extern.slf4j.Slf4j;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.RequestParam;import org.springframework.web.bind.annotation.RestController;@Slf4j@RestController@RequestMapping("testUser")public class TestController { @Autowired UserMapper userMapper; //直接分页查询 @RequestMapping(value = "/selectPage",method = RequestMethod.GET) public IPage<User> selectPage(){ log.info("selectPage start"); IPage<User> page = new Page<>(1,2); userMapper.selectPage(page,null); if(CollUtil.isNotEmpty(page.getRecords())){ page.getRecords().forEach(data->{ log.info("{}",data); }); } log.info("selectPage end"); return page; } @RequestMapping(value = "/selectById",method = RequestMethod.GET) public User selectById(@RequestParam("id")Integer id){ log.info("selectById start"); User user = userMapper.selectById(id); log.info("user:{}",user); log.info("selectById end"); return user; } }
4.4、 启动项目,接口进行测试
第一步先访问:http://127.0.0.1:9999/testUser/selectById?id=1
第二步再访问接口:http://127.0.0.1:9999/testUser/selectPage
控制台输出
. ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v2.5.3)2021-07-27 22:52:25.127 INFO 23542 --- [ main] c.e.s.SpringbootMybatisPlusApplication : Starting SpringbootMybatisPlusApplication using Java 1.8.0_231 on localhost with PID 23542 (/Users/xkq/Downloads/it/xkq_git项目/springboot-example/springboot-mybatis-plus/target/classes started by xkq in /Users/xkq/Downloads/it/xkq_git项目/springboot-example/springboot-mybatis-plus)2021-07-27 22:52:25.130 INFO 23542 --- [ main] c.e.s.SpringbootMybatisPlusApplication : No active profile set, falling back to default profiles: default2021-07-27 22:52:25.770 WARN 23542 --- [ main] o.m.s.mapper.ClassPathMapperScanner : No MyBatis mapper was found in '[com.baomidou.cloud.service.*.mapper*]' package. Please check your configuration.2021-07-27 22:52:26.039 INFO 23542 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 9999 (http)2021-07-27 22:52:26.045 INFO 23542 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]2021-07-27 22:52:26.046 INFO 23542 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.50]2021-07-27 22:52:26.093 INFO 23542 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext2021-07-27 22:52:26.093 INFO 23542 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 918 ms _ _ |_ _ _|_. ___ _ | _ | | |\/|_)(_| | |_\ |_)||_|_\ / | 3.4.1 2021-07-27 22:52:26.902 INFO 23542 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 9999 (http) with context path ''2021-07-27 22:52:26.903 INFO 23542 --- [ main] d.s.w.p.DocumentationPluginsBootstrapper : Context refreshed2021-07-27 22:52:26.913 INFO 23542 --- [ main] d.s.w.p.DocumentationPluginsBootstrapper : Found 1 custom documentation plugin(s)2021-07-27 22:52:26.922 INFO 23542 --- [ main] s.d.s.w.s.ApiListingReferenceScanner : Scanning for api listing references2021-07-27 22:52:27.026 INFO 23542 --- [ main] c.e.s.SpringbootMybatisPlusApplication : Started SpringbootMybatisPlusApplication in 2.274 seconds (JVM running for 2.733)2021-07-27 22:52:35.289 INFO 23542 --- [nio-9999-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'2021-07-27 22:52:35.289 INFO 23542 --- [nio-9999-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'2021-07-27 22:52:35.290 INFO 23542 --- [nio-9999-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 1 ms2021-07-27 22:52:45.023 INFO 23542 --- [nio-9999-exec-7] c.e.s.controller.TestController : selectById start2021-07-27 22:52:45.067 INFO 23542 --- [nio-9999-exec-7] com.alibaba.druid.pool.DruidDataSource : {dataSource-1} inited2021-07-27 22:52:45.273 INFO 23542 --- [nio-9999-exec-7] c.e.s.controller.TestController : user:User(id=1, name=Jone, age=18, email=test1@baomidou.com)2021-07-27 22:52:45.274 INFO 23542 --- [nio-9999-exec-7] c.e.s.controller.TestController : selectById end2021-07-27 22:53:38.385 INFO 23542 --- [nio-9999-exec-9] c.e.s.controller.TestController : selectPage start2021-07-27 22:53:38.431 INFO 23542 --- [nio-9999-exec-9] c.e.s.controller.TestController : User(id=1, name=Jone, age=18, email=test1@baomidou.com)2021-07-27 22:53:38.432 INFO 23542 --- [nio-9999-exec-9] c.e.s.controller.TestController : User(id=2, name=Jack, age=20, email=test2@baomidou.com)2021-07-27 22:53:38.432 INFO 23542 --- [nio-9999-exec-9] c.e.s.controller.TestController : User(id=3, name=Tom, age=28, email=test3@baomidou.com)2021-07-27 22:53:38.432 INFO 23542 --- [nio-9999-exec-9] c.e.s.controller.TestController : User(id=4, name=Sandy, age=21, email=test4@baomidou.com)2021-07-27 22:53:38.432 INFO 23542 --- [nio-9999-exec-9] c.e.s.controller.TestController : User(id=5, name=Billie, age=24, email=test5@baomidou.com)2021-07-27 22:53:38.432 INFO 23542 --- [nio-9999-exec-9] c.e.s.controller.TestController : selectPage end
从日志中可以看到,selectById方法能查询数据,但是分页查询没有生效,后面会说怎么整合分页插件。
上面代码都是参考mybaits plus官方整合h2的例子,然后整合成mysql数据库的,mybaits plus详细文档可以访问官方地址
二、mybatis plus 分页插件
上面的分页没有生效,我们可以输出执行的SQL,看下实际执行的SQL
1、application.yml 配置打印SQL日志
mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #配置这个 会把输出执行的SQL
2、访问下面接口,查看日志输出
继续:第一步先访问:http://127.0.0.1:9999/testUser/selectById?id=1
第二步再访问接口:http://127.0.0.1:9999/testUser/selectPage
. ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v2.5.3)2021-07-27 22:57:56.973 INFO 26426 --- [ main] c.e.s.SpringbootMybatisPlusApplication : Starting SpringbootMybatisPlusApplication using Java 1.8.0_231 on localhost with PID 26426 (/Users/xkq/Downloads/it/xkq_git项目/springboot-example/springboot-mybatis-plus/target/classes started by xkq in /Users/xkq/Downloads/it/xkq_git项目/springboot-example/springboot-mybatis-plus)2021-07-27 22:57:56.976 INFO 26426 --- [ main] c.e.s.SpringbootMybatisPlusApplication : No active profile set, falling back to default profiles: default2021-07-27 22:57:57.620 WARN 26426 --- [ main] o.m.s.mapper.ClassPathMapperScanner : No MyBatis mapper was found in '[com.baomidou.cloud.service.*.mapper*]' package. Please check your configuration.2021-07-27 22:57:57.895 INFO 26426 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 9999 (http)2021-07-27 22:57:57.902 INFO 26426 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]2021-07-27 22:57:57.902 INFO 26426 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.50]2021-07-27 22:57:57.966 INFO 26426 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext2021-07-27 22:57:57.966 INFO 26426 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 941 msLogging initialized using 'class org.apache.ibatis.logging.stdout.StdOutImpl' adapter.Parsed mapper file: 'file [/Users/xkq/Downloads/it/xkq_git项目/springboot-example/springboot-mybatis-plus/target/classes/mapper/TestTableMapper.xml]' _ _ |_ _ _|_. ___ _ | _ | | |\/|_)(_| | |_\ |_)||_|_\ / | 3.4.1 2021-07-27 22:57:58.826 INFO 26426 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 9999 (http) with context path ''2021-07-27 22:57:58.827 INFO 26426 --- [ main] d.s.w.p.DocumentationPluginsBootstrapper : Context refreshed2021-07-27 22:57:58.836 INFO 26426 --- [ main] d.s.w.p.DocumentationPluginsBootstrapper : Found 1 custom documentation plugin(s)2021-07-27 22:57:58.846 INFO 26426 --- [ main] s.d.s.w.s.ApiListingReferenceScanner : Scanning for api listing references2021-07-27 22:57:58.968 INFO 26426 --- [ main] c.e.s.SpringbootMybatisPlusApplication : Started SpringbootMybatisPlusApplication in 2.363 seconds (JVM running for 2.816)2021-07-27 22:58:04.020 INFO 26426 --- [nio-9999-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'2021-07-27 22:58:04.020 INFO 26426 --- [nio-9999-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'2021-07-27 22:58:04.021 INFO 26426 --- [nio-9999-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 1 ms2021-07-27 22:58:04.044 INFO 26426 --- [nio-9999-exec-1] c.e.s.controller.TestController : selectById startCreating a new SqlSessionSqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6ca5a623] was not registered for synchronization because synchronization is not active2021-07-27 22:58:04.087 INFO 26426 --- [nio-9999-exec-1] com.alibaba.druid.pool.DruidDataSource : {dataSource-1} initedJDBC Connection [com.mysql.jdbc.JDBC4Connection@2a83b478] will not be managed by Spring==> Preparing: SELECT id,name,age,email FROM user WHERE id=?==> Parameters: 1(Integer)<== Columns: id, name, age, email<== Row: 1, Jone, 18, test1@baomidou.com<== Total: 1Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6ca5a623]2021-07-27 22:58:04.295 INFO 26426 --- [nio-9999-exec-1] c.e.s.controller.TestController : user:User(id=1, name=Jone, age=18, email=test1@baomidou.com)2021-07-27 22:58:04.295 INFO 26426 --- [nio-9999-exec-1] c.e.s.controller.TestController : selectById end2021-07-27 22:58:09.794 INFO 26426 --- [nio-9999-exec-2] c.e.s.controller.TestController : selectPage startCreating a new SqlSessionSqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@28b417c9] was not registered for synchronization because synchronization is not activeJDBC Connection [com.mysql.jdbc.JDBC4Connection@2a83b478] will not be managed by Spring==> Preparing: SELECT id,name,age,email FROM user==> Parameters: <== Columns: id, name, age, email<== Row: 1, Jone, 18, test1@baomidou.com<== Row: 2, Jack, 20, test2@baomidou.com<== Row: 3, Tom, 28, test3@baomidou.com<== Row: 4, Sandy, 21, test4@baomidou.com<== Row: 5, Billie, 24, test5@baomidou.com<== Total: 5Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@28b417c9]2021-07-27 22:58:09.818 INFO 26426 --- [nio-9999-exec-2] c.e.s.controller.TestController : User(id=1, name=Jone, age=18, email=test1@baomidou.com)2021-07-27 22:58:09.818 INFO 26426 --- [nio-9999-exec-2] c.e.s.controller.TestController : User(id=2, name=Jack, age=20, email=test2@baomidou.com)2021-07-27 22:58:09.818 INFO 26426 --- [nio-9999-exec-2] c.e.s.controller.TestController : User(id=3, name=Tom, age=28, email=test3@baomidou.com)2021-07-27 22:58:09.818 INFO 26426 --- [nio-9999-exec-2] c.e.s.controller.TestController : User(id=4, name=Sandy, age=21, email=test4@baomidou.com)2021-07-27 22:58:09.818 INFO 26426 --- [nio-9999-exec-2] c.e.s.controller.TestController : User(id=5, name=Billie, age=24, email=test5@baomidou.com)2021-07-27 22:58:09.818 INFO 26426 --- [nio-9999-exec-2] c.e.s.controller.TestController : selectPage end
从执行SQL的日志看到selectById方法没问题,主要是selectPage方法没有加limit分页
3、配置mybatis plus分页插件,添加MybatisPlusConfig.java
import com.baomidou.mybatisplus.annotation.DbType;import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;import com.baomidou.mybatisplus.extension.plugins.pagination.Page;import com.baomidou.mybatisplus.extension.plugins.pagination.optimize.JsqlParserCountOptimize;import org.mybatis.spring.annotation.MapperScan;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;//Spring boot方式@Configurationpublic class MybatisPlusConfig {// // 旧版// @Bean// public PaginationInterceptor paginationInterceptor() {// PaginationInterceptor paginationInterceptor = new PaginationInterceptor();// // 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求 默认false// // paginationInterceptor.setOverflow(false);// // 设置最大单页限制数量,默认 500 条,-1 不受限制// // paginationInterceptor.setLimit(500);// // 开启 count 的 join 优化,只针对部分 left join// paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true));// return paginationInterceptor;// } // 最新版 @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); return interceptor; } }
4、测试MybatisPlusInterceptor分页插件
加完MybatisPlusConfig后重启服务,访问接口: http://127.0.0.1:9999/testUser/selectPage
从SQL执行日志可以看出 先执行COUNT查询总条数,最后在LIMIT分页取数据,说明分页插件配置成功了
2021-07-27 23:02:40.225 INFO 28656 --- [nio-9999-exec-2] c.e.s.controller.TestController : selectPage startCreating a new SqlSessionSqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6acc6ecd] was not registered for synchronization because synchronization is not activeJDBC Connection [com.mysql.jdbc.JDBC4Connection@2320cee0] will not be managed by Spring==> Preparing: SELECT COUNT(*) FROM user==> Parameters: <== Columns: COUNT(*)<== Row: 5<== Total: 1==> Preparing: SELECT id,name,age,email FROM user LIMIT ?==> Parameters: 2(Long)<== Columns: id, name, age, email<== Row: 1, Jone, 18, test1@baomidou.com<== Row: 2, Jack, 20, test2@baomidou.com<== Total: 2Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6acc6ecd]2021-07-27 23:02:40.299 INFO 28656 --- [nio-9999-exec-2] c.e.s.controller.TestController : User(id=1, name=Jone, age=18, email=test1@baomidou.com)2021-07-27 23:02:40.299 INFO 28656 --- [nio-9999-exec-2] c.e.s.controller.TestController : User(id=2, name=Jack, age=20, email=test2@baomidou.com)2021-07-27 23:02:40.299 INFO 28656 --- [nio-9999-exec-2] c.e.s.controller.TestController : selectPage end
三、 mybatis plus 代码生成器
我对 mybatis plus 代码生成器的需求就是:
1、生成的代码 需要支持单表的crud
2、代码生成器通常默认生成的文件是controller、service、servieImpl、mapper(dao)、xml、entity;但是我还想多生成一个Vo类(多生成一个vo,主要是为了后期业务熟练了,想对已有的模版 进行修改 或者 增加生成新的生成文件,可以做一个参考)
3、xml文件 我要生成到 /src/main/resources/mapper文件夹下面
1、这是代码生成器需要生成的表,及测试数据
-- 创建表CREATE TABLE `test_table` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(100) DEFAULT NULL COMMENT '名称', `start_date` date DEFAULT NULL COMMENT '开始日期', `create_time` datetime DEFAULT NULL COMMENT '创建时间', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT='测试-表';-- 创建一条测试数据INSERT INTO `test_table` VALUES (1, '你好', '2021-07-27', '2021-07-27 23:10:02');
2、Vo类模版文件
路径及文件名是:/my_template/my_entity_vo.java.ftl
把mybatis-plus-generator.jar包的entity模版文件复制出来,模版内容稍微改了下类名和package,实际生成的文件跟entity差不多
下图就是我复制模版的位置,因为我选择的是freemarker 模版,就复制了后缀是ftl的文件
最终my_entity_vo.java.ftl模版内容如下:
package com.example.springbootmybatisplus.vo; <#list table.importPackages as pkg>import ${pkg}; </#list><#if swagger2>import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; </#if><#if entityLombokModel>import lombok.Data; import lombok.EqualsAndHashCode; <#if chainModel>import lombok.experimental.Accessors; </#if></#if>/** * <p> * ${table.comment!} * </p> * * @author ${author} * @since ${date} */ <#if entityLombokModel>@Data <#if superEntityClass??>@EqualsAndHashCode(callSuper = true) <#else>@EqualsAndHashCode(callSuper = false) </#if> <#if chainModel>@Accessors(chain = true) </#if></#if><#if table.convert>@TableName("${table.name}") </#if><#if swagger2>@ApiModel(value="${entity}对象", description="${table.comment!}") </#if><#if superEntityClass??>public class ${entity}Vo extends ${superEntityClass}<#if activeRecord><${entity}></#if> {<#elseif activeRecord>public class ${entity}Vo extends Model<${entity}> { <#else>public class ${entity}Vo implements Serializable { </#if><#if entitySerialVersionUID> private static final long serialVersionUID = 1L; </#if><#-- ---------- BEGIN 字段循环遍历 ----------><#list table.fields as field> <#if field.keyFlag> <#assign keyPropertyName="${field.propertyName}"/> </#if> <#if field.comment!?length gt 0> <#if swagger2> @ApiModelProperty(value = "${field.comment}") <#else> /** * ${field.comment} */ </#if> </#if> <#if field.keyFlag> <#-- 主键 --> <#if field.keyIdentityFlag> @TableId(value = "${field.annotationColumnName}", type = IdType.AUTO) <#elseif idType??> @TableId(value = "${field.annotationColumnName}", type = IdType.${idType}) <#elseif field.convert> @TableId("${field.annotationColumnName}") </#if> <#-- 普通字段 --> <#elseif field.fill??> <#-- ----- 存在字段填充设置 -----> <#if field.convert> @TableField(value = "${field.annotationColumnName}", fill = FieldFill.${field.fill}) <#else> @TableField(fill = FieldFill.${field.fill}) </#if> <#elseif field.convert> @TableField("${field.annotationColumnName}") </#if> <#-- 乐观锁注解 --> <#if (versionFieldName!"") == field.name> @Version </#if> <#-- 逻辑删除注解 --> <#if (logicDeleteFieldName!"") == field.name> @TableLogic </#if> private ${field.propertyType} ${field.propertyName}; </#list><#------------ END 字段循环遍历 ----------><#if !entityLombokModel> <#list table.fields as field> <#if field.propertyType == "boolean"> <#assign getprefix="is"/> <#else> <#assign getprefix="get"/> </#if> public ${field.propertyType} ${getprefix}${field.capitalName}() { return ${field.propertyName}; } <#if chainModel> public ${entity} set${field.capitalName}(${field.propertyType} ${field.propertyName}) { <#else> public void set${field.capitalName}(${field.propertyType} ${field.propertyName}) { </#if> this.${field.propertyName} = ${field.propertyName}; <#if chainModel> return this; </#if> } </#list></#if><#if entityColumnConstant> <#list table.fields as field> public static final String ${field.name?upper_case} = "${field.name}"; </#list></#if><#if activeRecord> @Override protected Serializable pkVal() { <#if keyPropertyName??> return this.${keyPropertyName}; <#else> return null; </#if> } </#if><#if !entityLombokModel> @Override public String toString() { return "${entity}{" + <#list table.fields as field> <#if field_index==0> "${field.propertyName}=" + ${field.propertyName} + <#else> ", ${field.propertyName}=" + ${field.propertyName} + </#if> </#list> "}"; } </#if>}
3、添加maven依赖
我选择使用freemarker作为模版引擎,所以需要引入freemarker依赖
<!--mybatis-plus 代码生成器 start--> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-generator</artifactId> <version>3.4.1</version> </dependency> <dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker</artifactId> <version>2.3.28</version> </dependency> <!--mybatis-plus 代码生成器 end-->
4、配置文件添加扫描xml位置以及实体类的位置
这个主要是为了让mapper(dao)跟xml文件里面的方法关联起来
mybatis-plus: #xml文件路径,多个路径有xml文件用逗号分隔 mapper-locations: classpath*:/mapper/**/*.xml #实体扫描,多个package用逗号或者分号分隔 typeAliasesPackage: com.example.springbootmybatisplus.entity
5、代码生成器启动类
import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;import com.baomidou.mybatisplus.core.toolkit.StringPool;import com.baomidou.mybatisplus.core.toolkit.StringUtils;import com.baomidou.mybatisplus.generator.AutoGenerator;import com.baomidou.mybatisplus.generator.InjectionConfig;import com.baomidou.mybatisplus.generator.config.*;import com.baomidou.mybatisplus.generator.config.po.TableInfo;import com.baomidou.mybatisplus.generator.config.rules.DateType;import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;import lombok.extern.slf4j.Slf4j;import java.util.ArrayList;import java.util.List;import java.util.Scanner;// 演示例子,执行 main 方法控制台输入模块表名回车自动生成对应项目目录中@Slf4jpublic class CodeGenerator { /** * <p> * 读取控制台内容 * </p> */ public static String scanner(String tip) { Scanner scanner = new Scanner(System.in); StringBuilder help = new StringBuilder(); help.append("请输入" + tip + ":"); System.out.println(help.toString()); if (scanner.hasNext()) { String ipt = scanner.next(); if (StringUtils.isNotBlank(ipt)) { return ipt; } } throw new MybatisPlusException("请输入正确的" + tip + "!"); } public static void main(String[] args) { // 代码生成器 AutoGenerator mpg = new AutoGenerator(); // 全局配置 GlobalConfig gc = new GlobalConfig(); String projectPath = System.getProperty("user.dir"); log.info("projectPath:{}",projectPath); gc.setOutputDir(projectPath + "/src/main/java"); gc.setAuthor("小旋风");//开发人员 gc.setOpen(false);//代码生成后,是否打开文件夹 gc.setSwagger2(true);// 实体属性 Swagger2 注解 gc.setFileOverride(false);//是否覆盖已有文件(true会覆盖 已经存在的文件) /** * 只使用 java.util.date 代替 */ gc.setDateType(DateType.ONLY_DATE); gc.setBaseColumnList(true);//开启 baseColumnList gc.setBaseResultMap(true);//开启 BaseResultMap mpg.setGlobalConfig(gc); // 数据源配置 DataSourceConfig dsc = new DataSourceConfig(); dsc.setUrl("jdbc:mysql://127.0.0.1:3308/test?useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&serverTimezone=Asia/Shanghai&useSSL=false"); // dsc.setSchemaName("public"); dsc.setDriverName("com.mysql.jdbc.Driver"); dsc.setUsername("root"); dsc.setPassword("999999999"); mpg.setDataSource(dsc); // 包配置 PackageConfig pc = new PackageConfig();// pc.setModuleName(scanner("模块名")); pc.setParent("com.example.springbootmybatisplus"); pc.setMapper("dao");//生产的mapper 放到dao目录下 mpg.setPackageInfo(pc); // 自定义配置 InjectionConfig cfg = new InjectionConfig() { @Override public void initMap() { // to do nothing } }; // 如果模板引擎是 freemarker String templatePath = "/my_template/my_entity_req.java.ftl";//多生成一个实体类,仅仅做参考,没有这个需求的,可以去掉 // 如果模板引擎是 velocity // String templatePath = "/templates/mapper.xml.vm"; String templatePathXml = "/templates/mapper.xml.ftl";//下面templateConfig.setXml(null); 自定义生成xml,默认的xml设置为null // 自定义输出配置 List<FileOutConfig> focList = new ArrayList<>(); // 自定义配置会被优先输出 focList.add(new FileOutConfig(templatePathXml) { @Override public String outputFile(TableInfo tableInfo) { // 自定义输出文件名 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!! return projectPath + "/src/main/resources/mapper/" + "/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML; } }); focList.add(new FileOutConfig(templatePath) { @Override public String outputFile(TableInfo tableInfo) { // 自定义输出文件名 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!! return projectPath + "/src/main/java/com/example/springbootmybatisplus/vo/" +tableInfo.getEntityName() + "Vo" + StringPool.DOT_JAVA; } }); /* cfg.setFileCreate(new IFileCreate() { @Override public boolean isCreate(ConfigBuilder configBuilder, FileType fileType, String filePath) { // 判断自定义文件夹是否需要创建 checkDir("调用默认方法创建的目录,自定义目录用"); if (fileType == FileType.MAPPER) { // 已经生成 mapper 文件判断存在,不想重新生成返回 false return !new File(filePath).exists(); } // 允许生成模板文件 return true; } }); */ cfg.setFileOutConfigList(focList); mpg.setCfg(cfg); // 配置模板 TemplateConfig templateConfig = new TemplateConfig(); // 配置自定义输出模板 //指定自定义模板路径,注意不要带上.ftl/.vm, 会根据使用的模板引擎自动识别 // templateConfig.setEntity("templates/entity2.java"); // templateConfig.setService(); // templateConfig.setController(); /** * 设置不生成 默认的xml,因为生成的位置会在 java文件夹下面, * 我想生成的xml放到resources.mapper文件夹下面, * 所以使用设置了自定义【templatePathXml】的模版去生成 */ templateConfig.setXml(null); mpg.setTemplate(templateConfig); // 策略配置 StrategyConfig strategy = new StrategyConfig(); strategy.setNaming(NamingStrategy.underline_to_camel); strategy.setColumnNaming(NamingStrategy.underline_to_camel);// strategy.setSuperEntityClass("你自己的父类实体,没有就不用设置!"); strategy.setEntityLombokModel(true); strategy.setRestControllerStyle(true); // 公共父类// strategy.setSuperControllerClass("你自己的父类控制器,没有就不用设置!"); // 写于父类中的公共字段// strategy.setSuperEntityColumns("id"); //没有父类公共字段的去掉 strategy.setInclude(scanner("表名,多个英文逗号分割").split(",")); strategy.setControllerMappingHyphenStyle(true); strategy.setTablePrefix(pc.getModuleName() + "_"); mpg.setStrategy(strategy); mpg.setTemplateEngine(new FreemarkerTemplateEngine()); mpg.execute(); } }
5、运行CodeGenerator类的main方法
在控制台输入要生成的表名【test_table】,下面是输出日志:
23:43:45.919 [main] INFO com.example.springbootmybatisplus.generator.CodeGenerator - projectPath:/Users/xkq/Downloads/it/xkq_git项目/springboot-example/springboot-mybatis-plus 请输入表名,多个英文逗号分割: test_table23:43:55.961 [main] DEBUG com.baomidou.mybatisplus.generator.AutoGenerator - ==========================准备生成文件...==========================23:43:56.555 [main] DEBUG com.baomidou.mybatisplus.generator.engine.AbstractTemplateEngine - 模板:/templates/mapper.xml.ftl; 文件:/Users/xkq/Downloads/it/xkq_git项目/springboot-example/springboot-mybatis-plus/src/main/resources/mapper//TestTableMapper.xml23:43:56.641 [main] DEBUG com.baomidou.mybatisplus.generator.engine.AbstractTemplateEngine - 模板:/templates/entity.java.ftl; 文件:/Users/xkq/Downloads/it/xkq_git项目/springboot-example/springboot-mybatis-plus/src/main/java/com/example/springbootmybatisplus/entity/TestTable.java23:43:56.643 [main] DEBUG com.baomidou.mybatisplus.generator.engine.AbstractTemplateEngine - 模板:/templates/mapper.java.ftl; 文件:/Users/xkq/Downloads/it/xkq_git项目/springboot-example/springboot-mybatis-plus/src/main/java/com/example/springbootmybatisplus/dao/TestTableMapper.java23:43:56.645 [main] DEBUG com.baomidou.mybatisplus.generator.engine.AbstractTemplateEngine - 模板:/templates/service.java.ftl; 文件:/Users/xkq/Downloads/it/xkq_git项目/springboot-example/springboot-mybatis-plus/src/main/java/com/example/springbootmybatisplus/service/ITestTableService.java23:43:56.646 [main] DEBUG com.baomidou.mybatisplus.generator.engine.AbstractTemplateEngine - 模板:/templates/serviceImpl.java.ftl; 文件:/Users/xkq/Downloads/it/xkq_git项目/springboot-example/springboot-mybatis-plus/src/main/java/com/example/springbootmybatisplus/service/impl/TestTableServiceImpl.java23:43:56.648 [main] DEBUG com.baomidou.mybatisplus.generator.engine.AbstractTemplateEngine - 模板:/templates/controller.java.ftl; 文件:/Users/xkq/Downloads/it/xkq_git项目/springboot-example/springboot-mybatis-plus/src/main/java/com/example/springbootmybatisplus/controller/TestTableController.java23:43:56.648 [main] DEBUG com.baomidou.mybatisplus.generator.AutoGenerator - ==========================文件生成完成!!!==========================
6、最终生成的效果图如下
7、测试生成的代码
写个查询方法,来测试一下
7.1、TestTableMapper.xml 添加getCustomOne方法
<?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.example.springbootmybatisplus.dao.TestTableMapper"> <!-- 通用查询映射结果 --> <resultMap id="BaseResultMap" type="com.example.springbootmybatisplus.entity.TestTable"> <id column="id" property="id" /> <result column="name" property="name" /> <result column="start_date" property="startDate" /> <result column="create_time" property="createTime" /> </resultMap> <!-- 通用查询结果列 --> <sql id="Base_Column_List"> id, name, start_date, create_time </sql> <select id="getCustomOne" resultMap="BaseResultMap" > select id, name, start_date, create_time from test_table limit 1 </select></mapper>
7.2、TestTableMapper.java 添加getCustomOne方法
import com.example.springbootmybatisplus.entity.TestTable;import com.baomidou.mybatisplus.core.mapper.BaseMapper;/** * <p> * 测试-表 Mapper 接口 * </p> * * @author 小旋风 * @since 2021-07-27 */public interface TestTableMapper extends BaseMapper<TestTable> { public TestTable getCustomOne(); }
7.3、编写接口进行测试
import com.baomidou.mybatisplus.core.metadata.IPage;import com.baomidou.mybatisplus.extension.plugins.pagination.Page;import com.example.springbootmybatisplus.dao.TestTableMapper;import com.example.springbootmybatisplus.entity.TestTable;import com.example.springbootmybatisplus.service.ITestTableService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.RestController;/** * <p> * 测试-表 前端控制器 * </p> * * @author 小旋风 * @since 2021-07-27 */@RestController@RequestMapping("/test-table")public class TestTableController { @Autowired private ITestTableService testTableService; @Autowired private TestTableMapper testTableMapper; @RequestMapping(value = "/getCustomOne",method = RequestMethod.GET) public TestTable getCustomOne(){ //这个方法主要是验证 mapper跟xml文件 关联上了,mapper-locations生效了 return testTableMapper.getCustomOne(); } @RequestMapping(value = "/page",method = RequestMethod.GET) public IPage<TestTable> page(){ Page<TestTable> page = new Page(); page.setSize(10); return testTableService.page(page); } }
7.4、访问接口
访问接口:http://127.0.0.1:9999/test-table/getCustomOne
日志输出如下:
Creating a new SqlSessionSqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@262025d3] was not registered for synchronization because synchronization is not active2021-07-27 23:53:18.981 INFO 55251 --- [nio-9999-exec-1] com.alibaba.druid.pool.DruidDataSource : {dataSource-1} initedJDBC Connection [com.mysql.jdbc.JDBC4Connection@30c4c95c] will not be managed by Spring==> Preparing: select id, name, start_date, create_time from test_table limit 1==> Parameters: <== Columns: id, name, start_date, create_time<== Row: 1, 你好, 2021-07-27, 2021-07-27 23:10:02.0<== Total: 1Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@262025d3]
日志输出无报错,浏览器上也看到返回结果了,说明代码生成器整合成功了~
三、集成swaager
上面的例子,不放整合swagger的代码了,毕竟spring boot整合mybaits plus需要配置的东西不多,放在一起有点乱,就单独拎出来写,集成swagger 是为了方便测试接口用。
1、pom.xml添加依赖:
<!--测试接口 添加swagger start--> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>2.6.1</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.6.1</version> </dependency> <!--测试接口 添加swagger end-->
2、配置SwaggerConfig
import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import springfox.documentation.builders.ApiInfoBuilder;import springfox.documentation.builders.PathSelectors;import springfox.documentation.builders.RequestHandlerSelectors;import springfox.documentation.service.ApiInfo;import springfox.documentation.spi.DocumentationType;import springfox.documentation.spring.web.plugins.Docket;import springfox.documentation.swagger2.annotations.EnableSwagger2;@Configuration@EnableSwagger2public class SwaggerConfig { private Boolean swaggerEnabled = true;//是否启用swagger 可以把配置放到配置文件 @Bean public Docket createRestApi() { return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) .enable(swaggerEnabled) .select() .apis(RequestHandlerSelectors.basePackage("com.example.springbootmybatisplus")) .paths(PathSelectors.any()) .build(); } private ApiInfo apiInfo() { return new ApiInfoBuilder() .title("接口文档") .description("spring boot整合mybatis plus~") .termsOfServiceUrl("https://www.cnblogs.com/x-kq/p/15068023.html") .version("6.6.6") .build(); } }
3、swagger访问地址
访问这个地址测试接口比较方便
http://127.0.0.1:9999/swagger-ui.html
代码我已经传到gitee了,有兴趣的可以clone,传送门
人生很多烦恼,是因为想得太多,做得太少
来源https://www.cnblogs.com/x-kq/p/15068023.html