MyBatis 逆向工程实用笔记(Spring 整合完整版)
本文基于 SSM 架构(Spring+SpringMVC+MyBatis),详细讲解 MyBatis 逆向工程(MBG)的配置、执行、Spring 整合及公共代码抽取,附完整代码和常见问题解决方案,适用于新手快速上手,可直接复制到项目中使用。
一、逆向工程核心作用
MyBatis 逆向工程(MyBatis Generator,简称 MBG)是 MyBatis 官方提供的代码生成工具,核心价值是解放重复劳动,具体作用如下:
- 自动根据数据库表结构生成「实体类(Model)+ Mapper 接口(Dao)+ Mapper 映射文件(XML)」
- 生成代码遵循 MyBatis 规范,支持 Spring 无缝整合,可直接通过
@Autowired注入使用 - 支持灵活扩展,手动新增的自定义方法不会被覆盖
- 适配多表场景,可批量生成,搭配公共代码抽取可大幅提升开发效率
二、前置准备(必做)
2.1 项目环境 & 依赖
本文基于 Maven 项目(ham-core 模块),需在pom.xml中添加以下依赖(版本适配稳定,直接复制即可):
<!-- MyBatis逆向工程核心依赖 -->
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.3.7</version>
</dependency>
<!-- MyBatis核心依赖 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.9</version>
</dependency>
<!-- Spring整合MyBatis依赖 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.7</version>
</dependency>
<!-- MySQL驱动(MySQL5/8通用,根据版本调整驱动类) -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
<scope>runtime</scope>
</dependency>
<!-- Druid连接池(性能更优,替代默认连接池) -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.15</version>
</dependency>
<!-- Spring核心依赖(上下文+JDBC+事务) -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.23</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.3.23</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.3.23</version>
</dependency>
<!-- 测试依赖(Spring+JUnit4整合) -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.3.23</version>
<scope>test</scope>
</dependency>
2.2 项目目录结构(规范版)
务必保证目录结构如下(否则会导致配置路径错误、代码生成失败):
ham-core/
├── src/
│ ├── main/
│ │ ├── java/ # 主代码目录(包名按实际项目调整)
│ │ │ └── cn/
│ │ │ └── tx/
│ │ │ ├── model/ # 逆向工程生成:实体类(Songer、Album)
│ │ │ ├── dao/ # 逆向工程生成:Mapper接口(SongerMapper)
│ │ │ ├── service/ # 手动创建:Service接口+实现类
│ │ │ │ └── impl/
│ │ │ └── generator/ # 手动创建:逆向工程执行类
│ │ └── resources/ # 资源配置目录(核心)
│ │ ├── mapper/ # 逆向工程生成:Mapper映射文件(SongerMapper.xml)
│ │ ├── log4j.properties # 日志配置(可选,打印SQL日志)
│ │ ├── db.properties # 数据库连接配置(必做)
│ │ ├── generatorConfig.xml # 逆向工程核心配置(必做)
│ │ ├── sqlMapConfig.xml # MyBatis全局配置(必做)
│ │ └── beans.xml # Spring核心配置(必做)
│ └── test/ # 测试目录(与main同级,必做)
│ └── java/
│ └── cn/
│ └── tx/
│ └── test/ # 测试类(SongerTest、AlbumTest)
└── pom.xml # 依赖配置文件
三、逆向工程核心配置(generatorConfig.xml)
这是最关键的一步,所有生成规则都在这里配置,文件放在src/main/resources下,完整配置 + 详细注释如下(直接复制,修改 3 处即可用):
<?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>
<!-- 上下文配置(核心,唯一标识一个生成规则) -->
<context id="mybatisGenerator" targetRuntime="MyBatis3">
<!-- 1. 注释生成器:控制是否生成注释(推荐关闭,简化代码) -->
<commentGenerator>
<property name="suppressAllComments" value="true" /> <!-- true:去除所有注释 -->
<property name="suppressDate" value="true" /> <!-- 去除生成日期注释 -->
</commentGenerator>
<!-- 2. 数据库连接配置(【必须修改】3处:URL、用户名、密码) -->
<jdbcConnection
driverClass="com.mysql.jdbc.Driver" <!-- 注意:MySQL8用com.mysql.cj.jdbc.Driver -->
connectionURL="jdbc:mysql://localhost:3306/ham?serverTimezone=CTT&useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true"
userId="root" <!-- 你的数据库用户名 -->
password="root"> <!-- 你的数据库密码 -->
</jdbcConnection>
<!-- 3. Java类型解析器:JDBC类型→Java类型映射(无需修改) -->
<javaTypeResolver>
<!-- false:JDBC DECIMAL/NUMERIC → Integer;true:→ BigDecimal(按业务选) -->
<property name="forceBigDecimals" value="false" />
</javaTypeResolver>
<!-- 4. 实体类(Model)生成配置(【按需修改】生成路径) -->
<javaModelGenerator
targetPackage="cn.tx.model" <!-- 实体类存放的包名 -->
targetProject=".\ham-core\src\main\java"> <!-- 存放目录(相对路径/绝对路径均可) -->
<property name="enableSubPackages" value="false" /> <!-- 是否按数据库schema分包(false=不分包) -->
<property name="trimStrings" value="true" /> <!-- 去除字段值前后空格(推荐true) -->
</javaModelGenerator>
<!-- 5. Mapper映射文件(XML)生成配置(【按需修改】) -->
<sqlMapGenerator
targetPackage="mapper" <!-- XML文件存放的包名(resources下) -->
targetProject=".\ham-core\src\main\resources">
<property name="enableSubPackages" value="false" />
</sqlMapGenerator>
<!-- 6. Mapper接口(Dao)生成配置(【按需修改】) -->
<javaClientGenerator
type="XMLMAPPER" <!-- 生成方式:XMLMAPPER(接口+XML分离,推荐) -->
targetPackage="cn.tx.dao" <!-- Mapper接口存放的包名 -->
targetProject=".\ham-core\src\main\java">
<property name="enableSubPackages" value="false" />
</javaClientGenerator>
<!-- 7. 指定要生成的数据库表(【必须修改】核心!) -->
<!-- tableName:数据库表名(支持通配符,如t_*=所有t_开头的表) -->
<!-- domainObjectName:实体类名(默认驼峰,可自定义,如songer→Songer) -->
<!-- enable*ByExample:关闭复杂查询(Example),只生成基础CRUD(推荐false) -->
<table
tableName="songer" <!-- 要生成的数据库表名 -->
domainObjectName="Songer" <!-- 对应实体类名 -->
enableCountByExample="false"
enableUpdateByExample="false"
enableDeleteByExample="false"
enableSelectByExample="false"
selectByExampleQueryId="false"/>
<!-- 如需生成多张表,复制上面的<table>标签修改即可 -->
<!-- <table tableName="album" domainObjectName="Album" .../> -->
</context>
</generatorConfiguration>
关键配置注意事项(避坑重点)
- 数据库连接 URL(高频坑):
- MySQL8 必须添加
serverTimezone=CTT(中国时区),否则会报时区错误 - XML 中
&需转义为&,否则配置文件解析失败 - 中文乱码解决:强制添加
useUnicode=true&characterEncoding=utf-8
- MySQL8 必须添加
- targetProject 路径(高频坑):
- 相对路径:以「项目根目录」为基准,如
./ham-core/src/main/java(前面的./不能少) - 绝对路径(推荐,避免路径错误):如
D:/workspace/ham-core/src/main/java
- 相对路径:以「项目根目录」为基准,如
- table 标签配置:
- 若数据库表名带下划线(如
song_id),生成的实体类属性会自动转为驼峰(songId) - 若想生成「带备注的实体类」,关闭
suppressAllComments,并添加addRemarkComments=true
- 若数据库表名带下划线(如
四、逆向工程执行(两种方式,推荐方式 1)
配置完成后,执行生成代码,两种方式任选,优先选「Java 代码执行」(灵活可控,新手易排查错误)
方式 1:Java 代码执行(推荐)
- 创建执行类:
cn.tx.generator.Generator(包路径按自己的目录调整) - 复制以下代码,仅需修改 1 处:配置文件路径
package cn.tx.generator;
import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.config.Configuration;
import org.mybatis.generator.config.xml.ConfigurationParser;
import org.mybatis.generator.internal.DefaultShellCallback;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
/**
* MyBatis逆向工程执行类(直接运行main方法即可生成代码)
*/
public class Generator {
public static void main(String[] args) throws Exception {
// 1. 存储生成过程中的警告信息
List<String> warnings = new ArrayList<>();
// 2. 是否覆盖已存在的代码(true=覆盖,false=不覆盖,新手推荐true)
boolean overwrite = true;
// 3. 【必须修改】逆向工程配置文件路径(与generatorConfig.xml路径一致)
File configFile = new File("ham-core/src/main/resources/generatorConfig.xml");
// 4. 解析配置文件并执行生成
ConfigurationParser parser = new ConfigurationParser(warnings);
Configuration config = parser.parseConfiguration(configFile);
DefaultShellCallback callback = new DefaultShellCallback(overwrite);
MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
myBatisGenerator.generate(null);
// 5. 输出警告信息(若有错误,在这里查看)
for (String warning : warnings) {
System.out.println(warning);
}
System.out.println("✅ 逆向工程执行完成!请查看model、dao、mapper目录");
}
}
3.执行步骤:
- 右键运行
main方法 - 无报错即生成成功,查看对应目录(model、dao、mapper)是否有生成的文件
方式 2:Maven 插件执行(便捷,无需写执行类)
- 在
pom.xml的build标签中添加 MBG 插件:
<build>
<plugins>
<!-- MyBatis逆向工程Maven插件 -->
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.7</version>
<dependencies>
<!-- 插件需单独引入数据库驱动(必加) -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
</dependencies>
<configuration>
<!-- 配置文件路径(与generatorConfig.xml一致) -->
<configurationFile>src/main/resources/generatorConfig.xml</configurationFile>
<overwrite>true</overwrite> <!-- 覆盖已存在文件 -->
<verbose>true</verbose> <!-- 输出执行日志 -->
</configuration>
</plugin>
</plugins>
</build>
2.执行步骤:
- IDEA 中:打开 Maven 面板 → Plugins → mybatis-generator → 双击
mybatis-generator:generate - 命令行:进入项目根目录,执行
mvn mybatis-generator:generate
执行成功验证(必做)
生成后会自动创建 3 类文件,缺一不可:
- 实体类:
cn.tx.model.Songer.java(含字段、getter/setter、toString) - Mapper 接口:
cn.tx.dao.SongerMapper.java(含 insert、selectByPrimaryKey 等基础 CRUD 方法) - Mapper 映射文件:
src/main/resources/mapper/SongerMapper.xml(含对应 SQL 语句)
五、Spring 整合 MyBatis(核心,让代码可运行)
逆向工程生成的是「数据层(Dao)」,需整合 Spring 才能注入使用,核心配置在beans.xml和sqlMapConfig.xml中,步骤如下:
5.1 数据库配置文件(db.properties)
集中管理数据库连接信息,放在resources下,避免硬编码:
# MySQL5配置(直接复制)
driverClass=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/ham?serverTimezone=CTT&useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true
uname=root
pword=root
# MySQL8配置(需使用时,注释上面4行,打开下面4行)
# driverClass=com.mysql.cj.jdbc.Driver
# url=jdbc:mysql://localhost:3306/ham?serverTimezone=CTT&useSSL=false&useUnicode=true&characterEncoding=utf-8
# uname=root
# pword=root
5.2 Spring 核心配置(beans.xml)
放在resources下,整合数据源、SqlSessionFactory、Mapper 扫描、事务,完整配置如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- 1. 扫描注解(Service、Component等,包名按自己的调整) -->
<context:component-scan base-package="cn.tx"/>
<!-- 2. 加载数据库配置文件(db.properties) -->
<context:property-placeholder location="classpath:db.properties"/>
<!-- 3. 配置Druid数据源(核心,替代默认连接池) -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${driverClass}"/>
<property name="url" value="${url}"/>
<property name="username" value="${uname}"/>
<property name="password" value="${pword}"/>
</bean>
<!-- 4. 配置SqlSessionFactory(MyBatis核心,关联数据源和MyBatis全局配置) -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/> <!-- 关联数据源 -->
<property name="configLocation" value="classpath:sqlMapConfig.xml"/> <!-- 关联MyBatis全局配置 -->
</bean>
<!-- 5. Mapper接口扫描(【关键】自动生成Mapper实现类,注入Spring) -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/> <!-- 关联SqlSessionFactory -->
<property name="basePackage" value="cn.tx.dao"/> <!-- Mapper接口所在包(递归扫描) -->
</bean>
<!-- 6. 事务配置(可选,Service层增删改需事务,推荐配置) -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 事务通知:配置哪些方法需要事务 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="add*" propagation="REQUIRED"/> <!-- 新增方法:必须有事务 -->
<tx:method name="update*" propagation="REQUIRED"/> <!-- 更新方法 -->
<tx:method name="del*" propagation="REQUIRED"/> <!-- 删除方法 -->
<tx:method name="select*" read-only="true"/> <!-- 查询方法:只读事务(优化性能) -->
<tx:method name="get*" read-only="true"/>
</tx:attributes>
</tx:advice>
<!-- AOP配置:事务作用于Service层 -->
<aop:config>
<aop:advisor advice-ref="txAdvice" pointcut="execution(* cn.tx.service..*.*(..))"/>
</aop:config>
</beans>
5.3 MyBatis 全局配置(sqlMapConfig.xml)
放在resources下,主要作用是注册 Mapper 映射文件,简化配置:
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 可选:开启驼峰命名自动转换(数据库字段名_abc → Java属性名abc) -->
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
<setting name="logImpl" value="STDOUT_LOGGING"/> <!-- 打印SQL日志(调试用) -->
</settings>
<!-- 注册Mapper映射文件(两种方式,选一种即可) -->
<mappers>
<!-- 方式1:单个注册(适合少量表) -->
<mapper resource="mapper/SongerMapper.xml"/>
<!-- <mapper resource="mapper/AlbumMapper.xml"/> -->
<!-- 方式2:批量注册(推荐,扫描mapper目录下所有XML) -->
<!-- <package name="mapper"/> -->
</mappers>
</configuration>
六、Service 层封装(基于生成的 Mapper)
逆向工程生成的是数据层(Dao),需手动封装 Service 层(业务逻辑层),实现 CRUD 业务,代码如下(以 Songer 为例):
6.1 Service 接口(cn.tx.service.SongerService)
package cn.tx.service;
import cn.tx.model.Songer;
import java.util.List;
/**
* Songer业务接口(基础CRUD+按需扩展)
*/
public interface SongerService {
// 新增歌手
void addSonger(Songer songer);
// 根据主键查询歌手
Songer getSongerById(Integer id);
// 选择性更新歌手(只更新非null字段,推荐)
void updateSonger(Songer songer);
// 根据主键删除歌手
void delSongerById(Integer id);
// 查询所有歌手(需手动扩展Mapper方法)
List<Songer> getAllSonger();
}
6.2 Service 实现类(cn.tx.service.impl.SongerServiceImpl)
package cn.tx.service.impl;
import cn.tx.dao.SongerMapper;
import cn.tx.model.Songer;
import cn.tx.service.SongerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* Songer业务实现类(注入Mapper,调用数据层方法)
*/
@Service // 交给Spring管理,允许@Autowired注入
public class SongerServiceImpl implements SongerService {
// 注入逆向工程生成的Mapper接口(Spring自动生成实现类,无需手动写)
@Autowired
private SongerMapper songerMapper;
@Override
public void addSonger(Songer songer) {
songerMapper.insert(songer); // 调用逆向工程生成的insert方法
}
@Override
public Songer getSongerById(Integer id) {
return songerMapper.selectByPrimaryKey(id); // 调用生成的查询方法
}
@Override
public void updateSonger(Songer songer) {
songerMapper.updateByPrimaryKeySelective(songer); // 选择性更新
}
@Override
public void delSongerById(Integer id) {
songerMapper.deleteByPrimaryKey(id); // 调用生成的删除方法
}
@Override
public List<Songer> getAllSonger() {
// 若逆向工程未生成selectAll方法,需手动在SongerMapper接口+XML中扩展
return songerMapper.selectObjectAll();
}
}
七、测试验证(SpringJUnit,必做,避免踩坑)
通过 JUnit 测试整合结果,确保 Dao、Service、Spring 能正常联动,测试类放在src/test/java/cn/tx/test下:
package cn.tx.test;
import cn.tx.model.Songer;
import cn.tx.service.SongerService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* Songer业务测试类(Spring+JUnit4整合)
*/
// 固定注解:整合Spring和JUnit4
@RunWith(SpringJUnit4ClassRunner.class)
// 加载Spring配置文件(beans.xml路径)
@ContextConfiguration(locations = "classpath:beans.xml")
public class SongerTest {
// 注入Service(测试Service层,间接测试Dao层)
@Autowired
private SongerService songerService;
// 测试新增(先执行此方法)
@Test
public void testAdd() {
Songer songer = new Songer();
songer.setArea("北京");
songer.setIntro("测试歌手");
songer.setIsHot(1);
songer.setPic("test.jpg");
songer.setSrname("测试名称");
songerService.addSonger(songer);
System.out.println("✅ 新增歌手成功!");
}
// 测试查询(新增成功后执行)
@Test
public void testGetById() {
Songer songer = songerService.getSongerById(1); // 主键id按实际新增的调整
System.out.println("✅ 查询结果:" + songer);
}
// 测试更新(查询成功后执行)
@Test
public void testUpdate() {
Songer songer = songerService.getSongerById(1);
songer.setSrname("更新后的歌手名称");
songerService.updateSonger(songer);
System.out.println("✅ 更新歌手成功!");
}
// 测试删除(最后执行)
@Test
public void testDelete() {
songerService.delSongerById(1);
System.out.println("✅ 删除歌手成功!");
}
}
测试注意事项(避坑)
- 测试前必须启动 MySQL 服务,且
ham数据库、songer表已创建(字段与实体类一致) - 测试方法执行顺序:
testAdd→testGetById→testUpdate→testDelete - 若出现「Mapper 注入失败」:检查
beans.xml中MapperScannerConfigurer的basePackage是否为cn.tx.dao - 若出现「SQL 执行失败」:打开
sqlMapConfig.xml的 SQL 日志,查看打印的 SQL,核对表名、字段名是否正确
八、公共代码抽取(优化扩展,多表场景必用)
当项目中有多个实体类(如 Songer、Album、User)时,每个实体类都要写 Dao、Service,会有大量重复代码,此时抽取「公共 BaseDao、BaseService」,简化开发:
8.1 公共 BaseDao 接口(cn.tx.dao.BaseDao)
所有 Mapper 接口继承此类,无需重复声明基础 CRUD 方法:
package cn.tx.dao;
import java.util.List;
/**
* 公共Dao接口(所有Mapper接口的父接口)
* @param <T> 实体类泛型(适配不同实体类)
*/
public interface BaseDao<T> {
// 基础CRUD方法(与逆向工程生成的方法一致)
void insert(T t);
T selectByPrimaryKey(Integer id);
void deleteByPrimaryKey(Integer id);
void updateByPrimaryKeySelective(T t);
List<T> selectObjectAll(); // 自定义查询所有(需在XML中手动实现)
}
8.2 Mapper 接口简化(继承 BaseDao)
package cn.tx.dao;
import cn.tx.model.Songer;
// 继承BaseDao,无需重复写CRUD方法(直接复用)
public interface SongerMapper extends BaseDao<Songer> {
// 按需扩展自定义方法(如复杂查询)
}
8.3 公共 BaseService 接口(cn.tx.service.BaseService)
package cn.tx.service;
import java.util.List;
/**
* 公共Service接口(所有Service接口的父接口)
* @param <T> 实体类泛型
*/
public interface BaseService<T> {
void insert(T t);
T selectByPrimaryKey(Integer id);
void deleteByPrimaryKey(Integer id);
void updateByPrimaryKeySelective(T t);
List<T> selectObjectAll();
}
8.4 公共 BaseService 实现类(cn.tx.service.impl.BaseServiceImpl)
package cn.tx.service.impl;
import cn.tx.dao.BaseDao;
import cn.tx.service.BaseService;
import java.util.List;
/**
* 公共Service实现类(抽象类,所有Service实现类继承)
* @param <T> 实体类泛型
*/
public abstract class BaseServiceImpl<T> implements BaseService<T> {
// 由子类注入具体的Mapper(父类定义,子类赋值)
protected BaseDao<T> baseDao;
// 抽象方法:子类必须实现,注入具体的Mapper
public abstract void setBaseDao(BaseDao<T> baseDao);
// 复用基础CRUD方法(无需子类重复写)
@Override
public void insert(T t) {
baseDao.insert(t);
}
@Override
public T selectByPrimaryKey(Integer id) {
return baseDao.selectByPrimaryKey(id);
}
@Override
public void deleteByPrimaryKey(Integer id) {
baseDao.deleteByPrimaryKey(id);
}
@Override
public void updateByPrimaryKeySelective(T t) {
baseDao.updateByPrimaryKeySelective(t);
}
@Override
public List<T> selectObjectAll() {
return baseDao.selectObjectAll();
}
}
8.5 子类 Service 实现类简化(以 Album 为例)
package cn.tx.service.impl;
import cn.tx.dao.AlbumMapper;
import cn.tx.dao.BaseDao;
import cn.tx.model.Album;
import cn.tx.service.AlbumService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* Album业务实现类(继承公共BaseServiceImpl,简化代码)
*/
@Service
public class AlbumServiceImpl extends BaseServiceImpl<Album> implements AlbumService {
// 注入具体的Mapper(AlbumMapper)
@Autowired
private AlbumMapper albumMapper;
// 实现父类抽象方法,注入baseDao
@Override
public void setBaseDao(BaseDao<Album> baseDao) {
this.baseDao = baseDao;
}
// 注入AlbumMapper,给baseDao赋值
@Autowired
public void setAlbumMapper(AlbumMapper albumMapper) {
this.albumMapper = albumMapper;
this.baseDao = albumMapper;
}
}
九、常见问题与解决方案(高频坑,必看)
| 问题描述 | 核心原因 | 解决方案 |
|---|---|---|
| 逆向工程执行失败,提示「配置文件找不到」 | generatorConfig.xml 路径错误 | 1. 改用绝对路径(如 D:/xxx/generatorConfig.xml);2. 相对路径以项目根目录为基准,核对层级 |
| 生成的实体类字段与数据库表字段不一致 | 未开启驼峰命名转换 | 在 sqlMapConfig.xml 中添加<setting name="mapUnderscoreToCamelCase" value="true"/> |
| Mapper 接口注入失败(@Autowired 报红) | 1. 未配置 MapperScannerConfigurer;2. basePackage 错误 | 1. 检查 beans.xml 中是否配置 MapperScannerConfigurer;2. 确认 basePackage 是 Mapper 接口所在包(cn.tx.dao) |
| 测试时提示「数据库连接失败」 | 1. 数据库未启动;2. 连接信息错误;3. 驱动版本不匹配 | 1. 启动 MySQL 服务;2. 核对 db.properties 的用户名、密码、数据库名;3. MySQL8 用 8.x 驱动,MySQL5 用 5.x 驱动 |
| 逆向工程生成的 XML 中 SQL 报错 | 数据库字段类型与 Java 类型映射错误 | 在 generatorConfig.xml 的<table>标签中添加<columnOverride column="字段名" javaType="Java类型"/> |
| 执行新增方法后,数据库无数据 | 未配置事务,新增方法抛异常未回滚 | 1. 配置 beans.xml 中的事务;2. 检查实体类字段是否与表字段一致(如主键是否自增) |
十、实用技巧(提升开发效率)
- 批量生成多张表:在 generatorConfig.xml 中添加多个<table>标签,或用通配符
tableName="t_*"(生成所有 t_开头的表) - 保留手动修改的代码:将执行类中的
overwrite改为false,逆向工程只会生成「新增表」的代码,不会覆盖已修改的代码 - 生成带备注的实体类:关闭
suppressAllComments,添加<property name="addRemarkComments" value="true"/>,实体类会显示数据库字段备注 - 调试 SQL:在 sqlMapConfig.xml 中开启
STDOUT_LOGGING,打印执行的 SQL、参数、返回值,快速排查 SQL 错误 - 多环境适配:将 db.properties 按环境拆分(db-dev.properties、db-test.properties),在 beans.xml 中通过
profile切换环境
总结
MyBatis 逆向工程是 SSM 项目的「效率神器」,核心流程可概括为:配置generatorConfig.xml → 执行逆向工程生成代码 → Spring整合MyBatis → 封装Service层 → 测试验证 → 公共代码抽取优化
本文所有代码均经过实测,可直接复制到项目中使用,新手只需修改「数据库连接信息、生成路径、数据库表名」3 处,即可快速上手。多表场景下,通过公共 BaseDao、BaseService 抽取,可大幅减少重复代码,提升项目可维护性。
如果觉得本文有用,欢迎点赞 + 收藏,后续会持续更新 SSM 项目实战技巧~
更多推荐



所有评论(0)