# mybatis-plus 通用组件
特别提示
基于MybatisPlus (opens new window),数据库基于Mysql5.6以上
# 安装
在 Maven 工程中使用
<dependency>
<groupId>com.zhengcheng</groupId>
<artifactId>zc-mybatis-plus-spring-boot-starter</artifactId>
</dependency>
1
2
3
4
2
3
4
# 配置
属性配置
mybatis-plus.mapper-locations = classpath*:**/*Mapper.xml
mybatis-plus.type-aliases-package = com.zhengcheng.user.entity
mybatis-plus.configuration.map-underscore-to-camel-case = true
mybatis-plus.type-enums-package = com.zhengcheng.user.enums
1
2
3
4
2
3
4
要求Mapper
接口的包路径满足以下条件(否则不能自动扫描到Mapper):
@MapperScan(basePackages = "com.zhengcheng.**.mapper*")
1
# 核心功能
按照阿里巴巴JAVA
开发手册、规定,每张数据库表都有以下的公共字段:
CREATE TABLE `t_base` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',
`create_time` datetime NOT NULL COMMENT '创建时间',
`update_time` datetime NOT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`is_deleted` tinyint unsigned NOT NULL COMMENT '是否删除',
PRIMARY KEY (`id`),
KEY `idx_type` (`type`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=REDUNDANT COMMENT='公共字段模板表';
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
当你在项目中的entity
继承BaseEntity
后,就自动拥有了公共字段,不需要你在添加、更新时维护,代码示例如下:
- 表对应的实体
import com.baomidou.mybatisplus.annotation.TableName;
import com.zhengcheng.mybatis.plus.model.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* 数据字典表(DictItem)实体类
*
* @author quansheng1.zhang
* @since 2020-10-29 20:15:38
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
@TableName("t_dict_item")
public class DictItem extends BaseEntity<DictItem> {
private static final long serialVersionUID = 836566997638888136L;
/**
* 类型
*/
private String type;
/**
* 字典编码
*/
private String code;
/**
* 字典名称
*/
private String name;
}
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
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
- 添加记录
@Autowired
private IDictItemService dictItemService;
DictItem dictItem = this.toEntity(dictItemCommand);
dictItemService.save(dictItem);
private DictItem toEntity(DictItemCommand dictItemCommand) {
DictItem dictItem = new DictItem();
dictItem.setType(dictItemCommand.getType());
dictItem.setCode(dictItemCommand.getCode());
dictItem.setName(dictItemCommand.getName());
return dictItem;
}
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
- 解决了繁琐的配置,让
mybatis
优雅的使用枚举属性!对应代码如下:
/**
* 登录结果
*
* @author : quansheng.zhang
* @date : 2019/10/29 11:02
*/
@Getter
public enum LoginResultEnum {
SUCCESS(0, "成功"),
FAILURE(1, "失败");
@EnumValue
private final int value;
private final String desc;
LoginResultEnum(final int value, final String desc) {
this.value = value;
this.desc = desc;
}
/**
* 根据value获取类型
*
* @param value
* 值
* @return 枚举
*/
public static LoginResultEnum getByValue(Integer value) {
for (LoginResultEnum loginResultEnum : LoginResultEnum.values()) {
if (value.equals(loginResultEnum.getValue())) {
return loginResultEnum;
}
}
return LoginResultEnum.SUCCESS;
}
}
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
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
# mybatis-plus-sample-wrapper
@RunWith(SpringRunner.class)
@SpringBootTest
public class WrapperTest {
@Resource
private UserMapper userMapper;
@Resource
private RoleMapper roleMapper;
@Test
public void tests() {
System.out.println("----- 普通查询 ------");
List<User> plainUsers = userMapper.selectList(new QueryWrapper<User>().eq("role_id", 2L));
List<User> lambdaUsers = userMapper.selectList(new QueryWrapper<User>().lambda().eq(User::getRoleId, 2L));
Assert.assertEquals(plainUsers.size(), lambdaUsers.size());
print(plainUsers);
System.out.println("----- 带子查询(sql注入) ------");
List<User> plainUsers2 = userMapper.selectList(new QueryWrapper<User>()
.inSql("role_id", "select id from role where id = 2"));
List<User> lambdaUsers2 = userMapper.selectList(new QueryWrapper<User>().lambda()
.inSql(User::getRoleId, "select id from role where id = 2"));
Assert.assertEquals(plainUsers2.size(), lambdaUsers2.size());
print(plainUsers2);
System.out.println("----- 带嵌套查询 ------");
List<User> plainUsers3 = userMapper.selectList(new QueryWrapper<User>()
.nested(i -> i.eq("role_id", 2L).or().eq("role_id", 3L))
.and(i -> i.ge("age", 20)));
List<User> lambdaUsers3 = userMapper.selectList(new QueryWrapper<User>().lambda()
.nested(i -> i.eq(User::getRoleId, 2L).or().eq(User::getRoleId, 3L))
.and(i -> i.ge(User::getAge, 20)));
Assert.assertEquals(plainUsers3.size(), lambdaUsers3.size());
print(plainUsers3);
System.out.println("----- 自定义(sql注入) ------");
List<User> plainUsers4 = userMapper.selectList(new QueryWrapper<User>()
.apply("role_id = 2"));
print(plainUsers4);
UpdateWrapper<User> uw = new UpdateWrapper<>();
uw.set("email", null);
uw.eq("id", 4);
userMapper.update(new User(), uw);
User u4 = userMapper.selectById(4);
Assert.assertNull(u4.getEmail());
}
@Test
public void lambdaQueryWrapper() {
System.out.println("----- 普通查询 ------");
List<User> plainUsers = userMapper.selectList(new LambdaQueryWrapper<User>().eq(User::getRoleId, 2L));
List<User> lambdaUsers = userMapper.selectList(new QueryWrapper<User>().lambda().eq(User::getRoleId, 2L));
Assert.assertEquals(plainUsers.size(), lambdaUsers.size());
print(plainUsers);
System.out.println("----- 带子查询(sql注入) ------");
List<User> plainUsers2 = userMapper.selectList(new LambdaQueryWrapper<User>()
.inSql(User::getRoleId, "select id from role where id = 2"));
List<User> lambdaUsers2 = userMapper.selectList(new QueryWrapper<User>().lambda()
.inSql(User::getRoleId, "select id from role where id = 2"));
Assert.assertEquals(plainUsers2.size(), lambdaUsers2.size());
print(plainUsers2);
System.out.println("----- 带嵌套查询 ------");
List<User> plainUsers3 = userMapper.selectList(new LambdaQueryWrapper<User>()
.nested(i -> i.eq(User::getRoleId, 2L).or().eq(User::getRoleId, 3L))
.and(i -> i.ge(User::getAge, 20)));
List<User> lambdaUsers3 = userMapper.selectList(new QueryWrapper<User>().lambda()
.nested(i -> i.eq(User::getRoleId, 2L).or().eq(User::getRoleId, 3L))
.and(i -> i.ge(User::getAge, 20)));
Assert.assertEquals(plainUsers3.size(), lambdaUsers3.size());
print(plainUsers3);
System.out.println("----- 自定义(sql注入) ------");
List<User> plainUsers4 = userMapper.selectList(new QueryWrapper<User>()
.apply("role_id = 2"));
print(plainUsers4);
UpdateWrapper<User> uw = new UpdateWrapper<>();
uw.set("email", null);
uw.eq("id", 4);
userMapper.update(new User(), uw);
User u4 = userMapper.selectById(4);
Assert.assertNull(u4.getEmail());
}
private <T> void print(List<T> list) {
if (!CollectionUtils.isEmpty(list)) {
list.forEach(System.out::println);
}
}
/**
* SELECT id,name,age,email,role_id FROM user
* WHERE ( 1 = 1 ) AND ( ( name = ? AND age = ? ) OR ( name = ? AND age = ? ) )
*/
@Test
public void testSql() {
QueryWrapper<User> w = new QueryWrapper<>();
w.and(i -> i.eq("1", 1))
.nested(i ->
i.and(j -> j.eq("name", "a").eq("age", 2))
.or(j -> j.eq("name", "b").eq("age", 2)));
userMapper.selectList(w);
}
}
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# mybatis-plus-sample-pagination
@Slf4j
@SpringBootTest
public class PaginationTest {
@Resource
private UserMapper mapper;
@Test
public void lambdaPagination() {
Page<User> page = new Page<>(1, 3);
Page<User> result = mapper.selectPage(page, Wrappers.<User>lambdaQuery().ge(User::getAge, 1).orderByAsc(User::getAge));
assertThat(result.getTotal()).isGreaterThan(3);
assertThat(result.getRecords().size()).isEqualTo(3);
}
@Test
public void tests1() {
log.error("----------------------------------baseMapper 自带分页-------------------------------------------------------");
Page<User> page = new Page<>(1, 5);
page.addOrder(OrderItem.asc("age"));
Page<User> userIPage = mapper.selectPage(page, Wrappers.<User>lambdaQuery().eq(User::getAge, 20).like(User::getName, "Jack"));
assertThat(page).isSameAs(userIPage);
log.error("总条数 -------------> {}", userIPage.getTotal());
log.error("当前页数 -------------> {}", userIPage.getCurrent());
log.error("当前每页显示数 -------------> {}", userIPage.getSize());
List<User> records = userIPage.getRecords();
assertThat(records).isNotEmpty();
log.error("----------------------------------json 正反序列化-------------------------------------------------------");
String json = JSON.toJSONString(page);
log.info("json ----------> {}", json);
Page<User> page1 = JSON.parseObject(json, new TypeReference<Page<User>>() {
});
List<User> records1 = page1.getRecords();
assertThat(records1).isNotEmpty();
assertThat(records1.get(0).getClass()).isEqualTo(User.class);
log.error("----------------------------------自定义 XML 分页-------------------------------------------------------");
MyPage<User> myPage = new MyPage<User>(1, 5).setSelectInt(20).setSelectStr("Jack");
ParamSome paramSome = new ParamSome(20, "Jack");
MyPage<User> userMyPage = mapper.mySelectPage(myPage, paramSome);
assertThat(myPage).isSameAs(userMyPage);
log.error("总条数 -------------> {}", userMyPage.getTotal());
log.error("当前页数 -------------> {}", userMyPage.getCurrent());
log.error("当前每页显示数 -------------> {}", userMyPage.getSize());
}
@Test
public void tests2() {
/* 下面的 left join 不会对 count 进行优化,因为 where 条件里有 join 的表的条件 */
MyPage<UserChildren> myPage = new MyPage<>(1, 5);
myPage.setSelectInt(18).setSelectStr("Jack");
MyPage<UserChildren> userChildrenMyPage = mapper.userChildrenPage(myPage);
List<UserChildren> records = userChildrenMyPage.getRecords();
records.forEach(System.out::println);
/* 下面的 left join 会对 count 进行优化,因为 where 条件里没有 join 的表的条件 */
myPage = new MyPage<UserChildren>(1, 5).setSelectInt(18);
userChildrenMyPage = mapper.userChildrenPage(myPage);
records = userChildrenMyPage.getRecords();
records.forEach(System.out::println);
}
private <T> void print(List<T> list) {
if (!CollectionUtils.isEmpty(list)) {
list.forEach(System.out::println);
}
}
@Test
public void testMyPageMap() {
MyPage<User> myPage = new MyPage<User>(1, 5).setSelectInt(20).setSelectStr("Jack");
mapper.mySelectPageMap(myPage, Maps.newHashMap("name", "%a"));
myPage.getRecords().forEach(System.out::println);
}
@Test
public void testMap() {
mapper.mySelectMap(Maps.newHashMap("name", "%a")).forEach(System.out::println);
}
@Test
public void myPage() {
MyPage<User> page = new MyPage<>(1, 5);
page.setName("a");
mapper.myPageSelect(page).forEach(System.out::println);
}
@Test
public void iPageTest() {
IPage<User> page = new Page<User>(1, 5) {
private String name = "%";
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
};
List<User> list = mapper.iPageSelect(page);
System.out.println("list.size=" + list.size());
System.out.println("page.total=" + page.getTotal());
}
@Test
public void rowBoundsTest() {
RowBounds rowBounds = new RowBounds(0, 5);
List<User> list = mapper.rowBoundList(rowBounds, Maps.newHashMap("name", "%"));
System.out.println("list.size=" + list.size());
}
@Test
public void selectAndGroupBy() {
LambdaQueryWrapper<User> lq = new LambdaQueryWrapper<>();
lq.select(User::getAge).groupBy(User::getAge);
for (User user : mapper.selectList(lq)) {
System.out.println(user.getAge());
}
}
@Autowired
IUserService userService;
@Test
public void lambdaPageTest() {
LambdaQueryChainWrapper<User> wrapper2 = userService.lambdaQuery();
wrapper2.like(User::getName, "a");
userService.page(new Page<>(1, 10), wrapper2.getWrapper()).getRecords().forEach(System.out::print);
}
@Test
public void test() {
userService.lambdaQuery().like(User::getName, "a").list().forEach(System.out::println);
Page page = userService.lambdaQuery().like(User::getName, "a").page(new Page<>(1, 10));
page.getRecords().forEach(System.out::println);
}
}
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142