失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > SpringBoot+Gradle+ MyBatisPlus3.x搭建企业级的后台分离框架

SpringBoot+Gradle+ MyBatisPlus3.x搭建企业级的后台分离框架

时间:2021-11-22 13:54:21

相关推荐

SpringBoot+Gradle+ MyBatisPlus3.x搭建企业级的后台分离框架

程序员的成长之路

互联网/程序员/技术/资料共享

阅读本文大概需要 12分钟。

作者:任务加油站

原文:/i6861456496740270604

1、技术选型

解析器:FastJSON

开发工具:JDK1.8 、Gradle、IDEA

技术框架:SpringBoot 2.1.5.RELEASE

ORM技术:MyBatisPlus3.1.2

数据库:MySQL8.0.21

Apache 工具:HttpClient、Lang3

Git代码版本控制

Web服务器:undertow

hutool 国产工具类包

lombok 简化代码工具 -druid 数据库连接池框架

2、Spring Boot 发展路线简要描述

随着动态语言的流行 (Ruby、Groovy、Scala、Node.js),Java 的开发显得格外的笨重:繁多的配置、低下的开发效率、复杂的部署流程以及第三方技术集成难度大。

在上述环境下,Spring Boot 应运而生。它使用“习惯优于配置”(项目中存在大量的配置,此外还内置了一个习惯性的配置,让你无需手动进行配置)的理念让你的项目快速的运行起来。使用 Spring Boot 很容易创建一个独立运行(运行 Jar,内嵌 Servlet 容器)准生产级别的基于 Spring 框架的项目,使用 Spring Boot 你可以不用或者只需很少的 Spring 配置。

3、SpringBoot插件使用

spring-boot-devtools 实现热部署,实际开发过程中,修改应用的业务逻辑时常常需要重启应用,这显得非常繁琐,降低了开发效率,所以热部署对于开发来说显得十分必要了

spring-boot-starter-aop 此插件没什么好说的了,aop是spring的两大功能模块之一,功能非常强大,为解耦提供了非常优秀的解决方案。如:面向方面编程

spring-boot-starter-undertow 与spring boot 内置undertow 插件

spring-boot-starter-test 测试工具

mybatis-plus-boot-starter 与spring boot整合MyBatisPlus的jar

spring-boot-configuration-processor 整合SpringBoot配置提示

4、fastJson

阿里JSON解析器,详细文档请看官方 /alibaba/fastjson

5、Hutool

Hutool是一个Java工具包,也只是一个工具包,它帮助我们简化每一行代码,减少每一个方法,让Java语言也可以“甜甜的”。Hutool最初是我项目中“util”包的一个整理,后来慢慢积累并加入更多非业务相关功能,并广泛学习其它开源项目精髓,经过自己整理修改,最终形成丰富的开源工具集。

6、Gradle

Gradle是一个基于Apache Ant和Apache Maven概念的项目自动化构建开源工具。它使用一种基于Groovy的特定领域语言(DSL)来声明项目设置,目前也增加了基于Kotlin语言的kotlin-based DSL,抛弃了基于XML的各种繁琐配置

官方 /

不会Gradle的先自己补习一下,比如:安装Gradle,配置环境变量,一些jar引入如何配置,基本使用怎么使用

7、工程结构

此工程是通过Kotlin+SpringBoot+MyBatisPlus搭建最简洁的前后端分离框架 框架升级Java语言SpringBoot+MyBatisPlus3.X+Gradle版本的框架,想学习Kotlin版本的请点击蓝色文章进行下载源代码。

8、Gradle配置

plugins{id'java'id'idea'}/***使用Groovy语言语法定义版本号变量*/defspring_boot_version="2.1.5.RELEASE"defmybatis_plus_version="3.1.2"defmysql_version="8.0.21"defdruid_version="1.1.23"deflogback_version="1.2.1"deffastjson_version="1.2.73"deflombok_version="1.18.12"deflang_version="3.4"defio_version="2.6"defguava_version="18.0"defhutool_version="5.3.10"group='com.flong'version='0.0.1-SNAPSHOT'//jdk版本sourceCompatibility=JavaVersion.VERSION_1_8targetCompatibility=JavaVersion.VERSION_1_8repositories{//指定阿里云镜像maven{url'/nexus/content/groups/public/'}mavenLocal()mavenCentral()}/***1、implementation履行、compile编译*2、Gradle使用双引号可${变量}可以放入引号里面,单引号是不可以的。*3、Gragle使用lombok需要引入annotationProcessor注解,否则不能使用lombok.*4、mybatis-plus3.2.x以上版本引用了Kotlin的支持*5、高版本Springboogt在spring-boot-dependencies-2.3.0.RELEASE.pom里面引入了mysql8.0.2的`<mysql.version>8.0.20</mysql.version>`配置*/dependencies{implementation"org.springframework.boot:spring-boot-starter:${spring_boot_version}"//排除tomcat使用undertowcompile("org.springframework.boot:spring-boot-starter-web:${spring_boot_version}"){excludemodule:"spring-boot-starter-tomcat"}compile"org.springframework.boot:spring-boot-starter-undertow:${spring_boot_version}"//runtimegroup:'mysql',name:'mysql-connector-java',version:'5.1.42'compile"org.springframework.boot:spring-boot-devtools:${spring_boot_version}"compile"org.springframework.boot:spring-boot-configuration-processor:${spring_boot_version}"compile"org.springframework.boot:spring-boot-starter-test:${spring_boot_version}"compile"com.baomidou:mybatis-plus-extension:${mybatis_plus_version}"compile"com.baomidou:mybatis-plus-boot-starter:${mybatis_plus_version}"compile"mysql:mysql-connector-java:${mysql_version}"compile"com.alibaba:druid:${druid_version}"compile"ch.qos.logback:logback-classic:${logback_version}"compile"com.alibaba:fastjson:${fastjson_version}"annotationProcessor"org.projectlombok:lombok:${lombok_version}"compileOnly"org.projectlombok:lombok:${lombok_version}"//testAnnotationProcessor"org.projectlombok:lombok:${lombok_version}"//testCompileOnly"org.projectlombok:lombok:${lombok_version}"compile"mons:commons-lang3:${lang_version}"compile"commons-io:commons-io:${io_version}"compile"com.google.guava:guava:${guava_version}"compile"cn.hutool:hutool-all:${hutool_version}"}tasks.withType(JavaCompile){options.encoding="UTF-8"}[compileJava,javadoc,compileTestJava]*.options*.encoding="UTF-8"

9、数据库SQL脚本

-- 创建表字段不建议用is开头,在我Kotlin+Springboot+MyBatisPlus2.x整合也提到此问题,

-- 故此整合MyBatisPlus3.x版本,把表的is_deleted字段修改成del_flag,阿里开发手册也提到此问题.

DROPTABLEIFEXISTS`t_user`;CREATETABLE`t_user`(`id`int(11)NOTNULLAUTO_INCREMENTCOMMENT'自增id',`user_id`bigint(20)unsignedNOTNULLDEFAULT'0'COMMENT'用户Id主键,IdWork生成',`user_name`varchar(255)DEFAULT''COMMENT'用户名',`pass_word`varchar(255)DEFAULT''COMMENT'密码',`del_flag`int(2)unsignedNOTNULLDEFAULT'0'COMMENT'是否删除,0-不删除,1-删除',`create_time`timestampNOTNULLDEFAULTCURRENT_TIMESTAMPCOMMENT'创建时间',PRIMARYKEY(`user_id`)USINGBTREE,UNIQUEKEY`id`(`id`)USINGBTREE)ENGINE=INNODBDEFAULTCHARSET=utf8mb4COMMENT='用户表';

10、SpringBoot与MyBatisPlus3整合分页代码

importcom.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;@ConfigurationpublicclassMyBatisPlusConfig{/***分页插件*/@BeanpublicPaginationInterceptorpaginationInterceptor(){returnnewPaginationInterceptor();}}

11、SpringBoot与MyBatisPlus3分页条件组装器

packagecom.flong.springboot.core.util;importcn.hutool.core.util.StrUtil;importcom.baomidou.mybatisplus.annotation.TableField;importcom.baomidou.mybatisplus.core.conditions.query.QueryWrapper;importcom.baomidou.mybatisplus.core.toolkit.Wrappers;importcom.flong.springboot.core.vo.Condition;importjava.lang.reflect.Field;importjava.util.List;importcom.flong.springboot.core.enums.JoinType;importcom.flong.springboot.core.exception.BaseException;/***将condition数据转换成wrapper*/publicclassBuildConditionWrapper{publicstatic<T>QueryWrapper<T>build(List<Condition>conditions,Class<T>clazz){//初始化mybatis条件构造器QueryWrapperwrapper=Wrappers.query();if(conditions==null||conditions.size()==0){returnwrapper;}try{for(inti=0;i<conditions.size();i++){Conditioncondition=conditions.get(i);if(condition.getFieldName()==null){thrownewBaseException("调用搜索接口时,缺少关键字[fieldName]!");}//列名称StringcolumnName=getColumnName(condition.getFieldName(),clazz);if(condition==null||condition.getOperation()==null){thrownewBaseException("操作符不能为空!");}switch(condition.getOperation()){//等于caseEQ:wrapper.eq(columnName,condition.getValue());break;//大于caseGT:wrapper.gt(columnName,condition.getValue());break;//小于caseLT:wrapper.lt(columnName,condition.getValue());break;//不等于caseNEQ:wrapper.ne(columnName,condition.getValue());break;//大于等于caseGTANDEQ:wrapper.ge(columnName,condition.getValue());break;//小于等于caseLTANDEQ:wrapper.le(columnName,condition.getValue());break;caseLIKE:wrapper.like(columnName,condition.getValue());break;caseISNULL:wrapper.isNull(columnName);break;caseIN://value:1,2,3,4,5,6wrapper.inSql(columnName,condition.getValue());break;default:break;}if(condition.getJoinType()==JoinType.OR&&i<conditions.size()-1){//下个条件为or连接且非最后一个条件,使用or进行连接wrapper.or();}}returnwrapper;}catch(Exceptione){thrownewBaseException("查询条件不存在");}}/***@Descript此条件构建包装器方法是支持多个表组装成SQL字段的虚拟表,不支持实际存在的表*@Date/6/2113:32*@Authorliangjl*/publicstatic<T>QueryWrapper<T>buildWarpper(List<Condition>conditions){//初始化mybatis条件构造器QueryWrapperwrapper=Wrappers.query();if(conditions==null||conditions.size()==0){returnwrapper;}try{for(inti=0;i<conditions.size();i++){Conditioncondition=conditions.get(i);if(condition.getFieldName()==null){thrownewBaseException("调用搜索接口时,缺少关键字[fieldName]!");}//列名称StringcolumnName=condition.getFieldName();if(condition==null||condition.getOperation()==null){thrownewBaseException("操作符不能为空!");}switch(condition.getOperation()){//等于caseEQ:wrapper.eq(columnName,condition.getValue());break;//大于caseGT:wrapper.gt(columnName,condition.getValue());break;//小于caseLT:wrapper.lt(columnName,condition.getValue());break;//不等于caseNEQ:wrapper.ne(columnName,condition.getValue());break;//大于等于caseGTANDEQ:wrapper.ge(columnName,condition.getValue());break;//小于等于caseLTANDEQ:wrapper.le(columnName,condition.getValue());break;caseLIKE:wrapper.like(columnName,condition.getValue());break;caseIN://value:1,2,3,4,5,6wrapper.inSql(columnName,condition.getValue());break;default:break;}if(condition.getJoinType()==JoinType.OR&&i<conditions.size()-1){//下个条件为or连接且非最后一个条件,使用or进行连接wrapper.or();}}returnwrapper;}catch(Exceptione){thrownewBaseException("查询条件不存在");}}/****@Descript获取指定实体Bean的字段属性*@Date/6/1914:51*@Authorliangjl*/publicstaticStringgetColumnName(StringfieldName,Classclazz){try{//获取泛型类型字段Fieldfield=clazz.getDeclaredField(fieldName);TableFieldtableFieldAnno=field.getAnnotation(TableField.class);StringcolumnName="";//获取对应数据库字段if(tableFieldAnno!=null&&StrUtil.isNotBlank(tableFieldAnno.value())){//已定义数据库字段,取定义值columnName=tableFieldAnno.value();}else{//未指定数据库字段,默认驼峰转下划线columnName=NamingStrategyUtils.camelToUnderline(field.getName());}returncolumnName;}catch(NoSuchFieldExceptione){thrownewBaseException("查询条件不存在");}}}

12、 实体

importcom.baomidou.mybatisplus.annotation.IdType;importcom.baomidou.mybatisplus.annotation.TableId;importcom.baomidou.mybatisplus.annotation.TableLogic;importcom.baomidou.mybatisplus.annotation.TableName;importcom.baomidou.mybatisplus.extension.activerecord.Model;importlombok.*;importjava.io.Serializable;importjava.util.Date;@Data@Builder@AllArgsConstructor@NoArgsConstructor@EqualsAndHashCode(callSuper=false)@TableName("t_user")publicclassUserextendsModel<User>implementsSerializable{@TableId(type=IdType.ID_WORKER)privateLonguserId;/***用户名*/privateStringuserName;/***密码*/privateStringpassWord;/***逻辑删除(0-未删除,1-已删除)*/@TableLogicprivateStringdelFlag;/***创建时间,允许为空,让数据库自动生成即可*/privateDatecreateTime;}

13、 Mapper

BaseMapper是继承了mybatisplus底层的代码

importcom.baomidou.mybatisplus.core.mapper.BaseMapper;importcom.flong.springboot.modules.entity.User;publicinterfaceUserMapperextendsBaseMapper<User>{}

14、 Service

ServiceImplr是继承了mybatisplus底层的代码

importcom.baomidou.mybatisplus.extension.service.impl.ServiceImpl;importcom.flong.springboot.modules.entity.User;importcom.flong.springboot.modules.mapper.UserMapper;importorg.springframework.stereotype.Service;@ServicepublicclassUserServiceextendsServiceImpl<UserMapper,User>{}

15 、controller

控制层主要实现CURD,增加,修改,查询,删除、分页无大常规操作接口操作

用户分页,参数有多个使用下标索引进行处理.如果有两个参数(如用户名和地址):conditionList[0].fieldName=userName、 conditionList[0].fieldName=address

查询是通过反射fieldName进行去获取表结构userName、address 字段的。

未转码请求分页地址: http://localhost:7011/user/page?conditionList[0].fieldName=userName&conditionList[0].operation=LIKE&conditionList[0].value=周

已转码请求分页地址: http://localhost:7011/user/page?conditionList[0].fieldName=userName&conditionList[0].operation=LIKE&conditionList[0].value=%E5%91%A8

packagecom.flong.springboot.modules.controller;importcom.alibaba.fastjson.JSON;importcom.baomidou.mybatisplus.core.conditions.query.QueryWrapper;importcom.baomidou.mybatisplus.core.metadata.IPage;importcom.baomidou.mybatisplus.extension.plugins.pagination.Page;importcom.flong.springboot.modules.entity.User;importcom.flong.springboot.modules.mapper.UserMapper;importcom.flong.springboot.modules.service.UserService;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.web.bind.annotation.*;importcom.flong.springboot.core.vo.Conditions;importcom.flong.springboot.core.util.BuildConditionWrapper;importjava.util.List;/***@Author:liangjl*@Date:-08-16*@Description:用户控制层*/@RestController@RequestMapping("/user")publicclassUserController{@AutowiredprivateUserMapperuserMapper;@AutowiredprivateUserServiceuserService;/***添加*/@RequestMapping("/add")publicvoidadd(){userMapper.insert(User.builder().userName("周伯通").passWord("123456").build());}/***修改*@paramuser*/@PutMapping("/updateById")publicvoidupdateById(@RequestBodyUseruser){userMapper.updateById(user);}/***删除通过多个主键Id进行删除*@paramids*/@DeleteMapping("/deleteByIds")publicvoiddeleteByIds(@RequestBodyList<String>ids){userMapper.deleteBatchIds(ids);}/***通过指定Id进行查询**@paramuserId*/@GetMapping("/getOne/{userId}")publicvoidgetOne(@PathVariable("userId")LonguserId){Useruser=userMapper.selectById(userId);System.out.println(JSON.toJSON(user));}/***用户分页,参数有多个使用下标索引进行处理.如果有两个参数(如用户名和地址):conditionList[0].fieldName=userName、 conditionList[0].fieldName=address*未转码请求分页地址:http://localhost:7011/user/page?conditionList[0].fieldName=userName&conditionList[0].operation=LIKE&conditionList[0].value=周*已转码请求分页地址:http://localhost:7011/user/page?conditionList[0].fieldName=userName&conditionList[0].operation=LIKE&conditionList[0].value=%E5%91%A8*@parampage*@paramconditions条件*@return*/@GetMapping("/page")publicIPage<User>page(Pagepage,Conditionsconditions){QueryWrapper<User>build=BuildConditionWrapper.build(conditions.getConditionList(),User.class);//通过lambda反射找到User实体类的createTime自动进行排序build.lambda().orderByDesc(User::getCreateTime);returnuserService.page(page,build);}}

16、WebCofig工具类统一处理配置

消息转换器,中文乱码,Long的精度长度问题,时间格式等问题

cors 跨域支持 可以用@CrossOrigin在controller上单独设置

统一处理请求URL拦截器

@Configuration@ConditionalOnClass(WebMvcConfigurer.class)@Order(Ordered.HIGHEST_PRECEDENCE)publicclassWebConfigimplementsWebMvcConfigurer{@BeanpublicHttpMessageConverterscustomConverters(){//创建fastJson消息转换器FastJsonHttpMessageConverterfastJsonConverter=newFastJsonHttpMessageConverter();//创建配置类FastJsonConfigfastJsonConfig=newFastJsonConfig();//修改配置返回内容的过滤fastJsonConfig.setSerializerFeatures(//格式化SerializerFeature.PrettyFormat,//可解决long精度丢失但会有带来相应的中文问题//SerializerFeature.BrowserCompatible,//消除对同一对象循环引用的问题,默认为false(如果不配置有可能会进入死循环)SerializerFeature.DisableCircularReferenceDetect,//是否输出值为null的字段,默认为falseSerializerFeature.WriteMapNullValue,//字符类型字段如果为null,输出为"",而非nullSerializerFeature.WriteNullStringAsEmpty,//List字段如果为null,输出为[],而非nullSerializerFeature.WriteNullListAsEmpty);//日期格式fastJsonConfig.setDateFormat("yyyy-MM-ddHH:mm:ss");//long精度问题SerializeConfigserializeConfig=SerializeConfig.globalInstance;serializeConfig.put(BigInteger.class,ToStringSerializer.instance);serializeConfig.put(Long.class,ToStringSerializer.instance);serializeConfig.put(Long.TYPE,ToStringSerializer.instance);fastJsonConfig.setSerializeConfig(serializeConfig);//处理中文乱码问题List<MediaType>fastMediaTypes=newArrayList<>();fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);fastJsonConverter.setSupportedMediaTypes(fastMediaTypes);fastJsonConverter.setFastJsonConfig(fastJsonConfig);//将fastjson添加到视图消息转换器列表内returnnewHttpMessageConverters(fastJsonConverter);}/***拦截器*/@OverridepublicvoidaddInterceptors(InterceptorRegistryregistry){//registry.addInterceptor(logInterceptor).addPathPatterns("/**");//registry.addInterceptor(apiInterceptor).addPathPatterns("/**");}/***cors跨域支持可以用@CrossOrigin在controller上单独设置*/@OverridepublicvoidaddCorsMappings(CorsRegistryregistry){registry.addMapping("/**")//设置允许跨域请求的域名.allowedOrigins("*")//设置允许的方法.allowedMethods("*")//设置允许的头信息.allowedHeaders("*")//是否允许证书不再默认开启.allowCredentials(Boolean.TRUE);}}

17、运行结果

添加 http://localhost:7011/user/add

分页 http://localhost:7011/user/page?conditionList[0].fieldName=userName&conditionList[0].operation=LIKE&conditionList[0].value=%E5%91%A8

默认当前current 为1当前第一页,size为10,当前页可以显示10条数据,也可以根据自己的情况进行自定义

http://localhost:7011/user/page?current=1&size=20&conditionList[0].fieldName=userName&conditionList[0].operation=LIKE&conditionList[0].value=%E5%91%A8

18、工程代码与说明

1 、以上问题都是根据自己学习实际情况进行总结整理,除了技术问题查很多网上资料通过进行学习之后梳理。

2、 在学习过程中也遇到很多困难和疑点,如有问题或误点,望各位老司机多多指出或者提出建议。本人会采纳各种好建议和正确方式不断完善现况,人在成长过程中的需要优质的养料。

3、 导入代码的时候遇到最多的问题,我想应该是Maven较多,此时不懂maven的童鞋们可以通过自身情况,进行网上查资料学习。如通过网上找资料长时间解决不了,或者框架有不明白可以通过博客留言,在能力范围内会尽力帮助大家解决问题所在,希望在过程中一起进步,一起成长。

工程代码在 base 分支 /jilongliang/springboot/tree/base

<END>

推荐阅读:

经验:在MySQL数据库中,这4种方式可以避免重复的插入数据!

fastjson的作者,在阿里内网挨骂了?!

5T技术资源大放送!包括但不限于:C/C++,Linux,Python,Java,PHP,人工智能,单片机,树莓派,等等。在公众号内回复「2048」,即可免费获取!!

微信扫描二维码,关注我的公众号

写留言

朕已阅

如果觉得《SpringBoot+Gradle+ MyBatisPlus3.x搭建企业级的后台分离框架》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。