本文,我们来了解 MyBatis
。
什么是 MyBatis
下面这段介绍是摘自中文官网:
MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
可以概括为:MyBatis
为数据库服务。桥接 Java
原始类型、接口和 老式 Java
对象。
引入 MyBatis
在依赖中添加如下代码:
代码语言:javascript复制<!-- MyBatis -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.0.0</version>
</dependency>
<!-- MySQL Driver -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>
<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
CRUD 注解
CRUD -> Create,Read,Update,Delete
增删改查是主要的业务操作。
注释 | 说明 | 升级版本(3.X) |
---|---|---|
@Select | 用于构建查询语句 | @SelectProvider |
@Insert | 用于构建添加语句 | @InsertProvider |
@Update | 用于构建修改语句 | @UpdateProvider |
@Delete | 用于构建删除语句 | @DeleteProvider |
@Mapper
public interface UserMapper {
@Select("SELECT * FROM user WHERE id = #{id}")
User queryById(@Param("id") int id);
@Insert("INSERT INTO user(name,age) VALUES(#{name},#{age})")
int add(User user);
@Delete("DELETE FROM user WHERE id = #{id}")
int deleteById(int id);
@Update("UPDATE user SET name=#{name},age=#{age} WHERE id = #{id}")
int updateById(User user)
}
映射注解
可以直接将对象和数据库之间的映射关系直接定义在 Java
代码中,而不需要编写繁琐的 XML
配置文件(用于建立实体和数据库关系的映射
)。有以下三个注解:
注释 | 说明 |
---|---|
@Results | 结果集多个字段的映射关系 |
@Result | 结果集单个字段的映射关系 |
@ResultMap | 根据 ID 关联 XML 里面的 <resultMap> |
@Results({
@Result(property = "username", column = "USERNAME"),
@Result(property = "password", column = "PASSWORD")
})
@Select("SELECT * FROM user")
List<User> list();
简单案例
下面我们实现一个增删改查的案例。
Spring Boot 版本 3.1.2 , java sdk 版本为 17
版本太高,会出现错误 Field userMapper in com.launch.controller.UserController required a bean of type 'com.launch.mapper.UserMapper' that could not be found.
之后将版本 Spring Boot
降为 2.1.3.RELEASE
。
文末给出完整的
pom.xml
数据表自动初始化
我们在 resources
文件夹下新增 db
目录,新增名为 schema.sql
文件。
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user`
(
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
`age` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
这里,我们将创建表用户表并进行初始化。
在 application.properties
文件中设定数据库的连接:
spring.datasource.url=jdbc:mysql://localhost:3306/jimmy_db?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&useSSL=true
spring.datasource.username=root
spring.datasource.password=
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.properties.hibernate.hbm2ddl.auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.show-sql= true
spring.sql.init.mode=always
spring.datasource.platform=mysql
spring.sql.init.schema-locations=classpath:db/schema.sql
这里设定了连接的数据库为 jimmy_db
,并设定了初始化的 schema
路径为 classpath:db/schema.sql
。
我们运行项目之后,会看到生成了一张 user
表。如果没有生成,可自动导入 SQL
语句,或者自己书写。
User 实体对象建模
我们新建包 model
,User.java
创建 User
实体。
package com.launch.model;
import lombok.Data;
@Data
public class User {
private Integer id;
private String name;
private Integer age;
}
实体和数据表的映射关系
我们新建 mapper
包,并实现 UserMapper.java
接口文件:
package com.launch.mapper;
import com.github.pagehelper.Page;
import com.launch.model.User;
import org.apache.ibatis.annotations.*;
import java.util.List;
@Mapper
public interface UserMapper {
@Select("SELECT * FROM user")
List<User> queryAll();
@Select("SELECT * FROM user WHERE id = #{id}")
User queryById(@Param("id") int id);
@Insert({"INSERT INTO user(name,age) VALUES(#{name},#{age})"})
int add(User user);
@Update("UPDATE user SET name=#{name},age=#{age} WHERE id = #{id}")
int updateById(User user);
@Delete("DELETE FROM user WHERE id = #{id}")
int deleteById(int id);
// 分页
@Select("SELECT * FROM user")
Page<User> getUserList();
}
我们在类上添加 @Mapper
注解实现实体和数据表的映射关系。当然,也可以在入口类中添加 @MapperScan("com.launch.mapper")
实现,读者可以尝试。
操作数据 API
下面我们在包 controller
下,创建控制器 UserController.java
文件:
package com.launch.controller;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.launch.mapper.UserMapper;
import com.launch.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api/user")
public class UserController {
@Autowired
UserMapper userMapper;
@GetMapping("/")
List<User> queryAll() {
return userMapper.queryAll();
}
@GetMapping("/query_by_id")
User queryById(int id) {
return userMapper.queryById(id);
}
@PostMapping("/add")
String add(User user) {
return userMapper.add(user) == 1 ? "success" : "failed";
}
@PutMapping("/update_by_id")
String updateById(User user) {
return userMapper.updateById(user) == 1 ? "success" : "failed";
}
@DeleteMapping("/delete_by_id")
String deleteById(int id) {
return userMapper.deleteById(id) == 1 ? "success" : "failed";
}
// 分页
@GetMapping("/list_page")
public Page<User> getUserList(Integer pageNum, Integer pageSize) {
PageHelper.startPage(pageNum, pageSize);
Page<User> userList = userMapper.getUserList();
return userList;
}
}
因为我们需要进行分页,我们引入包:
代码语言:javascript复制<!-- pom.xml -->
<!-- Page Helper -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>4.1.6</version>
</dependency>
我们新建包 config
,在文件 PageHelperConfig.java
文件添加:
package com.launch.config;
import com.github.pagehelper.PageHelper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Properties;
@Configuration
public class PageHelperConfig {
@Bean
public PageHelper pageHelper() {
PageHelper pageHelper = new PageHelper();
Properties p = new Properties();
p.setProperty("offsetAsPageNum", "true");
p.setProperty("rowBoundsWithCount", "true");
p.setProperty("readonly", "true");
pageHelper.setProperties(p);
return pageHelper;
}
}
现在,我们正式完成了 CRUD
的内容,我们启动项目后,可以通过下面的操作进行:
作用 | 请求方法 | 请求路径 |
---|---|---|
添加用户 | POST | http://localhost:8080/api/user/query_by_id?id=1 |
查询所有用户 | GET | http://localhost:8080/api/user/ |
查询指定 ID 用户 | GET | http://localhost:8080/api/user/add?name=Jimmy&age=18 |
更改指定 ID 用户 | PUT | http://localhost:8080/api/user/update_by_id?id=1&name=Jimmy007&age=20 |
删除指定 ID 用户 | DELETE | http://localhost:8080/api/user/delete_by_id?id=1 |
分页查询 | GET | http://localhost:8080/api/user/list_page?pageNum=1&pageSize=1 |
上面的测试,通过 params 传递参数,感兴趣读者可以优化下。
总结:留意版本之间是否有冲突等
完整的 pom.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.launch</groupId>
<artifactId>launch</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>launch</name>
<description>launch</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- MyBatis -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
<!-- MySql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!-- Page Helper -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>4.1.6</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>RELEASE</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
参考
- mybatis
- 《Spring Boot 实战派》
- Java 中 Spring Boot 使用 MyBatis 访问 MySql 数据库
- Java Web 编写 Restful API