springboot項目快速代碼生成工具


1.框架

 

2.詳細代碼

package com.company.project.configurer;

import com.github.pagehelper.PageHelper;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import tk.mybatis.spring.mapper.MapperScannerConfigurer;

import javax.annotation.Resource;
import javax.sql.DataSource;
import java.util.Properties;

import static com.company.project.core.ProjectConstant.*;

/**
* Mybatis & Mapper & PageHelper 配置
*/
@Configuration
public class MybatisConfigurer {

@Bean
public SqlSessionFactory sqlSessionFactoryBean(DataSource dataSource) throws Exception {
SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
factory.setDataSource(dataSource);
factory.setTypeAliasesPackage(MODEL_PACKAGE);

//配置分頁插件,詳情請查閱官方文檔
PageHelper pageHelper = new PageHelper();
Properties properties = new Properties();
properties.setProperty("pageSizeZero", "true");//分頁尺寸為0時查詢所有紀錄不再執行分頁
properties.setProperty("reasonable", "true");//頁碼<=0 查詢第一頁,頁碼>=總頁數查詢最后一頁
properties.setProperty("supportMethodsArguments", "true");//支持通過 Mapper 接口參數來傳遞分頁參數
pageHelper.setProperties(properties);

//添加插件
factory.setPlugins(new Interceptor[]{pageHelper});

//添加XML目錄
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
factory.setMapperLocations(resolver.getResources("classpath:mapper/*.xml"));
return factory.getObject();
}

@Bean
public MapperScannerConfigurer mapperScannerConfigurer() {
MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
mapperScannerConfigurer.setSqlSessionFactoryBeanName("sqlSessionFactoryBean");
mapperScannerConfigurer.setBasePackage(MAPPER_PACKAGE);

//配置通用Mapper,詳情請查閱官方文檔
Properties properties = new Properties();
properties.setProperty("mappers", MAPPER_INTERFACE_REFERENCE);
properties.setProperty("notEmpty", "false");//insert、update是否判斷字符串類型!='' 即 test="str != null"表達式內是否追加 and str != ''
properties.setProperty("IDENTITY", "MYSQL");
mapperScannerConfigurer.setProperties(properties);

return mapperScannerConfigurer;
}

}




























































package com.company.project.configurer;

import java.io.IOException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;

import com.company.project.core.Result;
import com.company.project.core.ResultCode;
import com.company.project.core.ServiceException;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.NoHandlerFoundException;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

/**
* Spring MVC 配置
*/
@Configuration
public class WebMvcConfigurer extends WebMvcConfigurerAdapter {

private final Logger logger = LoggerFactory.getLogger(WebMvcConfigurer.class);
@Value("${spring.profiles.active}")
private String env;//當前激活的配置文件

//使用阿里 FastJson 作為JSON MessageConverter
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
FastJsonConfig config = new FastJsonConfig();
config.setSerializerFeatures(SerializerFeature.WriteMapNullValue);//保留空的字段
//SerializerFeature.WriteNullStringAsEmpty,//String null -> ""
//SerializerFeature.WriteNullNumberAsZero//Number null -> 0
// 按需配置,更多參考FastJson文檔哈

converter.setFastJsonConfig(config);
converter.setDefaultCharset(Charset.forName("UTF-8"));
converter.setSupportedMediaTypes(Arrays.asList(MediaType.APPLICATION_JSON_UTF8));
converters.add(converter);
}


//統一異常處理
@Override
public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {
exceptionResolvers.add(new HandlerExceptionResolver() {
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception e) {
Result result = new Result();
if (e instanceof ServiceException) {//業務失敗的異常,如“賬號或密碼錯誤”
result.setCode(ResultCode.FAIL).setMessage(e.getMessage());
logger.info(e.getMessage());
} else if (e instanceof NoHandlerFoundException) {
result.setCode(ResultCode.NOT_FOUND).setMessage("接口 [" + request.getRequestURI() + "] 不存在");
} else if (e instanceof ServletException) {
result.setCode(ResultCode.FAIL).setMessage(e.getMessage());
} else {
result.setCode(ResultCode.INTERNAL_SERVER_ERROR).setMessage("接口 [" + request.getRequestURI() + "] 內部錯誤,請聯系管理員");
String message;
if (handler instanceof HandlerMethod) {
HandlerMethod handlerMethod = (HandlerMethod) handler;
message = String.format("接口 [%s] 出現異常,方法:%s.%s,異常摘要:%s",
request.getRequestURI(),
handlerMethod.getBean().getClass().getName(),
handlerMethod.getMethod().getName(),
e.getMessage());
} else {
message = e.getMessage();
}
logger.error(message, e);
}
responseResult(response, result);
return new ModelAndView();
}

});
}

//解決跨域問題
@Override
public void addCorsMappings(CorsRegistry registry) {
//registry.addMapping("/**");
}

//添加攔截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
//接口簽名認證攔截器,該簽名認證比較簡單,實際項目中可以使用Json Web Token或其他更好的方式替代。
if (!"dev".equals(env)) { //開發環境忽略簽名認證
registry.addInterceptor(new HandlerInterceptorAdapter() {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//驗證簽名
boolean pass = validateSign(request);
if (pass) {
return true;
} else {
logger.warn("簽名認證失敗,請求接口:{},請求IP:{},請求參數:{}",
request.getRequestURI(), getIpAddress(request), JSON.toJSONString(request.getParameterMap()));

Result result = new Result();
result.setCode(ResultCode.UNAUTHORIZED).setMessage("簽名認證失敗");
responseResult(response, result);
return false;
}
}
});
}
}

private void responseResult(HttpServletResponse response, Result result) {
response.setCharacterEncoding("UTF-8");
response.setHeader("Content-type", "application/json;charset=UTF-8");
response.setStatus(200);
try {
response.getWriter().write(JSON.toJSONString(result));
} catch (IOException ex) {
logger.error(ex.getMessage());
}
}

/**
* 一個簡單的簽名認證,規則:
* 1. 將請求參數按ascii碼排序
* 2. 拼接為a=value&b=value...這樣的字符串(不包含sign)
* 3. 混合密鑰(secret)進行md5獲得簽名,與請求的簽名進行比較
*/
private boolean validateSign(HttpServletRequest request) {
String requestSign = request.getParameter("sign");//獲得請求簽名,如sign=19e907700db7ad91318424a97c54ed57
if (StringUtils.isEmpty(requestSign)) {
return false;
}
List<String> keys = new ArrayList<String>(request.getParameterMap().keySet());
keys.remove("sign");//排除sign參數
Collections.sort(keys);//排序

StringBuilder sb = new StringBuilder();
for (String key : keys) {
sb.append(key).append("=").append(request.getParameter(key)).append("&");//拼接字符串
}
String linkString = sb.toString();
linkString = StringUtils.substring(linkString, 0, linkString.length() - 1);//去除最后一個'&'

String secret = "Potato";//密鑰,自己修改
String sign = DigestUtils.md5Hex(linkString + secret);//混合密鑰md5

return StringUtils.equals(sign, requestSign);//比較
}

private String getIpAddress(HttpServletRequest request) {
String ip = request.getHeader("x-forwarded-for");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_CLIENT_IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
// 如果是多級代理,那么取第一個ip為客戶端ip
if (ip != null && ip.indexOf(",") != -1) {
ip = ip.substring(0, ip.indexOf(",")).trim();
}

return ip;
}
}
 
        


 
        































































 
        


















 
        



 
        



































































 
        
package com.company.project.core;


import org.apache.ibatis.exceptions.TooManyResultsException;
import org.springframework.beans.factory.annotation.Autowired;
import tk.mybatis.mapper.entity.Condition;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.util.List;

/**
* 基於通用MyBatis Mapper插件的Service接口的實現
*/
public abstract class AbstractService<T> implements Service<T> {

@Autowired
protected Mapper<T> mapper;

private Class<T> modelClass; // 當前泛型真實類型的Class

public AbstractService() {
ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass();
modelClass = (Class<T>) pt.getActualTypeArguments()[0];
}

public void save(T model) {
mapper.insertSelective(model);
}

public void save(List<T> models) {
mapper.insertList(models);
}

public void deleteById(Integer id) {
mapper.deleteByPrimaryKey(id);
}

public void deleteByIds(String ids) {
mapper.deleteByIds(ids);
}

public void update(T model) {
mapper.updateByPrimaryKeySelective(model);
}

public T findById(Integer id) {
return mapper.selectByPrimaryKey(id);
}

@Override
public T findBy(String fieldName, Object value) throws TooManyResultsException {
try {
T model = modelClass.newInstance();
Field field = modelClass.getDeclaredField(fieldName);
field.setAccessible(true);
field.set(model, value);
return mapper.selectOne(model);
} catch (ReflectiveOperationException e) {
throw new ServiceException(e.getMessage(), e);
}
}

public List<T> findByIds(String ids) {
return mapper.selectByIds(ids);
}

public List<T> findByCondition(Condition condition) {
return mapper.selectByCondition(condition);
}

public List<T> findAll() {
return mapper.selectAll();
}
}






 
        























 

 

 

 

 

 

 

 

 

 

 

 

 









package com.company.project.core;

import tk.mybatis.mapper.common.BaseMapper;
import tk.mybatis.mapper.common.ConditionMapper;
import tk.mybatis.mapper.common.IdsMapper;
import tk.mybatis.mapper.common.special.InsertListMapper;

/**
* 定制版MyBatis Mapper插件接口,如需其他接口參考官方文檔自行添加。
*/
public interface Mapper<T>
extends
BaseMapper<T>,
ConditionMapper<T>,
IdsMapper<T>,
InsertListMapper<T> {
}

 

 

 

 

 

 

 

 

 

 

 
        
package com.company.project.core;

/**
* 項目常量
*/
public final class ProjectConstant {
public static final String BASE_PACKAGE = "com.company.project";//生成代碼所在的基礎包名稱,可根據自己公司的項目修改(注意:這個配置修改之后需要手工修改src目錄項目默認的包路徑,使其保持一致,不然會找不到類)

public static final String MODEL_PACKAGE = BASE_PACKAGE + ".model";//生成的Model所在包
public static final String MAPPER_PACKAGE = BASE_PACKAGE + ".dao";//生成的Mapper所在包
public static final String SERVICE_PACKAGE = BASE_PACKAGE + ".service";//生成的Service所在包
public static final String SERVICE_IMPL_PACKAGE = SERVICE_PACKAGE + ".impl";//生成的ServiceImpl所在包
public static final String CONTROLLER_PACKAGE = BASE_PACKAGE + ".web";//生成的Controller所在包

public static final String MAPPER_INTERFACE_REFERENCE = BASE_PACKAGE + ".core.Mapper";//Mapper插件基礎接口的完全限定名
}

 

 
        
package com.company.project.core;

import com.alibaba.fastjson.JSON;

/**
* 統一API響應結果封裝
*/
public class Result<T> {
private int code;
private String message;
private T data;

public Result setCode(ResultCode resultCode) {
this.code = resultCode.code();
return this;
}

public int getCode() {
return code;
}

public String getMessage() {
return message;
}

public Result setMessage(String message) {
this.message = message;
return this;
}

public T getData() {
return data;
}

public Result setData(T data) {
this.data = data;
return this;
}

@Override
public String toString() {
return JSON.toJSONString(this);
}
}




 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 
        
package com.company.project.core;

/**
* 響應碼枚舉,參考HTTP狀態碼的語義
*/
public enum ResultCode {
SUCCESS(200),//成功
FAIL(400),//失敗
UNAUTHORIZED(401),//未認證(簽名錯誤)
NOT_FOUND(404),//接口不存在
INTERNAL_SERVER_ERROR(500);//服務器內部錯誤

private final int code;

ResultCode(int code) {
this.code = code;
}

public int code() {
return code;
}
}

 

 

 

 

 

 

 

 

 

 

 

 

 
        
package com.company.project.core;

/**
* 響應結果生成工具
*/
public class ResultGenerator {
private static final String DEFAULT_SUCCESS_MESSAGE = "SUCCESS";

public static Result genSuccessResult() {
return new Result()
.setCode(ResultCode.SUCCESS)
.setMessage(DEFAULT_SUCCESS_MESSAGE);
}

public static <T> Result<T> genSuccessResult(T data) {
return new Result()
.setCode(ResultCode.SUCCESS)
.setMessage(DEFAULT_SUCCESS_MESSAGE)
.setData(data);
}

public static Result genFailResult(String message) {
return new Result()
.setCode(ResultCode.FAIL)
.setMessage(message);
}
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 
        
package com.company.project.core;

import org.apache.ibatis.exceptions.TooManyResultsException;
import tk.mybatis.mapper.entity.Condition;

import java.util.List;

/**
* Service 層 基礎接口,其他Service 接口 請繼承該接口
*/
public interface Service<T> {
void save(T model);//持久化
void save(List<T> models);//批量持久化
void deleteById(Integer id);//通過主鍵刪除
void deleteByIds(String ids);//批量刪除 eg:ids -> “1,2,3,4”
void update(T model);//更新
T findById(Integer id);//通過ID查找
T findBy(String fieldName, Object value) throws TooManyResultsException; //通過Model中某個成員變量名稱(非數據表中column的名稱)查找,value需符合unique約束
List<T> findByIds(String ids);//通過多個ID查找//eg:ids -> “1,2,3,4”
List<T> findByCondition(Condition condition);//根據條件查找
List<T> findAll();//獲取所有
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 
        
package com.company.project.core;

/**
* 服務(業務)異常如“ 賬號或密碼錯誤 ”,該異常只做INFO級別的日志記錄 @see WebMvcConfigurer
*/
public class ServiceException extends RuntimeException {
public ServiceException() {
}

public ServiceException(String message) {
super(message);
}

public ServiceException(String message, Throwable cause) {
super(message, cause);
}
}

 

 

 

 

 

 

 

 

 

  

3.如有需要完整測試代碼,請加QQ:2797205254      免費送


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM