写在前面
MyBatis
的增强方案确实有不少,甚至有种感觉是现在如果只用 “裸MyBatis
”,不来点增强插件都不好意思了。这不,在上一篇文章《Spring Boot项目利用MyBatis Generator进行数据层代码自动生成》 中尝试了一下 MyBatis Generator。这次来点更加先进的 Mybatis-Plus,SQL语句都不用写了,分页也是自动完成,嗯,真香!
数据库准备
DROP TABLE IF EXISTS `dept`;
CREATE TABLE `dept` (
`dept_no` bigint(20) NOT NULL AUTO_INCREMENT,
`dept_name` varchar(60) DEFAULT NULL,
`dept_source` varchar(60) DEFAULT NULL,
PRIMARY KEY (`dept_no`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8 COMMENT='部门表';
-- ----------------------------
-- Records of dept
-- ----------------------------
INSERT INTO `dept` VALUES ('1', '开发部', 'db01');
INSERT INTO `dept` VALUES ('2', '人事部', 'db01');
INSERT INTO `dept` VALUES ('3', '财务部', 'db01');
INSERT INTO `dept` VALUES ('4', '市场部', 'db01');
INSERT INTO `dept` VALUES ('5', '运维部', 'db01');
MyBatis-Plus加持
- 工程搭建 (不赘述了)
- 依赖引入
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- mybatis-plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.1</version>
</dependency>
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.17</version>
</dependency>
</dependencies>
主要是 Mybatis Plus、Lombok(不知道Lombok干嘛的?可以看这里)、Druid连接池 等依赖。
- MyBatis Plus配置
项目配置
server:
port: 10100 # 配置启动端口号
spring: #springboot的配置
datasource: #定义数据源
#127.0.0.1为本机测试的ip,3306是mysql的端口号。serverTimezone是定义时区,照抄就好,mysql高版本需要定义这些东西
#useSSL也是某些高版本mysql需要问有没有用SSL连接
url: jdbc:mysql://127.0.0.1:3306/db01?serverTimezone=GMT%2B8&useSSL=FALSE
username: root #数据库用户名,root为管理员
password: 123456 #该数据库用户的密码
# 使用druid数据源
type: com.alibaba.druid.pool.DruidDataSource
# mybatis-plus相关配置
mybatis-plus:
# xml扫描,多个目录用逗号或者分号分隔(告诉 Mapper 所对应的 XML 文件位置)
mapper-locations: classpath:mapper/*.xml
# 以下配置均有默认值,可以不设置
global-config:
db-config:
#主键类型 AUTO:"数据库ID自增" INPUT:"用户输入ID",ID_WORKER:"全局唯一ID (数字类型唯一ID)", UUID:"全局唯一ID UUID";
id-type: auto
#字段策略 IGNORED:"忽略判断" NOT_NULL:"非 NULL 判断") NOT_EMPTY:"非空判断"
field-strategy: NOT_EMPTY
#数据库类型
db-type: MYSQL
configuration:
# 是否开启自动驼峰命名规则映射:从数据库列名到Java属性驼峰命名的类似映射
map-underscore-to-camel-case: true
# 如果查询结果中包含空值的列,则 MyBatis 在映射的时候,不会映射这个字段
call-setters-on-nulls: true
# 这个配置会将执行的sql打印出来,在开发或测试的时候可以用
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
新增 MyBatis Plus配置类
@Configuration
@MapperScan("com.dhx.mapper")
public class MybatisPlusConfig {
/**
* mybatis-plus SQL执行效率插件【生产环境可以关闭】
*/
@Bean
public PerformanceInterceptor performanceInterceptor() {
return new PerformanceInterceptor();
}
/**
* 分页插件
*/
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
}
看到没,几乎零配置啊,下面就可以写业务逻辑了
业务编写
- 实体类
@Data
@TableName("dept") //@TableName中的值对应着表名
public class Dept implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键
* @TableId中可以决定主键的类型,不写会采取默认值,默认值可以在yml中配置
* AUTO: 数据库ID自增
* INPUT: 用户输入ID
* ID_WORKER: 全局唯一ID,Long类型的主键
* ID_WORKER_STR: 字符串全局唯一ID
* UUID: 全局唯一ID,UUID类型的主键
* NONE: 该类型为未设置主键类型
*/
@TableId(type = IdType.AUTO)
private Long deptNo;
private String deptName;
private String deptSource;
}
- Mapper类
@Mapper
public interface DeptMapper extends BaseMapper<Dept> {
}
这里啥接口方法也不用写,就可以实现增删改查了!
- Service类
Service接口:
public interface DeptService extends IService<Dept> {
}
Service实现:
@Service
@AllArgsConstructor
public class DeptServiceImpl extends ServiceImpl<DeptMapper, Dept> implements DeptService {
}
- controller类
@RestController
@RequestMapping("/userInfo")
public class DeptInfoController {
@Autowired
private DeptService deptService;
/**
* 新增用户信息
*/
@RequestMapping("/saveInfo")
public Object saveInfo(@RequestBody Dept dept ){
return deptService.save(dept);
}
/**
* 批量新增用户信息
*/
@RequestMapping("/saveInfoList")
public Object saveInfoList(@RequestBody List<Dept> list){
//批量保存
return deptService.saveBatch(list);
}
/**
* 根据ID删除用户信息
*/
@RequestMapping("/deleteInfo")
public Object deleteInfo(@RequestBody Dept dept){
return deptService.removeById(dept);
}
/**
* 更新用户信息
*/
@RequestMapping("/updateInfo")
public Object updateInfo(@RequestBody Dept dept){
//根据实体中的ID去更新,其他字段如果值为null则不会更新该字段,参考yml配置文件
return deptService.updateById(dept);
}
/**
* 新增或者更新用户信息
* @Author Sans
* @CreateTime 2019/6/8 16:50
*/
@RequestMapping("/saveOrUpdateInfo")
public Object saveOrUpdate(@RequestBody Dept dept){
//传入的实体类userInfoEntity中ID为null就会新增(ID自增)
//实体类ID值存在,如果数据库存在ID就会更新,如果不存在就会新增
return deptService.saveOrUpdate(dept);
}
/**
* 根据ID获取部门信息
* @param dept
* @return Dept 部门实体
*/
@RequestMapping("/getInfo")
public Dept getInfo(@RequestBody Dept dept){
return deptService.getById(dept.getDeptNo());
}
/**
* 查询全部信息
* @return List<Dept> 部门实体集合
*/
@RequestMapping("/getList")
public List<Dept> getList(){
return deptService.list();
}
/**
* 分页查询全部数据
* @Return IPage<Dept> 分页数据
*/
@RequestMapping("/getInfoListPage")
public IPage<Dept> getInfoListPage(@RequestBody Page page ){
//需要在Config配置类中配置分页插件
page.setCurrent(page.getCurrent()); //当前页
page.setSize(page.getSize()); //每页条数
return deptService.page(page);
}
}
通过以上几个简单的步骤,我们就实现了 Dept表的增删改查,传统 MyBatis的 XML文件一个都不需要写!
实际实验
启动项目
接下来通过 Postman
来发送增删改查的请求
插入记录
通过 Postman
随便插入几条记录 POST http://localhost:10100/userInfo/saveInfo
{"deptName":"开发部","deptSource":"db01"}
删除记录
修改记录时同样需要带部门ID,比如删除ID=5
那条 运维部的记录
修改记录
修改记录时需要带部门ID,比如我们修改 开发部 那条记录的名字为 新开发部门
查询记录(普通查询,下文讲分页查询)
比如,查询全部信息: GET http://localhost:10100/userInfo/getList
最关心的分页问题
首先装配分页插件
/**
* 分页插件
*/
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
Controller类
/**
* 分页查询全部数据
* @Return IPage<Dept> 分页数据
*/
@RequestMapping("/getInfoListPage")
public IPage<Dept> getInfoListPage(@RequestBody Page page ){
//需要在Config配置类中配置分页插件
page.setCurrent(page.getCurrent()); //当前页
page.setSize(page.getSize()); //每页条数
return deptService.page(page);
}
首先装配分页插件
实际实验一下,我们分页查询 的多条记录:
可以看到结果数据中,除了给到当前页数据,还把总记录条数,总页数等一并返回了,很是优雅呢 !