SpringBoot开发,如何使用MyBatis全面代替JPA?
发布于 作者:苏南大叔 来源:程序如此灵动~

本文不往后扩展,而是回到项目的初始阶段。对数据库进行连接的部分,使用的是基于JPA
/Hibernate
的Entity
+Serive
文件。在本文中,它将增加使用MyBatis
的Mapper
文件。并不是说jpa
和mybatis
两者完全冲突,但是,想让它们两个和谐相处,也是比较费劲的。所以,全面改成mybatis
也是有它的需求点存在的。
苏南大叔的“程序如此灵动”博客,记录苏南大叔的代码编程经验总结。测试环境:win10
,openjdk@23.0.2
,IntelliJ IDEA 2024.3.4.1
,maven@3.3.2
,spring boot@2.5.4
,java@17
,mysql@5.7.26
,MyBatis@2.2.0
。mybatis
的存在点叫做mapper
文件,代替的是传统的jpa
中的repository
文件。
基础代码
本文是基于如下系列文章,进一步展开叙述的。所以,没有详细展开的代码内容,可以在下面的连接里面找到答案。
- https://newsn.net/say/springboot.html
- https://newsn.net/say/springboot-hot.html
- https://newsn.net/say/springboot-model.html
- https://newsn.net/say/springboot-entity.html【本文重点】
- https://newsn.net/say/springboot-jpa.html 【本文重点】
- https://newsn.net/say/springboot-session.html
- https://newsn.net/say/springboot-csrf.html
- https://newsn.net/say/springboot-aspect.html
- https://newsn.net/say/springboot-exception.html
mybatis
苏南大叔的使用感受上来说,mybatis
更加凸显是sql
语句,这和传统的模型的概念冲突的非常厉害。但是,实际功用上来说,它代替的确实就是model
/entity
。MyBatis
与JPA
的主要差异在于设计哲学,MyBatis
偏向于面向过程,而JPA
则将面向对象发挥到极致。
MyBatis
是一个可以灵活编写SQL
语句的框架。它更偏向于数据库,因此需要手写SQL
语句。MyBatis
完全避免了几乎全部的JDBC
代码和手动设置参数以及获取结果集,相比JDBC
更方便。另外,MyBatis
提供了很高的灵活性,可以通过定制化的SQL
语句实现各种复杂的查询操作。
安装依赖
修改pom.xml
,添加mybatis-spring-boot-starter
,(去除spring-boot-starter-data-jpa
)。
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.0</version>
</dependency>
执行mvn install
命令。
修改配置
src\main\resources\application.properties
:
spring.datasource.url=jdbc:mysql://localhost:3306/boot
spring.datasource.username=root
spring.datasource.password=root
# spring.jpa.hibernate.ddl-auto=update
# spring.jpa.show-sql=true
# spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL57Dialect
# spring.jpa.properties.hibernate.format_sql=true
# logging.level.org.hibernate.SQL=DEBUG
# logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
mybatis.mapper-locations=classpath*:mappers/*.xml
logging.level.com.example.demo.mapper=DEBUG
logging.level.org.mybatis=DEBUG
logging.level.jdbc.sqlonly=DEBUG
JPA
和MyBatis
还共享了设置:spring.datasource
。
代码修改
【第一步】,model
/entity
文件,没有任何变化。但是,这里增加了一个便于调试的.toString()
方法。
package com.example.demo.entity;
import org.apache.ibatis.type.Alias;
@Alias("User")
public class User {
private Integer id; // Ensure the ID field is Integer
private String name;
private String password;
// Getters and Setters
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", password='" + password + '\'' +
'}';
}
}
【第二步】,mapper
文件代替了repository
文件。mapper
文件选择了更简单的.java
形式。src\main\java\com\example\demo\mapper\UserMapper.java
:
package com.example.demo.mapper;
import com.example.demo.model.User;
import org.apache.ibatis.annotations.*;
import java.util.List;
@Mapper
public interface UserMapper {
@Select("SELECT * FROM user")
List<User> findAll();
@Select("SELECT * FROM user WHERE id = #{id}")
User findById(Long id);
@Select("SELECT * FROM user WHERE name = #{name}")
User findByName(String name);
@Insert("INSERT INTO user(name, password) VALUES(#{name}, #{password})")
@Options(useGeneratedKeys = true, keyProperty = "id")
void insert(User user);
@Update("UPDATE user SET name = #{name}, password = #{password} WHERE id = #{id}")
void update(User user);
@Delete("DELETE FROM user WHERE id = #{id}")
void deleteById(Long id);
@Select("SELECT COUNT(*) FROM user")
int count();
}
【第三步】修改serice
文件以及controller
文件(如果有必要)。
由于是mapper
平替修改repository
文件的。所以,对于service
文件以及controller
文件来说,比如有引用修改的情况发生。
src\main\java\com\example\demo\service\UserService.java
:
//...
import com.example.demo.mapper.UserMapper;
//...
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
//...
public List<User> getAllUsers() {
return userMapper.findAll();
}
public User getUserById(Long id) {
if (id == null) {
throw new IllegalArgumentException("ID不能为空");
}
return userMapper.findById(id);
}
//...
}
src\main\java\com\example\demo\controller\LoginController.java
:
//...
import com.example.demo.mapper.UserMapper;
//...
@Controller
public class LoginController {
@Autowired
private UserMapper userMapper;
//...
private boolean isValidUser(String username, String password) {
User user = userMapper.findByName(username);
if (user != null && user.getPassword().equals(password)) {
return true;
}
return false;
}
}
对比表格
名称 | 模型文件 | sql语句 | 其余 |
---|---|---|---|
JPA | entity + repository | 框架完成 | 搭配service |
MyBatis | entity + mapper | 自己完成 | 搭配service |
所以,对于springboot
项目来说,可以选择传统的JPA
,也可以选择新兴的MyBatis
。选择前者的话,就是编辑entity
文件,选择后者的话,就是编辑mapper
文件。前者由框架来组织sql
语句,后者你自己写sql
语句。别的基本上就差不多了。
结语
本文的代码,在实际测试的时候,创建新的user
的时候,id
总是会变成长整型。多方调整代码都不行,最终删除数据表,重建数据表成功。可能是autoincreace key
出了问题。
本文以快速入门mybatis
为主要目的,苏南大叔的更多java
相关经验文字,请点击:


