还在手动写CRUD的XML?兄弟,真得学习MBG了!
兄弟,如果你还在为MyBatis手写一堆XML的CRUD操作累得焦头烂额,那真得停下来看看MyBatis Generator(简称MBG)了!它能帮你自动生成Model、Mapper接口和XML配置文件,极大提升开发效率。本文将基于Spring Boot 3 + MyBatis 3的技术栈,带你从建表SQL到MBG配置,再到项目结构和手动写DAO的场景,全面解析MBG的用法和注意事项。话不多说,直接上干货!
一、建表SQL:先把数据库结构搭好
我们以一个简单的电商场景为例,创建三张表:user
(用户信息)、product
(商品信息)和order
(订单信息),并建立适当的外键关系。
sql
-- 创建用户表
CREATE TABLE `user` (
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '用户ID',
`username` VARCHAR(50) NOT NULL COMMENT '用户名',
`email` VARCHAR(100) NOT NULL COMMENT '邮箱',
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';
-- 创建商品表
CREATE TABLE `product` (
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '商品ID',
`name` VARCHAR(100) NOT NULL COMMENT '商品名称',
`price` DECIMAL(10, 2) NOT NULL COMMENT '价格',
`stock` INT NOT NULL COMMENT '库存',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='商品表';
-- 创建订单表
CREATE TABLE `order` (
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '订单ID',
`user_id` BIGINT NOT NULL COMMENT '用户ID',
`product_id` BIGINT NOT NULL COMMENT '商品ID',
`quantity` INT NOT NULL COMMENT '购买数量',
`order_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '下单时间',
PRIMARY KEY (`id`),
FOREIGN KEY (`user_id`) REFERENCES `user` (`id`),
FOREIGN KEY (`product_id`) REFERENCES `product` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订单表';
这些表结构简单明了,包含了主键、外键和常见字段类型,适合展示MBG的生成效果。
二、项目结构:MBG生成什么,手动写什么?
在使用MBG之前,先来看看项目的目录结构,方便你理解哪些文件是MBG自动生成的,哪些需要我们手动补充。
bash
project-root
├── src
│ ├── main
│ │ ├── java
│ │ │ └── com
│ │ │ └── example
│ │ │ ├── Application.java # Spring Boot 启动类
│ │ │ ├── config
│ │ │ │ └── MyBatisConfig.java # MyBatis 配置类
│ │ │ ├── dao
│ │ │ │ ├── UserMapper.java # MBG自动生成
│ │ │ │ ├── ProductMapper.java # MBG自动生成
│ │ │ │ ├── OrderMapper.java # MBG自动生成
│ │ │ │ └── CustomOrderDao.java # 手动编写的DAO
│ │ │ ├── model
│ │ │ │ ├── User.java # MBG自动生成
│ │ │ │ ├── UserExample.java # MBG自动生成
│ │ │ │ ├── Product.java # MBG自动生成
│ │ │ │ ├── ProductExample.java # MBG自动生成
│ │ │ │ ├── Order.java # MBG自动生成
│ │ │ │ └── OrderExample.java # MBG自动生成
│ │ │ ├── service
│ │ │ │ ├── UserService.java # 手动编写
│ │ │ │ ├── ProductService.java # 手动编写
│ │ │ │ └── OrderService.java # 手动编写
│ │ │ └── controller
│ │ │ └── OrderController.java # 手动编写
│ │ └── resources
│ │ ├── mapper
│ │ │ ├── UserMapper.xml # MBG自动生成
│ │ │ ├── ProductMapper.xml # MBG自动生成
│ │ │ └── OrderMapper.xml # MBG自动生成
│ │ ├── application.yml # Spring Boot 配置文件
│ │ └── generatorConfig.xml # MBG配置文件
│ └── test
│ └── java
│ └── com
│ └── example
│ └── ApplicationTests.java # 测试类
├── pom.xml # Maven配置文件
└── README.md
说明:
- MBG自动生成 :
UserMapper.java
、ProductMapper.java
、OrderMapper.java
(Mapper接口),User.java
、Product.java
、Order.java
(实体类),UserExample.java
、ProductExample.java
、OrderExample.java
(条件查询类),以及mapper
目录下的XML文件。 - 手动编写 :
CustomOrderDao.java
(自定义DAO,处理复杂业务逻辑)、Service层、Controller层,以及Spring Boot的配置文件和启动类。
三、MBG配置:让代码自动生成
MBG的核心是generatorConfig.xml
,我们需要配置数据库连接、生成规则和输出路径。下面是一个详细的配置文件,带注释说明每个部分的作用。
xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<!-- 数据库驱动:指定MySQL驱动的JAR包路径(需提前放入项目目录) -->
<classPathEntry location="mysql-connector-java-8.0.30.jar" />
<!-- 数据库连接配置 -->
<context id="MySQLTables" targetRuntime="MyBatis3">
<!-- 数据库连接信息 -->
<jdbcConnection
driverClass="com.mysql.cj.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/mbg_demo?useSSL=false&serverTimezone=UTC"
userId="root"
password="your_password" />
<!-- Java模型生成配置 -->
<javaModelGenerator targetPackage="com.example.model" targetProject="src/main/java">
<!-- 是否在当前路径下生成子包 -->
<property name="enableSubPackages" value="true" />
<!-- 是否对模型添加构造函数 -->
<property name="constructorBased" value="false" />
<!-- 是否对列名进行trim操作 -->
<property name="trimStrings" value="true" />
</javaModelGenerator>
<!-- SQL映射文件(XML)生成配置 -->
<sqlMapGenerator targetPackage="mapper" targetProject="src/main/resources">
<property name="enableSubPackages" value="true" />
</sqlMapGenerator>
<!-- Mapper接口生成配置 -->
<javaClientGenerator type="XMLMAPPER" targetPackage="com.example.dao" targetProject="src/main/java">
<property name="enableSubPackages" value="true" />
</javaClientGenerator>
<!-- 指定表和生成规则 -->
<table tableName="user" domainObjectName="User" enableCountByExample="true"
enableUpdateByExample="true" enableDeleteByExample="true"
enableSelectByExample="true" selectByExampleQueryId="true">
<!-- 是否生成Example类 -->
<generatedKey column="id" sqlStatement="MySQL" identity="true" />
</table>
<table tableName="product" domainObjectName="Product" enableCountByExample="true"
enableUpdateByExample="true" enableDeleteByExample="true"
enableSelectByExample="true" selectByExampleQueryId="true">
<generatedKey column="id" sqlStatement="MySQL" identity="true" />
</table>
<table tableName="order" domainObjectName="Order" enableCountByExample="true"
enableUpdateByExample="true" enableDeleteByExample="true"
enableSelectByExample="true" selectByExampleQueryId="true">
<generatedKey column="id" sqlStatement="MySQL" identity="true" />
</table>
</context>
</generatorConfiguration>
关键点:
- 数据库驱动 :需要下载
mysql-connector-java
并指定路径,或者通过Maven依赖引入。 - 生成路径 :
javaModelGenerator
、sqlMapGenerator
和javaClientGenerator
分别控制Model、XML和Mapper接口的输出位置。 - 表配置 :通过
<table>
标签指定要生成的表,generatedKey
用于设置主键自增。 - Example支持 :
enable*ByExample
属性开启条件查询功能,生成Example
类。
运行MBG的方式:
- 命令行 :
java -jar mybatis-generator-core-1.4.0.jar -configfile generatorConfig.xml -overwrite
- Maven插件 :配置
mybatis-generator-maven-plugin
并运行mvn mybatis-generator:generate
。
四、Spring Boot配置:整合MyBatis
为了让Spring Boot正常使用MyBatis和MBG生成的代码,我们需要配置application.yml
和MyBatis配置类。
1. application.yml
yaml
spring:
datasource:
url: jdbc:mysql://localhost:3306/mbg_demo?useSSL=false&serverTimezone=UTC
username: root
password: your_password
driver-class-name: com.mysql.cj.jdbc.Driver
mybatis:
mapper-locations: classpath:mapper/*.xml
type-aliases-package: com.example.model
说明:
spring.datasource
:配置数据库连接。mybatis.mapper-locations
:指定MBG生成的XML文件路径。mybatis.type-aliases-package
:指定Model类的包路径,简化XML中的类型引用。
2. MyBatisConfig.java
kotlin
package com.example.config;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@MapperScan("com.example.dao")
public class MyBatisConfig {
// 配置MyBatis的Mapper扫描路径
}
说明:
@MapperScan
注解自动扫描com.example.dao
包下的Mapper接口,省去手动添加@Mapper
注解的麻烦。
五、MBG的Example类:灵活查询的利器
MBG生成的Example
类是条件查询的核心,用于动态构建SQL的WHERE条件。比如,查询某个用户的订单:
ini
OrderExample example = new OrderExample();
example.createCriteria()
.andUserIdEqualTo(1L)
.andOrderTimeGreaterThan(new Date(System.currentTimeMillis() - 24 * 60 * 60 * 1000));
List<Order> orders = orderMapper.selectByExample(example);
Example的用处:
- 动态查询 :通过
createCriteria()
和or()
方法,可以灵活组合查询条件。 - 批量操作 :支持
updateByExample
、deleteByExample
等批量操作。 - 分页支持 :结合
RowBounds
实现分页查询。
使用场景:
- 复杂条件查询(如多字段组合、模糊查询)。
- 批量更新或删除(如更新某类用户的状态)。
六、MBG的缺陷和手动写DAO的场景
虽然MBG很强大,但它也有局限性,有些场景需要我们手动写DAO和XML。
MBG的缺陷
- 复杂SQL不支持:MBG只生成简单的CRUD,复杂的多表联查、子查询或存储过程需要手动实现。
- 业务逻辑耦合:MBG生成的代码是通用的,难以直接处理业务逻辑(如订单状态流转)。
- XML维护问题:如果表结构变更,MBG重新生成会覆盖自定义的XML内容(除非配置插件)。
什么时候需要手动写DAO?
- 多表关联查询 :比如查询订单详情,需关联
user
和product
表。 - 复杂业务逻辑:如订单创建时需要检查库存、更新用户积分等。
- 自定义SQL:如统计报表、复杂聚合查询。
- 性能优化:MBG生成的SQL可能不够高效,手动优化能减少查询开销。
示例:手动实现的CustomOrderDao
kotlin
package com.example.dao;
import com.example.model.Order;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import java.util.List;
@Mapper
public interface CustomOrderDao {
@Select("SELECT o.*, u.username, p.name AS product_name " +
"FROM `order` o " +
"JOIN `user` u ON o.user_id = u.id " +
"JOIN `product` p ON o.product_id = p.id " +
"WHERE o.user_id = #{userId}")
List<Order> selectOrderDetailsByUserId(Long userId);
}
对应的XML(可选) :
如果不用注解,可以在resources/mapper/CustomOrderMapper.xml
中定义:
xml
<?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.example.dao.CustomOrderDao">
<select id="selectOrderDetailsByUserId" resultType="com.example.model.Order">
SELECT o.*, u.username, p.name AS product_name
FROM `order` o
JOIN `user` u ON o.user_id = u.id
JOIN `product` p ON o.product_id = p.id
WHERE o.user_id = #{userId}
</select>
</mapper>
七、总结:MBG的正确打开方式
MBG是解放双手的神器,能自动生成80%的CRUD代码,但它不是万能的。简单单表操作交给MBG,复杂业务逻辑和多表查询还是得靠手动DAO。合理结合MBG的Example
类和自定义DAO,能让你的代码既高效又灵活。
小建议:
- 配置好
generatorConfig.xml
,跑一把MBG,感受自动化的快感。 - 对于复杂业务,写个
Custom*Dao
专门处理,别和MBG生成的代码混在一起。 - 善用
Example
类,动态查询省心又省力。
兄弟,赶紧把MBG用起来,告别手写XML的苦日子吧!如果有啥问题,欢迎留言讨论~