結構圖1
結構圖2
plugins { id &39; id &39;}/** * 使用Groovy語言語法定義版本號變量 */def spring_boot_version = &34;def mybatis_plus_version = &34;def mysql_version = &34;def druid_version = &34;def logback_version = &34;def fastjson_version = &34;def lombok_version = &34;def lang_version = &34;def io_version = &34;def guava_version = &34;def hutool_version = &34;group = &39;version = &39;//jdk版本sourceCompatibility = JavaVersion.VERSION_1_8targetCompatibility = JavaVersion.VERSION_1_8repositories { //指定阿里雲鏡像 maven { url &39; } 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 &34; //排除tomcat使用undertow compile(&34;) { exclude module: &34; } compile &34; //runtime group: &39;, name: &39;, version: &39; compile &34; compile &34; compile &34; compile &34; compile &34; compile &34; compile &34; compile &34; compile &34; annotationProcessor &34; compileOnly &34; //testAnnotationProcessor &34; //testCompileOnly &34; compile &34; compile &34; compile &34; compile &34;}tasks.withType(JavaCompile) { options.encoding = &34;}[compileJava, javadoc, compileTestJava]*.options*.encoding = &34;
DROP TABLE IF EXISTS `t_user`;CREATE TABLE `t_user` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT &39;, `user_id` bigint(20) unsigned NOT NULL DEFAULT &39; COMMENT &39;, `user_name` varchar(255) DEFAULT &39; COMMENT &39;, `pass_word` varchar(255) DEFAULT &39; COMMENT &39;, `del_flag` int(2) unsigned NOT NULL DEFAULT &39; COMMENT &39;, `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT &39;, PRIMARY KEY (`user_id`) USING BTREE, UNIQUE KEY `id` (`id`)USING BTREE)ENGINE=INNODB DEFAULT CHARSET=utf8mb4 COMMENT=&39;;
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(&34;); } //列名稱 String columnName = getColumnName(condition.getFieldName(), clazz); if (condition == null || condition.getOperation() == null) { throw new BaseException(&34;); } 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(&34;); } } /** * @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(&34;); } //列名稱 String columnName = condition.getFieldName(); if (condition == null || condition.getOperation() == null) { throw new BaseException(&34;); } 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(&34;); } } /*** * @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 = &34;; //獲取對應資料庫欄位 if (tableFieldAnno != null && StrUtil.isNotBlank(tableFieldAnno.value())) { //已定義資料庫欄位,取定義值 columnName = tableFieldAnno.value(); } else { //未指定資料庫欄位,默認駝峰轉下劃線 columnName = NamingStrategyUtils.camelToUnderline(field.getName()); } return columnName; } catch (NoSuchFieldException e) { throw new BaseException(&34;); } }}
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(&34;)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(&34;)public class UserController { @Autowired private UserMapper userMapper; @Autowired private UserService userService; /** * 添加 */ @RequestMapping(&34;) public void add() { userMapper.insert(User.builder().userName(&34;).passWord(&34;).build()); } /** * 修改 * @param user */ @PutMapping(&34;) public void updateById(@RequestBody User user) { userMapper.updateById(user); } /** * 刪除通過多個主鍵Id進行刪除 * @param ids */ @DeleteMapping(&34;) public void deleteByIds(@RequestBody List<String> ids) { userMapper.deleteBatchIds(ids); } /** * 通過指定Id進行查詢 * * @param userId */ @GetMapping(&34;) public void getOne(@PathVariable(&34;) 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(&34;) 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,輸出為&34;,而非null SerializerFeature.WriteNullStringAsEmpty, // List欄位如果為null,輸出為[],而非null SerializerFeature.WriteNullListAsEmpty ); // 日期格式 fastJsonConfig.setDateFormat(&34;); // 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(&34;); //registry.addInterceptor(apiInterceptor).addPathPatterns(&34;); } /** * cors 跨域支持 可以用@CrossOrigin在controller上單獨設置 */ @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping(&34;) //設置允許跨域請求的域名 .allowedOrigins(&34;) //設置允許的方法 .allowedMethods(&34;) //設置允許的頭信息 .allowedHeaders(&34;) //是否允許證書 不再默認開啟 .allowCredentials(Boolean.TRUE); }}