概述对比

JPA (Java Persistence API)

定义:Java官方ORM规范,Hibernate是其主要实现性质:标准化的ORM框架设计理念:对象关系映射,完全面向对象

MyBatis-Plus

定义:基于MyBatis的增强工具性质:半自动化ORM框架设计理念:SQL映射,保持SQL的可控性

性能对比

JPA性能特点

// 优势:

// 1. 懒加载

@Entity

public class User {

@OneToMany(fetch = FetchType.LAZY) // 懒加载,需要时才查询

private List orders;

}

// 2. 一级缓存(Session级别)

@Service

@Transactional

public class UserService {

public void testFirstLevelCache() {

User user1 = userRepository.findById(1L).get(); // 查询数据库

User user2 = userRepository.findById(1L).get(); // 从缓存获取

}

}

// 3. 二级缓存

@Entity

@Cacheable

@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)

public class User {

// 实体会被缓存

}

// 劣势:

// 1. N+1问题

public void testNPlusOneProblem() {

List users = userRepository.findAll(); // 1次查询

for (User user : users) {

user.getOrders().size(); // 每个user一次查询,N次查询

}

}

// 解决方案:JOIN FETCH

@Query("SELECT u FROM User u LEFT JOIN FETCH u.orders")

List findAllWithOrders();

MyBatis-Plus性能特点

// 优势:

// 1. SQL完全可控

@Select("""

SELECT u.id, u.username,

COUNT(o.id) as order_count,

SUM(o.amount) as total_amount

FROM user u

LEFT JOIN order_table o ON u.id = o.user_id

GROUP BY u.id, u.username

HAVING COUNT(o.id) > 5

""")

List> selectUserStatistics();

// 2. 分页性能优化

@Service

public class UserService {

// 物理分页

public IPage findByPage(long current, long size) {

Page page = new Page<>(current, size);

return baseMapper.selectPage(page, null);

}

// 自定义分页SQL

public IPage> findComplexDataByPage(long current, long size) {

Page> page = new Page<>(current, size);

return baseMapper.selectComplexDataPage(page);

}

}

// 3. 批量操作

public void batchInsert(List users) {

// MyBatis-Plus批量插入

this.saveBatch(users);

}

// 劣势:需要手动处理关联查询

使用场景选择

JPA适用场景

// 1. 标准CRUD操作为主的系统

@RestController

public class UserController {

@Autowired

private UserRepository userRepository;

@GetMapping("/users")

public Page getUsers(Pageable pageable) {

return userRepository.findAll(pageable); // 自动分页

}

@PostMapping("/users")

public User createUser(@RequestBody User user) {

return userRepository.save(user); // 自动保存

}

}

// 2. 快速开发的项目

// 3. 团队对SQL要求不高的项目

// 4. 需要跨数据库支持的项目

MyBatis-Plus适用场景

// 1. 复杂查询较多的系统

@Mapper

public interface ReportMapper extends BaseMapper {

@Select("""

""")

List> selectMonthlyReport(@Param("deptIds") List deptIds,

@Param("startDate") Date startDate);

}

// 2. 对SQL性能要求高的项目

// 3. 需要精细控制SQL的项目

// 4. 团队SQL能力较强的项目

总结对比表

对比维度JPAMyBatis-Plus学习成本中等,需要理解ORM概念较低,基于SQL开发效率简单CRUD很快,复杂查询较慢简单CRUD快,复杂查询仍需手写SQLSQL控制有限,依赖HQL/JPQL完全控制性能优化需要深入理解缓存、懒加载等直接优化SQL即可代码量较少中等可维护性关联复杂时难维护SQL较为直观团队要求需要理解ORM思想需要较强SQL能力项目规模中小型快速开发大型复杂业务系统

选择建议

选择JPA的情况:

快速开发原型或中小型系统团队对ORM熟悉,对SQL要求不高标准CRUD操作为主,复杂查询较少需要跨数据库支持

选择MyBatis-Plus的情况:

大型系统,复杂业务逻辑较多对性能要求较高,需要精细化SQL控制团队SQL能力强,喜欢SQL的直观性需要大量的统计报表查询

混合使用: 在大型项目中,也可以考虑混合使用:

简单的CRUD operations用JPA复杂的查询和报表用MyBatis-Plus

这样可以发挥两者的优势,但需要注意事务管理和数据一致性问题。