Spring Boot 应用 Mybatis-plus 和它的代码生成器
这篇文章第一局部解说 Mybatis-plus 的应用。点上面的链接可返回官网。
但要留神的是。应用它仅是为了疾速开发,因为 sql 优化的第一点就是 sql 语句里的 select 不应间接写 * 也就是查找全副,而是应该写上每一个要用的字段。
第二局部写 Mybatis-plus 里的代码生成器,首先代码生成的代码实际上间接用 Mybatis-plus 官网里的范例就能够了,但要把生成的代码变成本人想要的样子,还是须要本人批改模板代码,所以这篇文章会展现出我当初应用的模板。
文章目录:
- Mybatis-Plus 应用
- 代码生成器
Mybatis-Plus 应用
pom.xml 中所需增加的依赖
// Mybatis-Plus 的包
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.1.tmp</version>
</dependency>
// 代码结构器的包
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.3.1.tmp</version>
</dependency>
// 应用的页面模板是 freemarker
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.30</version>
</dependency>
// lombok 的包,倡议下载插件,不下载插件代码会带红,但能够运行
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
// 应用 pagehelper 来分页,Mybatis-plus 有分页的 Api,应用与否看本人
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.10</version>
</dependency>
// 如果打算应用 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>
上面是我的项目构造和代码 其中 exception,config,until 不是波及这篇教程
Application.java
@EnableCaching
// 扫描 mapper 文件夹
@MapperScan("com.generator.mapper")
@SpringBootApplication
public class GeneratorApplication {public static void main(String[] args) {SpringApplication.run(GeneratorApplication.class, args);
}
}
实体类 entity
@Data
// 这个如果是 true 的话在 equal 时要思考其父类,因为这个类是没父类的所以为 false
// 我倡议这个中央大家去理解以下,和 equals() 这个办法无关,波及到父类与子类的.equals()
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
// 上面这个注解是 swagger 的
@ApiModel(value="UserInfo 对象", description="")
public class UserInfo implements Serializable {
private static final long serialVersionUID = 1L;
// 上面这个是 Mybatis-Plus 的注解,主键申明,主动增长
@TableId(value = "user_id", type = IdType.AUTO)
private Integer userId;
private String pwd;
private String userName;
private String userRealName;
private String telephone;
// swagger 注解
@ApiModelProperty(value = "用户职业")
private String userPro;
}
service 包下的
// 此处须要继承 IService<Entity>,来取得 Mybatis-plus 里的办法。// 这里其实是能够不必写上面这些,因为 Mybatis-plus 外部就有相应的 select 这些办法,相干请本人看官网文档
// 但我还是倡议用本人设计的办法,可调用性更高
public interface IUserInfoService extends IService<UserInfo> {
/**
* 查找 userInfo
* @param userInfo
* @param pageStart
* @param pageSize
* @return
*/
List<UserInfo> findUserInfo(UserInfo userInfo, Integer pageStart, Integer pageSize);
/**
* 增加 userInfo
* @param userInfo
* @return
*/
int insertUserInfo(UserInfo userInfo);
/**
* 批改 userInfo
* @param userInfo
* @return
*/
int updateUserInfo(UserInfo userInfo);
/**
* 删除 userInfo
* @param id
* @return
*/
int deleteUserInfo(int id);
}
service 包里的 impl 文件夹下
// 申明是一个 Service 服务类,继承 ServiceImpl<Entity> 应用 Mybatis-plus 里的办法
// 实现 IUserInfoService 里申明的接口
@Service
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements IUserInfoService {
@Autowired
private UserInfoMapper userInfoMapper;
@Override
public List<UserInfo> findUserInfo(UserInfo userInfo, Integer pageStart, Integer pageSize) {
/*
这个是调用 QueryWrapper 里的 eq 这类的办法来本人构建一个 sql 语句
QueryWrapper<UserInfo> queryWrapper=new QueryWrapper<>();
queryWrapper.eq("userName",userInfo.getUserName());
*/
// 应用 QueryWrapper 条件结构器,此处是将对象间接存入,还有别的应用办法,外面间接依据状况调用 eq 这些 api 命令
QueryWrapper<UserInfo> queryWrapper=new QueryWrapper<>(userInfo);
// 应用 pagehelper 来分页
PageHelper.startPage(pageStart,pageSize);
// 调用 ServiceImpl 里的 selectList 办法
return userInfoMapper.selectList(queryWrapper);
}
@Override
public int insertUserInfo(UserInfo userInfo) {return userInfoMapper.insert(userInfo);
}
@Override
public int updateUserInfo(UserInfo userInfo) {return userInfoMapper.updateById(userInfo);
}
@Override
public int deleteUserInfo(int id) {return userInfoMapper.deleteById(id);
}
}
mapper 文件夹下
// 申明是一个接口, 继承 BaseMapper<Entity>
@Repository
public interface UserInfoMapper extends BaseMapper<UserInfo> {// 此处加自定义的 mapper}
resources 下的 mapper 文件夹
<?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.generator.mapper.UserInfoMapper">
</mapper>
controller 文件夹下
// swagger 注解
@Api(tags = "UserInfoController", description = "用户治理")
@RestController
@RequestMapping("/user-info")
public class UserInfoController {
// 这里我是以接口来申明一个变量,可间接应用 service 来申明
@Autowired
private IUserInfoService userInfoService;
// swagger 注解
@ApiOperation("查问用户")
@RequestMapping(value = "/list", method = RequestMethod.GET)
public RespBody findUserInfo(UserInfo userInfo,
@RequestParam(value = "pageStart",defaultValue = "1")Integer pageStart,
@RequestParam(value = "pageSize", defaultValue = "10")Integer pageSize){List<UserInfo> userInfoList = userInfoService.findUserInfo(userInfo, pageStart, pageSize);
// pagehelper 的返回类
PageInfo<UserInfo> pageInfo = new PageInfo<>(userInfoList);
return RespBody.ok(pageInfo);
}
@ApiOperation("增加用户")
@RequestMapping(value = "/insert", method = RequestMethod.POST)
public RespBody insertUserInfo(UserInfo userInfo) {int result = userInfoService.insertUserInfo(userInfo);
if (result == 1) {return RespBody.ok();
}
return RespBody.error();}
@ApiOperation("批改用户")
@RequestMapping(value = "/update", method = RequestMethod.POST)
public RespBody updateUserInfo(UserInfo userInfo) {int result = userInfoService.updateUserInfo(userInfo);
if (result == 1) {return RespBody.ok();
}
return RespBody.error();}
@ApiOperation("删除用户")
@RequestMapping(value = "/delete", method = RequestMethod.POST)
public RespBody updateUserInfo(@RequestParam("id")int id) {int result = userInfoService.deleteUserInfo(id);
if (result == 1) {return RespBody.ok();
}
return RespBody.error();}
}
到此,下面就是应用我设计模板生成的相应代码了
我的 Mybatis-plus 代码生成器
代码
// 做出了一些批改,但总体上与官网里的代码雷同
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");
// 输入的门路
gc.setOutputDir(projectPath + "/src/main/java");
// 作者
gc.setAuthor("dell");
gc.setOpen(false);
// 是否应用实体属性 Swagger2 注解
gc.setSwagger2(true);
mpg.setGlobalConfig(gc);
// mysql 数据源配置
DataSourceConfig dsc = new DataSourceConfig();
dsc.setUrl("jdbc:mysql://localhost:3306/mall?serverTimezone=GMT%2B8&characterEncoding=UTF-8");
dsc.setDriverName("com.mysql.cj.jdbc.Driver");
dsc.setUsername("root");
dsc.setPassword("*****");
mpg.setDataSource(dsc);
// 包配置
PackageConfig pc = new PackageConfig();
// pc.setModuleName(scanner("模块名")); 示例中有一个输出模块名的步骤,我舍去了
// 设置前缀名
pc.setParent("com.generator");
mpg.setPackageInfo(pc);
String myName = scanner("数据名:例(userInfo)");
String myTitle = scanner("模块名:例(用户)");
// 自定义配置
InjectionConfig cfg = new InjectionConfig() {
@Override
public void initMap() {// 可看作设置了几个全局量,用于将本人模板生成的形容更好,在模板中的应用办法 ${cfg.myName}
Map<String, Object> map = new HashMap<>();
map.put("myName", myName);
map.put("myTitle", myTitle);
this.setMap(map);
}
};
// 如果模板引擎是 freemarker
String templatePath = "/templates/mapper.xml.ftl";
// 自定义输入配置
List<FileOutConfig> focList = new ArrayList<>();
// 自定义配置会被优先输入
focList.add(new FileOutConfig(templatePath) {
@Override
public String outputFile(TableInfo tableInfo) {
// 这里是 resources 里的 mapper.xml
return projectPath + "/src/main/resources/mapper/"
+ tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;}
});
cfg.setFileOutConfigList(focList);
mpg.setCfg(cfg);
// 配置模板
TemplateConfig templateConfig = new TemplateConfig();
// 配置自定义输入模板, 不写上面的代码就是应用默认的模板输入。// 模板地位找到 mybatis-plus-generator 包关上 templates,上面还会有一张图
templateConfig.setService("templates/service2.java");
templateConfig.setController("templates/controller2.java");
templateConfig.setServiceImpl("templates/serviceImpl2.java");
templateConfig.setMapper("templates/mapper2.java");
// 如果向生成的 xml 里也有代码设置门路,我没有设置
templateConfig.setXml(null);
mpg.setTemplate(templateConfig);
// 策略配置,骆峰这类的设置
StrategyConfig strategy = new StrategyConfig();
strategy.setNaming(NamingStrategy.underline_to_camel);
strategy.setColumnNaming(NamingStrategy.underline_to_camel);
// 抉择是否有父类实体
String ipt = scanner("请输出是否抉择父类实体,1 为没有,否则请输出父类");
if (!("1".equals(ipt))) {
// 设置父类实体
strategy.setSuperEntityClass(ipt);
}
// 是否应用 Lombok 的形式
strategy.setEntityLombokModel(true);
// 是否应用 RestController
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();}
}
默认模板地位
运行示例
最初放上模板代码
将模板放入 resources 下的 templates 里
controller2.java.ftl
package ${package.Controller};
// 这个中央请本人改变,改成本人的门路
import com.generator.entity.RespBody;
import com.generator.entity.${entity};
import com.generator.service.${table.serviceName};
import com.github.pagehelper.PageInfo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
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 java.util.List;
<#if restControllerStyle>
import org.springframework.web.bind.annotation.RestController;
<#else>
import org.springframework.stereotype.Controller;
</#if>
<#if superControllerClassPackage??>
import ${superControllerClassPackage};
</#if>
/**
* <p>
* ${table.comment!} 前端控制器
* </p>
*
* @author ${author}
* @since ${date}
*/
@Api(tags = "${table.controllerName}", description = "${cfg.myTitle} 治理")
<#if restControllerStyle>
@RestController
<#else>
@Controller
</#if>
@RequestMapping("<#if package.ModuleName??>/${package.ModuleName}</#if>/<#if controllerMappingHyphenStyle??>${controllerMappingHyphen}<#else>${table.entityPath}</#if>")
<#if kotlin>
class ${table.controllerName}<#if superControllerClass??> : ${superControllerClass}()</#if>
<#else>
<#if superControllerClass??>
public class ${table.controllerName} extends ${superControllerClass} {
<#else>
public class ${table.controllerName} {
</#if>
@Autowired
private ${table.serviceName} ${cfg.myName}Service;
@ApiOperation("查问 ${cfg.myTitle}")
@RequestMapping(value = "/list", method = RequestMethod.GET)
public RespBody find${entity}(${entity} ${cfg.myName},
@RequestParam(value = "pageStart",defaultValue = "1")Integer pageStart,
@RequestParam(value = "pageSize", defaultValue = "10")Integer pageSize){List<${entity}> ${cfg.myName}List = ${cfg.myName}Service.find${entity}(${cfg.myName}, pageStart, pageSize);
PageInfo<${entity}> pageInfo = new PageInfo<>(${cfg.myName}List);
return RespBody.ok(pageInfo);
}
@ApiOperation("增加 ${cfg.myTitle}")
@RequestMapping(value = "/insert", method = RequestMethod.POST)
public RespBody insert${entity}(${entity} ${cfg.myName}) {int result = ${cfg.myName}Service.insert${entity}(${cfg.myName});
if (result == 1) {return RespBody.ok();
}
return RespBody.error();}
@ApiOperation("批改 ${cfg.myTitle}")
@RequestMapping(value = "/update", method = RequestMethod.POST)
public RespBody update${entity}(${entity} ${cfg.myName}) {int result = ${cfg.myName}Service.update${entity}(${cfg.myName});
if (result == 1) {return RespBody.ok();
}
return RespBody.error();}
@ApiOperation("删除 ${cfg.myTitle}")
@RequestMapping(value = "/delete", method = RequestMethod.DELETE)
public RespBody update${entity}(@RequestParam("id")int id) {int result = ${cfg.myName}Service.delete${entity}(id);
if (result == 1) {return RespBody.ok();
}
return RespBody.error();}
}
</#if>
service2.java.ftl
package ${package.Service};
import ${package.Entity}.${entity};
import ${superServiceClassPackage};
import java.util.List;
/**
* <p>
* ${table.comment!} 服务类
* </p>
*
* @author ${author}
* @since ${date}
*/
<#if kotlin>
interface ${table.serviceName} : ${superServiceClass}<${entity}>
<#else>
public interface ${table.serviceName} extends ${superServiceClass}<${entity}> {
/**
* 查找 ${cfg.myName}
* @param ${cfg.myName}
* @param pageStart
* @param pageSize
* @return
*/
List<${entity}> find${entity}(${entity} ${cfg.myName}, Integer pageStart, Integer pageSize);
/**
* 增加 ${cfg.myName}
* @param ${cfg.myName}
* @return
*/
int insert${entity}(${entity} ${cfg.myName});
/**
* 批改 ${cfg.myName}
* @param ${cfg.myName}
* @return
*/
int update${entity}(${entity} ${cfg.myName});
/**
* 删除 ${cfg.myName}
* @param id
* @return
*/
int delete${entity}(int id);
}
</#if>
serviceImpl2.java.ftl
package ${package.ServiceImpl};
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
import ${package.Entity}.${entity};
import ${package.Mapper}.${table.mapperName};
import ${package.Service}.${table.serviceName};
import ${superServiceImplClassPackage};
import org.springframework.stereotype.Service;
/**
* <p>
* ${table.comment!} 服务实现类
* </p>
*
* @author ${author}
* @since ${date}
*/
@Service
<#if kotlin>
open class ${table.serviceImplName} : ${superServiceImplClass}<${table.mapperName}, ${entity}>(), ${table.serviceName} {
}
<#else>
public class ${table.serviceImplName} extends ${superServiceImplClass}<${table.mapperName}, ${entity}> implements ${table.serviceName} {
@Autowired
private ${table.mapperName} ${cfg.myName}Mapper;
@Override
public List<${entity}> find${entity}(${entity} ${cfg.myName}, Integer pageStart, Integer pageSize) {
// 这里依据具体的条件进行裁减
QueryWrapper<${entity}> queryWrapper=new QueryWrapper<>(${cfg.myName});
PageHelper.startPage(pageStart,pageSize);
return ${cfg.myName}Mapper.selectList(queryWrapper);
}
@Override
public int insert${entity}(${entity} ${cfg.myName}) {return ${cfg.myName}Mapper.insert(${cfg.myName});
}
@Override
public int update${entity}(${entity} ${cfg.myName}) {return ${cfg.myName}Mapper.updateById(${cfg.myName});
}
@Override
public int delete${entity}(int id) {return ${cfg.myName}Mapper.deleteById(id);
}
}
</#if>
mapper2.java.ftl
package ${package.Mapper};
import ${package.Entity}.${entity};
import ${superMapperClassPackage};
import org.springframework.stereotype.Repository;
/**
* <p>
* ${table.comment!} Mapper 接口
* </p>
*
* @author ${author}
* @since ${date}
*/
<#if kotlin>
interface ${table.mapperName} : ${superMapperClass}<${entity}>
<#else>
@Repository
public interface ${table.mapperName} extends ${superMapperClass}<${entity}> {
}
</#if>
更近一步,相干 api 的应用还是要看官网文档 Mybatis-plus 才能够。