结构图1
结构图2
plugins { id 'java' id 'idea'}/** * 使用Groovy语言语法定义版本号变量 */def spring_boot_version = "2.1.5.RELEASE"def mybatis_plus_version = "3.1.2"def mysql_version = "8.0.21"def druid_version = "1.1.23"def logback_version = "1.2.1"def fastjson_version = "1.2.73"def lombok_version = "1.18.12"def lang_version = "3.4"def io_version = "2.6"def guava_version = "18.0"def hutool_version = "5.3.10"group = 'com.flong'version = '0.0.1-SNAPSHOT'//jdk版本sourceCompatibility = JavaVersion.VERSION_1_8targetCompatibility = JavaVersion.VERSION_1_8repositories { //指定阿里云镜像 maven { url 'http://maven.aliyun.com/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使用undertow compile("org.springframework.boot:spring-boot-starter-web:${spring_boot_version}") { exclude module: "spring-boot-starter-tomcat" } compile "org.springframework.boot:spring-boot-starter-undertow:${spring_boot_version}" //runtime group: '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 "org.apache.commons: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"
DROP TABLE IF EXISTS `t_user`;CREATE TABLE `t_user` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '自增id', `user_id` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT '用户Id主键,IdWork生成', `user_name` varchar(255) DEFAULT '' COMMENT '用户名', `pass_word` varchar(255) DEFAULT '' COMMENT '密码', `del_flag` int(2) unsigned NOT NULL DEFAULT '0' COMMENT '是否删除,0-不删除,1-删除', `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', PRIMARY KEY (`user_id`) USING BTREE, UNIQUE KEY `id` (`id`)USING BTREE)ENGINE=INNODB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;@Configurationpublic class MyBatisPlusConfig { /** * 分页插件 */ @Bean public PaginationInterceptor paginationInterceptor() { return new PaginationInterceptor(); }}
/*
* 提示:该行代码过长,系统自动注释不进行高亮。一键复制会移除系统注释
* package com.flong.springboot.core.util;import cn.hutool.core.util.StrUtil;import com.baomidou.mybatisplus.annotation.TableField;import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;import com.baomidou.mybatisplus.core.toolkit.Wrappers;import com.flong.springboot.core.vo.Condition;import java.lang.reflect.Field;import java.util.List;import com.flong.springboot.core.enums.JoinType;import com.flong.springboot.core.exception.BaseException;/** * 将condition数据转换成wrapper */public class BuildConditionWrapper { public static <T> QueryWrapper<T> build(List<Condition> conditions, Class<T> clazz) { //初始化mybatis条件构造器 QueryWrapper wrapper = Wrappers.query(); if (conditions == null || conditions.size() == 0) { return wrapper; } try { for (int i = 0; i < conditions.size(); i++) { Condition condition = conditions.get(i); if (condition.getFieldName() == null) { throw new BaseException("调用搜索接口时,缺少关键字[fieldName]!"); } //列名称 String columnName = getColumnName(condition.getFieldName(), clazz); if (condition == null || condition.getOperation() == null) { throw new BaseException("操作符不能为空!"); } switch (condition.getOperation()) { //等于 case EQ: wrapper.eq(columnName, condition.getValue()); break; //大于 case GT: wrapper.gt(columnName, condition.getValue()); break; //小于 case LT: wrapper.lt(columnName, condition.getValue()); break; //不等于 case NEQ: wrapper.ne(columnName, condition.getValue()); break; //大于等于 case GTANDEQ: wrapper.ge(columnName, condition.getValue()); break; //小于等于 case LTANDEQ: wrapper.le(columnName, condition.getValue()); break; case LIKE: wrapper.like(columnName, condition.getValue()); break; case ISNULL: wrapper.isNull(columnName); break; case IN: //value :1,2,3,4,5,6 wrapper.inSql(columnName, condition.getValue()); break; default: break; } if (condition.getJoinType() == JoinType.OR && i < conditions.size() - 1) { //下个条件为or连接且非最后一个条件,使用or进行连接 wrapper.or(); } } return wrapper; } catch (Exception e) { throw new BaseException("查询条件不存在"); } } /** * @Descript 此条件构建包装器方法是支持多个表组装成SQL字段的虚拟表,不支持实际存在的表 * @Date 2019/6/21 13:32 * @Author liangjl */ public static <T> QueryWrapper<T> buildWarpper(List<Condition> conditions) { //初始化mybatis条件构造器 QueryWrapper wrapper = Wrappers.query(); if (conditions == null || conditions.size() == 0) { return wrapper; } try { for (int i = 0; i < conditions.size(); i++) { Condition condition = conditions.get(i); if (condition.getFieldName() == null) { throw new BaseException("调用搜索接口时,缺少关键字[fieldName]!"); } //列名称 String columnName = condition.getFieldName(); if (condition == null || condition.getOperation() == null) { throw new BaseException("操作符不能为空!"); } switch (condition.getOperation()) { //等于 case EQ: wrapper.eq(columnName, condition.getValue()); break; //大于 case GT: wrapper.gt(columnName, condition.getValue()); break; //小于 case LT: wrapper.lt(columnName, condition.getValue()); break; //不等于 case NEQ: wrapper.ne(columnName, condition.getValue()); break; //大于等于 case GTANDEQ: wrapper.ge(columnName, condition.getValue()); break; //小于等于 case LTANDEQ: wrapper.le(columnName, condition.getValue()); break; case LIKE: wrapper.like(columnName, condition.getValue()); break; case IN: //value :1,2,3,4,5,6 wrapper.inSql(columnName, condition.getValue()); break; default: break; } if (condition.getJoinType() == JoinType.OR && i < conditions.size() - 1) { //下个条件为or连接且非最后一个条件,使用or进行连接 wrapper.or(); } } return wrapper; } catch (Exception e) { throw new BaseException("查询条件不存在"); } } /*** * @Descript 获取指定实体Bean的字段属性 * @Date 2019/6/19 14:51 * @Author liangjl */ public static String getColumnName(String fieldName, Class clazz) { try { //获取泛型类型字段 Field field = clazz.getDeclaredField(fieldName); TableField tableFieldAnno = field.getAnnotation(TableField.class); String columnName = ""; //获取对应数据库字段 if (tableFieldAnno != null && StrUtil.isNotBlank(tableFieldAnno.value())) { //已定义数据库字段,取定义值 columnName = tableFieldAnno.value(); } else { //未指定数据库字段,默认驼峰转下划线 columnName = NamingStrategyUtils.camelToUnderline(field.getName()); } return columnName; } catch (NoSuchFieldException e) { throw new BaseException("查询条件不存在"); } }}
*/
import com.baomidou.mybatisplus.annotation.IdType;import com.baomidou.mybatisplus.annotation.TableId;import com.baomidou.mybatisplus.annotation.TableLogic;import com.baomidou.mybatisplus.annotation.TableName;import com.baomidou.mybatisplus.extension.activerecord.Model;import lombok.*;import java.io.Serializable;import java.util.Date;@Data@Builder@AllArgsConstructor@NoArgsConstructor@EqualsAndHashCode(callSuper=false)@TableName("t_user")public class User extends Model<User> implements Serializable { @TableId(type = IdType.ID_WORKER) private Long userId; /** * 用户名 */ private String userName; /** * 密码 */ private String passWord; /** * 逻辑删除(0-未删除,1-已删除) */ @TableLogic private String delFlag; /** * 创建时间,允许为空,让数据库自动生成即可 */ private Date createTime;}
import com.baomidou.mybatisplus.core.mapper.BaseMapper;import com.flong.springboot.modules.entity.User;public interface UserMapper extends BaseMapper<User> {}
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;import com.flong.springboot.modules.entity.User;import com.flong.springboot.modules.mapper.UserMapper;import org.springframework.stereotype.Service;@Servicepublic class UserService extends ServiceImpl<UserMapper, User> {}
package com.flong.springboot.modules.controller;import com.alibaba.fastjson.JSON;import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;import com.baomidou.mybatisplus.core.metadata.IPage;import com.baomidou.mybatisplus.extension.plugins.pagination.Page;import com.flong.springboot.modules.entity.User;import com.flong.springboot.modules.mapper.UserMapper;import com.flong.springboot.modules.service.UserService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.*;import com.flong.springboot.core.vo.Conditions;import com.flong.springboot.core.util.BuildConditionWrapper;import java.util.List;/** * @Author:liangjl * @Date:2020-08-16 * @Description:用户控制层 */@RestController@RequestMapping("/user")public class UserController { @Autowired private UserMapper userMapper; @Autowired private UserService userService; /** * 添加 */ @RequestMapping("/add") public void add() { userMapper.insert(User.builder().userName("周伯通").passWord("123456").build()); } /** * 修改 * @param user */ @PutMapping("/updateById") public void updateById(@RequestBody User user) { userMapper.updateById(user); } /** * 删除通过多个主键Id进行删除 * @param ids */ @DeleteMapping("/deleteByIds") public void deleteByIds(@RequestBody List<String> ids) { userMapper.deleteBatchIds(ids); } /** * 通过指定Id进行查询 * * @param userId */ @GetMapping("/getOne/{userId}") public void getOne(@PathVariable("userId") Long userId) { User user = 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 * @param page * @param conditions 条件 * @return */ @GetMapping("/page") public IPage<User> page(Page page, Conditions conditions) { QueryWrapper<User> build = BuildConditionWrapper.build(conditions.getConditionList(), User.class); //通过lambda反射找到User实体类的createTime自动进行排序 build.lambda().orderByDesc(User::getCreateTime); return userService.page(page, build); }}
@Configuration@ConditionalOnClass(WebMvcConfigurer.class)@Order(Ordered.HIGHEST_PRECEDENCE)public class WebConfig implements WebMvcConfigurer { @Bean public HttpMessageConverters customConverters() { //创建fastJson消息转换器 FastJsonHttpMessageConverter fastJsonConverter = new FastJsonHttpMessageConverter(); //创建配置类 FastJsonConfig fastJsonConfig = new FastJsonConfig(); //修改配置返回内容的过滤 fastJsonConfig.setSerializerFeatures( // 格式化 SerializerFeature.PrettyFormat, // 可解决long精度丢失 但会有带来相应的中文问题 //SerializerFeature.BrowserCompatible, // 消除对同一对象循环引用的问题,默认为false(如果不配置有可能会进入死循环) SerializerFeature.DisableCircularReferenceDetect, // 是否输出值为null的字段,默认为false SerializerFeature.WriteMapNullValue, // 字符类型字段如果为null,输出为"",而非null SerializerFeature.WriteNullStringAsEmpty, // List字段如果为null,输出为[],而非null SerializerFeature.WriteNullListAsEmpty ); // 日期格式 fastJsonConfig.setDateFormat("yyyy-MM-dd HH:mm:ss"); // long精度问题 SerializeConfig serializeConfig = 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 = new ArrayList<>(); fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8); fastJsonConverter.setSupportedMediaTypes(fastMediaTypes); fastJsonConverter.setFastJsonConfig(fastJsonConfig); //将fastjson添加到视图消息转换器列表内 return new HttpMessageConverters(fastJsonConverter); } /** * 拦截器 */ @Override public void addInterceptors(InterceptorRegistry registry) { //registry.addInterceptor(logInterceptor).addPathPatterns("/**"); //registry.addInterceptor(apiInterceptor).addPathPatterns("/**"); } /** * cors 跨域支持 可以用@CrossOrigin在controller上单独设置 */ @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") //设置允许跨域请求的域名 .allowedOrigins("*") //设置允许的方法 .allowedMethods("*") //设置允许的头信息 .allowedHeaders("*") //是否允许证书 不再默认开启 .allowCredentials(Boolean.TRUE); }}
本文由 Java架构师必看 作者:system_mush 发表,其版权均为 Java架构师必看 所有,文章内容系作者个人观点,不代表 Java架构师必看 对观点赞同或支持。如需转载,请注明文章来源。