双剑合璧————Spring Boot + Mybatis Plus

引言

最近在学习Mybatis Plus的使用,希望通过spring boot快速将mybatis plus整合进来。

对于springboot项目,mybatis plus团队也有自己的启动器 :mybatis-plus-boot-starter。这个依赖内部已经整合了mybatis-spring,也包括非快速启动的mybatis-plus(这个依赖需要额外的配置数据源等信息),所以如果您在网上看到引入两个和mybatis-plus有关的依赖的话完全是多余的。

操作步骤

一、创建spring boot

首先创建一个spring boot项目(参考:《SpringBoot————快速搭建springboot项目》),在创建项目时直接引入最基本的两个依赖:

二、添加必需依赖

接着再去引一下阿里的fastjson,以及模板生成需要的freemarker(mybatis-plus默认使用velocity,无需纠结于此,两者任选其一)。最重要的,我们需要引入mybatis-plus-boot-starter依赖(可以从maven库找到:maven中央库)

此处选用2.2.0版本的mp启动器:

        <!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-boot-starter --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>2.2.0</version></dependency>

说明:mybatis plus 2.3版本引入后会出现莫名其妙的异常,但是同样的应用环境下,2.2.0就完全没有问题,我在查询用户列表的时候使用2.2.0版本的依赖是完全OK的,但是把版本号改为2.3后就会在查询时报错,但未纠结于此,有碰到同样问题的朋友欢迎文末留言。

至此,我们的pom依赖全部完毕(是不是很惊喜?!),完整pom.xml如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.mht</groupId><artifactId>spring-boot-mybatis-plus</artifactId><version>0.0.1-SNAPSHOT</version><packaging>jar</packaging><name>spring-boot-mybatis-plus</name><description>Demo project for Spring Boot</description><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.0.3.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-boot-starter --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>2.2.0</version></dependency><!-- freemarker --><dependency><groupId>org.freemarker</groupId><artifactId>freemarker</artifactId></dependency><!-- fastjson --><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.15</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>
</project>

说明:可以看到,包括web依赖和mysql驱动依赖,总共就添加了五个依赖。当然,此处也只是一个Demo样例,并未添加阿里的Druid连接池,但是完全不会影响我们实现大量而基本的持久层操作。

三、spring boot数据源配置

这个不说废话,直接上完整application.properties文件:

server.port=8080#mysql
spring.datasource.url=jdbc:mysql://localhost:3306/ease-run?useUnicode=true&characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
#mybatis-plus
mybatis-plus.mapper-locations=classpath:com/mht/springbootmybatisplus/mapper/xml/*.xml
mybatis-plus.type-aliases-package=com.mht.springbootmybatisplus.entity

说明:mybatis plus的xml路径和实体类包名,是要和你项目中一致的,包括datasourse信息,赋值粘贴请记得修改!

 

四、代码生成器

 

数据库user表:

生成器:

package com.mht.springbootmybatisplus.generate;import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.converts.MySqlTypeConvert;
import com.baomidou.mybatisplus.generator.config.rules.DbColumnType;
import com.baomidou.mybatisplus.generator.config.rules.DbType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;/*** <p>* 代码生成器演示* </p>*/
public class MpGenerator {public static void main(String[] args) {
//        assert (false) : "代码生成属于危险操作,请确定配置后取消断言执行代码生成!";AutoGenerator mpg = new AutoGenerator();// 选择 freemarker 引擎,默认 Velocitympg.setTemplateEngine(new FreemarkerTemplateEngine());// 全局配置GlobalConfig gc = new GlobalConfig();gc.setAuthor("Mht");gc.setOutputDir("D://workspace/spring-boot-mybatis-plus/src/main/java");gc.setFileOverride(false);// 是否覆盖同名文件,默认是falsegc.setActiveRecord(true);// 不需要ActiveRecord特性的请改为falsegc.setEnableCache(false);// XML 二级缓存gc.setBaseResultMap(true);// XML ResultMapgc.setBaseColumnList(false);// XML columList/* 自定义文件命名,注意 %s 会自动填充表实体属性! */// gc.setMapperName("%sDao");// gc.setXmlName("%sDao");// gc.setServiceName("MP%sService");// gc.setServiceImplName("%sServiceDiy");// gc.setControllerName("%sAction");mpg.setGlobalConfig(gc);// 数据源配置DataSourceConfig dsc = new DataSourceConfig();dsc.setDbType(DbType.MYSQL);dsc.setTypeConvert(new MySqlTypeConvert() {// 自定义数据库表字段类型转换【可选】@Overridepublic DbColumnType processTypeConvert(String fieldType) {System.out.println("转换类型:" + fieldType);// 注意!!processTypeConvert 存在默认类型转换,如果不是你要的效果请自定义返回、非如下直接返回。return super.processTypeConvert(fieldType);}});dsc.setDriverName("com.mysql.jdbc.Driver");dsc.setUsername("root");dsc.setPassword("root");dsc.setUrl("jdbc:mysql://localhost:3306/ease-run?useUnicode=true&characterEncoding=utf8");mpg.setDataSource(dsc);// 策略配置StrategyConfig strategy = new StrategyConfig();// strategy.setCapitalMode(true);// 全局大写命名 ORACLE 注意strategy.setTablePrefix(new String[] { "user_" });// 此处可以修改为您的表前缀strategy.setNaming(NamingStrategy.nochange);// 表名生成策略strategy.setInclude(new String[] { "user" }); // 需要生成的表// strategy.setExclude(new String[]{"test"}); // 排除生成的表// 自定义实体父类// strategy.setSuperEntityClass("com.baomidou.demo.TestEntity");// 自定义实体,公共字段// strategy.setSuperEntityColumns(new String[] { "test_id", "age" });// 自定义 mapper 父类// strategy.setSuperMapperClass("com.baomidou.demo.TestMapper");// 自定义 service 父类// strategy.setSuperServiceClass("com.baomidou.demo.TestService");// 自定义 service 实现类父类// strategy.setSuperServiceImplClass("com.baomidou.demo.TestServiceImpl");// 自定义 controller 父类// strategy.setSuperControllerClass("com.baomidou.demo.TestController");// 【实体】是否生成字段常量(默认 false)// public static final String ID = "test_id";// strategy.setEntityColumnConstant(true);// 【实体】是否为构建者模型(默认 false)// public User setName(String name) {this.name = name; return this;}// strategy.setEntityBuilderModel(true);mpg.setStrategy(strategy);// 包配置PackageConfig pc = new PackageConfig();pc.setParent("com.mht.springbootmybatisplus");// pc.setModuleName("test");mpg.setPackageInfo(pc);// 注入自定义配置,可以在 VM 中使用 cfg.abc 【可无】// InjectionConfig cfg = 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);// }// };//// // 自定义 xxList.jsp 生成// List<FileOutConfig> focList = new ArrayList<>();// focList.add(new FileOutConfig("/template/list.jsp.vm") {// @Override// public String outputFile(TableInfo tableInfo) {// // 自定义输入文件名称// return "D://my_" + tableInfo.getEntityName() + ".jsp";// }// });// cfg.setFileOutConfigList(focList);// mpg.setCfg(cfg);//// // 调整 xml 生成目录演示// focList.add(new FileOutConfig("/templates/mapper.xml.vm") {// @Override// public String outputFile(TableInfo tableInfo) {// return "/develop/code/xml/" + tableInfo.getEntityName() + ".xml";// }// });// cfg.setFileOutConfigList(focList);// mpg.setCfg(cfg);//// // 关闭默认 xml 生成,调整生成 至 根目录// TemplateConfig tc = new TemplateConfig();// tc.setXml(null);// mpg.setTemplate(tc);// 自定义模板配置,可以 copy 源码 mybatis-plus/src/main/resources/templates 下面内容修改,// 放置自己项目的 src/main/resources/templates 目录下, 默认名称一下可以不配置,也可以自定义模板名称// TemplateConfig tc = new TemplateConfig();// tc.setController("...");// tc.setEntity("...");// tc.setMapper("...");// tc.setXml("...");// tc.setService("...");// tc.setServiceImpl("...");// 如上任何一个模块如果设置 空 OR Null 将不生成该模块。// mpg.setTemplate(tc);// 执行生成mpg.execute();// 打印注入设置【可无】// System.err.println(mpg.getCfg().getMap().get("abc"));}
}

代码生成器请参考:《Mybatis Plus————代码生成器》

注意事项:

需要更改的地方有:文件输出路径(根据项目需要定制),数据源(此类是单独的数据库反向生成代码执行文件,因此springboot的数据源不起作用),包配置,以及一些基本的生成策略...总之还是参考一下我的另一篇文章吧,谢谢!

执行,刷新,获得自动生成的业务代码,不再赘述。

注意!!!生成后一定记得在spring boot项目中添加mybatis的包扫描路径,或@Mapper注解:

@SpringBootApplication
@MapperScan("com.mht.springbootmybatisplus.mapper")
public class SpringBootMybatisPlusApplication {private static final Logger logger = LoggerFactory.getLogger(SpringBootMybatisPlusApplication.class);public static void main(String[] args) {SpringApplication.run(SpringBootMybatisPlusApplication.class, args);logger.info("========================启动完毕========================");}
}

或:

@Mapper
public interface UserMapper extends BaseMapper<User> {
}

否则会报:Error creating bean with name 'xxxServiceImpl': Unsatisfied dependency expressed through field 'baseMapper';

至此,我们的底层增删改查操作全部完毕!下面来编写简单的controller来测试效果。

五、紧张有序的测试准备工作

controller:

package com.mht.springbootmybatisplus.web;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.plugins.Page;
import com.mht.springbootmybatisplus.entity.User;
import com.mht.springbootmybatisplus.service.IUserService;/*** <p>* 前端控制器* </p>** @author Mht* @since 2018-06-23*/
@RestController
@RequestMapping("/user")
public class UserController {@Autowiredprivate IUserService userSvc;@GetMapping(value = "/show")public JSONObject testEnum() {Page<User> users = userSvc.selectPage(new Page<>(1, 10));JSONObject result = new JSONObject();result.put("users", users);return result;}
}

数据库中的数据:

说明:mybatis-plus已经为我们将基本的crud操作封装以待,在代码生成的过程中我们也已经看到UserMapper接口自动继承了BaseMapper接口,它里面有丰富的接口方法且已经按照常规的开发习惯实现完毕,虽然我们的Mapper接口中一个方法都没有,却可以实现大部分crud操作。

六、测试

结果如图:

总结

通读全文,我们轻松实现了自己的mybatis持久层整合操作。不得不说mybatis-plus真的非常不错,本文的对应项目在我的GitHub上,地址是:https://github.com/DragonWatcher/spring-boot-mybatis-plus

简单,高效,使用起来清晰易懂。不过在整合过程中,依然走了不少弯路,网上的大多解释都不尽如人意,另外,本项目并未整合Druid(因为还没接触过)。

基本流程大概就是这样,如果在按照上述步骤搭建和部署的过程中出现任何问题,都可以在文末留言和我讨论。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/558981.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Git初学札记(一)————Git简介与安装

前言 Git是一个开源的分布式版本控制系统&#xff0c;可以有效、高速地处理从很小到非常大的项目版本管理。Git是Linus Torvalds为了帮助管理Linux内核开发而开发的一个开放源码的版本控制软件。&#xff08;在这里再一次致敬Linus大神&#xff09;特点 分布式相比于集中式的最…

Git初学札记(二)————EGit导入远程Git仓库项目(Clone操作)

引言 我们在实际开发项目的时候&#xff0c;难免要使用像Eclipse或者IDEA这样的继承开发工具&#xff0c;除了部分“牙牙学语”的程序员需要手动输入javac去编译程序以外&#xff0c;在实际开发中手动编译并运行项目的“猿族”应该是已经绝种了。 我个人认为&#xff0c;使用gi…

Git初学札记(三)————创建Git版本库

引言 版本库即所谓的Git仓库&#xff0c;英文名称是Repository&#xff0c;可以简单理解为一个目录&#xff08;.git folder&#xff09;&#xff0c;这个目录可以记录并保存直接父级及其子目录下的全部文本文件的修改操作&#xff0c;谓之“版本控制”&#xff01; 手动建库 不…

Git初学札记(四)————Git Push的常规操作与Pull冲突解决

目录 引言 Git命令行的远程Push EGit Push操作中的冲突问题 同步 工作区与本地库同步 工作区与远程库同步 图标 重点 引言 在团队开发当中&#xff0c;Git Push是多人协作环节中的最重要的一环可能没有之一。同SVN一样&#xff0c;push操作可以看做是对远端程序的提交…

Git初学札记(五)————Branch分支管理

引言 正如之前的博客中提到的&#xff0c;Git区别于Svn的一个最明显的功能就是分支管理功能。 那么什么是分支&#xff1f;分支又能为我们的开发带来什么翻天覆地的变化呢&#xff1f;&#xff08;为了使博客的内容更具权威性和专业性&#xff0c;以下部分内容摘自官方文档《Gi…

Git初学札记(六)————在远程新建本地Branch与在本地新建远程Branch

引言 本篇博客介绍将现有的本地分支以新的分支形式推送到远程库中&#xff0c;和以新的分支的形式从远程库中拉取一个分支。这两个功能都是比较简单的操作&#xff0c;但是在实际开发中&#xff0c;可能会在开发初期有所触及。比如我们希望将远程的dev分支拉取到本地来进行开发…

Git初学札记(七)————合并分支(merge)

目录 引言 开始Merge 1、History视图 2、Team菜单 3、Git Repositories视图 巧用Git Staging视图 放弃Merging 可能的Merge结果 引言 Git鼓励开发者使用分支来进行程序的开发。但是最终只会有一个版本发行出去&#xff0c;因此&#xff0c;我们需要将开发好的分支merg…

公钥,私钥和数字签名这样理解轻松入门!

公钥&#xff0c;私钥和数字签名这样理解轻松入门&#xff01;参考博文&#xff1a;https://blog.csdn.net/21aspnet/article/details/7249401 &#xff08;公钥和私钥是成对出现的&#xff0c;可以把他们看成锁头和钥匙的关系&#xff0c;公钥为锁头&#xff0c;私钥是钥匙&am…

Spring Boot + JSP

目录 引言 Maven依赖 JSP页面 application.properties配置 controller 结果展示 引言 在尝试使用shiro的时候需要页面登录的加持&#xff0c;但是长期的前后端分离工作&#xff0c;导致页面的知识几乎忘光。突然想通过jsp这种简单的形式来学习其他的技术&#xff0c;作为…

https和http的区别

https和http的区别一、基本概念&#xff08;http服务器-->本地浏览器&#xff0c;正确快速传输&#xff1b;https安全套接字层&#xff0c;http的安全版本&#xff0c; httpssl层&#xff0c;建立一个信息安全的通道&#xff0c;保证数据传输的安全&#xff0c;确认网站的…

Markdown简明使用

#Markdown使用技巧 ##代码背景 可以使用反引号&#xff0c;来将特殊文字括起来&#xff0c;这样Markdown会自动为引号中的内容加入背景。 形如&#xff1a;内容 例如&#xff1a;Java project > team > share project ##图片上传 图片无法像正常的文本编辑器那样直接粘贴…

Spring Boot + Mybatis 快速整合

引言 最近在工作结束后抽时间学习了一下mybatis的知识&#xff0c;因为之前有学习过&#xff0c;但是经久不用&#xff0c;也未曾踏实地整理&#xff0c;因此有所淡忘。 super meeting会议管理系统是我厂最近开发的一套会议预约平台。持久层框架经讨论&#xff0c;选为灵活优…

SQL关联查询————LEFT JOIN关键字的使用

引言 关联查询一直是非常重要的SQL使用技巧。 在一次查询操作中&#xff0c;使用mybatis进行条件查询&#xff0c;在没有使用 LEFT JOIN 关键字的情况下是这样写的&#xff1a; <!-- 查找成员 --><select id"selectUsers" resultMap"selectUsers_Res…

Java知识点全面汇总

&#xfeff;&#xfeff; 相关概念 面向对象的三个特征 封装&#xff0c;继承&#xff0c;多态&#xff0c;这个应该是人人皆知&#xff0c;有时候也会加上抽象。 多态的好处 允许不同类对象对同一消息做出响应&#xff0c;即同一消息可以根据发送对象的不同而采用多种不…

Git初学札记(八)————版本回退

引言 不论是使用svn还是git&#xff0c;版本回退都是一个非常重要的功能。 EGit版本回退 在History视图中&#xff0c;我们可以看到我们的commit历史&#xff0c;选中任意一个commit版本&#xff0c;右键reset —>Hard &#xff0c;即可回退到指定版本。 注意&#xff0c…

Java实现用户头像上传(修改默认文件大小限制)

概述 每次说起文件上传&#xff0c;就不得不提一下前端的实现方式&#xff0c;说来也奇怪&#xff0c;本博主最热门的博客居然也是文件上传&#xff0c;3万多的访问量占了总访问量的一多半&#xff1a;《传统form表单提交方式的文件上传与文件存储》&#xff0c;而且&#xff…

垃圾回收机制和JVM垃圾回收常见算法

垃圾回收机制和JVM垃圾回收常见算法垃圾回收的好处和特点&#xff1a; 好处&#xff1a; 1. 提高编程效率&#xff1b; 2. 垃圾回收机制保护程序的完整性。特点&#xff1a; 1. 只能回收无用对象的内存空间&#xff0c;对其他物理资源无能为力&#xff1b; 2. 为了更快回收不再…

Java 多线程 —— 死锁与锁的错误用法

引言 死锁状态的大致情况是&#xff1a;Thread_1在获得A对象的锁后&#xff0c;紧接着去请求B对象的锁 &#xff0c;Thread_2在获得了B对象的锁后&#xff0c;紧接着又去请求A对象的锁&#xff0c;如下图&#xff1a; 一、模拟一个死锁 public class DeadLockDemo {static cl…

Java零基础并发编程入门

Java零基础并发编程入门并发编程主要包括&#xff1a; 线程&#xff0c;同步&#xff0c;future&#xff0c;锁&#xff0c;fork/join&#xff0c; volatile&#xff0c;信号量&#xff0c;cas&#xff08;原子性&#xff0c;可见性&#xff0c;顺序一致性&#xff09;&#xf…

Java内置锁——synchronized

一、给对象加把锁 synchronized关键字是Java唯一内置的互斥锁&#xff0c;通过关键字 synchronized 可以保证同一时刻只有一个线程获得某个同步代码块的执行权&#xff0c;但不会导致其他线程执行非同步方法时阻塞。 当获得锁的线程执行完同步代码块后&#xff0c;线程会将锁…