若依框架中MyBatis依赖的引入方式详解
若依(RuoYi)作为一款基于Spring Boot的快速开发框架,在持久层选型上选择了MyBatis作为ORM框架。MyBatis凭借其灵活性和对复杂查询的强大支持,在企业级应用开发中占据重要地位。本文将详细剖析若依框架中MyBatis依赖的引入机制与配置方式。
一、Maven依赖的声明与管理
若依框架遵循Maven项目结构,在根pom.xml文件中声明核心依赖版本号,在子模块的pom.xml中引入具体依赖。MyBatis相关依赖的引入主要通过以下几个步骤完成。
1. 父工程中定义版本号
在若依框架根级别pom.xml中,通过<properties>标签统一管理MyBatis及其相关组件的版本号,确保各模块版本一致。
<properties>
<!-- 其他属性 -->
<mybatis-spring-boot-starter.version>2.2.2</mybatis-spring-boot-starter.version>
<pagehelper-spring-boot-starter.version>1.4.1</pagehelper-spring-boot-starter.version>
<druid.version>1.2.11</druid.version>
</properties>通过集中管理版本号,若依框架能够轻松维护依赖之间的兼容性。当需要升级MyBatis版本时,只需修改一处即可。
2. 子模块引入具体依赖
在ruoyi-framework子模块的pom.xml中,声明对MyBatis及配套组件的实际依赖。以下是关键依赖片段:
<!-- MyBatis Spring Boot Starter -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>${mybatis-spring-boot-starter.version}</version>
</dependency>
<!-- PageHelper 分页插件 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>${pagehelper-spring-boot-starter.version}</version>
</dependency>
<!-- Druid 数据库连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>${druid.version}</version>
</dependency>这三个依赖是若依框架持久层的核心支柱。mybatis-spring-boot-starter提供自动配置能力,pagehelper-spring-boot-starter实现物理分页,druid-spring-boot-starter则提供高效的连接池和监控功能。
二、数据源与MyBatis配置
若依框架通过YAML配置文件对数据源和MyBatis运行参数进行精细化控制。
1. 数据源配置
在application-druid.yml文件中配置Druid连接池和数据源信息:
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
druid:
# 主库数据源
master:
url: jdbc:mysql://localhost:3306/ruoyi?useUnicode=true&characterEncoding=utf8mb4&serverTimezone=Asia/Shanghai
username: root
password: root
# 从库数据源(可选配置)
slave:
enabled: false
url:
username:
password:
# 连接池配置
initial-size: 5
min-idle: 5
max-active: 20
max-wait: 60000
time-between-eviction-runs-millis: 60000
min-evictable-idle-time-millis: 300000
validation-query: SELECT 1 FROM DUAL
test-while-idle: true
test-on-borrow: false
test-on-return: false
pool-prepared-statements: true
max-pool-prepared-statement-per-connection-size: 20
filters: stat,wall,log4j2上述配置中,master节点定义了主数据库的连接信息,slave节点预留了读写分离的扩展能力。Druid的连接池参数经过精心调优,适应企业级应用的高并发场景。
2. MyBatis全局配置
在application.yml中设置MyBatis的运行参数:
mybatis:
# 指定实体类所在包
type-aliases-package: com.ruoyi.**.domain
# 映射文件路径
mapper-locations: classpath*:mapper/**/*Mapper.xml
# 核心配置
configuration:
# 开启驼峰命名转换
map-underscore-to-camel-case: true
# 开启二级缓存
cache-enabled: true
# 设置懒加载
lazy-loading-enabled: true
aggressive-lazy-loading: false
# 日志实现
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl通过type-aliases-package配置,MyBatis能够自动识别若依框架中所有domain包下的实体类,无需为每个实体类配置别名。mapper-locations指定了SQL映射文件的位置,支持通配符匹配。
三、核心配置类的支持
若依框架通过Java配置类对MyBatis进行深度定制,实现读写分离、分页插件注册等功能。
1. Druid数据源配置类
DruidConfig类负责创建Druid数据源并注册监控Servlet和过滤器:
@Configuration
public class DruidConfig {
@Bean
@ConfigurationProperties("spring.datasource.druid.master")
public DataSource masterDataSource() {
return DruidDataSourceBuilder.create().build();
}
@Bean
@ConditionalOnProperty(prefix = "spring.datasource.druid.slave", name = "enabled", havingValue = "true")
@ConfigurationProperties("spring.datasource.druid.slave")
public DataSource slaveDataSource() {
return DruidDataSourceBuilder.create().build();
}
@Bean
public ServletRegistrationBean druidServlet() {
ServletRegistrationBean reg = new ServletRegistrationBean();
reg.setServlet(new StatViewServlet());
reg.addUrlMappings("/druid/*");
// 设置管理员账号密码
reg.addInitParameter("loginUsername", "admin");
reg.addInitParameter("loginPassword", "admin");
return reg;
}
@Bean
public FilterRegistrationBean webStatFilter() {
FilterRegistrationBean bean = new FilterRegistrationBean();
bean.setFilter(new WebStatFilter());
bean.addUrlPatterns("/*");
bean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
return bean;
}
}该配置类根据配置文件中的master和slave前缀,创建对应的数据源Bean。同时注册Druid内置的StatViewServlet用于监控页面访问,WebStatFilter用于采集Web请求统计信息。
2. MyBatis配置类
MyBatisConfig类负责注册分页插件和配置SqlSessionFactory:
@Configuration
@MapperScan(basePackages = {"com.ruoyi.**.mapper"}, sqlSessionFactoryRef = "sqlSessionFactory")
public class MyBatisConfig {
@Bean
public PageInterceptor pageInterceptor() {
PageInterceptor interceptor = new PageInterceptor();
Properties properties = new Properties();
properties.setProperty("helperDialect", "mysql");
properties.setProperty("reasonable", "true");
properties.setProperty("supportMethodsArguments", "true");
properties.setProperty("params", "count=countSql");
interceptor.setProperties(properties);
return interceptor;
}
@Bean(name = "sqlSessionFactory")
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
MybatisSqlSessionFactoryBean bean = new MybatisSqlSessionFactoryBean();
bean.setDataSource(dataSource);
// 设置实体类别名包
bean.setTypeAliasesPackage("com.ruoyi.**.domain");
// 设置Mapper XML文件路径
bean.setMapperLocations(new PathMatchingResourcePatternResolver()
.getResources("classpath*:mapper/**/*Mapper.xml"));
// 注册分页插件
bean.setPlugins(pageInterceptor());
return bean.getObject();
}
}@MapperScan注解指定了Mapper接口的扫描路径,若依框架约定所有Mapper接口位于com.ruoyi.**.mapper包下。PageInterceptor是PageHelper分页组件的核心,通过helperDialect属性指定数据库方言为MySQL。
四、Mapper与XML映射的实践
若依框架遵循MyBatis的标准开发模式,每个Mapper接口对应一个XML映射文件。
1. Mapper接口示例
@Repository
public interface SysUserMapper {
/**
* 根据条件分页查询用户列表
*/
List<SysUser> selectUserList(SysUser user);
/**
* 通过用户名查询用户
*/
SysUser selectUserByUserName(String userName);
/**
* 新增用户信息
*/
int insertUser(SysUser user);
/**
* 修改用户信息
*/
int updateUser(SysUser user);
/**
* 批量删除用户信息
*/
int deleteUserByIds(Long[] userIds);
}Mapper接口中的方法名称与XML映射文件中的id属性保持一致,MyBatis通过动态代理机制将接口调用映射到具体的SQL执行。
2. 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.ruoyi.system.mapper.SysUserMapper">
<resultMap type="SysUser" id="SysUserResult">
<id property="userId" column="user_id" />
<result property="userName" column="user_name" />
<result property="password" column="password" />
<result property="status" column="status" />
<result property="createTime" column="create_time" />
</resultMap>
<select id="selectUserList" parameterType="SysUser" resultMap="SysUserResult">
SELECT u.user_id, u.user_name, u.password, u.status, u.create_time
FROM sys_user u
WHERE u.del_flag = '0'
<if test="userName != null and userName != ''">
AND u.user_name LIKE CONCAT('%', #{userName}, '%')
</if>
<if test="status != null and status != ''">
AND u.status = #{status}
</if>
ORDER BY u.create_time DESC
</select>
<insert id="insertUser" parameterType="SysUser" useGeneratedKeys="true" keyProperty="userId">
INSERT INTO sys_user (
user_name, password, status, create_time
) VALUES (
#{userName}, #{password}, #{status}, sysdate()
)
</insert>
</mapper>XML映射文件通过namespace属性与Mapper接口绑定,resultMap定义了数据库字段与实体类属性的映射关系。若依框架大量使用动态SQL(如<if>标签)来构建灵活的查询条件。
五、自动配置的原理与优势
若依框架选择mybatis-spring-boot-starter而非直接引入MyBatis核心库,主要基于以下考虑:
- 自动装配简化开发:Starter包自动配置
SqlSessionFactory和SqlSessionTemplate,开发者无需手动创建这些核心Bean。 - 约定优于配置:Starter遵循Spring Boot的自动配置哲学,提供合理的默认值,开发者只需关注个性化的配置项。
- 与Spring Boot生命周期整合:Starter能够感知应用的启动和关闭事件,正确管理数据库连接的创建和销毁。
六、依赖引入的常见问题排查
在引入MyBatis依赖时,若依框架的开发者可能会遇到以下典型问题:
| 问题现象 | 可能原因 | 解决方案 |
|---|---|---|
启动报错Invalid bound statement (not found) | Mapper XML文件路径配置错误或XML文件未被扫描 | 检查mapper-locations配置是否为classpath*:mapper/**/*Mapper.xml,确认XML文件放置在正确目录 |
| 分页查询不生效 | PageHelper插件未正确注册 | 确认PageInterceptor Bean是否存在,同时检查pagehelper-spring-boot-starter依赖是否完整引入 |
| 数据源连接失败 | Druid数据源配置中的URL、账号或密码有误 | 核对application-druid.yml中的连接信息,测试数据库是否可正常访问 |
| MyBatis二级缓存不生效 | cache-enabled配置为false或Mapper XML中未配置<cache>标签 | 将cache-enabled设置为true,并在需要缓存的Mapper XML中添加<cache/>标签 |
七、总结
若依框架通过Maven依赖管理机制,合理引入了mybatis-spring-boot-starter、pagehelper-spring-boot-starter和druid-spring-boot-starter三个核心组件,构建了一套高效、稳定的持久层解决方案。依赖的引入遵循了Spring Boot的自动配置理念,配合细致的YAML配置和Java配置类,使开发者能够快速上手并进行深度定制。理解这一依赖引入机制,对于掌握若依框架的整体架构设计和日常开发维护具有重要意义。