【Java实战㉟】Spring Boot与MyBatis:数据库交互的进阶之旅
目录
- 一、Spring Boot 整合 MyBatis 基础
- 1.1 整合依赖导入
- 1.2 核心配置
- 1.3 Mapper 接口与映射文件
- 1.4 简化开发
- 二、Spring Boot 整合 MyBatis 进阶
- 2.1 分页插件
- 2.2 多数据源配置
- 2.3 事务管理
- 2.4 实战案例
- 三、Spring Boot 整合其他 ORM 框架
- 3.1 Spring Boot 整合 Spring Data JPA
- 3.2 Spring Boot 整合 MyBatis-Plus
- 3.3 不同 ORM 框架对比
一、Spring Boot 整合 MyBatis 基础
1.1 整合依赖导入
在 Spring Boot 项目中,若想整合 MyBatis,首要任务是在pom.xml文件中导入关键依赖。其中,mybatis-spring-boot-starter起着核心作用,它是 Spring Boot 与 MyBatis 整合的桥梁,极大地简化了配置流程,让开发者能轻松将 MyBatis 融入 Spring Boot 项目中。以 Maven 项目为例,在pom.xml中添加如下依赖:
<dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>最新版本号</version>
</dependency>
同时,还需引入数据库驱动依赖,它负责建立 Java 应用与数据库之间的连接,使应用能够与不同类型的数据库进行交互。假设使用 MySQL 数据库,添加 MySQL 驱动依赖如下:
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope>
</dependency>
这里的scope设置为runtime,表明该依赖仅在运行时需要,编译时不会被打包进项目,从而减少了项目的体积。
1.2 核心配置
完成依赖导入后,需在application.yml文件中进行核心配置。数据库连接配置是关键,它包含数据库的地址、端口、名称、用户名和密码等信息。以 MySQL 为例,配置如下:
spring:datasource:url: jdbc:mysql://localhost:3306/your_database_name?useSSL=false&serverTimezone=UTCusername: your_usernamepassword: your_passworddriver-class-name: com.mysql.cj.jdbc.Driver
在上述配置中,url指定了数据库的连接地址,?useSSL=false&serverTimezone=UTC分别表示不使用 SSL 连接以及设置服务器时区为 UTC;username和password是登录数据库的凭证;driver-class-name明确了使用的 JDBC 驱动类。
此外,还需配置 MyBatis 相关属性。例如,指定 Mapper XML 文件的位置和实体类包别名,配置如下:
mybatis:mapper-locations: classpath:mapper/*.xmltype-aliases-package: com.example.demo.entity
mapper-locations用于指定 Mapper XML 文件的路径,这里classpath:mapper/*.xml表示在src/main/resources/mapper目录下查找所有的 XML 文件;type-aliases-package则指定了实体类所在的包路径,这样在 Mapper XML 文件中就可以直接使用实体类名,而无需写全限定名,简化了配置。
1.3 Mapper 接口与映射文件
Mapper 接口是 MyBatis 中操作数据库的关键,它定义了对数据库的各种操作方法。为了让 Spring 能够识别并管理 Mapper 接口,需要在接口上添加@Mapper注解。例如:
import org.apache.ibatis.annotations.Mapper;@Mapper
public interface UserMapper {// 定义数据库操作方法
}
@Mapper注解的作用是将该接口标记为 Mapper 接口,Spring 会自动为其创建代理对象,使得在其他组件中可以通过依赖注入的方式使用该接口来操作数据库。
同时,还需要创建对应的 Mapper XML 文件,用于编写具体的 SQL 语句。Mapper XML 文件通常与 Mapper 接口位于同一包下,且文件名与接口名相同,只是后缀为.xml。例如,UserMapper.xml文件内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.mapper.UserMapper"><!-- 编写SQL语句 -->
</mapper>
其中,namespace属性的值必须与 Mapper 接口的全限定名一致,这样 MyBatis 才能正确地将接口方法与 XML 文件中的 SQL 语句关联起来。
为了让 Spring 能够扫描到 Mapper XML 文件,还需在application.yml中配置扫描路径,如前文所述的mybatis.mapper-locations: classpath:mapper/*.xml,确保 MyBatis 能够加载并解析这些 XML 文件,实现 SQL 语句的执行。
1.4 简化开发
MyBatis Generator 是一个强大的代码生成工具,它能根据数据库表结构自动生成 MyBatis 所需的实体类、Mapper 接口和 Mapper XML 文件,大大减少了开发人员编写重复性代码的工作量。其工作原理是读取配置文件中的数据库连接信息和表结构信息,然后依据这些信息按照既定的模板生成相应的代码文件。
使用 MyBatis Generator,首先要引入相关依赖。在pom.xml中添加:
<dependency><groupId>org.mybatis.generator</groupId><artifactId>mybatis-generator-core</artifactId><version>最新版本号</version>
</dependency>
接着,配置generatorConfig.xml文件,该文件是 MyBatis Generator 的核心配置文件,详细描述了数据库的连接信息、生成代码的规则以及需要生成代码的表等信息。例如:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfigurationPUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN""http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration><properties resource="jdbc.properties"/><context id="Mysql" targetRuntime="MyBatis3"><jdbcConnection driverClass="${jdbc.driver}"connectionURL="${jdbc.url}"userId="${jdbc.username}"password="${jdbc.password}"/><javaModelGenerator targetPackage="com.example.demo.entity"targetProject="src/main/java"/><sqlMapGenerator targetPackage="mapper"targetProject="src/main/resources"/><javaClientGenerator type="XMLMAPPER"targetPackage="com.example.demo.mapper"targetProject="src/main/java"/><table tableName="user" domainObjectName="User"/></context>
</generatorConfiguration>
在上述配置中,<properties>标签用于引入外部属性文件,这里jdbc.properties存放着数据库连接相关的配置;<jdbcConnection>标签指定了数据库的连接信息;<javaModelGenerator>、<sqlMapGenerator>和<javaClientGenerator>分别定义了实体类、Mapper XML 文件和 Mapper 接口的生成位置和命名规则;<table>标签指定了要生成代码的表以及生成的实体类名。
通过合理配置 MyBatis Generator,开发人员只需专注于业务逻辑的实现,而无需花费大量时间在基础的数据访问层代码编写上,提高了开发效率,同时也保证了代码的规范性和一致性。
二、Spring Boot 整合 MyBatis 进阶
2.1 分页插件
在实际的项目开发中,分页功能是非常常见的需求,尤其是在数据量较大的情况下。PageHelper 是一款优秀的 MyBatis 分页插件,它能极大地简化分页操作,提高开发效率。
要在 Spring Boot 项目中整合 PageHelper,首先需要在pom.xml文件中引入依赖:
<dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper-spring-boot-starter</artifactId><version>最新版本号</version>
</dependency>
引入依赖后,还需在application.yml文件中进行简单配置:
pagehelper:helper-dialect: mysql # 数据库方言,根据实际情况选择,这里以MySQL为例reasonable: true # 启用合理化参数,当页码小于1时,自动设置为1;当页码大于总页数时,自动设置为总页数support-methods-arguments: true # 支持通过方法参数来传递分页参数
以查询用户列表为例,展示分页查询的实现过程。假设我们有一个UserMapper接口,其中定义了查询所有用户的方法selectAllUsers。在业务层UserService中,使用 PageHelper 实现分页查询:
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.stereotype.Service;import javax.annotation.Resource;
import java.util.List;@Service
public class UserService {@Resourceprivate UserMapper userMapper;public PageInfo<User> getUserList(int pageNum, int pageSize) {// 设置分页参数,pageNum表示当前页码,pageSize表示每页显示的记录数PageHelper.startPage(pageNum, pageSize);// 执行查询操作,这里调用UserMapper中的查询方法List<User> userList = userMapper.selectAllUsers();// 使用PageInfo对查询结果进行封装,方便获取分页相关信息,如总页数、总记录数等return new PageInfo<>(userList);}
}
在上述代码中,PageHelper.startPage(pageNum, pageSize)方法用于设置分页参数,它会在执行后续的 SQL 查询语句时,自动为其添加分页相关的逻辑。PageInfo类则用于封装查询结果,通过它可以方便地获取总页数、总记录数、当前页数据等信息。
2.2 多数据源配置
在一些复杂的业务场景中,一个应用可能需要连接多个数据源,比如读写分离场景下,需要一个主数据源用于写操作,多个从数据源用于读操作;或者在处理不同业务模块时,需要连接不同类型的数据库。
配置主从数据源时,首先要在application.yml文件中配置多个数据源的连接信息。以 MySQL 数据库为例,配置如下:
spring:datasource:dynamic:primary: master # 设置主数据源strict: false # 开启严格模式,默认false,设置为true时,未匹配到指定数据源会抛出异常datasource:master:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/master_db?useSSL=false&serverTimezone=UTCusername: rootpassword: rootslave1:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/slave1_db?useSSL=false&serverTimezone=UTCusername: rootpassword: rootslave2:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/slave2_db?useSSL=false&serverTimezone=UTCusername: rootpassword: root
上述配置中,spring.datasource.dynamic.primary指定了主数据源为master;spring.datasource.dynamic.datasource下分别配置了主数据源master和两个从数据源slave1、slave2的连接信息。
为了实现动态数据源切换,通常会使用 AOP(面向切面编程)和自定义注解。首先定义一个自定义注解,用于标识方法使用的数据源,例如:
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface DataSource {String value() default "master";
}
然后创建一个切面类,在方法执行前根据注解切换数据源:
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;@Aspect
@Component
public class DataSourceAspect {@Around("@annotation(dataSource)")public Object around(ProceedingJoinPoint point, DataSource dataSource) throws Throwable {// 获取注解中的数据源名称String ds = dataSource.value();// 切换数据源DynamicDataSourceContextHolder.push(ds);try {// 执行目标方法return point.proceed();} finally {// 清除数据源,保证线程安全DynamicDataSourceContextHolder.poll();}}
}
在实际应用中,在需要切换数据源的方法上添加@DataSource注解,即可实现不同数据源的切换。例如:
import org.springframework.stereotype.Service;@Service
public class UserService {@DataSource("slave1")public void readDataFromSlave1() {// 从slave1数据源读取数据的逻辑}@DataSource("master")public void writeDataToMaster() {// 向master数据源写入数据的逻辑}
}
在配置多数据源时,要注意数据源的连接池配置、事务管理等问题。不同的数据源可能需要不同的连接池参数,同时事务管理也需要根据实际情况进行配置,以确保数据的一致性和完整性。
2.3 事务管理
在企业级应用开发中,事务管理是确保数据一致性和完整性的关键。Spring 提供了强大的事务管理功能,通过@Transactional注解可以方便地实现声明式事务管理。
@Transactional注解可以作用于类或方法上。当作用于类上时,该类中的所有公共方法都将应用事务管理;当作用于方法上时,只有该方法会应用事务管理。例如,在一个用户服务类UserService中,对保存用户的方法添加事务管理:
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;@Service
public class UserService {@Transactionalpublic void saveUser(User user) {// 保存用户的逻辑,可能涉及多个数据库操作userMapper.insertUser(user);// 其他可能的数据库操作}
}
在上述代码中,@Transactional注解使用了默认配置,即事务传播行为为Propagation.REQUIRED,事务隔离级别为Isolation.DEFAULT。
事务传播行为定义了一个事务方法在被另一个事务方法调用时,事务应该如何传播。Spring 提供了 7 种事务传播行为:
- Propagation.REQUIRED(默认):如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。适用于大多数业务场景,比如一个业务方法中调用多个其他业务方法,这些方法都需要在同一个事务中执行。
- Propagation.REQUIRES_NEW:创建一个新的事务,如果当前存在事务,则挂起当前事务。常用于需要独立事务执行的场景,例如日志记录,即使主业务事务回滚,日志记录也应成功提交。
- Propagation.SUPPORTS:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务方式执行。适用于方法可以在事务或非事务环境下执行的场景,比如一些只读操作,不需要事务支持也能正常执行。
- Propagation.MANDATORY:如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。适用于方法必须在事务中执行的场景,否则会抛出异常。
- Propagation.NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,则挂起当前事务。适用于不需要事务支持的操作,比如一些性能要求较高的查询操作,不希望受到事务的影响。
- Propagation.NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。适用于方法不能在事务中执行的场景,否则会抛出异常。
- Propagation.NESTED:如果当前存在事务,则在嵌套事务内执行;如果当前没有事务,则创建一个新的事务。适用于需要嵌套事务的场景,例如在一个大事务中,某些操作需要有自己的子事务,子事务回滚不会影响大事务,但大事务回滚会导致子事务回滚。
在实际应用中,应根据业务需求选择合适的事务传播行为,以确保事务的正确执行和数据的一致性。
2.4 实战案例
以用户订单管理模块开发为例,深入了解 MyBatis 在实际项目中的应用。该模块主要涉及用户订单的创建、查询、更新和删除等操作,通过 MyBatis 实现数据持久化。
首先,创建数据库表。假设我们有两张表:users表用于存储用户信息,orders表用于存储订单信息,orders表通过user_id与users表关联。创建表的 SQL 语句如下:
-- 创建users表
CREATE TABLE users (id INT AUTO_INCREMENT PRIMARY KEY,username VARCHAR(50) NOT NULL,password VARCHAR(50) NOT NULL
);-- 创建orders表
CREATE TABLE orders (id INT AUTO_INCREMENT PRIMARY KEY,order_number VARCHAR(50) NOT NULL,user_id INT NOT NULL,order_amount DECIMAL(10, 2) NOT NULL,FOREIGN KEY (user_id) REFERENCES users(id)
);
接着,创建实体类。在 Java 项目中,创建User和Order实体类,用于映射数据库表结构。例如:
public class User {private Integer id;private String username;private String password;// 省略getter和setter方法
}public class Order {private Integer id;private String orderNumber;private Integer userId;private BigDecimal orderAmount;// 省略getter和setter方法
}
然后,创建 Mapper 接口和映射文件。在UserMapper接口中定义用户相关的数据库操作方法,在OrderMapper接口中定义订单相关的操作方法。例如:
import org.apache.ibatis.annotations.Mapper;@Mapper
public interface UserMapper {void insertUser(User user);User selectUserById(Integer id);
}@Mapper
public interface OrderMapper {void insertOrder(Order order);Order selectOrderById(Integer id);List<Order> selectOrdersByUserId(Integer userId);
}
对应的UserMapper.xml和OrderMapper.xml文件中编写具体的 SQL 语句。以OrderMapper.xml为例:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.mapper.OrderMapper"><insert id="insertOrder" parameterType="Order">INSERT INTO orders (order_number, user_id, order_amount)VALUES (#{orderNumber}, #{userId}, #{orderAmount})</insert><select id="selectOrderById" resultType="Order">SELECT * FROM orders WHERE id = #{id}</select><select id="selectOrdersByUserId" resultType="Order">SELECT * FROM orders WHERE user_id = #{userId}</select>
</mapper>
在业务层,创建UserService和OrderService,用于处理业务逻辑。例如,在OrderService中实现创建订单的方法:
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;import javax.annotation.Resource;@Service
public class OrderService {@Resourceprivate OrderMapper orderMapper;@Resourceprivate UserMapper userMapper;@Transactionalpublic void createOrder(Order order, Integer userId) {// 检查用户是否存在User user = userMapper.selectUserById(userId);if (user == null) {throw new RuntimeException("用户不存在");}order.setUserId(userId);// 插入订单数据orderMapper.insertOrder(order);}
}
在上述代码中,createOrder方法首先检查用户是否存在,若存在则插入订单数据。由于添加了@Transactional注解,整个操作在一个事务中执行,确保了数据的一致性。
最后,在控制层创建OrderController,用于处理 HTTP 请求,接收前端传来的数据并调用业务层方法。例如:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;@RestController
public class OrderController {@Autowiredprivate OrderService orderService;@PostMapping("/orders")public void createOrder(@RequestBody Order order, Integer userId) {orderService.createOrder(order, userId);}
}
通过上述步骤,实现了一个简单的用户订单管理模块,展示了 MyBatis 在实际项目中的应用流程,从数据库表设计、实体类创建、Mapper 接口和映射文件编写,到业务层和控制层的实现,各个环节紧密配合,完成了数据的持久化和业务逻辑的处理。
三、Spring Boot 整合其他 ORM 框架
3.1 Spring Boot 整合 Spring Data JPA
Spring Data JPA 是 Spring Data 项目的一部分,它构建于 Java Persistence API(JPA)之上,极大地简化了基于 JPA 的数据访问层开发。在 Spring Boot 项目中整合 Spring Data JPA,能让开发者以面向对象的方式操作数据库,减少大量样板代码的编写。
使用 Spring Data JPA 时,核心在于定义 Repository 接口。Repository 接口是 Spring Data JPA 提供的核心接口,它充当标记接口,捕获要使用的类型。开发者通常定义一个接口继承自JpaRepository,JpaRepository提供了丰富的 CRUD 方法,无需开发者手动实现。例如:
import org.springframework.data.jpa.repository.JpaRepository;
import com.example.demo.entity.User;public interface UserRepository extends JpaRepository<User, Long> {// 可以自定义查询方法
}
在上述代码中,UserRepository接口继承自JpaRepository,并指定了操作的实体类User和主键类型Long。通过这种方式,UserRepository自动拥有了save、findById、findAll、deleteById等基本的 CRUD 操作方法,使用时只需在需要的地方注入UserRepository即可调用这些方法,例如:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;@Service
public class UserService {@Autowiredprivate UserRepository userRepository;public User saveUser(User user) {return userRepository.save(user);}public User findUserById(Long id) {return userRepository.findById(id).orElse(null);}
}
除了基本的 CRUD 方法,Spring Data JPA 还支持通过方法名定义查询。例如,定义一个根据用户名查询用户的方法:
User findByUsername(String username);
Spring Data JPA 会根据方法名自动解析生成相应的查询语句,这里会生成根据username字段进行查询的 SQL 语句。这种方式使得查询定义变得非常简洁,开发者无需编写复杂的 SQL 语句。
JPQL(Java Persistence Query Language)是一种面向对象的查询语言,与 SQL 语法类似,但它操作的是实体对象而非数据库表。在 Spring Data JPA 中,可以使用@Query注解来编写 JPQL 查询。例如,查询年龄大于指定值的用户列表:
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;import java.util.List;public interface UserRepository extends JpaRepository<User, Long> {@Query("SELECT u FROM User u WHERE u.age > :age")List<User> findByAgeGreaterThan(@Param("age") int age);
}
在上述代码中,@Query注解中的SELECT u FROM User u WHERE u.age > :age就是 JPQL 语句,:age是一个命名参数,通过@Param(“age”)注解将方法参数age与 JPQL 语句中的参数绑定。这种方式提供了更灵活的查询方式,能够满足复杂的业务查询需求。
3.2 Spring Boot 整合 MyBatis-Plus
MyBatis-Plus 是 MyBatis 的增强工具,它在 MyBatis 的基础上进行了扩展,提供了更强大、更便捷的功能,旨在简化开发流程、提高开发效率。MyBatis-Plus 与 MyBatis 完全兼容,引入它不会对现有基于 MyBatis 的工程产生影响。
MyBatis-Plus 的一个显著优势是简化了 CRUD 接口。通过继承BaseMapper接口,开发者可以获得一系列通用的 CRUD 方法,无需编写大量重复的 SQL 语句和 Mapper XML 文件。例如,定义一个UserMapper接口:
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.demo.entity.User;
import org.apache.ibatis.annotations.Mapper;@Mapper
public interface UserMapper extends BaseMapper<User> {// 可以自定义扩展方法
}
在上述代码中,UserMapper接口继承自BaseMapper<User>,这样就自动拥有了insert、delete、update、select等通用的 CRUD 方法。使用时,只需在需要的地方注入UserMapper即可调用这些方法,例如:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;@Service
public class UserService {@Autowiredprivate UserMapper userMapper;public void saveUser(User user) {userMapper.insert(user);}public User findUserById(Long id) {return userMapper.selectById(id);}
}
MyBatis-Plus 还提供了强大的条件构造器,如QueryWrapper和LambdaQueryWrapper,用于构建复杂的查询条件。以LambdaQueryWrapper为例,查询用户名包含特定字符串且年龄大于指定值的用户列表:
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.example.demo.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.util.List;@Service
public class UserService {@Autowiredprivate UserMapper userMapper;public List<User> findUsers(String usernameLike, int age) {LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();wrapper.like(User::getUsername, usernameLike);wrapper.gt(User::getAge, age);return userMapper.selectList(wrapper);}
}
在上述代码中,LambdaQueryWrapper通过链式调用的方式构建查询条件,like方法用于模糊查询用户名,gt方法用于查询年龄大于指定值的用户。这种方式使得查询条件的构建非常直观、简洁,提高了代码的可读性和可维护性。
3.3 不同 ORM 框架对比
Spring Data JPA、MyBatis-Plus 和 MyBatis 在适用场景和性能差异等方面各有特点,开发者应根据具体项目需求进行选择。
Spring Data JPA 适用于业务模型相对稳定、需求变更频繁、对开发效率要求较高的项目。它以对象为中心,通过极少的代码实现数据访问,适合采用领域驱动设计(DDD)的项目。在简单的 CRUD 操作和不太复杂的动态查询场景下,Spring Data JPA 能充分发挥其优势,减少开发工作量。但在复杂查询场景下,使用@Query注解编写 JPQL 或原生 SQL 较为繁琐,且由于其自动生成 SQL,在性能优化方面相对受限。
MyBatis-Plus 适用于对 SQL 灵活性和控制力要求较高的项目。它在保留原生 SQL 能力的同时,提供了方便的 CRUD 方法,适合处理复杂的联表查询、分组统计、自定义计算、存储过程调用等需求,常见于报表系统、数据看板等对性能有极致要求的场景。MyBatis-Plus 的 SQL 是显式的,开发者可以直接编写和优化 SQL,更易定位和优化性能瓶颈,但需要手动维护 SQL 和实体映射,在开发效率上相对 Spring Data JPA 稍逊一筹。
MyBatis 则更侧重于 SQL 的灵活编写和对数据库操作的完全控制 ,适用于复杂的 SQL 查询和需要精确控制映射和查询逻辑的场景。开发者需要自己编写 SQL 语句,这使得 MyBatis 在处理复杂业务逻辑时具有更高的灵活性,但也增加了开发的工作量和难度。与 MyBatis-Plus 相比,MyBatis 缺少一些便捷的通用 CRUD 方法和条件构造器,在简单操作场景下开发效率较低。
在性能方面,MyBatis 和 MyBatis-Plus 由于 SQL 由开发者手动编写和优化,在处理复杂多表查询和大数据量操作时,能够根据实际需求进行针对性的优化,性能表现相对较好。Spring Data JPA 虽然默认有一级、二级缓存,但在复杂查询场景下,自动生成的 SQL 可能存在性能问题,需要开发者对框架有深入理解才能进行优化。例如在高并发、大数据量的电商订单查询场景中,MyBatis 或 MyBatis-Plus 通过精心优化的 SQL 语句,能够更高效地获取数据;而在一个企业内部的小型管理系统中,业务逻辑简单,以 CRUD 操作居多,Spring Data JPA 则能凭借其简洁的开发方式提高开发效率。