目录
- 首先引入pom
- 通用Mapper是tk.mybais中的
- 也可以用代码进行配置
- 数据库创建一张表member以及相关字段
- 新建一个通用Mapper继承Mapper、MySqlMapper
- 比较详细的一个入门示例
- 举例我要写一个通用的单表分页
- 在自己的BaseMapper写一个方法
- 新建的BaseMapperProvider
- 对上诉实现代码的描述
- 返回后通用Mapper是怎么处理的
最近公司在用的通用mapper,自己感兴趣,然后就来搭建了一个springboot项目试验通用mapper
这个项目是国内的大神写的一个mybatis插件,里面有很多的增删改查方法
官方解释的是通用mapper支持3.2.4以及以上的版本
首先引入pom
org.mybatis.spring.boot
mybatis-spring-boot-starter
1.1.1
org.mybatis.generator
mybatis-generator
1.3.5
pom
com.github.pagehelper
pagehelper
4.2.1
tk.mybatis
mapper-spring-boot-starter
1.1.4
通用Mapper是tk.mybais中的
配置文件application.yml:
server:
port: 8081
# 下面是配置undertow作为服务器的参数
undertow:
# 设置IO线程数, 它主要执行非阻塞的任务,它们会负责多个连接, 默认设置每个CPU核心一个线程
io-threads: 4
# 阻塞任务线程池, 当执行类似servlet请求阻塞操作, undertow会从这个线程池中取得线程,它的值设置取决于系统的负载
worker-threads: 20
# 以下的配置会影响buffer,这些buffer会用于服务器连接的IO操作,有点类似netty的池化内存管理
# 每块buffer的空间大小,越小的空间被利用越充分
buffer-size: 1024
# 是否分配的直接内存
direct-buffers: true
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.jdbc.Driver
driver-class-name: com.mysql.jdbc.Driver
platform: mysql
url: jdbc:mysql://xxx.xxx.xxx.xxx:5306/miniprogram?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&useSSL=false
username: xxxxx
password: xxxxx
initialSize: 5
minIdle: 5
maxActive: 20
maxWait: 60000
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 300000
validationQuery: SELECT1FROMDUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
filters: stat,wall
logSlowSql: true
redis:
database: 1
host: xxxxx
port: xxxx
password: xxxx
timeout: 10000
activemq:
queueName: mvp.queue
topicName: mvp.topic
#账号密码
user: user
password: user
#URL of the ActiveMQ broker.
broker-url: tcp://localhost:61616
in-memory: false
#必须使用连接池
pool:
#启用连接池
enabled: true
#连接池最大连接数
max-connections: 5
#空闲的连接过期时间,默认为30秒
idle-timeout: 30s
# jedis: 有默认值,源码:RedisProperties
# pool:
# max-active:
# max-idle:
# max-wait:
# min-idle:
mybatis:
typeAliasesPackage: com.pinyu.miniprogram.mysql.entity
mapper-locations: classpath:mapper/**/*Mapper.xml
mapper:
mappers: com.pinyu.miniprogram.mysql.mappers.BaseMapper
identity: mysql
#logging.config:
# classpath: test/log4j2_test.xml
xxxx请配置自己的数据库相关信息
mapper:
mappers: com.pinyu.miniprogram.mysql.mappers.BaseMapper
identity: mysql
ctrl+鼠标点击com.pinyu.miniprogram.mysql.mappers.BaseMapper 进入源码可以看到 MapperProperties类

是一个集合,意思这里可以mappers配置多个通用Mapper,可以是直接继承它已有的通用Mapper,也可以是定义自己需要的通用Mapper,自定义通用Mapper(代替它的Mapper)继承实现的方式不一样,下面会讲到
也可以用代码进行配置
/**
* 通用mapper与分页插件的一些配置
*/
@Configuration
public class MyBatisMapperScannerConfig {
/**
* 使用通用Mapper之前需要初始化的一些信息
* 使用通用Mapper插件时请勿使用热加载,否则报错,插件作者后续应该会修复
*/
@Bean
public MapperScannerConfigurer mapperScannerConfigurer() {
MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
mapperScannerConfigurer.setSqlSessionFactoryBeanName("sqlSessionFactory");
mapperScannerConfigurer.setBasePackage("com.xx.xx.xx.mapper");//普通mapper的位置
Properties properties = new Properties();
properties.setProperty("mappers", BaseMapper.class.getName());//通用mapper的全名
properties.setProperty("notEmpty", "false");
properties.setProperty("IDENTITY", "MYSQL");//配置数据库方言
mapperScannerConfigurer.setProperties(properties);
return mapperScannerConfigurer;
}
/**
* 配置mybatis的分页插件pageHelper
*/
@Bean
public PageHelper pageHelper(){
PageHelper pageHelper = new PageHelper();
Properties properties = new Properties();
//设置为true时,会将RowBounds第一个参数offset当成pageNum页码使用
properties.setProperty("offsetAsPageNum","true");
//置为true时,使用RowBounds分页会进行count查询
properties.setProperty("rowBoundsWithCount","true");
//合理化查询,启用合理化时,
//如果pageNum<1会查询第一页,如果pageNum>pages会查询最后一页
//未开启时如果pageNum<1或pageNum>pages会返回空数据
properties.setProperty("reasonable","true");
//配置mysql数据库的方言
properties.setProperty("dialect","mysql");
pageHelper.setProperties(properties);
return pageHelper;
}
}
mappers对应的通用mapper类,不要和自己其他业务的mapper放在一起,不要被@MapperScan扫描到,不然会报错,因为继承了通用mapper,会有很多相应的方法,被扫描到以后,mybatis发现没有一个xml配置文件或者相应方法没有进行实现,这时候就会报错。但是继承自己的BaseMapper相关mapper肯定是要被扫描到的
数据库创建一张表member以及相关字段
/*
Navicat MySQL Data Transfer
Source Server : 120.79.81.103-5306-master
Source Server Version : 50719
Source Host : 120.79.81.103:5306
Source Database : miniprogram
Target Server Type : MYSQL
Target Server Version : 50719
File Encoding : 65001
Date: 2019-04-03 23:09:51
*/
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for member
-- ----------------------------
DROP TABLE IF EXISTS `member`;
CREATE TABLE `member` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`member_name` varchar(255) NOT NULL COMMENT '会员用户名',
`tel` varchar(255) DEFAULT NULL COMMENT '电话',
`nick_name` varchar(255) NOT NULL COMMENT '昵称',
`head_img` varchar(255) DEFAULT NULL COMMENT '头像地址',
`status` int(1) NOT NULL COMMENT '状态 1启用 2禁用',
`create_date` datetime NOT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '创建时间',
`update_date` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
`pwd` varchar(255) NOT NULL COMMENT '密码',
`signature` varchar(255) DEFAULT NULL COMMENT '个性签名',
`creat_id` bigint(20) DEFAULT NULL,
`delete_state` int(1) NOT NULL DEFAULT '1',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of member
-- ----------------------------
INSERT INTO `member` VALUES ('1', 'dsada', '15928878433', 'dasdas', null, '1', '2019-03-11 18:47:53', '2019-03-11 18:47:53', '123456', null, null, '1');
INSERT INTO `member` VALUES ('2', 'ypp', '15928878888', '6666', null, '1', '2019-03-11 19:35:39', null, 'EDGM@MAMABDACFDLLG', null, null, '1');
创建实体MemberEntity,一般创建实体我都会抽一些相同的字段出来
MemberEntity:
package com.pinyu.miniprogram.mysql.entity.member;
import javax.persistence.Table;
import com.pinyu.miniprogram.mysql.entity.BaseEntity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
@Data // getter、setter
@AllArgsConstructor // 全参构造方法
@NoArgsConstructor // 无参构造方法
@Accessors(chain = true) // 链式编程写法
@Table(name="member")
public class MemberEntity extends BaseEntity {
/**
*
*/
private static final long serialVersionUID = -2601234073734313278L;
private String memberName;// 会员登录用户名
private String nickName;// 昵称
private String tel;// 电话
private String pwd;// 密码
private String headImg;// 头像图片
private String signature;// 个性签名
private Integer status;//状态 1禁用 2启用
}
BaseEntity:
package com.pinyu.miniprogram.mysql.entity;
import java.util.Date;
import javax.persistence.Column;
import com.pinyu.miniprogram.mysql.entity.member.MemberEntity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
/**
* @author ypp
* @Description: TODO(用一句话描述该文件做什么)
*/
@Data // getter、setter
@AllArgsConstructor // 全参构造方法
@NoArgsConstructor // 无参构造方法
@Accessors(chain = true) // 链式编程写法
public class BaseEntity extends IdEntity {
/**
*
*/
private static final long serialVersionUID = 8575696766261326260L;
@Column(name="creat_id")
private Integer creatId;
@Column(name="create_date")
private Date createDate;
@Column(name="delete_state")
private Integer deleteState;// 删除状态 1正常 2已删除
}
IdEntity:
package com.pinyu.miniprogram.mysql.entity;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import com.pinyu.miniprogram.mysql.entity.member.MemberEntity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
/**
* @author ypp
* @Description: TODO(用一句话描述该文件做什么)
*/
@Data // getter、setter
@AllArgsConstructor // 全参构造方法
@NoArgsConstructor // 无参构造方法
@Accessors(chain = true) // 链式编程写法
public class IdEntity implements Serializable {
/**
*
*/
private static final long serialVersionUID = -9089706482760436909L;
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
}
@Table
:对应数据库的表,如果不写默认是类名首字母小写作为表名,比Member,不写数据库表默认指向member
@Column
:的属性name对应数据库表的字段,如果不写默认是驼峰下划线匹配,比如private Long myId,如果不写得话,就是对应数据库表字段my_id
@Id
:把当前字段作为数据库主键使用,匹配数据库主键。如果不贴此注解,在某些查询语句的时候会把表字段一起作为联合主键查询
@GeneratedValue
:让通用mapper在执行insert操作之后将自动生成的主键值回写到当前实体对象对应的属性当中
新建一个通用Mapper继承Mapper、MySqlMapper
点击进去看
package com.pinyu.miniprogram.mysql.mappers;
import com.pinyu.miniprogram.mysql.entity.BaseEntity;
import tk.mybatis.mapper.common.Mapper;
import tk.mybatis.mapper.common.MySqlMapper;
/**
* @author ypp
* 创建时间:2018年12月27日 下午1:29:03
* @Description: TODO(用一句话描述该文件做什么)
*/
public interface BaseMapper extends Mapper,MySqlMapper{
}
BaseMapper是我自己定义的通用Mapper,注意在被继承Mapper上面也有BaseMapper,注意区分,我这里名字取一样了而已。
被Mapper继承的BaseMapper里面有还有很多增删改查的方法

这是源码
看了下,里面有大概20个左右方法,都是比较基础的增删改查

测试:



MemberMapper并没有selectAll方法,沿用的继承的selectAll方法
比较详细的一个入门示例
希望能帮助到用到的小伙伴

自定义通用Mapper,也有可能在实际工作中通用Mapper并不能满足工作,需要额外的一些通用方法,但是这种的情况很少,通用Mapper提供的方法基本都能满足单表操作需求了
举例我要写一个通用的单表分页
1、自己定义的通用Mapper必须包含泛型,例如MysqlMapper。这一点在这里可以忽略,这里并没有自定义自己的通用Mapper,而是使用了它自带的通用Mapper,我们继承的它
2、自定义的通用Mapper接口中的方法需要有合适的注解。具体可以参考Mapper
3、需要继承MapperTemplate来实现具体的操作方法。必须要新建一个类继承MapperTemplate,必须继承MapperTemplate,必须继承MapperTemplate
4、通用Mapper中的Provider一类的注解只能使用相同的type类型(这个类型就是第三个要实现的类。)。实际上method也都写的一样。
在自己的BaseMapper写一个方法
改造后的BaseMapper
package com.pinyu.miniprogram.mysql.mappers;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.SelectProvider;
import com.pinyu.miniprogram.mysql.entity.BaseEntity;
import tk.mybatis.mapper.common.Mapper;
import tk.mybatis.mapper.common.MySqlMapper;
/**
* @author ypp 创建时间:2018年12月27日 下午1:29:03
* @Description: TODO(用一句话描述该文件做什么)
*/
public interface BaseMapper extends Mapper, MySqlMapper {
/**
* * 单表分页查询 * * @param object * @param offset * @param limit * @return
*/
@SelectProvider(type = BaseMapperProvider.class, method = "dynamicSQL")
List selectPage(@Param("entity") T object, @Param("offset") int offset, @Param("limit") int limit);
}
返回结果为List,入参分别为查询条件和分页参数。在Mapper的接口方法中,当有多个入参的时候建议增加@Param注解,否则就得用param1,param2...来引用参数。
同时必须在方法上添加注解。查询使用SelectProvider,插入使用@InsertProvider,更新使用UpdateProvider,删除使用DeleteProvider。不同的Provider就相当于xml中不同的节点,如