上一篇博文,主要对后端系统进行了整体的一个介绍,以及后面的演化方向。前面提到过在后端中持久层采用的框架的是mybatis-plus,所以这里就介绍一下mybatis-plus以及它里面代码生成器和其他插件的使用。
如果你会使用mybatis,那么我相信mybatis-plus将会变得很容易,当然如果不了解mybatis那么请先去了解mybatis,因为mybatis-plus是mybatis的增强。
先说一下他的基本使用吧。mybatis-plus在项目的中的使用可以参考官网中快速开始的例子, 不过这个例子并不是写的很完整,所以我就在官网中的例子的基础上把他补全吧。把这例子看完后,我觉得就可以在项目中直接使用了。
这里直接使用官网的:
DROP TABLE IF EXISTS user;
CREATE TABLE user
(
id INT 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)
);
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.2.4.RELEASEversion>
<relativePath/>
parent>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starterartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>com.baomidougroupId>
<artifactId>mybatis-plus-boot-starterartifactId>
<version>3.3.0version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<scope>runtimescope>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>druid-spring-boot-starterartifactId>
<version>1.1.21version>
dependency>
dependencies>
这里直接在application.yml中进行配置
spring:
# DataSource druid Config
datasource:
username: root
password: you_parssword
url: jdbc:mysql://localhost:3306/myadmin_db?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Hongkong
driver-class-name: com.mysql.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
#mybatis-plus配置
mybatis-plus:mapping包下
#mapper.xml文件位置,放在项目中的mapping包下
mapper-locations: classpath:com/myadminmain/**/mapping/*.xml
configuration:
#下划线大写转换,这个官网中的配置说是默认开启的,所以不加也行
map-underscore-to-camel-case: true
添加 @MapperScan
注解,Mapper 文件扫描,当然如果不添加也行,不过你要在每个mapper接口中添加@Mapper
注解。所以还是建议使用@MapperScan
注解,@MapperScan
注解可以添加在启动类中,也可以添加在mybatis-plus的配置类中。推荐加到配置类上,不过这里为了好演示就直接加到启动类中了
@SpringBootApplication
@MapperScan(basePackages = {"com.myadminmain.modular.*.dao","com.myadminmain.sys.*.dao"})
public class MyadminMainApplication {
public static void main(String[] args) {
SpringApplication.run(MyadminMainApplication.class, args);
}
}
@TableName("user")
public class User {
// id 使用数据库自增
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@TableField("name")
private String name;
@TableField("age")
private Integer age;
@TableField("email")
private String email;
//get和set方法省略,当然有可能像官网中那样使用lombok,来自动添加get和set方法
}
这里如果数据库中的字段名和代码中的属性名一致,注解可以不用添加,但是在不一致的时候必须添加
@RestController
@RequestMapping("/user")
public class UserController{
@Autowired
private UserService userService;
/**
* 功能描述: 查询所有用户
* @param
* @return java.util.List
* @author cdfan
* @date 2020-03-22
*/
@RequestMapping(value="/userInfo", method= RequestMethod.GET)
public List<User> list() {
return userService.userList();
}
/**
* 功能描述: 根据主键查询用户,这里直接调用mybatis-plus提供的方法
* @param userId
* @return com.myadminmain.sys.user.entity.User
* @author cdfan
* @date 2020-03-22
*/
@RequestMapping(value="/userInfo/{userId}", method= RequestMethod.GET)
public User get(@PathVariable("userId") Integer userId) {
return userService.getById(userId);
}
/**
* 功能描述: 根据用户名,查询用户
* @param name
* @return java.util.List
* @author cdfan
* @date 2020-03-22
*/
@RequestMapping(value="/getUserByName", method= RequestMethod.GET)
public List<User> getUserByName(@RequestParam(value = "name", required = false) String name) {
return userService.getUserByName(name);
}
}
public interface UserService extends IService<User> {
/**
* 功能描述: 查询所有用户
* @param
* @return java.util.List
* @author cdfan
* @date 2020-03-22
*/
List<User> userList();
/**
* 功能描述: 根据用户名,查询用户
* @param name
* @return java.util.List
* @author cdfan
* @date 2020-03-22
*/
List<User> getUserByName(String name);
}
这里一定要继承mybatis-plus提供的IService接口并指定我们的实体类型,在这个接口中提供类很多他为我们写好的接口方法,所以继承后我们其实在Controller中就可以直接调用mybatis-plus为我们提供的方法了
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
@Override
public List<User> userList() {
return this.list();
}
@Override
public List<User> getUserByName(String name) {
return this.baseMapper.getUserByName(name);
}
}
这里实现类也要继承mybatis-plus提供的ServiceImpl类并指定mapper类以及实体类的泛型。这样在我们的service实现类里面就可以直接使用ServiceImpl中定义的接口方法了,当我们要调用我们自己定义的mapper中的接口方法,我们可以通过this.baseMapper.xxx()
来调用。其实我们点击去看源码可以发现,ServiceImpl他是实现了IService的,而我们使用的baseMapper其实就是我们传入mapper类,这样我们就可以使用baseMapper来调用我们自己的mapper接口方法了,当然baseMapper还可以调用mybatis-plus提供的方法
//ServiceImpl部分源码
public class ServiceImpl<M extends BaseMapper<T>, T> implements IService<T> {
protected Log log = LogFactory.getLog(getClass());
@Autowired
protected M baseMapper;
}
public interface UserMapper extends BaseMapper<User> {
/**
* 功能描述: 根据用户名,查询用户
* @param name
* @return java.util.List
* @author cdfan
* @date 2020-03-22
*/
List<User> getUserByName(@Param("name") String name);
}
从上面的service实现类中的源码中可以看出,他要求传入的mapper必须要是一个继承了BaseMapper的mapper,所以我们定义自己的mapper的时候需要继承BaseMapper并指定对应的泛型类。
<mapper namespace="com.myadminmain.sys.user.dao.UserMapper">
<resultMap id="BaseResultMap" type="com.myadminmain.sys.user.entity.User">
<id column="id" property="id" />
<result column="name" property="name" />
<result column="age" property="age" />
<result column="email" property="email" />
resultMap>
<select id="getUserByName" resultMap="BaseResultMap">
SELECT u.id,u.name,u.age,r.email
FROM user u
WHERE u.name = #{name}
select>
mapper>
mapper.xml里面我们就可以直接写sql我们要的sql了。我的建议是由于mybatis-plus提供了基本的crud方法,所有如果是一些复杂的查询我们可以自己写sql,如果是简单的直接使用mybatis-plus提供的方法就可以了。
通过上面的例子,我相信基本的使用流程是木有问题了的,在了解了基本的使用流程之后,那么你可能会有怎么几个疑问
其实这些问题在官网中都可以找到答案,具体链接我放在问题后面了,至于最后一个问题,我认为在mybatis-plus中称得上复杂查询的应该是有多表连接的查询,如果是单表查询不管怎么查我们都可以通过条件构造器构造出来,但是如果多表查询mybatis-plus好像没有实现,不过hibernate倒是实现了。所以如果是多表关联查询还是自己写sql吧。
还有就是mybatis为什么可以直接调用方法就可以实现数据库的操作呢,这里简单说一下原理,具体的还请参考官网。
我们直接调用方法就可以操作数据是通过自动注入sql来实现的。mybatis中执行sql的时候实际的sql语句是通过SqlSessionFacotry → Configuration→ MappedStatements
中获取的每一个mappedStatement获取的,而mybatis-plus在启动的时候会挨个分析 xxxMapper 中的方法,并且将对应的 SQL 语句处理好,保存到 configuration 对象中的 mappedStatements 中。而这些语句是通过事先预定好的模板在结合数据生成的。因为在mappedStatements 已经有对应的sql了,所以我们使用的时候就可以直接调用
前面说了mybatis-plus的基本使用,下面在来说一个最常用的分页功能吧,在mybatis-plus中是提供了分页插件的。使用起来也很简单,在添加分页插件之后我们要做的就是是把分页对象构建好,然后传给对应的操作接口就可以了。
分页插件的配置只需要在容器中添加一个组件就可以了
@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;
}
}
使用的时候分两种情况:
一种是直接调用mybatis-plus提供的分页方法进行分页例如:IPage
这里page为分页对象,而queryWarpper为查询时的条件构造对象
还有一种方法是我们调用我们自己写的sql进行分页,在调用我们自己写的sql时,我们只需要在定义mapper接口时第一个参数要求传入分页对象就可以了,如果第一个参数为分页对象,那么mapper接口调用时mybatis-plus对自动对sql进行分页。
在我们调用分页方法的时候他会自动返回一个分页对象,至于对象中有哪些属性,大家可以自己去源码里面看看page对象中的属性哈。
分页对象的构建这里写一下我自己的方案。首先在需要进行分页的时候前端会自动传入这么几个参数:
所以我们可以自己定义一个方法,使用的时候直接调用这个方法就可以获取分页对象了
protected <T> Page<T> defaultPage(Class<T> clazz) {
HttpServletRequest request = HttpUtil.getRequest();
//当前页,页码
int currentPage = Integer.valueOf(ObjectUtils.isEmpty(request.getParameter("page")) ? "1" : request.getParameter("page"));
//每页多少条数据
int limit = Integer.valueOf(ObjectUtils.isEmpty(request.getParameter("limit")) ? "10" : request.getParameter("limit"));
//排序字段名称
String sort = request.getParameter("sort");
if(StringUtils.isNotEmpty(sort)){
// 将大写转换为下划线的格式
sort = StrUtil.underscoreName(sort);
}
//asc或desc(升序或降序)
String order = request.getParameter("order");
Page<T> page = new Page<T>(currentPage, limit);
if (ObjectUtils.isEmpty(sort)) {
return page;
} else {
List<OrderItem> orderList;
if (Order.DESC.getDes().equals(order)) {
orderList = OrderItem.descs(sort);
} else {
orderList = OrderItem.ascs(sort);
}
page.setOrders(orderList);
return page;
}
}
添加这个工厂之后,后面获取分页对象我们只需要在Controller中直接使用Page
就可以获取分页对象了。
代码生成器的核心的实现无非就是定义好模板之后,在将获取的数据填充到模板中在生成文件。市面上代码生成器有很多例如:懒猴子CG、MagicalCoder等等这些都是免费的。但是把代码的生成依赖于第三方这个好像不太合适哈,首先安全性得不到保障而且万一没有外网呢。所以项目里面还是得有自己的代码生成器的。为了避免重复造轮子,mybatis-plus是为我们提供了代码生成器的,通过mybatis-plus可以帮我们生成后台中用的代码。并且模板、数据都可以自定义。
并且mybatis-plus除了可以生成代码中经常使用的Controller、Service、ServiceImpl、Mapper、Mapper.xml、Entity这几个文件我们还可以用它来生成一些其他额外的文件,例如我们可以让他生成前端的文件,当然这需要进行额外配置,具体可以参考官网的例子写的还是挺详细的
生成器的使用在官网上有个很完整的例子根据提供的配置项进行配置就可以了,配置项可以分为这么几部分:
DataSourceConfig(数据源配置)、StrategyConfig( 数据库表配置)、PackageConfig( 包名配置)、TemplateConfig( 模板配置)、GlobalConfig(全局策略配置)、InjectionConfig(注入配置)
每种配置都提供了很多的配置项,结合官网的例子根据实际情况进行配置就可以了,这里就不给实际例子了。大家可以参考官网中的例子
这里主要说一个很重要的问题:那就是通常我们的代码不可能每个项目都相同,所以这个时候我们就需要自定义模板。
mybatis-plus支持的模板引擎有3分别是:Velocity、Freemarker以及Beetl,默认使用的是Velocity。我们可以自己选择熟悉的模板引擎来编写模板。由于我那个都不熟悉所以就选择了默认的,而且sprinboot指定的模板引擎也是Velocity所以这个不会差。其实选择模板引擎就是选择哪种语法来编写你的模板,这个so easy啦,语法嘛看几眼就会了哈。所以Velocity的使用大家可以自己问度娘哈。
模板的语法搞定了之后,那么还存在一个问题,那就是模板中可以使用的变量有那些呢?
这个问题我之前由于眼瞎找了很久(看文档一定要仔细啊),模板中可以使用的变量在官网中其实已经说了,但是之前没仔细看文档还找了一下午,哎,说多了都是泪。这个我给个官网的截图:
其实就写在最前面,他说: 在AbstractTemplateEngine 类中方法 getObjectMap 返回 objectMap 的所有值都可以在模板中使用。我们来看看AbstractTemplateEngine 中的getObjectMap 方法
/**
* 渲染对象 MAP 信息
*
* @param tableInfo 表信息对象
* @return ignore
*/
public Map<String, Object> getObjectMap(TableInfo tableInfo) {
Map<String, Object> objectMap = new HashMap<>(30);
ConfigBuilder config = getConfigBuilder();
if (config.getStrategyConfig().isControllerMappingHyphenStyle()) {
objectMap.put("controllerMappingHyphenStyle", config.getStrategyConfig().isControllerMappingHyphenStyle());
objectMap.put("controllerMappingHyphen", StringUtils.camelToHyphen(tableInfo.getEntityPath()));
}
objectMap.put("restControllerStyle", config.getStrategyConfig().isRestControllerStyle());
objectMap.put("config", config);
objectMap.put("package", config.getPackageInfo());
GlobalConfig globalConfig = config.getGlobalConfig();
objectMap.put("author", globalConfig.getAuthor());
objectMap.put("idType", globalConfig.getIdType() == null ? null : globalConfig.getIdType().toString());
objectMap.put("logicDeleteFieldName", config.getStrategyConfig().getLogicDeleteFieldName());
objectMap.put("versionFieldName", config.getStrategyConfig().getVersionFieldName());
objectMap.put("activeRecord", globalConfig.isActiveRecord());
objectMap.put("kotlin", globalConfig.isKotlin());
objectMap.put("swagger2", globalConfig.isSwagger2());
objectMap.put("date", new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
objectMap.put("table", tableInfo);
objectMap.put("enableCache", globalConfig.isEnableCache());
objectMap.put("baseResultMap", globalConfig.isBaseResultMap());
objectMap.put("baseColumnList", globalConfig.isBaseColumnList());
objectMap.put("entity", tableInfo.getEntityName());
objectMap.put("entitySerialVersionUID", config.getStrategyConfig().isEntitySerialVersionUID());
objectMap.put("entityColumnConstant", config.getStrategyConfig().isEntityColumnConstant());
objectMap.put("entityBuilderModel", config.getStrategyConfig().isEntityBuilderModel());
objectMap.put("chainModel", config.getStrategyConfig().isChainModel());
objectMap.put("entityLombokModel", config.getStrategyConfig().isEntityLombokModel());
objectMap.put("entityBooleanColumnRemoveIsPrefix", config.getStrategyConfig().isEntityBooleanColumnRemoveIsPrefix());
objectMap.put("superEntityClass", getSuperClassName(config.getSuperEntityClass()));
objectMap.put("superMapperClassPackage", config.getSuperMapperClass());
objectMap.put("superMapperClass", getSuperClassName(config.getSuperMapperClass()));
objectMap.put("superServiceClassPackage", config.getSuperServiceClass());
objectMap.put("superServiceClass", getSuperClassName(config.getSuperServiceClass()));
objectMap.put("superServiceImplClassPackage", config.getSuperServiceImplClass());
objectMap.put("superServiceImplClass", getSuperClassName(config.getSuperServiceImplClass()));
objectMap.put("superControllerClassPackage", verifyClassPacket(config.getSuperControllerClass()));
objectMap.put("superControllerClass", getSuperClassName(config.getSuperControllerClass()));
return Objects.isNull(config.getInjectionConfig()) ? objectMap : config.getInjectionConfig().prepareObjectMap(objectMap);
}
所以说只要在这个方法中添加到objectMap中的数据在模板中都是可以直接使用的。
当然除了objectMap中的数据,我们还可以自己传入我们额外自定义的数据
InjectionConfig injectionConfig = new InjectionConfig() {
//自定义属性注入:abc
//在.ftl(或者是.vm)模板中,通过${cfg.abc}获取属性
@Override
public void initMap() {
Map<String, Object> map = new HashMap<>();
// 设置自定义的值
map.put("customKey", "value");
this.setMap(map);
}
};
AutoGenerator mpg = new AutoGenerator();
//配置自定义属性注入
mpg.setCfg(injectionConfig);
这样配置之后我们在模板中直接通过$!{cfg.customKey}
就可以引用我们设置的属性了。
最后给一个我的Controller的模板,这里面包含了基本的curd操作:
package ${package.Controller};
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.common.factory.PageFactory;
import com.common.resultdata.ResultData;
import com.myadminmain.core.annotion.BussinessLog;
import com.myadminmain.core.annotion.Permission;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
#if(${restControllerStyle})
import org.springframework.web.bind.annotation.RestController;
#else
import org.springframework.stereotype.Controller;
#end
#if(${superControllerClassPackage})
import ${superControllerClassPackage};
#end
import ${package.Entity}.${entity};
import ${package.Service}.${table.serviceName};
import java.util.List;
/**
* @author ${author}
* @date ${date}
* @description: $!{table.comment} 前端控制器
* @version: 1.0
*/
#if(${restControllerStyle})
@RestController
#else
@Controller
#end
@RequestMapping("#if(${package.ModuleName})/${package.ModuleName}#end/#if(${controllerMappingHyphenStyle})${controllerMappingHyphen}#else${table.entityPath}#end")
@Api(tags = "$!{table.controllerName}",description = "$!{cfg.modelName}操作api")
#if(${kotlin})
class ${table.controllerName}#if(${superControllerClass}) : ${superControllerClass}()
#end
#else
#if(${superControllerClass})
public class ${table.controllerName} extends ${superControllerClass} {
#else
public class ${table.controllerName} {
#end
@Autowired
private ${table.serviceName} ${table.entityPath}Service;
## 获取主键
#foreach($field in ${table.fields})
#if(${field.keyFlag})
#set($keyPropertyName=${field.propertyName})
#end
#end
/**
* 功能描述: 根据主键查询-$!{cfg.modelName}
* @param ${keyPropertyName}
* @return ${package.Entity}.${entity}
* @author ${author}
* @date ${date}
*/
@Permission("${table.entityPath}_query")
@BussinessLog("$!{cfg.modelName}-单记录查询")
@ApiOperation(value="$!{cfg.modelName}-单记录查询", notes="根据主键查询-$!{cfg.modelName}")
@ApiImplicitParam(name = "${keyPropertyName}", value = "$!{cfg.modelName}id", required = true, dataType = "int", paramType = "path")
@RequestMapping(value="/${table.entityPath}Info/{${keyPropertyName}}", method= RequestMethod.GET)
public ResultData<${entity}> get(@PathVariable("${keyPropertyName}") Integer ${keyPropertyName}) {
return new ResultData<${entity}>(${table.entityPath}Service.getById(${keyPropertyName}));
}
/**
* 功能描述: 列表查询所有$!{cfg.modelName}
* @param
* @return java.util.List<${package.Entity}.${entity}>
* @author ${author}
* @date ${date}
*/
@Permission("${table.entityPath}_query")
@BussinessLog("$!{cfg.modelName}-列表查询")
@ApiOperation(value="$!{cfg.modelName}-列表查询", notes="查询所有-$!{cfg.modelName}")
@RequestMapping(value="/${table.entityPath}Info", method= RequestMethod.GET)
public ResultData<List<${entity}>> list() {
return new ResultData<List<${entity}>>(${table.entityPath}Service.list());
}
/**
* 功能描述: 分页查询$!{cfg.modelName}
* @param
* @return com.baomidou.mybatisplus.core.metadata.IPage
* @author ${author}
* @date ${date}
*/
@Permission("${table.entityPath}_query")
@BussinessLog("$!{cfg.modelName}-分页查询")
@ApiOperation(value="$!{cfg.modelName}-分页查询", notes="分页查询-$!{cfg.modelName}")
@ApiImplicitParams({
@ApiImplicitParam(name = "currentPage", value = "当前页,页码,默认为1", dataType = "int", paramType = "query"),
@ApiImplicitParam(name = "limit", value = "每页多少条数据,默认为10", dataType = "int", paramType = "query"),
@ApiImplicitParam(name = "sort", value = "排序字段名称,多个用逗号(,)分割", dataType = "String",paramType = "query"),
@ApiImplicitParam(name = "order", value = "asc或desc(升序或降序),默认为升序", dataType = "String",paramType = "query"),
})
@RequestMapping(value="/${table.entityPath}InfoPage", method= RequestMethod.GET)
public ResultData<IPage<${entity}>> page() {
Page<${entity}> page = this.defaultPage(${entity}.class);
return new ResultData<IPage<${entity}>>(${table.entityPath}Service.page(page));
}
/**
* 功能描述: 根据${entity}对象创建$!{cfg.modelName}
* @param ${table.entityPath}
* @return com.common.tips.Tip
* @author ${author}
* @date ${date}
*/
@Permission("${table.entityPath}_add")
@BussinessLog("$!{cfg.modelName}-新增")
@ApiOperation(value="$!{cfg.modelName}-新增", notes="根据${entity}对象新增-$!{cfg.modelName}")
@ApiImplicitParam(name = "${table.entityPath}", value = "$!{cfg.modelName}实体", required = true, dataType = "${entity}", paramType = "body")
@RequestMapping(value="/${table.entityPath}Info", method= RequestMethod.POST)
public ResultData add(@RequestBody ${entity} ${table.entityPath}) {
boolean save = ${table.entityPath}Service.save(${table.entityPath});
return save ? SUCCESS : ERROR;
}
/**
* 功能描述: 根据${entity}对象修改$!{cfg.modelName},对象中必须有主键
* @param ${table.entityPath}
* @return com.common.tips.Tip
* @author ${author}
* @date ${date}
*/
@Permission("${table.entityPath}_edit")
@BussinessLog("$!{cfg.modelName}-修改")
@ApiOperation(value="$!{cfg.modelName}-修改", notes="根据${entity}对象修改$!{cfg.modelName},对象中必须有主键")
@ApiImplicitParam(name = "${table.entityPath}", value = "$!{cfg.modelName}实体", required = true, dataType = "${entity}", paramType = "body")
@RequestMapping(value="/${table.entityPath}Info", method= RequestMethod.PUT)
public ResultData update(@RequestBody ${entity} ${table.entityPath}) {
boolean update = ${table.entityPath}Service.updateById(${table.entityPath});
return update ? SUCCESS : ERROR;
}
/**
* 功能描述: 根据主键删除-$!{cfg.modelName}
* @param ${keyPropertyName}
* @return com.common.tips.Tip
* @author ${author}
* @date ${date}
*/
@Permission("${table.entityPath}_delete")
@BussinessLog("$!{cfg.modelName}-删除")
@ApiOperation(value="$!{cfg.modelName}-删除", notes="根据主键删除-$!{cfg.modelName}")
@ApiImplicitParam(name = "${keyPropertyName}", value = "$!{cfg.modelName}id", required = true, dataType = "int", paramType = "path")
@RequestMapping(value="/${table.entityPath}Info/{${keyPropertyName}}", method= RequestMethod.DELETE)
public ResultData delete(@PathVariable("${keyPropertyName}") Integer ${keyPropertyName}) {
boolean delete = ${table.entityPath}Service.removeById(${keyPropertyName});
return delete ? SUCCESS : ERROR;
}
}
#end
除了上面说的这几个功能,mybatis-plus还提供了很多很好用的插件,例如自动填充功能、性能分析插件等等,有兴趣大家可以自己去官网上逛逛哈
使用mybatis-plus以及他的代码生成器在实际开发中大概可以减少50%-80%的工作量,因为首先我们对于数据库表的插入、修改、删除是不需要在编写sql了的当然一些简单的查询也不需要在编写sql,直接调用对应的方法就可以了,还有就是对于项目中用到的文件类我们都可以通过代码生成器直接生成,因为可以自定义模板,所以我们可以在模板中将一些常用的以及可以预知的代码逻辑写入模板到时候直接生成就可以了。所以使用mybatis-plus以及代码生成器之后,我们的主要工作就是编写业务逻辑,以及在代码生成不符合要求的时候改改代码就可以了。这样在很大程度上减少了一些重复的工作从而极大的提高工作效率。
下一篇,独立完成系统开发六:权限控制之认证