Java工具类(持续补充)

Java工具类

一、Java发送邮件

  1. 引入依赖

    <!-- email -->
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-email</artifactId>
        <version>1.5</version>
    </dependency>
    <!-- lombok -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    
  2. 在qq邮箱得到IMAP/SMTP服务获取的授权码

    )

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  3. 写入工具类

    @Component
    @Data
    public class EmailUtil {
        // 验证码长度
        private int codeLen = 6;
    
        // 发送邮箱验证码的qq号
        private String qq = "your qq";
    
        // 发送邮件的邮箱
        private String toSendEmail = "your email";
    
        // 发件人
        private String sender = "AI-联机对战小游戏";
    
        // 开启IMAP/SMTP服务获取的授权码
        private String authPwd = "your code";
    
        // 邮件的主题
        private String title = "验证码";
    
        // 邮件的内容
        private String content = "【AI-联机对战小游戏】您获得的验证码是:";
    
        /**
         * 获取指定长度的验证码
         */
        public String getAuthCode() {  //由于数字0,1 和字母 o,l 有时分不清,所有没有数字0和1
            String[] strArr = new String[]{"2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F",
                    "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "a",
                    "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v",
                    "w", "x", "y", "z"};
            List list = Arrays.asList(strArr);//将数组转换为集合
            Collections.shuffle(list);  //打乱集合顺序
            StringBuilder stringBuilder = new StringBuilder();
            for (int i = 0; i < list.size(); i++) {
                stringBuilder.append(list.get(i)); //将集合转化为字符串
            }
            return stringBuilder.toString().substring(stringBuilder.length() - codeLen); //截取字符串为验证码长度
        }
    
        /**
         * 发送邮箱验证码
         * @param email 发送目的邮箱
         * @param authCode 发送的验证码
         */
        public void sendAuthCodeEmail(String email, String authCode) {
            try {
                SimpleEmail mail = new SimpleEmail();
                mail.setHostName("smtp.qq.com");//发送邮件的服务器
                mail.setAuthentication(qq, authPwd);//第一个参数是发送邮箱验证码的qq号,第二个参数是开启IMAP/SMTP服务获取的授权码
                mail.setFrom(toSendEmail, sender, "UTF-8");  //第一个参数是发送邮件的邮箱,第二个参数是发件人,第三个是字符集
                mail.setSSLOnConnect(true); //使用安全链接
                mail.addTo(email);//接收的邮箱
                mail.setCharset("UTF-8");//设置主题字符集
                mail.setSubject(title);//设置邮件的主题
                mail.buildMimeMessage();
                mail.getMimeMessage().setText(content + authCode + ",有效期为10分钟。", "UTF-8");//设置邮件的内容以及字符集
                mail.sendMimeMessage();//发送
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    
  4. 测试案例

    @Autowired
    private EmailUtil emailUtil;
    
    @Test
    public void testEmailUtil() {
        String authCode = emailUtil.getAuthCode();
        String email = "xxx@qq.com";
        emailUtil.sendAuthCodeEmail(email, authCode);
    }
    

二、各种格式的验证

  1. 引入依赖

    <!--hutool-->
    <dependency>
        <groupId>cn.hutool</groupId>
        <artifactId>hutool-all</artifactId>
        <version>5.7.17</version>
    </dependency>
    
  2. 写入工具类

    public abstract class RegexPatterns {
        /**
         * 手机号正则
         */
        public static final String PHONE_REGEX = "^1([38][0-9]|4[579]|5[0-3,5-9]|6[6]|7[0135678]|9[89])\\d{8}$";
        /**
         * 邮箱正则
         */
        public static final String EMAIL_REGEX = "^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)+$";
        /**
         * 密码正则。4~32位的字母、数字、下划线
         */
        public static final String PASSWORD_REGEX = "^\\w{4,32}$";
        /**
         * 验证码正则, 6位数字或字母
         */
        public static final String VERIFY_CODE_REGEX = "^[a-zA-Z\\d]{6}$";
    }
    
    import cn.hutool.core.util.StrUtil;
    
    // 注意返回true为不符合
    public class RegexUtils {
        /**
         * 是否是无效手机格式
         * @param phone 要校验的手机号
         * @return true:符合,false:不符合
         */
        public static boolean isPhoneInvalid(String phone){
            return mismatch(phone, RegexPatterns.PHONE_REGEX);
        }
        /**
         * 是否是无效邮箱格式
         * @param email 要校验的邮箱
         * @return true:符合,false:不符合
         */
        public static boolean isEmailInvalid(String email){
            return mismatch(email, RegexPatterns.EMAIL_REGEX);
        }
    
        /**
         * 是否是无效验证码格式
         * @param code 要校验的验证码
         * @return true:符合,false:不符合
         */
        public static boolean isCodeInvalid(String code){
            return mismatch(code, RegexPatterns.VERIFY_CODE_REGEX);
        }
    
        /**
         * 是否是无效密码格式
         * @param password 要校验的密码
         * @return true:符合,false:不符合
         */
        public static boolean isPasswordInvalid(String password){
            return mismatch(password, RegexPatterns.PASSWORD_REGEX);
        }
    
        // 校验是否不符合正则格式
        private static boolean mismatch(String str, String regex){
            if (StrUtil.isBlank(str)) {
                return true;
            }
            return !str.matches(regex);
        }
    }
    

三、JWT工具类

  1. 引入依赖

    <dependency>
        <groupId>io.jsonwebtoken</groupId>
        <artifactId>jjwt</artifactId>
        <version>0.9.0</version>
    </dependency>
    
  2. JwtUtil用于生成和解析jwt

    public class JwtUtil {
        //有效期为
        private static final Long JWT_TTL = 60L * 60 * 1000; // 默认jwt的有效期,当前为一个小时
    
        //设置秘钥明文
        private static final String JWT_KEY =
                "dushfvihsduVSUD72VCSJBFBVS6372428DBVFJS72hhfdfhdjYUCFYD67ggv7s7874uysg787FSYFUGSFBS7262BCBSDBHS4FDfdfsscsd5465";
    
        /**
         * 获取一个随机字符串
         * @return 随机字符串
         */
        public static String getUUID(){
            return UUID.randomUUID().toString().replaceAll("-", "");
        }
    
        /**
         * 传入待解析的jwt返回Claims对象,调用此对象的getSubject方法可以获取到原生的字符串
         * @param jwt 待解析的jwt
         * @return Claims对象
         */
        public static Claims parseJWT(String jwt) {
            SecretKey secretKey = generalKey();
            return Jwts.parser()
                    .setSigningKey(secretKey)
                    .parseClaimsJws(jwt)
                    .getBody();
        }
    
        /**
         * 根据传入的字符串生成jwt
         * @param subject 传入的字符串
         * @return 生成的jwt
         */
        public static String createJWT(String subject) {
            JwtBuilder builder = getJwtBuilder(subject, null, getUUID());
            return builder.compact();
        }
    
        public static String createJWT(String subject, Long ttlMillis) {
            JwtBuilder builder = getJwtBuilder(subject, ttlMillis, getUUID());
            return builder.compact();
        }
    
        public static String createJWT(String subject, Long ttlMillis, String id) {
            JwtBuilder builder = getJwtBuilder(subject, ttlMillis, id);
            return builder.compact();
        }
    
        private static JwtBuilder getJwtBuilder(String subject, Long ttlMillis, String uuid) {
            SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
            SecretKey secretKey = generalKey();
            long nowMillis = System.currentTimeMillis();
            Date now = new Date(nowMillis);
            if(ttlMillis==null){
                ttlMillis=JwtUtil.JWT_TTL;
            }
            long expMillis = nowMillis + ttlMillis;
            Date expDate = new Date(expMillis);
            return Jwts.builder()
                    .setId(uuid)              //唯一的ID
                    .setSubject(subject)   // 主题  可以是JSON数据
                    .setIssuer("sg")     // 签发者
                    .setIssuedAt(now)      // 签发时间
                    .signWith(signatureAlgorithm, secretKey) //使用HS256对称加密算法签名, 第二个参数为秘钥
                    .setExpiration(expDate);
        }
    
        private static SecretKey generalKey() {
            byte[] encodedKey = Base64.getDecoder().decode(JwtUtil.JWT_KEY);
            return new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
        }
    }
    

四、解决跨域

  1. CorsConfig配置类用于解决跨域问题

    @Configuration
    public class CorsConfig implements Filter {
        @Override
        public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
            HttpServletResponse response = (HttpServletResponse) res;
            HttpServletRequest request = (HttpServletRequest) req;
    
            String origin = request.getHeader("Origin");
            if(origin!=null) {
                response.setHeader("Access-Control-Allow-Origin", origin);
            }
    
            String headers = request.getHeader("Access-Control-Request-Headers");
            if(headers!=null) {
                response.setHeader("Access-Control-Allow-Headers", headers);
                response.setHeader("Access-Control-Expose-Headers", headers);
            }
    
            response.setHeader("Access-Control-Allow-Methods", "*");
            response.setHeader("Access-Control-Max-Age", "3600");
            response.setHeader("Access-Control-Allow-Credentials", "true");
    
            chain.doFilter(request, response);
        }
    
        @Override
        public void init(FilterConfig filterConfig) {
    
        }
    
        @Override
        public void destroy() {
        }
    }
    

五、Http工具类

  1. 引入依赖

    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-lang3</artifactId>
        <version>3.1</version>
    </dependency>
    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpclient</artifactId>
        <version>4.5.13</version>
    </dependency>
    
  2. HttpClientUtil用于发送http请求

    public class HttpClientUtil {
        private static final CloseableHttpClient HTTP_CLIENT;
    
        private static final String CHARSET = "UTF-8";
    
        static {
            // 设置创建连接时间、从连接池获取连接时间、数据传输时间
            RequestConfig config = RequestConfig.custom()
                    .setConnectTimeout(30 * 1000)
                    .setConnectionRequestTimeout(30 * 1000)
                    .setSocketTimeout(30 * 1000)
                    .build();
            PoolingHttpClientConnectionManager pc = new PoolingHttpClientConnectionManager();
            // 设置连接池最大允许的连接数
            pc.setMaxTotal(3030);
            // 设置每个路由(也就是目标服务器的主机名和端口号)最大允许的连接数
            pc.setDefaultMaxPerRoute(1510);
            // 设置连接池中每个连接的存活时间
            pc.setValidateAfterInactivity(30 * 60 * 1000);
            HTTP_CLIENT = HttpClients.custom()
                    .setConnectionManager(pc)
                    .setDefaultRequestConfig(config)
                    .build();
        }
    
        public static String doGet(String url, Map<String, String> params) throws IOException {
            if (StringUtils.isBlank(url)) {
                return null;
            }
            if (params != null && !params.isEmpty()) {
                List<NameValuePair> pairs = new ArrayList<>(params.size());
                for (Map.Entry<String, String> entry : params.entrySet()) {
                    String value = entry.getValue();
                    if (value != null) {
                        pairs.add(new BasicNameValuePair(entry.getKey(), value));
                    }
                }
                url += "?" + EntityUtils.toString(new UrlEncodedFormEntity(pairs, CHARSET));
            }
            HttpGet httpGet = new HttpGet(url);
            try (CloseableHttpResponse response = HTTP_CLIENT.execute(httpGet)) {
                int statusCode = response.getStatusLine().getStatusCode();
                if (statusCode != 200) {
                    httpGet.abort();
                    throw new RuntimeException("HttpClientUtil,error status code :" + statusCode);
                }
                HttpEntity entity = response.getEntity();
                if (entity != null) {
                    String result = EntityUtils.toString(entity, CHARSET);
                    EntityUtils.consume(entity);
                    return result;
                }
            }
            return null;
        }
    
        public static String doPost(String url, Map<String, String> params) throws IOException {
            if (StringUtils.isBlank(url)) {
                return null;
            }
            List<NameValuePair> pairs = null;
            if (params != null && !params.isEmpty()) {
                pairs = new ArrayList<>(params.size());
                for (Map.Entry<String, String> entry : params.entrySet()) {
                    String value = entry.getValue();
                    if (value != null) {
                        pairs.add(new BasicNameValuePair(entry.getKey(), value));
                    }
                }
            }
            HttpPost httpPost = new HttpPost(url);
            if (pairs != null && pairs.size() > 0) {
                httpPost.setEntity(new UrlEncodedFormEntity(pairs, CHARSET));
            }
            try (CloseableHttpResponse response = HTTP_CLIENT.execute(httpPost)) {
                int statusCode = response.getStatusLine().getStatusCode();
                if (statusCode != 200) {
                    httpPost.abort();
                    throw new RuntimeException("HttpClientUtil,error status code :" + statusCode);
                }
                HttpEntity entity = response.getEntity();
                if (entity != null) {
                    String result = EntityUtils.toString(entity, CHARSET);
                    EntityUtils.consume(entity);
                    return result;
                }
            }
            return null;
        }
    }
    

六、Java写入Excel

  1. 引入依赖

    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi</artifactId>
        <version>4.0.1</version>
    </dependency>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml</artifactId>
        <version>4.0.1</version>
    </dependency>
    
  2. 具体使用

    // 1. 创建一个excel,参数是java内存中最多存多少条记录(防止爆内存)
    SXSSFWorkbook workbook = new SXSSFWorkbook(5000);
    // 2. 创建excel里的一个sheet
    SXSSFSheet sheet = workbook.createSheet("sheetName");
    // 3. 创建第x行(下标从0开始)
    SXSSFRow row = sheet.createRow(x);
    // 4. 创建第y列(下标从0开始)
    SXSSFCell cell = row.createCell(y);
    // 5. 在(x, y)坐标下写入xxx
    cell.setCellValue("xxx");
    // 6. 写入磁盘
    workbook.write("OutputStream");
    

七、Java获取网站的HTML

  1. 引入依赖

    <dependency>
        <groupId>org.jsoup</groupId>
        <artifactId>jsoup</artifactId>
        <version>1.10.2</version>
    </dependency>
    
  2. 具体使用

    // 方式一:
    // 1. 获取连接
    Connection connect = Jsoup.connect("www.baidu.com");
    // 2. 设置一些连接条件
    connect.timeout(5000).method(Connection.Method.DELETE);
    // 3.1 通过get或者post方法获取html
    Document get = connect.get();
    Document post = connect.post();
    // 4.1 获取html子标签集合
    Elements links = get.select("a");
    // 4.2 获取单个Element
    Element element = links.first();
    // 4.3 获取该标签的一个属性值
    String href = element.attr("href");
    // ...
    
    // 方式二:
    // 通过HttpClientUtil获取html
    Document get = Jsoup.parse(HttpClientUtil.doGet(url, null));
    

八、log4j2日志

  1. 引入依赖

    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-api</artifactId>
        <version>2.8.2</version>
    </dependency>
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-core</artifactId>
        <version>2.8.2</version>
    </dependency>
    
  2. log4j2.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->
    <!--Configuration后面的status,这个用于设置log4j2自身内部的信息输出,可以不设置,当设置成trace时,你会看到log4j2内部各种详细输出-->
    <!--monitorInterval:Log4j能够自动检测修改配置 文件和重新配置本身,设置间隔秒数-->
    <configuration status="WARN" monitorInterval="30">
        <!--先定义所有的appender-->
        <appenders>
            <!--这个输出控制台的配置-->
            <console name="Console" target="SYSTEM_ERR">
                <!--输出日志的格式-->
                <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%t] [%p] - %l - %m%n"/>
            </console>
            <!--文件会打印出所有信息,这个log每次运行程序会自动清空,由append属性决定,这个也挺有用的,适合临时测试用-->
            <File name="log" fileName="log/test.log" append="false">
                <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/>
            </File>
            <!-- 这个会打印出所有的info及以下级别的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
            <RollingFile name="RollingFileInfo" fileName="${sys:user.home}/logs/info.log"
                         filePattern="${sys:user.home}/logs/$${date:yyyy-MM}/info-%d{yyyy-MM-dd}-%i.log">
                <!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
                <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
                <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%t] [%p] - %l - %m%n"/>
                <Policies>
                    <TimeBasedTriggeringPolicy/>
                    <SizeBasedTriggeringPolicy size="100 MB"/>
                </Policies>
            </RollingFile>
            <RollingFile name="RollingFileWarn" fileName="${sys:user.home}/logs/warn.log"
                         filePattern="${sys:user.home}/logs/$${date:yyyy-MM}/warn-%d{yyyy-MM-dd}-%i.log">
                <ThresholdFilter level="warn" onMatch="ACCEPT" onMismatch="DENY"/>
                <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%t]  [%p] - %l - %m%n"/>
                <Policies>
                    <TimeBasedTriggeringPolicy/>
                    <SizeBasedTriggeringPolicy size="100 MB"/>
                </Policies>
                <!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件,这里设置了20 -->
                <DefaultRolloverStrategy max="20"/>
            </RollingFile>
            <RollingFile name="RollingFileError" fileName="${sys:user.home}/logs/error.log"
                         filePattern="${sys:user.home}/logs/$${date:yyyy-MM}/error-%d{yyyy-MM-dd}-%i.log">
                <ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/>
                <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%t] [%p] - %l - %m%n"/>
                <Policies>
                    <TimeBasedTriggeringPolicy/>
                    <SizeBasedTriggeringPolicy size="100 MB"/>
                </Policies>
            </RollingFile>
        </appenders>
        <!--然后定义logger,只有定义了logger并引入的appender,appender才会生效-->
        <loggers>
            <!--过滤掉spring和mybatis的一些无用的DEBUG信息-->
            <logger name="org.springframework" level="INFO"></logger>
            <logger name="org.mybatis" level="INFO"></logger>
            <root level="DEBUG">
                <appender-ref ref="Console"/>
                <appender-ref ref="RollingFileInfo"/>
                <appender-ref ref="RollingFileWarn"/>
                <appender-ref ref="RollingFileError"/>
            </root>
        </loggers>
    </configuration>
    
  3. 使用

    @Log4j2
    public class Test {
        public static void main(String[] args) {
            log.debug("debug");
            log.info("info");
            log.warn("warn");
            log.error("error");
        }
    }
    

九、Web统一结果集

  1. Result封装

    @Data
    public class Result<T> {
        private Integer code;
     
        private String message;
     
        private T data;
     
        protected static <T> Result<T> build(T data) {
            Result<T> result = new Result<>();
            if (data != null)
                result.setData(data);
            return result;
        }
     
        public static <T> Result<T> build(T data, ResultCodeEnum resultCodeEnum) {
            Result<T> result = build(data);
            result.setCode(resultCodeEnum.getCode());
            result.setMessage(resultCodeEnum.getMessage());
            return result;
        }
     
        public static <T> Result<T> build(Integer code, String message) {
            Result<T> result = build(null);
            result.setCode(code);
            result.setMessage(message);
            return result;
        }
     
        public static<T> Result<T> ok(){
            return Result.ok(null);
        }
     
        public static<T> Result<T> ok(T data){
            Result<T> result = build(data);
            return build(data, ResultCodeEnum.SUCCESS);
        }
     
        public static<T> Result<T> fail(){
            return Result.fail(null);
        }
     
        public static<T> Result<T> fail(T data){
            Result<T> result = build(data);
            return build(data, ResultCodeEnum.FAIL);
        }
    }
    
  2. ResultCodeEnum封装

    @Getter
    public enum ResultCodeEnum {
        SUCCESS(200, "成功"),
        FAIL(201, "失败"),
        PARAM_ERROR(202, "参数不正确"),
        SERVICE_ERROR(203, "服务异常"),
        LOGIN_AUTH_ERROR(204, "未登陆"),
        PERMISSIONS_ERROR(205, "没有权限"),
        CODE_ERROR(206, "验证码错误"),
        LOGIN_ERROR(207, "登录失败"),
        REGISTER_ERROR(208, "注册失败"),
        LOGIN_DISABLED_ERROR(209, "改用户已被禁用"),
        ILLEGAL_CALLBACK_REQUEST_ERROR(210, "非法回调请求");
    
        private final Integer code;
        private final String message;
    
        ResultCodeEnum(Integer code, String message) {
            this.code = code;
            this.message = message;
        }
    }
    
  3. GlobalExceptionHandler封装

    @RestControllerAdvice
    @Log4j2
    public class GlobalExceptionHandler {
        @ExceptionHandler(value = Exception.class)
        public Result<Object> handleException(Exception e, HttpServletRequest request) {
            log.error("url {}, exception {}", request.getRequestURL(), e);
            Map<String, String> data = new HashMap<>();
            data.put("url", "请求地址:" + request.getRequestURL());
            data.put("exception", "错误信息:" + e);
            return Result.fail(data);
        }
    }
    

十、代码生成器

  1. 引入依赖

    <!-- mybatis-plus启动器 -->
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>3.3.2</version>
    </dependency>
    <!-- 生成器 -->
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-generator</artifactId>
        <version>3.3.2</version>
    </dependency>
    <!-- 生成器默认版本依赖 -->
    <dependency>
        <groupId>org.apache.velocity</groupId>
        <artifactId>velocity-engine-core</artifactId>
        <version>2.0</version>
    </dependency>
    <!-- 代码简写 -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.26</version>
    </dependency>
    <!-- mysql -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.31</version>
    </dependency>
    
  2. CodeGenerator

    package com.nuc.dao;
    
    import com.baomidou.mybatisplus.core.toolkit.StringPool;
    import com.baomidou.mybatisplus.generator.AutoGenerator;
    import com.baomidou.mybatisplus.generator.InjectionConfig;
    import com.baomidou.mybatisplus.generator.config.*;
    import com.baomidou.mybatisplus.generator.config.po.TableInfo;
    import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
    import com.baomidou.mybatisplus.generator.engine.VelocityTemplateEngine;
    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    import org.apache.commons.lang3.StringUtils;
    
    import java.util.*;
    import java.util.stream.Collectors;
    
    public class CodeGenerator {
        public static void main(String[] args) {
            List<DbConfig> dbConfigs = new ArrayList<>();
            // ------>配置
            // 配置数据库
            dbConfigs.add(new DbConfig("es_test" , "127.0.0.1" , "3306" , "root" , "root"));
            // 包名
            String packName = "com.nuc.dao";
            // mysql8以下版本去掉cj
            String driverName = "com.mysql.cj.jdbc.Driver";
            // <------
            List<String> dbNames = dbConfigs.stream().map(m -> m.dbName).collect(Collectors.toList());
            String dbname = scanner("请输入库名,可选:" + StringUtils.join(dbNames, ","));
            DbConfig dbConfig = dbConfigs.stream().filter(m -> m.getDbName().equals(dbname)).findFirst().orElse(null);
            if (dbConfig == null) {
                System.err.println("库名不存在");
                return;
            }
            String[] tables = scanner("请输入表名,多个英文逗号分割").split(",");
            boolean changePath = scanner("输入y生成到c盘根目录,默认回车生成到项目").equalsIgnoreCase("y");
            String generatePath = changePath ? "c:/mybatis-plus/" : System.getProperty("user.dir") + "/src/main/";
            // 代码生成器
            AutoGenerator mpg = new AutoGenerator();
            // 全局配置
            GlobalConfig gc = new GlobalConfig();
            gc.setOutputDir(generatePath + "/java/");
            gc.setAuthor("mybatis-plus生成");
            gc.setOpen(false);
            gc.setSwagger2(true); //实体属性 Swagger2 注解
            gc.setBaseResultMap(true);
            gc.setBaseColumnList(true);
            gc.setEntityName("%sEntity");
            gc.setMapperName("%sDao");
            gc.setFileOverride(changePath); //生成到项目时不覆盖源文件
            gc.setOpen(changePath); //弹出生成的文件夹窗口
            mpg.setGlobalConfig(gc);
            // 数据源配置
            DataSourceConfig dsc = new DataSourceConfig();
            dsc.setUrl("jdbc:mysql://" + dbConfig.getIp() + ":" + dbConfig.getPort() + "/" + dbname + "?useUnicode=true&useSSL=false&characterEncoding=utf8");
            dsc.setDriverName(driverName);
            dsc.setUsername(dbConfig.getUsername());
            dsc.setPassword(dbConfig.getPassword());
            mpg.setDataSource(dsc);
            // 包配置
            PackageConfig pc = new PackageConfig();
            pc.setParent(changePath ? "auto" : packName);
            pc.setMapper("dao." + dbname.toLowerCase());
            pc.setEntity("entity." + dbname.toLowerCase());
            mpg.setPackageInfo(pc);
            // 模板配置
            TemplateConfig tc = new TemplateConfig();
            tc.setController(null);
            tc.setService(null);
            tc.setServiceImpl(null);
            tc.setXml(null);
            mpg.setTemplate(tc);
            // 自定义配置
            InjectionConfig cfg = new InjectionConfig() {
                @Override
                public void initMap() {
                    Map<String, Object> map = new HashMap<>();
                    map.put("dbname" , dbname);
                    this.setMap(map);
                }
            };
            // 如果模板引擎是 velocity
            String templatePath = "/templates/mapper.xml.vm";
            // 自定义输出配置
            List<FileOutConfig> focList = new ArrayList<>();
            // 自定义配置会被优先输出
            focList.add(new FileOutConfig(templatePath) {
                @Override
                public String outputFile(TableInfo tableInfo) {
                    // 自定义输出文件名 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!!
                    return generatePath + "/resources/mapper/" + dbname.toLowerCase() + "/"
                            + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
                }
            });
            cfg.setFileOutConfigList(focList);
            mpg.setCfg(cfg);
            // 策略配置
            StrategyConfig strategy = new StrategyConfig();
            strategy.setNaming(NamingStrategy.underline_to_camel);
            strategy.setColumnNaming(NamingStrategy.underline_to_camel);
            strategy.setInclude(tables);
            mpg.setStrategy(strategy);
            mpg.setTemplateEngine(new VelocityTemplateEngine());
            mpg.execute();
        }
    
        @Data
        @AllArgsConstructor
        @NoArgsConstructor
        private static class DbConfig {
            private String dbName;
            private String ip;
            private String port;
            private String username;
            private String password;
        }
    
        /**
         * 读取控制台内容
         */
        public static String scanner(String tip) {
            Scanner scanner = new Scanner(System.in);
            System.out.println(tip + ":");
            return scanner.nextLine();
        }
    }
    

十一、swagger接口文档

  1. 引入依赖

    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger2</artifactId>
        <version>2.9.2</version>
    </dependency>
    <dependency>
        <groupId>com.github.xiaoymin</groupId>
        <artifactId>swagger-bootstrap-ui</artifactId>
        <version>1.9.6</version>
    </dependency>
    
  2. SwaggerConfig

    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import springfox.documentation.builders.ApiInfoBuilder;
    import springfox.documentation.builders.PathSelectors;
    import springfox.documentation.builders.RequestHandlerSelectors;
    import springfox.documentation.service.ApiInfo;
    import springfox.documentation.spi.DocumentationType;
    import springfox.documentation.spring.web.plugins.Docket;
    import springfox.documentation.swagger2.annotations.EnableSwagger2;
    
    @Configuration
    @EnableSwagger2
    public class SwaggerConfig {
        @Bean
        public Docket api() {
            return new Docket(DocumentationType.SWAGGER_2)
                    .apiInfo(apiInfo())
                    .select()
                    .apis(RequestHandlerSelectors.basePackage("com.zb.pro.web.controller"))
                    .paths(PathSelectors.any())
                    .build();
        }
    
        private ApiInfo apiInfo() {
            return new ApiInfoBuilder()
                    .title("swagger-bootstrap-ui RESTful APIs")
                    .description("swagger-bootstrap-ui")
                    .termsOfServiceUrl("http://localhost:8080/")
                    .contact("developer@mail.com")
                    .version("1.0")
                    .build();
        }
    }
    
  3. 访问路径:http://127.0.0.1:8080/doc.html

  4. 常用注解:点击传送

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值