Spring Boot整合MyBatis
在Spring Boot项目中,使用MyBatis是一种十分流行的数据访问方式。相对于Javaweb通过原生JDBC访问数据库,MyBatis的操作会非常的简单。
原生JDBC访问数据库
使用原生JDBC进行数据库操作如下:
- 加载数据库驱动程序。
- 获取数据库连接。
- 创建Statement/PreparedStatement对象。
- 执行SQL语句。
- 处理查询结果。
- 关闭资源。
使用原生JDBC进行数据库操作需要手动处理Connection、Statement、PreparedStatement以及Resultset的生命周期,以及手动编写SQL语句和解析查询结果。这种方式比较繁琐,容易出错,并且无法享受到框架提供的便利功能,如事务管理、连接池管理等。
原生JDBC缺点和ORM框架介绍
原生JDBC访问数据库缺点
1.繁琐的编程模型:
- 需要手动管理数据库连接的创建、获取和关闭。
- 需要手动创建和关闭Statement/PreparedStatement对象。
- 需要手动处理查询结果集ResultSet的遍历和数据提取。
2.低层次的抽象:
- JDBC API提供的是底层的数据库访问接口,开发者需要关注很多细节性的问题,如SQL语句的拼装、结果集的映射等。
- 开发效率较低,可维护性较差。
3. 缺乏高级功能支持:
- JDBC无法提供诸如事务管理、一级缓存、延迟加载等高级功能。
- 需要开发者自行实现这些功能,增加开发难度。
4. SQL语句耦合:
- JDBC中的SQL语句通常硬编码在Java代码中,与业务逻辑紧耦合。
- 不利于SQL语句的维护和优化。
5.缺乏安全性保障:
- JDBC容易受到SQL注入等安全问题的影响。
- 需要开发者手动进行参数转义和校验。
6.数据类型映射复杂:
- JDBC需要开发者手动处理Java对象与数据库类型之间的映射。
- 转换逻辑往往需要编写大量重复性的代码。
ORM框架
对数据库的表和POJO(Plain Ordinary Java Object)Java对象的做映射的框架。现在市面上的ORM框架大概如下:
- Hibernate:Hibernate是一个成熟且功能丰富的Java ORM框架,它支持多种数据库,提供了高度抽象的数据访问层,能够自动将Java对象映射到数据库表。
- MyBatis:MyBatis是一个半自动的ORM框架,它允许开发者编写自定义的SQL语句同时提供了映射Java对象到数据库表的功能。
- Spring Data JPA:Spring Data JPA是Spring框架的一部分,它提供了对JPA(Java Persistence APl)的支持,简化了数据访问层的开发。
我们更多的选择MyBatis作为我们的ORM框架的理由如下:
- 简洁性:MyBatis的API相对简单直观,不需要像Hibernate那样配置大量的XML或注解,这可以减少配置的复杂性,加快开发速度。
- Spring集成:虽然Spring Data JPA提供了简化的数据访问层开发,但MyBatis也可以很好地与Spring框架集成,同时提供了比Spring Data JPA更细粒度的控制。
- 轻量级:MyBatis相比于Hibernate来说更加轻量级,对于小型项目或者需要快速开发的项目MyBatis可能是一个更优的选择。
- 社区和扩展:MyBatis拥有一个活跃的社区,并且有许多扩展和插件,如MyBatis-Plus和MyBatis-flex,这些扩展提供了额外的功能和便利性。
Restful编程
REST(Representationa State Transfer)是一种软件架构风格,它定义了一组用于创建高性能、可伸缩性以及易于维护的应用程序的设计原则和约束条件。RESTfuI 编程就是基于这种REST 架构风格进行 Web 服务的设计和开发。
REST特点如下:
- 资源定位和访问:
- RESTful架构中,一切皆资源,每个资源都有唯一的资源标识符(URI)。
- 客户端通过发送 HTTP 动词(GET、POST、PUT、DELETE 等)来对资源进行增删改查操作。
- 无状态性:
- RESTful架构是无状态的,即每个请求都是独立的,不依赖于之前的请求。
- 服务器不需要保存客户端的状态信息,这有利于提高系统的可伸缩性和可靠性。
- 使用标准 HTTP 方法:
- RESTful服务严格遵循HTTP协议,使用HTTP动词来表达不同的操作:
- GET:读取资源
- POST:创建资源
- PUT:更新资源
- DELETE:删除资源
- RESTful服务严格遵循HTTP协议,使用HTTP动词来表达不同的操作:
- 响应格式标准化:
- RESTful服务通常使用 JSON 或 XML 等标准数据格式来表示资源。
- 这样可以提高系统的可扩展性和互操作性。
Spring Boot整合MyBatis实践
我们将创建一个简单的应用程序,用于管理用户信息,整合MyBatis并使用REST的编程。
代码实现
实体类User:
包含三个字段:id、username、email
@Entity
@Table(name = "users")
public class User {
@Id
private Long id;
private String username;
private String email;
// Getters and Setters
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
映射器接口UserMapper:
定义了对User实体执行数据库操作的方法,使用MyBatis注解来指定SQL语句
@Service
public interface UserMapper {
@Select("SELECT * FROM users WHERE id = #{id}")
User findById(@Param("id") Long id);
@Select("SELECT * FROM users")
@Results({
@Result(property = "id", column = "id"),
@Result(property = "username", column = "username"),
@Result(property = "email", column = "email")
})
List<User> findAll();
@Insert("INSERT INTO users(username, email) VALUES(#{username}, #{email})")
@Options(useGeneratedKeys = true, keyProperty = "id")
void insert(User user);
@Update("UPDATE users SET username = #{username}, email = #{email} WHERE id = #{id}")
void update(User user);
@Delete("DELETE FROM users WHERE id = #{id}")
void delete(Long id);
}
服务类UserService:
一个Spring服务组件,注入了UserMapper的用例,提供业务逻辑,调用UserMapper的方法来执行数据库操作。
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
public User getUser(Long id) {
return userMapper.findById(id);
}
public List<User> getAllUsers() {
return userMapper.findAll();
}
public void addUser(User user) {
userMapper.insert(user);
}
public void updateUser(User user) {
userMapper.update(user);
}
public void deleteUser(Long id) {
userMapper.delete(id);
}
}
控制器类UserController:
一个Spring MVC控制器,提供了REST的端点来访问用户数据。
@RestController
@RequestMapping("/users")
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/{id}")
public User getUserById(@PathVariable Long id) {
return userService.getUser(id);
}
@GetMapping
public List<User> getAllUsers() {
return userService.getAllUsers();
}
@PostMapping
public void addUser(@RequestBody User user) {
userService.addUser(user);
}
@PutMapping("/{id}")
public void updateUser(@PathVariable Long id, @RequestBody User user) {
user.setId(id);
userService.updateUser(user);
}
@DeleteMapping("/{id}")
public void deleteUser(@PathVariable Long id) {
userService.deleteUser(id);
}
}
Mapper无法被扫秒装配问题
Spring Boot项目在整合MyBatis时经常出现Mapper类扫秒问题。
这里给出我最终的解决办法:
在我们启动类的上面添加一个注解@ComponentScan,参数为Mapper这个包,如下:
Postman测试
测试 getAllUsers 接囗:
在 Postman 中选择 GET 方法,在 URL输入框中输入http://localhost:8080/users。
测试getUserById接囗:
假设您想获取ID为1 的用户信息,选择GET方法,在URL输入框中输入 http://localhost:8080/users/1。
测试addUser接囗:
选择POST方法,在URL输入框中输入http://localhost:8080/users,转到"Body"选项卡,选择"raw",并设置类型为"JSON(application/json)"D。输入一个 JSON 对象。
测试updateUser接囗:
假设您要更新ID为1的用户信息,选择PUT方法,在 URL输入框中输入 http://localhost:8080/users/1,转到"Body"选项卡,选择"raw",并设置类型为"JSON(application/json)",输入一个 JSON 对象。
测试 deleteUser 接囗:
假设您要删除 ID 为 1的用户,选择DELETE方法,在URL输入框中输入 http://localhost:8080/users/1。