Spring Boot项目通用功能之《通用Mapper》

前言
接下来这几篇文章中我们主要说说,在我们的项目中会使用哪些通用的功能,例如:通用Mapper(mybatis框架的)、通用service和分页功能等等,这些通用功能的使用会大大降低我们的开发时间,也会让我们的代码变得更加有规范更加合理,今天这篇文章我们说说怎么使用通用mapper。

通用mapper简介
通用mapper是一个国人编写的工具jar,它可以极其方便的做单表增删改查(使用Mybatis框架),目前不支持通用的多表联合查询,在使用mybatis时,就不需要重复的维护功能类似单表操作mapper.xml文件和mapper接口的定义,下面给出它的码云和github地址。

码云:https://gitee.com/free/Mapper
GitHub:https://github.com/abel533/Mybatis-Spring
使用前疑问
这个东西使用后,会不会降低我们的代码执行效率呢?
答:其实他的原理就是利用反射机制拼出的 XML形式的动态SQL然后去执行,所以你说代码时间消耗肯定也会有一些,但是这是很小很小的,再者在现在项目中,对于提供给前端的接口,通常都会利用些组件进行访问加速(毕竟直接从数据中检索不如在内存中来的快些),比如:redis、memcache、elastic search、solr等,所以执行效率问题是可以避免或忽略的。
如果有些方法不想使用,例如:用户的接口服务不能使用删除方法也不想暴漏出来,该怎么办呢?
答:我们通常会定义增、删、改、查四个基础Mapper接口,你可以按需要引入进行使用,其实即使你使用了公共的CrudMapper(代表增删改查都在一起的类)也没有问题,只要你在你的service层不要放出删除方法也是可以的。
使用心得
详细使用方式其实在码云上和Github上说的也算是详细,至少基础入门是没有问题,下面我们说说在spring boot项目中的配置和使用方法。

1 首先引入包
        <dependency>
            <groupId>tk.mybatis</groupId>
            <artifactId>mapper</artifactId>
            <version>3.4.0</version><!--这里使用时去看看最新版本哈-->
        </dependency>
1
2
3
4
5
如果是spring boot项目直接引入:

        <dependency>
            <groupId>tk.mybatis</groupId>
            <artifactId>mapper-spring-boot-starter</artifactId>
            <version>1.2.3</version>
        </dependency>
1
2
3
4
5
2 增加配置类
package com.zhuma.demo.config.mybatis;

import com.zhuma.demo.comm.mapper.CrudMapper;
import org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import tk.mybatis.spring.mapper.MapperScannerConfigurer;

import java.util.Properties;

@Configuration
@AutoConfigureAfter(MybatisAutoConfiguration.class)
public class MyBatisConfig {

    @Bean
    public MapperScannerConfigurer mapperScannerConfigurer() {
        MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
        mapperScannerConfigurer.setSqlSessionFactoryBeanName("sqlSessionFactory");
        mapperScannerConfigurer.setBasePackage("com.zhuma.demo.mapper");

        Properties properties = new Properties();
        properties.setProperty("mappers", CrudMapper.class.getName());
        properties.setProperty("notEmpty", "false");
        properties.setProperty("IDENTITY", "MYSQL");
        properties.setProperty("ORDER","BEFORE");
        mapperScannerConfigurer.setProperties(properties);
        return mapperScannerConfigurer;
    }

}
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
备注

这里需要注意的是MapperScannerConfigurer 类是tk.mybatis.spring.mapper这个包下的
mapperScannerConfigurer.setBasePackage(“com.zhuma.demo.mapper”),这里去配置你自己数据库对应Mapper类的包路径,如果有多个用英文逗号分隔
上面配置类中引入了一个CrudMapper类,这个是我们自己定义的它是提供增删改查的基础接口,下面会给出详细代码。(注意不要跟自定义功能mapper放到这个下面)
3 常规方法接口整合到自己的自定义Mapper接口上
备注:因为我们使用的是mysql数据库,所以在使用通用功能的时候就选择性引入一些经常使用的方法,下面是自己定义的常用mapper类的整合(这里会抛弃一些不常用的类或不是mysql的方法类)。
① 提供新增功能Mapper类:

package com.zhuma.demo.comm.mapper;

import tk.mybatis.mapper.common.Marker;
import tk.mybatis.mapper.common.MySqlMapper;
import tk.mybatis.mapper.common.base.insert.InsertSelectiveMapper;

/**
 * @desc 基础插入功能mapper
 * 
 * @author zhumaer
 * @since 10/18/2017 18:31 PM
 */
public interface InsertMapper<T> extends Marker,
        tk.mybatis.mapper.common.base.insert.InsertMapper<T>,
                                                InsertSelectiveMapper<T>,
                                                MySqlMapper<T>{
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
② 提供删除功能的Mapper类

package com.zhuma.demo.comm.mapper;

import tk.mybatis.mapper.common.Marker;
import tk.mybatis.mapper.common.base.delete.DeleteByPrimaryKeyMapper;
import tk.mybatis.mapper.common.condition.DeleteByConditionMapper;
import tk.mybatis.mapper.common.ids.DeleteByIdsMapper;

/**
 * @desc 基础删除功能mapper
 * 
 * @author zhumaer
 * @since 10/18/2017 18:31 PM
 */
public interface DeleteMapper<T> extends Marker,
        tk.mybatis.mapper.common.base.delete.DeleteMapper<T>,
                                                DeleteByPrimaryKeyMapper<T>,
                                                DeleteByConditionMapper<T>,
                                                DeleteByIdsMapper<T> {
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
③ 提供修改功能的Mapper类

package com.zhuma.demo.comm.mapper;

import tk.mybatis.mapper.common.Marker;
import tk.mybatis.mapper.common.base.update.UpdateByPrimaryKeyMapper;
import tk.mybatis.mapper.common.base.update.UpdateByPrimaryKeySelectiveMapper;
import tk.mybatis.mapper.common.condition.UpdateByConditionMapper;
import tk.mybatis.mapper.common.condition.UpdateByConditionSelectiveMapper;
import tk.mybatis.mapper.common.example.UpdateByExampleSelectiveMapper;

/**
 * @desc 基础更新功能mapper
 *
 * @author zhumaer
 * @since 10/18/2017 18:31 PM
 */
public interface UpdateMapper<T> extends Marker,
        UpdateByPrimaryKeyMapper<T>,
        UpdateByPrimaryKeySelectiveMapper<T>,
        UpdateByConditionMapper<T>,
        UpdateByConditionSelectiveMapper<T>,
        UpdateByExampleSelectiveMapper<T> {
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
④ 提供查询功能的Mapper

package com.zhuma.demo.comm.mapper;

import tk.mybatis.mapper.common.Marker;
import tk.mybatis.mapper.common.base.select.*;
import tk.mybatis.mapper.common.condition.SelectByConditionMapper;
import tk.mybatis.mapper.common.condition.SelectCountByConditionMapper;
import tk.mybatis.mapper.common.example.SelectByExampleMapper;
import tk.mybatis.mapper.common.ids.SelectByIdsMapper;

/**
 * @desc 基础查询功能mapper
 *
 * @author zhumaer
 * @since 10/18/2017 18:31 PM
 */
public interface SelectMapper<T> extends Marker,
        SelectOneMapper<T>,
        tk.mybatis.mapper.common.base.select.SelectMapper<T>,
        SelectAllMapper<T>,
        SelectCountMapper<T>,
        SelectByPrimaryKeyMapper<T>,
        ExistsWithPrimaryKeyMapper<T>,
        SelectByIdsMapper<T>,
        SelectByConditionMapper<T>,
        SelectCountByConditionMapper<T>,
        SelectByExampleMapper<T> {
}

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
⑤ 提供增删改查功能Mapper(上面配置是直接引入的这个)

package com.zhuma.demo.comm.mapper;

/**
 * @desc 基础增删改查功能mapper
 * 
 * @author zhumaer
 * @since 10/18/2017 18:31 PM
 */
public interface CrudMapper<T> extends
        InsertMapper<T>,
        DeleteMapper<T>,
        UpdateMapper<T>,
        SelectMapper<T> {
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
3 以用为例我们进行创建并查询用户
① 用户PO类

package com.zhuma.demo.model.po;

import com.zhuma.demo.annotation.EnumValue;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotBlank;

import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import java.io.Serializable;
import java.util.Date;

/**
 * @desc 用户PO

 * @author zhumaer
 * @since 6/15/2017 2:48 PM
 */
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Data
public class User implements Serializable {

    private static final long serialVersionUID = -7491215402569546437L;

    /**
     * 用户ID
     */
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY, generator = "select uuid()")
    @Length(min=1, max=64)
    private String id;

    /**
     * 昵称
     */
    @NotBlank
    @Length(min=1, max=64)
    private String nickname;

    /**
     * 性别
     */
    @NotBlank
    @EnumValue(enumClass=UserGenderEnum.class, enumMethod="isValidName")
    private String gender;

    /**
     * 头像
     */
    @Length(max=256)
    private String avatar;

    /**
     * 状态
     */
    @NotBlank
    @EnumValue(enumClass=UserTypeEnum.class, enumMethod="isValidName")
    private String type;

    /**
     * 账号状态
     */
    @EnumValue(enumClass=UserStatusEnum.class, enumMethod="isValidName")
    private String status;

    private Date createTime;

    private Date updateTime;

    /**
     * 用户性别枚举
     */
    public enum UserGenderEnum {
        /**男*/
        MALE,
        /**女*/
        FEMALE,
        /**未知*/
        UNKNOWN;

        public static boolean isValidName(String name) {
            for (UserGenderEnum userGenderEnum : UserGenderEnum.values()) {
                if (userGenderEnum.name().equals(name)) {
                    return true;
                }
            }
            return false;
        }
    }

    /**
     * 用户类型枚举
     */
    public enum UserTypeEnum {
        /**普通*/
        NORMAL,
        /**管理员*/
        ADMIN;

        public static boolean isValidName(String name) {
            for (UserTypeEnum userTypeEnum : UserTypeEnum.values()) {
                if (userTypeEnum.name().equals(name)) {
                    return true;
                }
            }
            return false;
        }
    }

    /**
     * 用户状态枚举
     */
    public enum UserStatusEnum {
        /**启用*/
        ENABLED,
        /**禁用*/
        DISABLED;

        public static boolean isValidName(String name) {
            for (UserStatusEnum userStatusEnum : UserStatusEnum.values()) {
                if (userStatusEnum.name().equals(name)) {
                    return true;
                }
            }
            return false;
        }
    }
}

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
备注

这里注意我们的用户ID通常都是使用UUID作为主键的,所以我们也一样,如果是主键自增就加@GeneratedValue(strategy = GenerationType.IDENTITY)注解。
这个对象中是没有getter、setter方法的,其实是使用了lombok的缘故(如果你不太会使用,可以学一学,还是很简化代码的,lombok入门教程)
② 用户Mpper类

package com.zhuma.demo.mapper;

import com.zhuma.demo.comm.mapper.CrudMapper;
import com.zhuma.demo.model.po.User;
import org.springframework.stereotype.Repository;

/**
 * @desc 用户Mapper
 *
 * @author zhumaer
 * @since 25/1/2018 22:39 PM
 */
@Repository
public interface UserMapper extends CrudMapper<User> {
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
③ 用户控制器(我们还是以保存用户为例)

package com.zhuma.demo.web.user;

import java.util.Date;

import com.zhuma.demo.annotation.ResponseResult;
import com.zhuma.demo.comm.result.DefaultErrorResult;
import com.zhuma.demo.comm.result.PlatformResult;
import com.zhuma.demo.comm.result.Result;
import com.zhuma.demo.exception.BusinessException;
import com.zhuma.demo.exception.DataNotFoundException;
import com.zhuma.demo.exception.UserNotLoginException;
import com.zhuma.demo.mapper.UserMapper;
import com.zhuma.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import com.zhuma.demo.model.po.User;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @desc 用户管理控制器
 * 
 * @author zhumaer
 * @since 6/20/2017 16:37 PM
 */
@ResponseResult
@RestController
@RequestMapping("/users")
public class UserController {

    @Autowired
    private UserMapper userMapper;

    @PostMapping
    @ResponseStatus(HttpStatus.CREATED)
    public User addUser(@Validated @RequestBody User user) {
        Date currentDate = new Date();
        user.setCreateTime(currentDate);
        user.setUpdateTime(currentDate);
        userMapper.insert(user);
        return userMapper.selectByPrimaryKey(user.getId());
    }

}

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
备注
这里省略了service层,真实开发中还是需要的哈。

④ 响应结果

数据中记录

备注

这里注意我们建议在正常创建信息时,需返回201状态码
你可能不清楚为什么我在Controller方法中返回了User对象但是却有code、msg、data这种包装呢,如果你感兴趣可以看一下我的这篇文章就会清楚《接口响应体格式统一封装》
最后
好啦,这篇文章我们主要就是讲解下使用通用Mapper的一个完整实例,如果你还是感觉不太会使用,下两篇文章会介绍在项目中如果实现《通用分页功能》和通用Service(这两篇文章也会有对通用mapper的使用),对于通用mapper的使用,不知道你还有什么疑惑呢,可以关注我的微信号或留言,很愿意和你一起讨论学习O(∩_∩)O~

源码github地址:https://github.com/zhumaer/zhuma
QQ群号:629446754(欢迎加群)
————————————————
版权声明:本文为CSDN博主「筑码-井哥」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/aiyaya_/article/details/79146763

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值