当前位置: 首页 > news >正文

论MyBatis和JPA权威性

MyBatis和JPA都是常用的持久层框架,让我们来详细讲解两者的区别和使用方法。

1. JPA vs MyBatis 对比

特性Spring Data JPAMyBatis
理念面向对象,不用写SQLSQL映射,需要写SQL
SQL控制自动生成SQL,也可自定义完全手动控制SQL
学习曲线较陡峭,需要理解JPA规范较平缓,就是写SQL
灵活性相对固定,复杂查询麻烦非常灵活,复杂SQL优势明显
开发效率简单CRUD效率极高所有SQL都要自己写
适用场景标准CRUD、快速开发复杂查询、存储过程、现有数据库

2. Spring Data JPA 详细使用

2.1 添加依赖

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope>
</dependency>

2.2 配置数据库

# application.properties
spring.datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver# JPA配置
spring.jpa.database=mysql
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect

2.3 创建实体类(Entity)

package com.msb.entity;import javax.persistence.*;@Entity
@Table(name = "user")  // 对应数据库表名
public class User {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)  // 自增主键private Long id;@Column(name = "name", length = 50, nullable = false)private String name;@Column(name = "email", unique = true)private String email;@Column(name = "age")private Integer age;// 必须有无参构造器public User() {}// 有参构造器public User(String name, String email, Integer age) {this.name = name;this.email = email;this.age = age;}// Getter和Setter方法public Long getId() { return id; }public void setId(Long id) { this.id = id; }public String getName() { return name; }public void setName(String name) { this.name = name; }public String getEmail() { return email; }public void setEmail(String email) { this.email = email; }public Integer getAge() { return age; }public void setAge(Integer age) { this.age = age; }
}

2.4 创建Repository接口

package com.msb.repository;import com.msb.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import java.util.List;// 继承JpaRepository,已经包含基本的CRUD方法
public interface UserRepository extends JpaRepository<User, Long> {// 方法名自动生成查询List<User> findByName(String name);List<User> findByAgeGreaterThan(Integer age);List<User> findByNameContaining(String keyword);// 自定义查询@Query("SELECT u FROM User u WHERE u.email LIKE %:email%")List<User> findByEmailLike(@Param("email") String email);@Query("SELECT u FROM User u WHERE u.age BETWEEN :minAge AND :maxAge")List<User> findUsersByAgeRange(@Param("minAge") Integer minAge, @Param("maxAge") Integer maxAge);
}

2.5 创建Service

package com.msb.service;import com.msb.entity.User;
import com.msb.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Optional;@Service
public class UserService {@Autowiredprivate UserRepository userRepository;// 保存用户public User saveUser(User user) {return userRepository.save(user);}// 查询所有用户public List<User> getAllUsers() {return userRepository.findAll();}// 根据ID查询public User getUserById(Long id) {Optional<User> user = userRepository.findById(id);return user.orElse(null);  // 如果不存在返回null}// 根据姓名查询public List<User> getUsersByName(String name) {return userRepository.findByName(name);}// 查询年龄大于指定值的用户public List<User> getUsersByAgeGreaterThan(Integer age) {return userRepository.findByAgeGreaterThan(age);}// 删除用户public void deleteUser(Long id) {userRepository.deleteById(id);}
}

2.6 创建Controller

package com.msb.controller;import com.msb.entity.User;
import com.msb.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;@RestController
@RequestMapping("/api/users")
public class UserController {@Autowiredprivate UserService userService;// 获取所有用户@GetMappingpublic List<User> getAllUsers() {return userService.getAllUsers();}// 根据ID获取用户@GetMapping("/{id}")public User getUserById(@PathVariable Long id) {return userService.getUserById(id);}// 创建用户@PostMappingpublic User createUser(@RequestBody User user) {return userService.saveUser(user);}// 更新用户@PutMapping("/{id}")public User updateUser(@PathVariable Long id, @RequestBody User user) {user.setId(id);return userService.saveUser(user);}// 删除用户@DeleteMapping("/{id}")public void deleteUser(@PathVariable Long id) {userService.deleteUser(id);}// 根据姓名查询@GetMapping("/search")public List<User> searchUsersByName(@RequestParam String name) {return userService.getUsersByName(name);}
}

3. MyBatis 详细使用

3.1 添加依赖

<dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.3.1</version>
</dependency>
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope>
</dependency>

3.2 配置MyBatis

# application.properties
spring.datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver# MyBatis配置
mybatis.mapper-locations=classpath:mapper/*.xml
mybatis.type-aliases-package=com.msb.entity
mybatis.configuration.map-underscore-to-camel-case=true

3.3 创建实体类

package com.msb.entity;public class User {private Long id;private String name;private String email;private Integer age;// 构造器、getter、setterpublic User() {}public User(String name, String email, Integer age) {this.name = name;this.email = email;this.age = age;}// getter和setter...public Long getId() { return id; }public void setId(Long id) { this.id = id; }public String getName() { return name; }public void setName(String name) { this.name = name; }public String getEmail() { return email; }public void setEmail(String email) { this.email = email; }public Integer getAge() { return age; }public void setAge(Integer age) { this.age = age; }
}

3.4 创建Mapper接口

package com.msb.mapper;import com.msb.entity.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;@Mapper
public interface UserMapper {// 插入用户int insert(User user);// 根据ID查询User selectById(Long id);// 查询所有用户List<User> selectAll();// 根据姓名查询List<User> selectByName(String name);// 更新用户int update(User user);// 删除用户int deleteById(Long id);// 复杂查询:根据年龄范围查询List<User> selectByAgeRange(@Param("minAge") Integer minAge, @Param("maxAge") Integer maxAge);// 复杂查询:统计用户数量int countUsers();
}

3.5 创建Mapper XML文件

src/main/resources/mapper/UserMapper.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.msb.mapper.UserMapper"><!-- 结果映射 --><resultMap id="BaseResultMap" type="User"><id column="id" property="id" /><result column="name" property="name" /><result column="email" property="email" /><result column="age" property="age" /></resultMap><!-- 插入用户 --><insert id="insert" parameterType="User" useGeneratedKeys="true" keyProperty="id">INSERT INTO user (name, email, age)VALUES (#{name}, #{email}, #{age})</insert><!-- 根据ID查询 --><select id="selectById" parameterType="Long" resultMap="BaseResultMap">SELECT id, name, email, age FROM user WHERE id = #{id}</select><!-- 查询所有用户 --><select id="selectAll" resultMap="BaseResultMap">SELECT id, name, email, age FROM user</select><!-- 根据姓名查询 --><select id="selectByName" parameterType="String" resultMap="BaseResultMap">SELECT id, name, email, age FROM user WHERE name LIKE CONCAT('%', #{name}, '%')</select><!-- 更新用户 --><update id="update" parameterType="User">UPDATE user SET name = #{name}, email = #{email}, age = #{age}WHERE id = #{id}</update><!-- 删除用户 --><delete id="deleteById" parameterType="Long">DELETE FROM user WHERE id = #{id}</delete><!-- 根据年龄范围查询 --><select id="selectByAgeRange" resultMap="BaseResultMap">SELECT id, name, email, age FROM user WHERE age BETWEEN #{minAge} AND #{maxAge}ORDER BY age ASC</select><!-- 统计用户数量 --><select id="countUsers" resultType="int">SELECT COUNT(*) FROM user</select></mapper>

3.6 创建Service

package com.msb.service;import com.msb.entity.User;
import com.msb.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;@Service
public class UserService {@Autowiredprivate UserMapper userMapper;public User saveUser(User user) {if (user.getId() == null) {userMapper.insert(user);} else {userMapper.update(user);}return user;}public List<User> getAllUsers() {return userMapper.selectAll();}public User getUserById(Long id) {return userMapper.selectById(id);}public List<User> getUsersByName(String name) {return userMapper.selectByName(name);}public void deleteUser(Long id) {userMapper.deleteById(id);}public List<User> getUsersByAgeRange(Integer minAge, Integer maxAge) {return userMapper.selectByAgeRange(minAge, maxAge);}public int getUserCount() {return userMapper.countUsers();}
}

3.7 创建Controller(与JPA版本类似)

package com.msb.controller;import com.msb.entity.User;
import com.msb.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;@RestController
@RequestMapping("/api/users")
public class UserController {@Autowiredprivate UserService userService;@GetMappingpublic List<User> getAllUsers() {return userService.getAllUsers();}@GetMapping("/{id}")public User getUserById(@PathVariable Long id) {return userService.getUserById(id);}@PostMappingpublic User createUser(@RequestBody User user) {return userService.saveUser(user);}@PutMapping("/{id}")public User updateUser(@PathVariable Long id, @RequestBody User user) {user.setId(id);return userService.saveUser(user);}@DeleteMapping("/{id}")public void deleteUser(@PathVariable Long id) {userService.deleteUser(id);}@GetMapping("/search")public List<User> searchUsersByName(@RequestParam String name) {return userService.getUsersByName(name);}@GetMapping("/age-range")public List<User> getUsersByAgeRange(@RequestParam Integer minAge, @RequestParam Integer maxAge) {return userService.getUsersByAgeRange(minAge, maxAge);}@GetMapping("/count")public int getUserCount() {return userService.getUserCount();}
}

4. 总结建议

选择JPA的情况:

  • 项目简单,主要是CRUD操作
  • 想要快速开发,不想写SQL
  • 团队熟悉面向对象编程

选择MyBatis的情况:

  • 复杂SQL查询,需要精细优化
  • 已有数据库,表结构复杂
  • 需要调用存储过程
  • 团队SQL能力强

初学者建议:

从MyBatis开始,因为:

  1. SQL直观,容易理解和调试
  2. 能真正理解数据库操作
  3. 遇到问题容易排查
http://www.dtcms.com/a/482644.html

相关文章:

  • SAP MM采购订单创建接口分享
  • 基于单片机的简易智能衣架控制系统设计
  • rrk3588 与 NPU 主机下的异构通信:基于 PCIe 的设计与实现
  • 2025年--Lc185--63.不同路径II(动态规划,矩阵)--Java版
  • 跨境电商网站排行榜wordpress数据量大网站访问
  • 从零起步学习MySQL || 第四章:DQL语句定义及常见用法示例
  • 网站建设费如何核算.la域名的门户网站
  • 场景中的建筑静态物体转为actor,保持建筑的相对位置。
  • 数字孪生为什么需要5G?低延迟与高可靠实现精准控制
  • Idea 启动项目把启动类显示在左下角 并显示端口号
  • 网站网页模板网页设计培训哪家机构好
  • SLAM: 如何生成odom数据
  • 环境搭建node.js gnvm
  • 网站建设 就业方向东莞房价2021
  • Spring容器的实现
  • JWT 漏洞全解析:从原理到实战
  • 基于Redis6.2.8版本部署Redis Cluster集群
  • 工控一体机在智慧称重食堂中的应用
  • 网络包封装全解析:从字节流到数据帧
  • Spring MVC入门补充2
  • 石家庄站列车时刻表美食网站二级页面模板
  • GS016电动工具调速控制电路
  • Gartner:AI增强软件测试工具魔力象限报告精编(2025年10月)
  • 绵阳公司商务网站制作沈阳企业网站制作公司
  • elasticsearch-8.12.2集群部署
  • 【教程】增强版 print 函数,支持彩色与样式化终端输出
  • Python下载实战技巧技术文章大纲
  • TCP 拆包现象解决方案(一)
  • 陕西省城乡建设学校网站网页设计图片加载不出来
  • 商业智能BI与业务结构分析