使用idea 构建spring boot项目本身是非常方便的,而且十分快速。
本来数据持久层我是打算用mybatis的,然后用mybatis-generator生成dao和mapper,但是我最近知道了mybatis-plus这个东西。
mybatis-plus是国人开发的,不仅完全支持mybatis,而且还可以如mybatis-generator一样,自动生成model、dao、mapper,甚至更强大到可以生成service、serviceImpl、controller!!
mybatis-plus官方文档:https://mp.baomidou.com/
如果仅仅只简单使用mybatis-plus,可以只用写model类,然后dao继承它的basemapper类,就可以在spring中注入dao,确实非常方便。
但是我对它的代码生成器更感兴趣,于是看文档教程,配置文件赋值下来,修修改改,出错,再修改,以下是对官方配置文件的修改心得:
// 演示例子,执行 main 方法控制台输入模块表名回车自动生成对应项目目录中
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.isNotEmpty(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");
gc.setOutputDir(projectPath + "/src/main/java");
gc.setAuthor("jobob");
gc.setOpen(false);
// gc.setSwagger2(true); 实体属性 Swagger2 注解
mpg.setGlobalConfig(gc);
// 数据源配置
DataSourceConfig dsc = new DataSourceConfig();
dsc.setUrl("jdbc:mysql://localhost:3306/ant?useUnicode=true&useSSL=false&characterEncoding=utf8");
// dsc.setSchemaName("public");
dsc.setDriverName("com.mysql.jdbc.Driver");
dsc.setUsername("root");
dsc.setPassword("密码");
mpg.setDataSource(dsc);
// 包配置
PackageConfig pc = new PackageConfig();
pc.setModuleName(scanner("模块名"));
pc.setParent("com.baomidou.ant");
mpg.setPackageInfo(pc);
// 自定义配置
InjectionConfig cfg = new InjectionConfig() {
@Override
public void initMap() {
// to do nothing
}
};
// 如果模板引擎是 freemarker
String templatePath = "/templates/mapper.xml.ftl";
// 如果模板引擎是 velocity
// String templatePath = "/templates/mapper.xml.vm";
// 自定义输出配置
List<FileOutConfig> focList = new ArrayList<>();
// 自定义配置会被优先输出
focList.add(new FileOutConfig(templatePath) {
@Override
public String outputFile(TableInfo tableInfo) {
// 自定义输出文件名 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!!
return projectPath + "/src/main/resources/mapper/" + pc.getModuleName()
+ "/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
}
});
/*
cfg.setFileCreate(new IFileCreate() {
@Override
public boolean isCreate(ConfigBuilder configBuilder, FileType fileType, String filePath) {
// 判断自定义文件夹是否需要创建
checkDir("调用默认方法创建的目录");
return false;
}
});
*/
cfg.setFileOutConfigList(focList);
mpg.setCfg(cfg);
// 配置模板
TemplateConfig templateConfig = new TemplateConfig();
// 配置自定义输出模板
//指定自定义模板路径,注意不要带上.ftl/.vm, 会根据使用的模板引擎自动识别
// templateConfig.setEntity("templates/entity2.java");
// templateConfig.setService();
// templateConfig.setController();
templateConfig.setXml(null);
mpg.setTemplate(templateConfig);
// 策略配置
StrategyConfig strategy = new StrategyConfig();
strategy.setNaming(NamingStrategy.underline_to_camel);
strategy.setColumnNaming(NamingStrategy.underline_to_camel);
strategy.setSuperEntityClass("com.baomidou.ant.common.BaseEntity");
strategy.setEntityLombokModel(true);
strategy.setRestControllerStyle(true);
// 公共父类
strategy.setSuperControllerClass("com.baomidou.ant.common.BaseController");
// 写于父类中的公共字段
strategy.setSuperEntityColumns("id");
strategy.setInclude(scanner("表名,多个英文逗号分割").split(","));
strategy.setControllerMappingHyphenStyle(true);
strategy.setTablePrefix(pc.getModuleName() + "_");
mpg.setStrategy(strategy);
mpg.setTemplateEngine(new FreemarkerTemplateEngine());
mpg.execute();
}
}
对配置文件修改:其实在使用mybatis-plus时,只要你dao继承了basemapper,就可以不用mapper.xml配置文件。
这里有个坑,如果使用官方文档对mapper.xml的生成配置的话,需要使用模板,但是模板不好找,我从网上看到说可以从源码中找到,但是没找到。所以如果报错,就不要使用任何自定义模板相关的配置,就使用默认的。
所以对主要修改为以下类容:
- 生成文件存放的路径
- 数据库4连配(驱动,url,账号,密码)
- 取消mapper.xml生成
final static String dirPath = "D:\\mybatis\\src"; //这里是生成的文件要存放的路径
/**
* <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.isNotEmpty(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"); // 官方文档默认是在CodeGenerator 所在项目中生成代码,我这里改成我所指定的路径
// gc.setOutputDir(projectPath + "/src/main/java");
gc.setOutputDir(dirPath); //改为我指定的路径
gc.setAuthor("baima46"); //设置作者,这样会在生成的类上增加相关的注释
gc.setOpen(true); //设置文件生成后打开文件夹
// gc.setSwagger2(true); 实体属性 Swagger2 注解
mpg.setGlobalConfig(gc);
// 数据源配置
DataSourceConfig dsc = new DataSourceConfig();
dsc.setUrl("jdbc:mysql://172.0.0.1:3306/baima46"); // 数据库url,必改!!!!
// dsc.setSchemaName("public");
dsc.setDriverName("com.mysql.cj.jdbc.Driver"); //驱动,我这里用的是MySQL8.0,所以要加cj
dsc.setUsername("root"); //账号,必改!!!!!!
dsc.setPassword("123456"); //密码,必改!!!
mpg.setDataSource(dsc);
// 包配置
PackageConfig pc = new PackageConfig();
// pc.setModuleName(scanner("模块名"));
pc.setParent("com");
pc.setController("controller");
pc.setEntity("entity");
pc.setMapper("mapper");
pc.setService("service");
pc.setServiceImpl("service.Impl");
mpg.setPackageInfo(pc);
// 自定义配置
InjectionConfig cfg = new InjectionConfig() {
@Override
public void initMap() {
// to do nothing
}
};
// 如果模板引擎是 freemarker
// String templatePath = "/templates/mapper.xml.ftl";
// 如果模板引擎是 velocity
String templatePath = "/templates/mapper.xml.vm";
// 自定义输出配置
List<FileOutConfig> focList = new ArrayList<>();
// 自定义配置会被优先输出
/* focList.add(new FileOutConfig(templatePath) {
@Override
public String outputFile(TableInfo tableInfo) {
// 自定义输出文件名 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!!
return projectPath + "/src/main/resources/mapper/" + pc.getModuleName()
+ "/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
}
});*/
/* cfg.setFileCreate(new IFileCreate() {
@Override
public boolean isCreate(ConfigBuilder configBuilder, FileType fileType, String filePath) {
// 判断自定义文件夹是否需要创建
checkDir("调用默认方法创建的目录");
return false;
}
});*/
// cfg.setFileOutConfigList(focList); // 这里我把自定义相关的配置不加入总配置里,这样就不会使用官方文档中配置的自定义模板配置的东西
mpg.setCfg(cfg);
// 配置模板
TemplateConfig templateConfig = new TemplateConfig();
// 配置自定义输出模板
//指定自定义模板路径,注意不要带上.ftl/.vm, 会根据使用的模板引擎自动识别
// templateConfig.setEntity("templates/entity2.java");
// templateConfig.setService();
// templateConfig.setController();
templateConfig.setXml(null);
mpg.setTemplate(templateConfig);
// 策略配置
StrategyConfig strategy = new StrategyConfig();
strategy.setNaming(NamingStrategy.underline_to_camel);
strategy.setColumnNaming(NamingStrategy.underline_to_camel);
// strategy.setSuperEntityClass("com.model.BaseEntity");
strategy.setEntityLombokModel(true);
strategy.setRestControllerStyle(true);
// 公共父类
// strategy.setSuperControllerClass("com.controller.BaseController");
// 写于父类中的公共字段
strategy.setSuperEntityColumns("id");
strategy.setInclude(scanner("表名,多个英文逗号分割").split(","));
strategy.setControllerMappingHyphenStyle(true);
// strategy.setTablePrefix(pc.getModuleName() + "_");
mpg.setStrategy(strategy);
mpg.setTemplateEngine(new FreemarkerTemplateEngine());
mpg.execute();
}
以上文件赋值下来,只需要改一下生成代码存放的路径,以及数据库4连配,应该是可以运行成功的。(注意官方除了要导入mybatis-plus相关的包,还要spring 相关的包)
运行成功后,控制台要求你输入要生成的表名,我这里输入一个user,生成的文件如下:
但是,这样生成的类,都是空壳,controller和service都是只有类名,继承基类,类中没有任何东西:(当然实体类是有东西的,而且会生成属性注释)
其实到这里已经很不错了,因为其实mybatis-plus在BaseMapper以及IService类中封装了大量常用的增删改查功能,到这里其实我们只用写一下controller,就可以使用了。
但当时我不满足于此,希望controller也给我生成了,因为网上一啪啦的说自动生成controller,我就想看看它到底如何生成。
然后我又了解到,如果要生成controller,就必须使用自定义模板,而官方没有默认模板。
于是我又了解什么是模板,mybatis-plus支持 Velocity(默认)、Freemarker、Beetl。
当时我不了解,然后看到网上一篇博文,说什么mybatis-plus还可以生成jsp文件(当然后来我理解到,确实可以),然后当时我就以为使用模板是生成表示层。
然后我还百度了为什么mybatis-plus不支持生成jsp,然就看到那篇生成jsp的博文。然后看了觉得乱七八糟,仅有一堆配置,照着改完全没用。
当时我还想那就不用jsp,用这三个代替jsp来表示吧,然后就网上搜了下三个的型男对比,看了一会儿,没看了,还是继续弄配置。
又是一啪啦的百度,无果,最后终于找到一篇博客:https://blog.csdn.net/gfl1427097103/article/details/91443861
这篇博客让我了解到,原来自定义模板是用来生成controller等文件的,而且需要自己提供。
于是我下了他的模板,然后修改,我的配置,运行,果不其然,总是提示我mapper.java.vm找不到。
明明我指定了mapper.java.vm的路径啊!!
后来我试了半天才发现,mapper.java.vm等模板文件,必须放置项目的resource下的templates文件夹下。
改了之后,终于生成文件了!!!
重点来了,生成的文件复制进spring boot项目后,疯狂报错,各种飘红。
因为原作者在自定义模板中,定义了他们公司特有的工具包,而他在下载文件中并没有提供。(大坑)。
怎么办?
只有手动改模板文件。或者自己创建那些类。
又是大量时间修改模板文件,删删改改,测试生成,最后终于不飘红了。
但是在运行的时候,spring总是提示找不到BaseMapper,注入失败。
我这个问题困扰了我很久,命名我在另一个空白项目,然后我赶紧用官方默认生成的代码,运行,成功!
于是我又将模板生成的代码,复制到那个空白项目中,运行,成功!!
这下我彻底懵逼了,同样的代码,一个运行成功,一个运行失败。。。
最后我忽然想起,在我测试Generator的时候,也总是提示找不到mapper.java.vm,明明那个时候我已经将mapper.java.vm复制到resource下的templates文件夹中。
然后一通百度,各种方法试过,无果,最后偶然发现一个回复:
重启idea。
然后我重启了,再次运行,成功,MD,谁能想到这是编译器的锅!!
有此经历,在整合过程中疯狂报莫名其妙的编译错误,什么java找不到符号,最后我重启了idea(清理maven也可以)。
成功!!
我的天,这些该死的配置、整合真的是太浪费时间了。
不过收获也是巨大的,首先是对spring boot的熟悉,对mybatis-plus的熟悉,同时学会使用自定义模板生成代码,这样在以后的开发中,会更加快捷。
最后,总结一下mybatis-plus代码生成器的坑:
**
1.使用默认生成的代码!!!!
1.使用默认生成的代码!!!!
1.使用默认生成的代码!!!!
**
默然生成的代码包括实体类、dao、service,这些都是可以用的,只用写controller,如有复杂业务,在service添加业务即可。
使用自定义模板太麻烦了,当然,有大佬带当我没说。