前言

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

多说几句

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

Mybatis-Plus

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

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

简单来说,Mybatis-PlusMybatis的增强工具包,其简化了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 UPDATE CURRENT_TIMESTAMP COMMENT '修改时间'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

1. pom依赖:

  <!--mybatis plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatisplus-spring-boot-starter</artifactId>
<version>1.0.5</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus</artifactId>
<version>2.1.9</version>
</dependency>

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

**spring-mybatis.xml **

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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"> <!--创建jdbc数据源 这里直接使用阿里的druid数据库连接池 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
<property name="driverClassName" value="${mysql.driver}"/>
<property name="url" value="${mysql.url}"/>
<property name="username" value="${mysql.username}"/>
<property name="password" value="${mysql.password}"/>
<!-- 初始化连接大小 -->
<property name="initialSize" value="0"/>
<!-- 连接池最大使用连接数量 -->
<property name="maxActive" value="20"/>
<!-- 连接池最大空闲 -->
<property name="maxIdle" value="20"/>
<!-- 连接池最小空闲 -->
<property name="minIdle" value="0"/>
<!-- 获取连接最大等待时间 -->
<property name="maxWait" value="60000"/> <property name="validationQuery" value="${validationQuery}"/>
<property name="testOnBorrow" value="false"/>
<property name="testOnReturn" value="false"/>
<property name="testWhileIdle" value="true"/> <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis" value="60000"/>
<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
<property name="minEvictableIdleTimeMillis" value="25200000"/> <!-- 打开removeAbandoned功能 -->
<property name="removeAbandoned" value="true"/>
<!-- 1800秒,也就是30分钟 -->
<property name="removeAbandonedTimeout" value="1800"/>
<!-- 关闭abanded连接时输出错误日志 -->
<property name="logAbandoned" value="true"/> <!-- 监控数据库 -->
<property name="filters" value="mergeStat"/>
</bean> <!-- (事务管理)transaction manager, use JtaTransactionManager for global tx -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean> <!-- 可通过注解控制事务 -->
<tx:annotation-driven transaction-manager="transactionManager"/> <!--mybatis-->
<bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<!-- 自动扫描mapper.xml文件,支持通配符 -->
<property name="mapperLocations" value="classpath:mapper/**/*.xml"/>
<!-- 配置文件,比如参数配置(是否启动驼峰等)、插件配置等 -->
<property name="configLocation" value="classpath:mybatis/mybatis-config.xml"/>
<!-- 启用别名,这样就无需写全路径类名了,具体可自行查阅资料 -->
<property name="typeAliasesPackage" value="cn.lqdev.learning.springboot.chapter9.biz.entity"/>
<!-- MP 全局配置注入 -->
<property name="globalConfig" ref="globalConfig"/>
</bean>
<bean id="globalConfig" class="com.baomidou.mybatisplus.entity.GlobalConfiguration">
<!--
AUTO->`0`("数据库ID自增")QW
INPUT->`1`(用户输入ID")
ID_WORKER->`2`("全局唯一ID")
UUID->`3`("全局唯一ID")
-->
<property name="idType" value="3" />
</bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 自动扫描包路径,接口自动注册为一个bean类 -->
<property name="basePackage" value="cn.lqdev.learning.springboot.chapter9.biz.dao"/>
</bean> </beans>

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就配置完成了,接下来,利用代码生成器一次性创建所需的daomapper、通用CRUDservice类。

**4. 编写代码生成器类 **

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

    <dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.0</version>
<scope>test</scope>
</dependency>

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"; /**
* <p>
* MySQL 生成演示
* </p>
*/
public static void main(String[] args) {
// 自定义需要填充的字段
List<TableFill> tableFillList = new ArrayList<TableFill>(); // 代码生成器
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[]{"demo_"})// 此处可以修改为您的表前缀
.setNaming(NamingStrategy.underline_to_camel)// 表名生成策略
// .setInclude(new String[] {"demo_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) {this.name = name; return this;}
.setEntityBuilderModel(true)
// 【实体】是否为lombok模型(默认 false)<a href="https://projectlombok.org/">document</a>
.setEntityLombokModel(true)
// Boolean类型字段是否移除is前缀处理
// .setEntityBooleanColumnRemoveIsPrefix(true)
// .setRestControllerStyle(true)
// .setControllerMappingHyphenStyle(true)
).setPackageInfo(
// 包配置
new PackageConfig().setModuleName(MODULE_NAME).setParent(PACKAGE_NAME)// 自定义包路径
.setController("controller")// 这里是控制器包名,默认 web
.setXml("mapper").setMapper("dao") ).setCfg(
// 注入自定义配置,可以在 VM 中使用 cfg.abc 设置的值
new InjectionConfig() {
@Override
public void initMap() {
Map<String, Object> map = new HashMap<String, Object>();
map.put("abc", this.getConfig().getGlobalConfig().getAuthor() + "-mp");
this.setMap(map);
}
}.setFileOutConfigList(
Collections.<FileOutConfig>singletonList(new FileOutConfig("/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

    <plugins>
<!-- 分页插件配置 -->
<plugin interceptor="com.baomidou.mybatisplus.plugins.PaginationInterceptor"></plugin>
</plugins>

编写控制层

/**
* 用户控制层 简单演示增删改查及分页
* @author oKong
*
*/
@RestController
@RequestMapping("/user")
public class UserController { @Autowired
IUserService userService; @PostMapping("add")
//正常业务时, 需要在user类里面进行事务控制,控制层一般不进行业务控制的。
//@Transactional(rollbackFor = Exception.class)
public Map<String,String> 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<String,String> result = new HashMap<String,String>();
result.put("respCode", "01");
result.put("respMsg", "新增成功");
//事务测试
//System.out.println(1/0);
return result;
} @PostMapping("update")
public Map<String,String> 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<String,String> result = new HashMap<String,String>();
result.put("respCode", "01");
result.put("respMsg", "更新成功");
return result;
} @GetMapping("/get/{id}")
public Map<String,Object> 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<String,Object> result = new HashMap<String,Object>();
result.put("respCode", "01");
result.put("respMsg", "成功");
result.put("data", resp);
return result;
} @GetMapping("/page")
public Map<String,Object> pageUser(int current, int size){
//分页
Page<User> page = new Page<>(current, size);
Map<String,Object> result = new HashMap<String,Object>();
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加入处理类

    <typeHandlers>
<typeHandler handler="org.apache.ibatis.type.EnumOrdinalTypeHandler"
javaType="cn.lqdev.learning.springboot.chapter9.biz.entity.StatusEnum"/>
</typeHandlers>

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

总结

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

最后

目前互联网上很多大佬都有springboot系列教程,如有雷同,请多多包涵了。本文是作者在电脑前一字一句敲的,每一步都是实践的。若文中有所错误之处,还望提出,谢谢。

老生常谈

  • 个人QQ:499452441
  • 微信公众号:lqdevOps

个人博客:https://blog.lqdev.cn

完整示例:chapter-9

原文地址:http://blog.lqdev.cn/2018/07/21/springboot/chapter-nine/

SpringBoot | 第九章:Mybatis-plus的集成和使用的更多相关文章

  1. <自动化测试方案_9>第九章、持续集成平台搭建

    第九章.持续集成平台搭建 (一)什么是持续集成 参考文章地址:https://blog.csdn.net/qq_32261399/article/details/76651376 敏捷软件开发(英语: ...

  2. SpringBoot系列-整合Mybatis(注解方式)

    目录 一.常用注解说明 二.实战 三.测试 四.注意事项 上一篇文章<SpringBoot系列-整合Mybatis(XML配置方式)>介绍了XML配置方式整合的过程,本文介绍下Spring ...

  3. 精通Web Analytics 2.0 (11) 第九章: 新兴分析—社交,移动和视频

    精通Web Analytics 2.0 : 用户中心科学与在线统计艺术 第九章: 新兴分析-社交,移动和视频 网络在过去几年中发生了不可思议的发展变化:从单向对话到双向对话的转变; 由视频,Ajax和 ...

  4. Laxcus大数据管理系统2.0(11)- 第九章 容错

    第九章 容错 在当前,由于集群庞大的组织体系和复杂性,以及用户普遍要求低成本硬件,使得集群在运行过程中发生的错误概率,远远高于单一且性能稳定的小型机服务器,并且集群在运行过程中几乎是不允许停止的,这就 ...

  5. Knockout应用开发指南 第九章:高级应用举例

    原文:Knockout应用开发指南 第九章:高级应用举例 1   Contacts editor 这个例子和微软为演示jQuery Data Linking Proposal例子提供的例子一样的提供的 ...

  6. 《Django By Example》第九章 中文 翻译 (个人学习,渣翻)

    书籍出处:https://www.packtpub.com/web-development/django-example 原作者:Antonio Melé (译者@ucag 注:哈哈哈,第九章终于来啦 ...

  7. 转-spring-boot 注解配置mybatis+druid(新手上路)-http://blog.csdn.net/sinat_36203615/article/details/53759935

    spring-boot 注解配置mybatis+druid(新手上路) 转载 2016年12月20日 10:17:17 标签: sprinb-boot / mybatis / druid 10475 ...

  8. CentOS6安装各种大数据软件 第九章:Hue大数据可视化工具安装和配置

    相关文章链接 CentOS6安装各种大数据软件 第一章:各个软件版本介绍 CentOS6安装各种大数据软件 第二章:Linux各个软件启动命令 CentOS6安装各种大数据软件 第三章:Linux基础 ...

  9. Java Persistence with MyBatis 3(中文版) 第一章 MyBatis入门

    本章将涵盖以下话题: ž  MyBatis是什么? ž  为什么选择MyBatis? ž  MyBatis安装配置 ž  域模型样例 1.1 MyBatis是什么 MyBatis是一个简化和实现了Ja ...

随机推荐

  1. C# 播放音乐

    用 .NET 自带的类库 System.Media 下面的 SoundPlayer 来播放音乐的方式,此种方式使用托管代码,应该是更为可取的方式吧 使用起来非常简单,下面稍作说明: . 支持同步.异步 ...

  2. VC6.0 工程转到VS2010一些问题的描述及解决方法

    下列为VC6.0 工程转到VS2008一些问题的描述及解决方法 //////////////////////////////////////////////////////////////////// ...

  3. fedora18下安装chrome

    ——杂言:这个fedora18是之前装着玩的,原本用的firefox来调试网站页面的,但是因为fedora上没有安装flash,以及一些其他plugin,所以还是没忍住装了chrome,一劳永逸,也好 ...

  4. C++零碎知识点(一)

    1.sizeof用法总结 ①与strlen比较       strlen 计算字符数组的字符数,以"\0"为结束判断,但不包括.   sizeof 计算数据(数组.变量.类型.结构 ...

  5. shell脚本备份系统的方法

    linux自动备份shell(使用全备份,增量备份策略) 在cron里设置,每周日晚12点执行(每周日全备份,其余时间增量备份)#vi backup.sh #!/bin/bash # definewe ...

  6. 使用JFileChooser保存文件

    --------------------siwuxie095                                 工程名:TestFileChooser 包名:com.siwuxie095 ...

  7. NIPT需要多大的数据量(reads number)?

    NIPT需要多大的数据量(reads number)? 调研 2014 Noninvasive prenatal diagnosis of common aneuploidies by semicon ...

  8. JAVA中判断char是否是中文的几种方法

    1.方法一 char c = 'a'; if((c >= 0x4e00)&&(c <= 0x9fbb)) { System.out.println("是中文&qu ...

  9. 26、生鲜电商平台-RBAC系统权限的设计与架构

    说明:根据上面的需求描述以及对需求的分析,我们得知通常的一个中小型系统对于权限系统所需实现的功能以及非功能性的需求,在下面我们将根据需求从技术角度上分析实现的策略以及基于目前两种比较流行的权限设计思想 ...

  10. Docker 启动配置和远程访问

    1. 添加Docker 启动时的配置:   vi /etc/default/docker 添加:   DOCKER_OPTS=" --label name=dockerServer1 -H ...