先创建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: 9999
spring:
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")
@SpringBootApplication
public class SpringbootMybatisPlusApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootMybatisPlusApplication.class, args);
}
}
4、编码,写例子测试
4.1、 编写实体类 User.java
@Data
public 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: default
2021-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 WebApplicationContext
2021-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 refreshed
2021-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 references
2021-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 ms
2021-07-27 22:52:45.023 INFO 23542 --- [nio-9999-exec-7] c.e.s.controller.TestController : selectById start
2021-07-27 22:52:45.067 INFO 23542 --- [nio-9999-exec-7] com.alibaba.druid.pool.DruidDataSource : {dataSource-1} inited
2021-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 end
2021-07-27 22:53:38.385 INFO 23542 --- [nio-9999-exec-9] c.e.s.controller.TestController : selectPage start
2021-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: default
2021-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 WebApplicationContext
2021-07-27 22:57:57.966 INFO 26426 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 941 ms
Logging 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 refreshed
2021-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 references
2021-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 ms
2021-07-27 22:58:04.044 INFO 26426 --- [nio-9999-exec-1] c.e.s.controller.TestController : selectById start
Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6ca5a623] was not registered for synchronization because synchronization is not active
2021-07-27 22:58:04.087 INFO 26426 --- [nio-9999-exec-1] com.alibaba.druid.pool.DruidDataSource : {dataSource-1} inited
JDBC 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: 1
Closing 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 end
2021-07-27 22:58:09.794 INFO 26426 --- [nio-9999-exec-2] c.e.s.controller.TestController : selectPage start
Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@28b417c9] was not registered for synchronization because synchronization is not active
JDBC 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: 5
Closing 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方式
@Configuration
public 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 start
Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6acc6ecd] was not registered for synchronization because synchronization is not active
JDBC 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: 2
Closing 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 方法控制台输入模块表名回车自动生成对应项目目录中
@Slf4j
public 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_table
23: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.xml
23: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.java
23: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.java
23: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.java
23: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.java
23: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.java
23: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 SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@262025d3] was not registered for synchronization because synchronization is not active
2021-07-27 23:53:18.981 INFO 55251 --- [nio-9999-exec-1] com.alibaba.druid.pool.DruidDataSource : {dataSource-1} inited
JDBC 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: 1
Closing 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
@EnableSwagger2
public 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