首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

SpringBoot第九章:Mybatis-plus集成使用

前言

本章节开始介绍数据访问方面的相关知识点。对于后端开发者而言,和数据库打交道是每天都在进行的,所以一个好用的ORM框架是很有必要的。目前,绝大部分公司都选择MyBatis框架作为底层数据库持久化框架。

多说几句

看着现在Mybatis框架的大行其道,让我不禁想起,大学时期,当时还是hibernate的时代,现在基本已经忘记了。而当时,Mybatis的前身iBatis还在书中的某个章节出现过。当时大学老师的意思是:目前国内基本没有使用iBatis的公司,所以这一章节略过,略,过。。。现在对这个还记忆犹新,看着现在Mybatis大行其道,不禁令人唏嘘呀。

Mybatis-Plus

Mybatis-Plus(简称MP)是一个 Mybatis 的增强工具,在 Mybatis 的基础上只做增强不做改变,为简化开发、提高效率而生。

官方网站:http://mp.baomidou.com

简单来说,Mybatis-Plus是Mybatis的增强工具包,其简化了CRUD操作,提供了代码生成器,强大的条件构造器(这是我最喜欢的一个),同时内置了多个实用插件:标配的分页插件、性能分析插件、全局拦截插件等。使得开发过程中,基本的范式代码都一句话解决了,省去了很多重复的操作(程序猿存在的意义呢,说好的让我们搬砖呢!)

SpringBoot集成

这里选用的mybatis-plus版本为:2.1.9,

mybatisplus-spring-boot-starter版本为:1.0.5。

对应Mybatis版本为:3.4.5

0. 这里以user表为例子,数据库为mysql

DROP TABLE IF EXISTS `user`;

CREATE TABLE `user` (

`id` bigint(20) DEFAULT NULL COMMENT '唯一标示',

`code` varchar(20) DEFAULT NULL COMMENT '编码',

`name` varchar(64) DEFAULT NULL COMMENT '名称',

`status` char(1) DEFAULT '1' COMMENT '状态 1启用 0 停用',

`gmt_create` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',

`gmt_modified` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATECURRENT_TIMESTAMP COMMENT '修改时间'

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

1. pom依赖:

com.baomidou

mybatisplus-spring-boot-starter

1.0.5

com.baomidou

mybatis-plus

2.1.9

2. 配置文件(当然也可以直接使用@Bean的方式进行或者通过application配置文件进行,详见官网)

spring-mybatis.xml

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"

xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

AUTO->`0`("数据库ID自增")QW

INPUT->`1`(用户输入ID")

ID_WORKER->`2`("全局唯一ID")

UUID->`3`("全局唯一ID")

3. 编写启动类,应用启动时自动加载配置xml文件

/**

* mybatisPlus 配置类,使其加载配置文件

* @author oKong

*

*/

@Configuration

@ImportResource(locations = {"classpath:/mybatis/spring-mybatis.xml"})

//@MapperScan("cn.lqdev.learning.springboot.chapter9.biz.dao")

//@EnableTransactionManagement

public class MybatisPlusConfig {

}

至此,mybatis-plus就配置完成了,接下来,利用代码生成器一次性创建所需的dao、mapper、通用CRUDservice类。

4. 编写代码生成器类

由于生成器依赖velocity模版引擎,故需要加入依赖:

org.apache.velocity

velocity-engine-core

2.0

test

MysqlGenerator,此类较长,相关配置可根据实际情况信息修改替换。

public class MysqlGenerator {

private static final String PACKAGE_NAME = "cn.lqdev.learning.springboot.chapter9";

private static final String MODULE_NAME = "biz";

private static final String OUT_PATH = "D:\develop\code";

private static final String AUTHOR = "oKong";

private static final String DRIVER = "com.mysql.jdbc.Driver";

private static final String URL = "jdbc:mysql://127.0.0.1:3306/learning?useUnicode=true&characterEncoding=UTF-8";

private static final String USER_NAME = "root";

private static final String PASSWORD = "123456";

/**

* MySQL 生成演示

*/

public static void main(String[] args) {

// 自定义需要填充的字段

List tableFillList = new ArrayList();

// 代码生成器

AutoGenerator mpg = new AutoGenerator().setGlobalConfig(

// 全局配置

new GlobalConfig().setOutputDir(OUT_PATH)// 输出目录

.setFileOverride(true)// 是否覆盖文件

.setActiveRecord(true)// 开启 activeRecord 模式

.setEnableCache(false)// XML 二级缓存

.setBaseResultMap(false)// XML ResultMap

.setBaseColumnList(true)// XML columList

.setAuthor(AUTHOR)

// 自定义文件命名,注意 %s 会自动填充表实体属性!

.setXmlName("%sMapper").setMapperName("%sDao")

// .setServiceName("MP%sService")

// .setServiceImplName("%sServiceDiy")

// .setControllerName("%sAction")

).setDataSource(

// 数据源配置

new DataSourceConfig().setDbType(DbType.MYSQL)// 数据库类型

.setTypeConvert(new MySqlTypeConvert() {

// 自定义数据库表字段类型转换【可选】

@Override

public DbColumnType processTypeConvert(String fieldType) {

System.out.println("转换类型:" + fieldType);

// if ( fieldType.toLowerCase().contains( "tinyint" ) ) {

// return DbColumnType.BOOLEAN;

// }

return super.processTypeConvert(fieldType);

}

}).setDriverName(DRIVER).setUsername(USER_NAME).setPassword(PASSWORD).setUrl(URL))

.setStrategy(

// 策略配置

new StrategyConfig()

// .setCapitalMode(true)// 全局大写命名

.setDbColumnUnderline(true)// 全局下划线命名

// .setTablePrefix(new String[]{"unionpay_"})// 此处可以修改为您的表前缀

.setNaming(NamingStrategy.underline_to_camel)// 表名生成策略

// .setInclude(new String[] {"citycode_org"}) // 需要生成的表

// .setExclude(new String[]{"test"}) // 排除生成的表

// 自定义实体,公共字段

// .setSuperEntityColumns(new String[]{"test_id"})

.setTableFillList(tableFillList)

// 自定义实体父类

// .setSuperEntityClass("com.baomidou.demo.common.base.BsBaseEntity")

// // 自定义 mapper 父类

// .setSuperMapperClass("com.baomidou.demo.common.base.BsBaseMapper")

// // 自定义 service 父类

// .setSuperServiceClass("com.baomidou.demo.common.base.BsBaseService")

// // 自定义 service 实现类父类

// .setSuperServiceImplClass("com.baomidou.demo.common.base.BsBaseServiceImpl")

// 自定义 controller 父类

// .setSuperControllerClass("com.baomidou.demo.TestController")

// 【实体】是否生成字段常量(默认 false)

// public static final String ID = "test_id";

.setEntityColumnConstant(true)

// 【实体】是否为构建者模型(默认 false)

// public User setName(String name)

.setEntityBuilderModel(true)

// 【实体】是否为lombok模型(默认 false)

document

.setEntityLombokModel(true)

// Boolean类型字段是否移除is前缀处理

// .setEntityBooleanColumnRemoveIsPrefix(true)

// .setRestControllerStyle(true)

// .setControllerMappingHyphenStyle(true)

).setPackageInfo(

// 包配置

newPackageConfig().setModuleName(MODULE_NAME).setParent(PACKAGE_NAME)// 自定义包路径

.setController("controller")// 这里是控制器包名,默认 web

.setXml("mapper").setMapper("dao")

).setCfg(

// 注入自定义配置,可以在 VM 中使用 cfg.abc 设置的值

new InjectionConfig() {

@Override

public void initMap() {

Map map = new HashMap();

map.put("abc", this.getConfig().getGlobalConfig().getAuthor() + "-mp");

this.setMap(map);

}

}.setFileOutConfigList(

Collections.singletonList(newFileOutConfig("/templates/mapper.xml.vm") {

// 自定义输出文件目录

@Override

public String outputFile(TableInfo tableInfo) {

return OUT_PATH + "/xml/" + tableInfo.getEntityName() + "Mapper.xml";

}

})))

.setTemplate(

// 关闭默认 xml 生成,调整生成 至 根目录

new TemplateConfig().setXml(null)

// 自定义模板配置,模板可以参考源码 /mybatis-plus/src/main/resources/template 使用 copy

// 至您项目 src/main/resources/template 目录下,模板名称也可自定义如下配置:

// .setController("...");

// .setEntity("...");

// .setMapper("...");

// .setXml("...");

// .setService("...");

// .setServiceImpl("...");

);

// 执行生成

mpg.execute();

}

}

运行后即可,省了多少事!

简单实例

简单演示下增删改查及分页的使用。

使用分页时,mybatis-config.xml需要加入分页插件:PerformanceInterceptor

编写控制层

/**

* 用户控制层 简单演示增删改查及分页

* @author oKong

*

*/

@RestController

@RequestMapping("/user")

public class UserController {

@Autowired

IUserService userService;

@PostMapping("add")

//正常业务时, 需要在user类里面进行事务控制,控制层一般不进行业务控制的。

//@Transactional(rollbackFor = Exception.class)

public Map addUser(@Valid @RequestBody UserReq userReq){

User user = new User();

user.setCode(userReq.getCode());

user.setName(userReq.getName());

//由于设置了主键策略 id可不用赋值 会自动生成

//user.setId(0L);

userService.insert(user);

Map result = new HashMap();

result.put("respCode", "01");

result.put("respMsg", "新增成功");

//事务测试

//System.out.println(1/0);

return result;

}

@PostMapping("update")

public Map updateUser(@Valid @RequestBody UserReq userReq){

if(userReq.getId() == null || "".equals(userReq.getId())) {

throw new CommonException("0000", "更新时ID不能为空");

}

User user = new User();

user.setCode(userReq.getCode());

user.setName(userReq.getName());

user.setId(Long.parseLong(userReq.getId()));

userService.updateById(user);

Map result = new HashMap();

result.put("respCode", "01");

result.put("respMsg", "更新成功");

return result;

}

@GetMapping("/get/")

public Map getUser(@PathVariable("id") String id){

//查询

User user = userService.selectById(id);

if(user == null) {

throw new CommonException("0001", "用户ID:" + id + ",未找到");

}

UserResp resp = UserResp.builder()

.id(user.getId().toString())

.code(user.getCode())

.name(user.getName())

.status(user.getStatus())

.build();

Map result = new HashMap();

result.put("respCode", "01");

result.put("respMsg", "成功");

result.put("data", resp);

return result;

}

@GetMapping("/page")

public Map pageUser(int current, int size){

//分页

Page page = new Page(current, size);

Map result = new HashMap();

result.put("respCode", "01");

result.put("respMsg", "成功");

result.put("data", userService.selectPage(page));

return result;

}

}

启动应用后,使用postman依次访问对应的url地址即可。

数据库:

分页

由于配置了分析插件,控制台会输出执行的sql语句

其他的就不一一贴图了。

关于事务

正常情况下,只需要在服务层中加入@Transactional即可,事务相关的此章节不进行阐述,之后有机会会专门拿一个章节来说明下。

示例中为了方便,直接在控制层中加入了@Transactional进行事务测试,正式开发过程中,强烈建议在服务层进行业务控制,控制层一般上是进行逻辑判断的!

实体对象字段为枚举类

可能在实际开发中,大家会碰到,为了方便,一些类型、状态字段会编写成枚举类型,比如启用状态:DISABLE(“0”),ENABLE(“1”)。此时可通过配置typeHandlers进行自定义类型的处理,这里简单以EnumOrdinalTypeHandler(存储enum类里的序号值)进行示例,当然也可根据需要进行自定义处理器的编写,比如编写一个通用的枚举转换器等,其他相关知识点,大家可自行谷歌。

StatusEnums

public enum StatusEnum {

DISABLE,

ENABLE;

}

将user对象修改成枚举类型

/**

* 状态1 启用 0 停用

*/

private StatusEnum status;

配置文件mybatis-config.xml加入处理类

javaType="cn.lqdev.learning.springboot.chapter9.biz.entity.StatusEnum"/>

之后就会自动进行转换了。大家可下载示例,进行实际操作下。

总结

本章节主要是对Mybatis-plus的集成和简单使用进行了说明,详细的用法,可到官网查看,官网有详细的使用指南,这里就不班门弄斧了。至此,对于一般的开发需求基本上都可以满足了。接下来的章节会重点讲解其他配套工具的使用,敬请期待!

最后

目前互联网上很多大佬都有springboot系列教程,如有雷同,请多多包涵了。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20190111A0OSVD00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券