今天听说在 SpringBoot 整合 mybatis 和通用 mapper 的时候会产生一个奇怪的问题,即执行 sql 语句的时候会找不到主键,比如下面这个样子

1
2
3
4
5
6
7
//这是我要执行的方法,很明显就只是查询user表中的所有数据
userMapper.selectAll();

//结果是这样的
2018-11-20 16:17:54.111 DEBUG 10640 --- [nio-8111-exec-1] p.gabriel.mapper.UserMapper.selectAll : ==> Preparing: SELECT username,password FROM user
2018-11-20 16:17:54.111 DEBUG 10640 --- [nio-8111-exec-1] p.gabriel.mapper.UserMapper.selectAll : ==> Parameters:
2018-11-20 16:17:54.129 DEBUG 10640 --- [nio-8111-exec-1] p.gabriel.mapper.UserMapper.selectAll : <== Total: 1

明显看到 id 这个列并没有被查询到,第一反应是先去查看User

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
package priv.gabriel.model;

import javax.persistence.*;

/**
* Created with Intellij IDEA.
*
* @Author: Gabriel
* @Date: 2018-11-20
* @Description:
*/
@Entity
@Table
public class User {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;

@Column
private String username;

@Column
private String password;

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public String getUsername() {
return username;
}

public void setUsername(String username) {
this.username = username;
}

public String getPassword() {
return password;
}

public void setPassword(String password) {
this.password = password;
}

@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
'}';
}
}

然而并没有什么问题,该标识的都标识了,然后又去查了一波dao

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package priv.gabriel.mapper;

import org.apache.ibatis.annotations.Mapper;
import priv.gabriel.model.User;
import tk.mybatis.mapper.common.BaseMapper;

/**
* Created with Intellij IDEA.
*
* @Author: Gabriel
* @Date: 2018-11-20
* @Description:
*/
@Mapper
public interface UserMapper extends BaseMapper<User>{

}

···根本不可能出现问题嘛,然后绞尽脑汁的考虑的各方面的问题,怀疑是版本问题甚至把tk.mapper的 2.x 版本挨个下载完了,但是,并没有什么用。
就在我怀疑人生的时候,突然瞟了一眼User类,灵光一闪,改造成了如下的款式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
package priv.gabriel.model;

import javax.persistence.*;

/**
* Created with Intellij IDEA.
*
* @Author: Gabriel
* @Date: 2018-11-20
* @Description:
*/
@Entity
@Table
public class User {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@Column
private String username;

@Column
private String password;

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 getPassword() {
return password;
}

public void setPassword(String password) {
this.password = password;
}

@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
'}';
}
}

看得出来区别吗?在这里我仅仅是把idint类型 转为了 Long类型居然就好了???

1
2
3
2018-11-20 16:33:10.236 DEBUG 10076 --- [nio-8111-exec-1] p.gabriel.mapper.UserMapper.selectAll    : ==>  Preparing: SELECT id,username,password FROM user
2018-11-20 16:33:10.257 DEBUG 10076 --- [nio-8111-exec-1] p.gabriel.mapper.UserMapper.selectAll : ==> Parameters:
2018-11-20 16:33:10.281 DEBUG 10076 --- [nio-8111-exec-1] p.gabriel.mapper.UserMapper.selectAll : <== Total: 1

。。。
timg.jpg
具体情况还不清楚,我已经准备潜伏到tk.mapper的群里问个明白,等搞清楚了再更新

#更新 2018.11.21
在 github 的文档上找到了

默认情况下,简单类型会被识别为表中的字段,但是不 包 含 Java 的 基 本 类 型

timg (1).jpg

继续翻翻文档,发现下面有一项配置可以支持基本类型
usePrimitiveType=true

#总结
虽然之后找到了解决方案,但同时也发现了对应的问题

使用基本数据类型就会有默认值,而在Mybatis中经常会判断属性值是否为空,为了避免这样的问题最好在类中声明属性时都使用包装类