# 基于 tk mapper 实现增删改查的 restfull 接口
首先创建一张演示表 stu
CREATE TABLE stu
(
id int primary key auto_increment,
name varchar(255) not null,
age int not null
) COMMENT = '演示表 ';
1
2
3
4
5
6
2
3
4
5
6
使用 mybatis 代码生成工具生成,然后开始开发增删改查的示例
# Tk Mapper 单表查询简单说明
我们逆向生成代码的时候,定义了一个接口
interface MyMapper<T> extends Mapper<T>,MySqlMapper<T>
1
它继承了两个父类,先来看看 MySqlMapper<T>
interface MySqlMapper<T> extends InsertListMapper<T>,InsertUseGeneratedKeysMapper<T>{}
1
它又继承了两个父类,从类名上看,是操作数据库的,里面分别有两个方法
| 方法名 | 操作 | 备注 |
|---|---|---|
insertList(list) | 数据批量插入 | 主键须自增 |
insertUseGeneratedKeys(record) | 插入表数据 | 主键须自增 |
很明显,在传统 JavaWeb 开发,这两个方法使用是没有问题的,但是我们的数据库表主键设计肯定是全局唯一的,所以不可能使用自增长 id(如何设计全局唯一 ID 部分,在后续课程里有具体的讲解),所以这两个方法在我们开发过程中是不会使用的,这一点需要注意。
在来看看 Mapper<T>
public interface Mapper<T> extends BaseMapper<T>, ExampleMapper<T>, RowBoundsMapper<T>, Marker {
}
1
2
2
BaseMapper<T>中又继承了好多的类,下面分别看看都提供了哪些方法类 方法 操作 BaseSelectMapper T selectOne(T record)根据实体类中的属性查询表数据,返回单个实体 List select(T record)根据实体类中的属性查询表数据,返回符合条件的 list List selectAll()返回该表所有记录 int selectCount(T record)根据条件查询记录数 T selectByPrimaryKey(Object key)根据主键查询单挑记录 boolean existsWithPrimaryKey(Object key)查询主键是否存在,返回 true 或 false BaseInsertMapper int insert(T record)插入一条记录,属性为空也会保存 int insertSelective(T record)插入一条记录,属性为空不保存,会使用默认值 BaseUpdateMapper int updateByPrimaryKey(T record)根据实体类更新数据库,属性有 null 会覆盖原记录 int updateByPrimaryKeySelective(T record)根据实体类更新数据库,属性有 null 该属性会忽略 BaseDeleteMapper int delete(T record)根据实体类中属性多条件删除记录 int deleteByPrimaryKey(Object key)根据主键删除记录 ExampleMapper<T>:用于自定义条件(where 语句)Exampl 是条件类,主要方法如下类 方法 SelectByExampleMapper List<T> selectByExample(Object example)按条件查询,返回多条记录 SelectOneByExampleMapper T selectOneByExample(Object example)按条件查询,返回单条记录,如果返回的是多条记录,则会发生异常 SelectCountByExampleMapper int selectCountByExample(Object example);按条件查询,返回符合条件的数量 DeleteByExampleMapper int deleteByExample*(Object example)按条件删除 UpdateByExampleMapper int updateByExample(@Param("record") T record, @Param*("example") Object example)根据 Example 条件更新实体 record包含的全部属性,null 值会被更新UpdateByExampleSelectiveMapper int updateByExampleSelective(@Param("record") T record, @Param("example") Object example)根据 Example 条件更新实体 record包含的全部属性,null 值会被忽略RowBoundsMapper:分页查询,配合分页插件 PageHelper 可以实现物理分页Marker:则是我们上面自定义实现的顶级父类
以上方法仅限于了解,具体的用法还是建议去 官方文档阅读 (opens new window)
# 开发测试用例
编写 service
package cn.mrcode.foodiedev.service.impl;
import cn.mrcode.foodiedev.mapper.StuMapper;
import cn.mrcode.foodiedev.pojo.Stu;
import cn.mrcode.foodiedev.service.StuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
@SuppressWarnings({"SpringJavaInjectionPointsAutowiringInspection"})
@Service
public class StuServiceImpl implements StuService {
@Autowired
private StuMapper stuMapper;
@Transactional(propagation = Propagation.SUPPORTS)
@Override
public Stu getStuInfo(int id) {
return stuMapper.selectByPrimaryKey(id);
}
...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
编写 controller
package cn.mrcode.foodiedev.api.controller;
import cn.mrcode.foodiedev.service.StuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class StuController {
@Autowired
private StuService stuService;
@GetMapping("/getStu")
public Object getStu(int id) {
return stuService.getStuInfo(id);
}
...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
非常重要的一个步骤:需要使用 tk mapper 的方式扫描我们之前生成的那些 mapper 接口
package cn.mrcode.foodiedev;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import tk.mybatis.spring.annotation.MapperScan;
@SpringBootApplication
@MapperScan("cn.mrcode.foodiedev.mapper") // 使用 tk mapper 扫描 mapper 目录
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
重启项目访问 http://localhost:8088/getStu?id=1 (先手动在 stu 表中新增一条数据,再尝试),如果返回结果则表明整合确实没有什么问题了
那么其他的几个方法,由于这里是演示,所以也是非常的简单
@PostMapping("/saveStu")
public Object saveStu() {
stuService.saveStu();
return "OK";
}
@PostMapping("/updateStu")
public Object updateStu(int id) {
stuService.updateStu(id);
return "OK";
}
@PostMapping("/deleteStu")
public Object deleteStu(int id) {
stuService.deleteStu(id);
return "OK";
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Transactional(propagation = Propagation.REQUIRED)
@Override
public void saveStu() {
Stu record = new Stu();
record.setName("jack");
record.setAge(19);
stuMapper.insert(record);
}
@Transactional(propagation = Propagation.REQUIRED)
@Override
public void updateStu(int id) {
Stu record = new Stu();
record.setId(id);
record.setName("jack-update");
record.setAge(50);
stuMapper.updateByPrimaryKey(record);
}
@Transactional(propagation = Propagation.REQUIRED)
@Override
public void deleteStu(int id) {
stuMapper.deleteByPrimaryKey(id);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 调试 RestFull 接口
此类工具有很多,比如 PostMan 工具,自己百度一下。
不过笔者这里推荐使用 IDEA 自带的测试工具,详情看这个笔记 (opens new window)