Spring Boot 2.5 + MyBatis-Plus 3.4.1 整合 PostgreSQL 实战指南
PostgreSQL 作为一款功能强大的开源关系型数据库,在企业级应用中越来越受欢迎。而 Spring Boot 和 MyBatis-Plus 的组合则为 Java 开发者提供了高效的数据访问解决方案。本文将带你从零开始,一步步完成三者的整合,并重点介绍 MyBatis-Plus 代码生成器的配置技巧。
1. 项目初始化与环境准备
在开始之前,确保你的开发环境已经准备好以下组件:
- JDK 1.8 或更高版本
- Maven 3.6+
- IntelliJ IDEA 或 Eclipse
- PostgreSQL 12+
首先,我们创建一个基本的 Spring Boot 项目。可以通过 Spring Initializr 快速生成,或者手动创建。以下是项目的基础结构:
springboot-mybatisplus-pg ├── src │ ├── main │ │ ├── java │ │ │ └── com │ │ │ └── example │ │ │ └── demo │ │ │ ├── DemoApplication.java │ │ └── resources │ │ ├── application.yml │ │ └── static │ └── test │ └── java └── pom.xml2. 依赖配置与数据库连接
2.1 Maven 依赖配置
打开pom.xml文件,添加必要的依赖:
<dependencies> <!-- Spring Boot Starter Web --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- PostgreSQL JDBC Driver --> <dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> <scope>runtime</scope> </dependency> <!-- MyBatis-Plus Starter --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.4.1</version> </dependency> <!-- Lombok --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <!-- MyBatis-Plus Generator --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-generator</artifactId> <version>3.4.1</version> </dependency> <!-- Velocity Template Engine --> <dependency> <groupId>org.apache.velocity</groupId> <artifactId>velocity-engine-core</artifactId> <version>2.3</version> </dependency> </dependencies>2.2 数据库连接配置
在application.yml中配置 PostgreSQL 连接信息:
spring: datasource: driver-class-name: org.postgresql.Driver url: jdbc:postgresql://localhost:5432/your_database username: your_username password: your_password mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl global-config: db-config: logic-delete-field: deleted # 逻辑删除字段名 logic-delete-value: 1 # 已删除值 logic-not-delete-value: 0 # 未删除值注意:确保你的 PostgreSQL 服务已启动,并且数据库已创建。可以使用以下命令检查连接:
psql -h localhost -U your_username -d your_database
3. MyBatis-Plus 代码生成器配置
MyBatis-Plus 的代码生成器可以极大提高开发效率。下面是一个完整的代码生成器配置示例:
public class CodeGenerator { 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("YourName"); gc.setOpen(false); gc.setFileOverride(true); gc.setServiceName("%sService"); gc.setIdType(IdType.AUTO); gc.setDateType(DateType.ONLY_DATE); gc.setSwagger2(true); mpg.setGlobalConfig(gc); // 数据源配置 DataSourceConfig dsc = new DataSourceConfig(); dsc.setUrl("jdbc:postgresql://localhost:5432/your_database"); dsc.setDriverName("org.postgresql.Driver"); dsc.setUsername("your_username"); dsc.setPassword("your_password"); dsc.setDbType(DbType.POSTGRE_SQL); mpg.setDataSource(dsc); // 包配置 PackageConfig pc = new PackageConfig(); pc.setParent("com.example.demo"); pc.setEntity("entity"); pc.setMapper("mapper"); pc.setService("service"); pc.setController("controller"); mpg.setPackageInfo(pc); // 策略配置 StrategyConfig strategy = new StrategyConfig(); strategy.setNaming(NamingStrategy.underline_to_camel); strategy.setColumnNaming(NamingStrategy.underline_to_camel); strategy.setEntityLombokModel(true); strategy.setRestControllerStyle(true); strategy.setInclude("user", "role"); // 表名,多个用逗号分隔 strategy.setControllerMappingHyphenStyle(true); strategy.setTablePrefix("t_"); // 表前缀 mpg.setStrategy(strategy); // 模板配置 TemplateConfig templateConfig = new TemplateConfig(); templateConfig.setXml(null); // 不生成XML文件 mpg.setTemplate(templateConfig); // 执行生成 mpg.execute(); } }运行此代码生成器后,你将获得以下结构:
com/example/demo/ ├── controller │ └── UserController.java ├── entity │ └── User.java ├── mapper │ └── UserMapper.java └── service ├── UserService.java └── impl └── UserServiceImpl.java4. 高级配置与优化
4.1 分页插件配置
MyBatis-Plus 提供了强大的分页功能。添加以下配置类:
@Configuration public class MybatisPlusConfig { @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); // 分页插件 interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.POSTGRE_SQL)); return interceptor; } }4.2 逻辑删除实现
在实体类中添加逻辑删除字段:
@Data @TableName("user") public class User { @TableId(type = IdType.AUTO) private Long id; private String username; private String email; @TableLogic private Integer deleted; }4.3 自动填充功能
实现自动填充创建时间和更新时间:
public class MyMetaObjectHandler implements MetaObjectHandler { @Override public void insertFill(MetaObject metaObject) { this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now()); this.strictInsertFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now()); } @Override public void updateFill(MetaObject metaObject) { this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now()); } }然后在实体类中添加相应字段:
@TableField(fill = FieldFill.INSERT) private LocalDateTime createTime; @TableField(fill = FieldFill.INSERT_UPDATE) private LocalDateTime updateTime;5. 常见问题与解决方案
5.1 PostgreSQL 数据类型映射
PostgreSQL 与 Java 类型之间的映射关系:
| PostgreSQL 类型 | Java 类型 | 说明 |
|---|---|---|
| varchar | String | |
| text | String | |
| int4 | Integer | |
| int8 | Long | |
| numeric | BigDecimal | |
| timestamp | LocalDateTime | |
| date | LocalDate | |
| boolean | Boolean |
5.2 性能优化建议
连接池配置:建议使用 HikariCP 连接池
spring: datasource: hikari: maximum-pool-size: 20 minimum-idle: 5 idle-timeout: 30000批量操作:使用 MyBatis-Plus 的批量操作方法
userService.saveBatch(userList);索引优化:为常用查询字段添加索引
5.3 调试技巧
开启 SQL 日志:
logging: level: com.example.demo.mapper: debug使用 MyBatis-Plus 的 SQL 注入器查看生成的 SQL
6. 实战示例:用户管理模块
6.1 基础 CRUD 操作
@RestController @RequestMapping("/users") public class UserController { @Autowired private UserService userService; @GetMapping("/{id}") public Result<User> getById(@PathVariable Long id) { return Result.success(userService.getById(id)); } @PostMapping public Result<Boolean> save(@RequestBody User user) { return Result.success(userService.save(user)); } @PutMapping public Result<Boolean> update(@RequestBody User user) { return Result.success(userService.updateById(user)); } @DeleteMapping("/{id}") public Result<Boolean> delete(@PathVariable Long id) { return Result.success(userService.removeById(id)); } @GetMapping("/page") public Result<IPage<User>> page(@RequestParam(defaultValue = "1") Integer current, @RequestParam(defaultValue = "10") Integer size) { Page<User> page = new Page<>(current, size); return Result.success(userService.page(page)); } }6.2 复杂查询示例
@Service public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService { public List<User> findUsersByCondition(UserQuery query) { LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>(); wrapper.like(StringUtils.isNotBlank(query.getUsername()), User::getUsername, query.getUsername()) .ge(query.getStartTime() != null, User::getCreateTime, query.getStartTime()) .le(query.getEndTime() != null, User::getCreateTime, query.getEndTime()) .orderByDesc(User::getCreateTime); return baseMapper.selectList(wrapper); } }6.3 事务管理
@Service public class OrderServiceImpl implements OrderService { @Transactional(rollbackFor = Exception.class) public void createOrder(OrderDTO orderDTO) { // 1. 保存订单 Order order = convertToOrder(orderDTO); orderMapper.insert(order); // 2. 扣减库存 productService.reduceStock(orderDTO.getProductId(), orderDTO.getQuantity()); // 3. 记录日志 logService.saveOrderLog(order); } }在实际项目中,这套技术栈组合表现非常稳定。特别是在处理复杂查询时,MyBatis-Plus 的 Wrapper 提供了极大的便利。对于 PostgreSQL 特有的 JSONB 类型,可以通过自定义 TypeHandler 来实现更灵活的数据处理。