在Java开发中,数据库操作代码编写繁琐且重复度高。MyBatis-Plus代码生成器能自动生成基础CRUD代码,极大提升开发效率。下面我将介绍其原理、使用步骤,并结合案例展示如何利用它简化开发流程。
一、引言
在企业级Java应用开发中,数据库操作是不可或缺的重要环节。从数据的增删改查(CRUD)到复杂的业务逻辑实现,都需要编写大量与数据库交互的代码。传统方式下,开发者需要手动编写SQL语句、映射实体类与数据库表字段、实现基础的CRUD方法等,不仅工作量大,而且容易出错,开发效率低下。MyBatis-Plus作为MyBatis的增强工具,其内置的代码生成器能够根据数据库表结构,自动生成对应的实体类、Mapper接口、Service接口及其实现类等代码,极大地简化了开发流程,提高了开发效率。本文将详细介绍MyBatis-Plus代码生成器的使用方法、核心配置以及在实际项目中的应用案例,帮助开发者快速掌握这一高效工具。
二、MyBatis-Plus代码生成器基础概念
2.1 核心功能
MyBatis-Plus代码生成器主要具备以下功能:
- 自动生成实体类:根据数据库表结构,生成对应的Java实体类,并自动映射表字段与实体类属性,支持常见的数据类型转换。
- 生成Mapper接口:创建继承自MyBatis-Plus的
BaseMapper
接口,包含基础的CRUD方法,开发者无需手动编写这些通用方法。 - 生成Service接口及实现类:自动生成Service接口及其实现类,Service实现类中默认实现了基础的业务逻辑方法,如新增、删除、修改、查询等,开发者可在此基础上扩展复杂业务逻辑。
- 生成Controller类:可选生成Controller类,提供基础的RESTful API接口,方便快速搭建前后端交互的接口层。
2.2 依赖引入
在Maven项目的pom.xml
文件中引入MyBatis-Plus和代码生成器相关依赖:
<!-- MyBatis-Plus核心依赖 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.3.1</version>
</dependency>
<!-- MyBatis-Plus代码生成器依赖 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.5.3.1</version>
</dependency>
<!-- 模板引擎依赖,这里使用Velocity -->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.3</version>
</dependency>
<!-- 数据库驱动依赖,以MySQL为例 -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>8.1.0</version>
</dependency>
若使用Gradle构建项目,在build.gradle
文件中添加如下依赖:
implementation 'com.baomidou:mybatis-plus-boot-starter:3.5.3.1'
implementation 'com.baomidou:mybatis-plus-generator:3.5.3.1'
implementation 'org.apache.velocity:velocity-engine-core:2.3'
implementation 'com.mysql:mysql-connector-j:8.1.0'
三、MyBatis-Plus代码生成器配置与使用
3.1 配置代码生成器
创建一个Java类用于配置和执行代码生成逻辑,例如CodeGenerator.java
:
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.engine.VelocityTemplateEngine;
import java.util.Collections;
public class CodeGenerator {
public static void main(String[] args) {
// 数据库连接信息
String url = "jdbc:mysql://localhost:3306/your_database?serverTimezone=UTC";
String username = "your_username";
String password = "your_password";
// 代码生成器配置
FastAutoGenerator.create(url, username, password)
.globalConfig(builder -> {
builder.author("Your Name") // 设置作者名
.outputDir(System.getProperty("user.dir") + "/src/main/java") // 设置生成文件输出目录
.fileOverride() // 覆盖已生成文件
.enableSwagger() // 开启Swagger2模式
.disableOpenDir(); // 禁止打开输出目录
})
.packageConfig(builder -> {
builder.parent("com.example") // 设置父包名
.moduleName("your_module") // 设置模块名
.pathInfo(Collections.singletonMap(OutputFile.mapperXml, System.getProperty("user.dir") + "/src/main/resources/mapper")); // 设置Mapper XML文件输出目录
})
.strategyConfig(builder -> {
builder.addInclude("your_table_name") // 设置需要生成代码的表名,可传入多个表名
.addTablePrefix("tb_"); // 设置表名前缀,生成代码时会去除前缀
})
.templateEngine(new VelocityTemplateEngine()) // 使用Velocity模板引擎
.execute();
}
}
3.2 配置说明
globalConfig
:全局配置,包括作者名、输出目录、是否覆盖已有文件、是否启用Swagger等。packageConfig
:包名配置,设置生成代码的父包名、模块名以及各类型文件的输出目录。strategyConfig
:策略配置,指定需要生成代码的表名,以及是否去除表名前缀等。templateEngine
:选择模板引擎,除了Velocity,还支持Freemarker等。
3.3 执行代码生成
运行CodeGenerator.java
类中的main
方法,代码生成器将根据配置自动生成相关代码,并输出到指定目录。生成的代码结构如下:
com/
└── example
└── your_module
├── entity
│ └── YourTableNameEntity.java
├── mapper
│ └── YourTableNameMapper.java
├── service
│ ├── YourTableNameService.java
│ └── impl
│ └── YourTableNameServiceImpl.java
└── controller
└── YourTableNameController.java
四、实际项目应用案例
假设我们正在开发一个电商项目,其中有一张商品表tb_product
,表结构如下:
字段名 | 数据类型 | 描述 |
id | bigint | 商品ID,主键,自增长 |
product_name | varchar | 商品名称 |
price | decimal | 商品价格 |
stock | int | 商品库存 |
category_id | bigint | 商品分类ID |
4.1 配置代码生成器
修改CodeGenerator.java
中的配置,使其针对tb_product
表生成代码:
FastAutoGenerator.create(url, username, password)
.globalConfig(builder -> {
builder.author("John Doe")
.outputDir(System.getProperty("user.dir") + "/src/main/java")
.fileOverride()
.enableSwagger()
.disableOpenDir();
})
.packageConfig(builder -> {
builder.parent("com.example.ecommerce")
.moduleName("product")
.pathInfo(Collections.singletonMap(OutputFile.mapperXml, System.getProperty("user.dir") + "/src/main/resources/mapper"));
})
.strategyConfig(builder -> {
builder.addInclude("tb_product")
.addTablePrefix("tb_");
})
.templateEngine(new VelocityTemplateEngine())
.execute();
4.2 生成代码解析
- 实体类
ProductEntity.java
:
package com.example.ecommerce.product.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* <p>
* 商品表
* </p>
*
* @author John Doe
* @since 2024-01-01
*/
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("tb_product")
public class ProductEntity implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 商品ID
*/
private Long id;
/**
* 商品名称
*/
private String productName;
/**
* 商品价格
*/
private java.math.BigDecimal price;
/**
* 商品库存
*/
private Integer stock;
/**
* 商品分类ID
*/
private Long categoryId;
}
- Mapper接口
ProductMapper.java
:
package com.example.ecommerce.product.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.ecommerce.product.entity.ProductEntity;
/**
* <p>
* 商品表 Mapper 接口
* </p>
*
* @author John Doe
* @since 2024-01-01
*/
public interface ProductMapper extends BaseMapper<ProductEntity> {
}
- Service接口
ProductService.java
:
package com.example.ecommerce.product.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.example.ecommerce.product.entity.ProductEntity;
/**
* <p>
* 商品表 服务类
* </p>
*
* @author John Doe
* @since 2024-01-01
*/
public interface ProductService extends IService<ProductEntity> {
}
- Service实现类
ProductServiceImpl.java
:
package com.example.ecommerce.product.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.ecommerce.product.entity.ProductEntity;
import com.example.ecommerce.product.mapper.ProductMapper;
import com.example.ecommerce.product.service.ProductService;
import org.springframework.stereotype.Service;
/**
* <p>
* 商品表 服务实现类
* </p>
*
* @author John Doe
* @since 2024-01-01
*/
@Service
public class ProductServiceImpl extends ServiceImpl<ProductMapper, ProductEntity> implements ProductService {
}
- Controller类
ProductController.java
:
package com.example.ecommerce.product.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.ecommerce.product.entity.ProductEntity;
import com.example.ecommerce.product.service.ProductService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* <p>
* 商品表 前端控制器
* </p>
*
* @author John Doe
* @since 2024-01-01
*/
@Api(tags = "商品表")
@RestController
@RequestMapping("/product")
public class ProductController {
@Autowired
private ProductService productService;
@ApiOperation("新增商品")
@PostMapping
public boolean save(@RequestBody ProductEntity productEntity) {
return productService.save(productEntity);
}
@ApiOperation("删除商品")
@DeleteMapping("/{id}")
public boolean remove(@PathVariable Long id) {
return productService.removeById(id);
}
@ApiOperation("修改商品")
@PutMapping
public boolean update(@RequestBody ProductEntity productEntity) {
return productService.updateById(productEntity);
}
@ApiOperation("根据ID查询商品")
@GetMapping("/{id}")
public ProductEntity getById(@PathVariable Long id) {
return productService.getById(id);
}
@ApiOperation("分页查询商品列表")
@GetMapping("/page")
public Page<ProductEntity> page(@RequestParam(defaultValue = "1") int current, @RequestParam(defaultValue = "10") int size) {
Page<ProductEntity> page = new Page<>(current, size);
return productService.page(page, new QueryWrapper<>());
}
}
4.3 扩展业务逻辑
生成的代码提供了基础的CRUD功能,开发者可根据实际业务需求进行扩展。例如,在ProductService
接口中添加一个根据商品分类ID查询商品列表的方法:
package com.example.ecommerce.product.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.example.ecommerce.product.entity.ProductEntity;
import java.util.List;
/**
* <p>
* 商品表 服务类
* </p>
*
* @author John Doe
* @since 2024-01-01
*/
public interface ProductService extends IService<ProductEntity> {
List<ProductEntity> listByCategoryId(Long categoryId);
}
在ProductServiceImpl
实现类中实现该方法:
package com.example.ecommerce.product.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.ecommerce.product.entity.ProductEntity;
import com.example.ecommerce.product.mapper.ProductMapper;
import com.example.ecommerce.product.service.ProductService;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* <p>
* 商品表 服务实现类
* </p>
*
* @author John Doe
* @since 2024-01-01
*/
@Service
public class ProductServiceImpl extends ServiceImpl<ProductMapper, ProductEntity> implements ProductService {
@Override
public List<ProductEntity> listByCategoryId(Long categoryId) {
QueryWrapper<ProductEntity> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("category_id", categoryId);
return baseMapper.selectList(queryWrapper);
}
}
同时,在ProductController
中添加对应的API接口:
@ApiOperation("根据分类ID查询商品列表")
@GetMapping("/listByCategoryId/{categoryId}")
public List<ProductEntity> listByCategoryId(@PathVariable Long categoryId) {
return productService.listByCategoryId(categoryId);
}
五、总结
MyBatis-Plus代码生成器通过自动化生成数据库操作相关代码,极大地提高了Java应用开发中数据库操作的效率,减少了开发者的重复劳动,降低了出错概率。通过合理配置代码生成器的参数,开发者可以快速生成符合项目需求的代码框架,并在此基础上进行业务逻辑的扩展和优化。在实际项目中,充分利用MyBatis-Plus代码生成器,能够帮助团队更快地完成开发任务,提升项目的整体开发效率和质量。随着项目规模的不断扩大和业务需求的日益复杂,MyBatis-Plus代码生成器的优势将更加明显,成为Java开发者不可或缺的高效开发工具。