3、后台数据库连接以及工具类编写 [木字楠博客]

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: Springboot项目引入Mysql以及MyBatisPlus等服务。

@[toc]

1、项目连接数据库

Springboot项目引入Mysql以及MyBatisPlus等服务。

1.1、引入依赖信息

首先在父类中引入相关依赖,并规定依赖版本信息
<!-- 版本控制 -->
    <properties>
        <!--===================== 数据库相关依赖版本  =========================-->
        <mysql.version>8.0.29</mysql.version>
        <mybatis-plus.version>3.4.2</mybatis-plus.version>
    </properties>

    <!-- 依赖管理 -->
    <dependencyManagement>
        <dependencies>
            <!--===================== 数据库相关依赖  =========================-->
            <!-- mysql8 -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>${mysql.version}</version>
            </dependency>
            <!-- MybatisPlus -->
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-boot-starter</artifactId>
                <version>${mybatis-plus.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
在common模块中引入对应依赖
        <!--===================== 数据库相关依赖  =========================-->
        <!-- mysql8 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <!-- MybatisPlus -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
        </dependency>

1.2、编写配置文件

server:
  port: 9000

spring:
  application:
    name: 木字楠博客后台服务
  # Database Configuration
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://[ip]:[port]/blog?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
    username: [用户名]
    password: [密码]
    
# MybatisPlus Configuration
mybatis-plus:
  mapper-locations: classpath*:/mapper/*.xml
  global-config:
    db-config:
      logic-delete-field: isDeleted
      logic-delete-value: 1
      logic-not-delete-value: 0

1.3、新增数据库配置类

/**
 * @author 木字楠
 * @version 1.0
 * @description MyBatisPlus配置文件
 * @date 2022/8/11
 */
@Configuration
@MapperScan("space.muzinan.mapper.**")
public class MybatisPlusConfig {

    /**
     * MyBatisPlus 分页插件
     * @return PaginationInterceptor
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }

}

1.4、代码生成器编写


public class MpGenerator {

    /**
     * <p>
     * MySQL 生成演示
     * </p>
     */
    public static void main(String[] args) {
        //1. 全局配置
        GlobalConfig config = new GlobalConfig();
        //是否支持AR模式
        config.setActiveRecord(true)
                .setAuthor("MuZiNan") //作者
                .setOutputDir("D:\\project\\MuZiNan\\MuZiNan-Server\\src\\main\\java")  //生成路径
                .setFileOverride(true)//是否文件覆盖,如果多次
                .setServiceName("%sService") //设置生成的service接口名首字母是否为I
                .setIdType(IdType.AUTO) //主键策略
                .setBaseResultMap(true)
                .setBaseColumnList(true)
                .setDateType(DateType.ONLY_DATE)
                .setSwagger2(true);
        //2. 数据源配置
        DataSourceConfig dsConfig = new DataSourceConfig();
        dsConfig.setDbType(DbType.MYSQL)
                .setUrl("jdbc:mysql://[ip]:[port]/blog?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true")
                .setDriverName("com.mysql.cj.jdbc.Driver")
                .setUsername("[用户名]")
                .setPassword("[密码]");
        //3.策略配置
        StrategyConfig stConfig = new StrategyConfig();
        stConfig.setCapitalMode(true) // 全局大写命名
                .setNaming(NamingStrategy.underline_to_camel)// 数据库表映射到实体的命名策略
                .setColumnNaming(NamingStrategy.underline_to_camel)
                .setInclude("article_view") //生成的表
                .setTablePrefix("")
                .setControllerMappingHyphenStyle(true)
                .setEntityLombokModel(true)
                .setRestControllerStyle(true); // 表前缀
        //4.包名策略
        PackageConfig pkConfig = new PackageConfig();
        pkConfig.setParent("space.muzinan")//父包名
                .setController("controller")
                .setEntity("entity")
                .setService("service")
                .setMapper("mapper")
                .setServiceImpl("service.impl");
        //5.整合配置
        AutoGenerator ag = new AutoGenerator().setGlobalConfig(config)
                .setDataSource(dsConfig)
                .setStrategy(stConfig)
                .setPackageInfo(pkConfig);
        ag.execute();
    }
}

2、通用枚举类编写

/**
 * @author 木字楠
 * @version 1.0
 * @date 2022/8/11
 */
@Getter
@AllArgsConstructor
public enum HttpCodeEnum {

    /**
     * 登陆超时
     */
    USER_LOGIN_TIME_OUT(100, "登陆超时"),
    /**
     * 用户未登录
     */
    USER_NOT_LOGIN(101, "用户未登录"),
    /**
     * 账户被禁用,请联系管理员解决
     */
    ACCOUNT_IS_DISABLED(102, "账户被禁用,请联系管理员解决"),
    /**
     * 参数格式不合法
     */
    PARAMETER_VALID_ERROR(103, "参数格式不合法"),
    /**
     * 用户名不能为空
     */
    USERNAME_CAN_NOT_BE_EMPTY(104, "用户名不能为空"),
    /**
     * 用户名或密码错误
     */
    USERNAME_OR_PASSWORD_ERROR(104, "用户名或密码错误"),
    /**
     * 验证码错误
     */
    CAPTCHA_ERROR(105, "验证码错误"),
    /**
     * 验证码过期
     */
    CAPTCHA_ALREADY_EXPIRE(106, "验证码已过期"),
    /**
     * 用户名已存在
     */
    USERNAME_ALREADY_EXISTED(107, "用户名已存在"),
    /**
     * 用户登录成功
     */
    USER_LOGIN_SUCCESS(108, "用户登录成功"),
    /**
     * 用户注销成功
     */
    USER_LOGOUT_SUCCESS(109, "用户注销成功"),
    /**
     * 操作成功
     */
    OPERATOR_IS_SUCCESS(200, "操作成功"),
    /**
     * 没有权限
     */
    PERMISSION_NOT_DEFINED(403, "您没有操作权限"),
    /**
     * 操作失败
     */
    OPERATOR_IS_FAILED(500, "操作失败");

    /**
     * 状态码
     */
    private int code;

    /**
     * 返回信息
     */
    private String message;
}
/**
 * @author 木字楠
 * @version 1.0
 * @description 请求类型枚举
 * @date 2022/8/11
 */
@Getter
@AllArgsConstructor
public enum RequestTypeEnum {
    
    /**
     * Get请求
     */
    GET_REQUEST_FIRST_UPPER_CASE("Get"),
    /**
     * Post请求
     */
    POST_REQUEST_FIRST_UPPER_CASE("Post"),
    /**
     * Put请求
     */
    PUT_REQUEST_FIRST_UPPER_CASE("Put"),
    /**
     * Delete请求
     */
    DELETE_REQUEST_FIRST_UPPER_CASE("Delete"),
    /**
     * GET请求
     */
    GET_REQUEST_ALL_UPPER_CASE("GET"),
    /**
     * POST请求
     */
    POST_REQUEST_ALL_UPPER_CASE("POST"),
    /**
     * PUT请求
     */
    PUT_REQUEST_ALL_UPPER_CASE("PUT"),
    /**
     * DELETE请求
     */
    DELETE_REQUEST_ALL_UPPER_CASE("DELETE"),
    /**
     * get请求
     */
    GET_REQUEST_ALL_LOWER_CASE("get"),
    /**
     * post请求
     */
    POST_REQUEST_ALL_LOWER_CASE("post"),
    /**
     * put请求
     */
    PUT_REQUEST_ALL_LOWER_CASE("put"),
    /**
     * delete请求
     */
    DELETE_REQUEST_ALL_LOWER_CASE("delete");

    /**
     * 请求类型
     */
    private final String REQUEST_TYPE;

}

3、统一结果集处理器

/**
 * @author 木字楠
 * @version 1.0
 * @description 统一结果集处理器
 * @date 2022/8/11
 */
@Data
public class ResponseResult<T> {

    /**
     * 状态码
     */
    private Integer code;

    /**
     * 是否请求成功
     */
    private Boolean success;

    /**
     * 响应消息
     */
    private String message;

    /**
     * 响应数据
     */
    private T data;

    /**
     * 私有构造
     *
     * @param success 请求状态
     * @param code    状态码
     * @param message 状态信息
     * @param data    数据
     * @param <T>     泛型数据
     * @return 结果集处理器
     */
    private static <T> ResponseResult<T> response(Boolean success, Integer code, String message, T data) {
        ResponseResult<T> result = new ResponseResult<>();
        result.setSuccess(success);
        result.setCode(code);
        result.setMessage(message);
        result.setData(data);
        return result;
    }

    /**
     * 请求成功返回(一)
     *
     * @param code    状态码
     * @param message 状态信息
     * @param data    数据
     * @param <T>     泛型数据
     * @return 结果集处理器
     */
    public static <T> ResponseResult<T> success(Integer code, String message, T data) {
        return response(true, code, message, data);
    }

    /**
     * 请求成功返回(二)
     *
     * @param message 状态信息
     * @param data    数据
     * @param <T>     泛型数据
     * @return 结果集处理器
     */
    public static <T> ResponseResult<T> success(String message, T data) {
        return response(true, HttpCodeEnum.OPERATOR_IS_SUCCESS.getCode(), message, data);
    }

    /**
     * 请求成功返回(三)
     *
     * @param message 状态信息
     * @param <T>     泛型数据
     * @return 结果集处理器
     */
    public static <T> ResponseResult<T> success(String message) {
        return response(true, HttpCodeEnum.OPERATOR_IS_SUCCESS.getCode(), message, null);
    }

    /**
     * 请求成功返回(四)
     *
     * @param httpCodeEnum 状态枚举
     * @param <T>          泛型数据
     * @return 结果集处理器
     */
    public static <T> ResponseResult<T> success(HttpCodeEnum httpCodeEnum) {
        return response(true, httpCodeEnum.getCode(), httpCodeEnum.getMessage(), null);
    }

    /**
     * 请求成功返回(五)
     *
     * @param httpCodeEnum 状态枚举
     * @param data         数据
     * @param <T>          泛型数据
     * @return 结果集处理器
     */
    public static <T> ResponseResult<T> success(HttpCodeEnum httpCodeEnum, T data) {
        return response(true, httpCodeEnum.getCode(), httpCodeEnum.getMessage(), data);
    }

    /**
     * 请求成功返回(六)
     * @param data 数据
     * @return 结果集处理器
     * @param <T> 泛型数据
     */
    public static <T> ResponseResult<T> success( T data) {
        return response(true, HttpCodeEnum.OPERATOR_IS_SUCCESS.getCode(),HttpCodeEnum.OPERATOR_IS_SUCCESS.getMessage(), data);
    }


    /**
     * 请求失败返回(一)
     *
     * @param code    状态码
     * @param message 状态信息
     * @param data    数据
     * @param <T>     泛型数据
     * @return 结果集处理器
     */
    public static <T> ResponseResult<T> fail(Integer code, String message, T data) {
        return response(false, code, message, data);
    }

    /**
     * 请求失败返回(二)
     *
     * @param message 状态信息
     * @param data    数据
     * @param <T>     泛型数据
     * @return 结果集处理器
     */
    public static <T> ResponseResult<T> fail(String message, T data) {
        return response(false, HttpCodeEnum.OPERATOR_IS_FAILED.getCode(), message, data);
    }

    /**
     * 请求失败返回(三)
     *
     * @param message 状态信息
     * @param <T>     泛型数据
     * @return 结果集处理器
     */
    public static <T> ResponseResult<T> fail(String message) {
        return response(false, HttpCodeEnum.OPERATOR_IS_FAILED.getCode(), message, null);
    }

    /**
     * 请求失败返回(四)
     *
     * @param httpCodeEnum 状态枚举
     * @param <T>          泛型数据
     * @return 结果集处理器
     */
    public static <T> ResponseResult<T> fail(HttpCodeEnum httpCodeEnum) {
        return response(false, httpCodeEnum.getCode(), httpCodeEnum.getMessage(), null);
    }

}
/**
 * @author 木字楠
 * @version 1.0
 * @description 分页结果集
 * @date 2022/8/11
 */
@Data
@AllArgsConstructor
public class PageResult<T> {

    /**
     * 总数据量
     */
    private long totalCount;

    /**
     * 数据列表
     */
    private List<T> dataList;

}

4、其他工具类

4.1、Bean拷贝工具类

/**
 * @description 复制对象或集合属性
 * @author 木字楠
 * @date 2022/8/11
 * @version 1.0
 */
public class BeanCopyUtils {

    /**
     * 复制对象
     *
     * @param source 源
     * @param target 目标
     * @return {@link T}
     */
    public static <T> T copyObject(Object source, Class<T> target) {
        T temp = null;
        try {
            temp = target.newInstance();
            if (null != source) {
                BeanUtils.copyProperties(source, temp);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return temp;
    }

    /**
     * 拷贝集合
     *
     * @param source 源
     * @param target 目标
     * @return {@link List<T>} 集合
     */
    public static <T, S> List<T> copyList(List<S> source, Class<T> target) {
        List<T> list = new ArrayList<>();
        if (null != source && source.size() > 0) {
            for (Object obj : source) {
                list.add(BeanCopyUtils.copyObject(obj, target));
            }
        }
        return list;
    }
}

4.2、Ip查询工具类

/**
 * ip工具类
 *
 * @author 11921
 */
@SuppressWarnings("all")
public class IpUtils {

    /**
     * 获取用户ip地址
     *
     * @param request 请求
     * @return ip地址
     */
    public static String getIpAddress(HttpServletRequest request) {
        String ipAddress = null;
        try {
            ipAddress = request.getHeader("x-forwarded-for");
            if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getHeader("Proxy-Client-IP");
            }
            if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getHeader("WL-Proxy-Client-IP");
            }
            if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getRemoteAddr();
                if ("127.0.0.1".equals(ipAddress)) {
                    // 根据网卡取本机配置的IP
                    InetAddress inet = null;
                    try {
                        inet = InetAddress.getLocalHost();
                    } catch (UnknownHostException e) {
                        e.printStackTrace();
                    }
                    ipAddress = inet.getHostAddress();
                }
            }
            // 对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割
            if (ipAddress != null && ipAddress.length() > 15) {
                // = 15
                if (ipAddress.indexOf(",") > 0) {
                    ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));
                }
            }
        } catch (Exception e) {
            ipAddress = "";
        }
        return ipAddress;
    }

    /**
     * 解析ip地址
     *
     * @param ipAddress ip地址
     * @return 解析后的ip地址
     */
    public static String getIpSource(String ipAddress) {
        try {
            URL url = new URL("http://opendata.baidu.com/api.php?query=" + ipAddress + "&co=&resource_id=6006&oe=utf8");
            BufferedReader reader = new BufferedReader(new InputStreamReader(url.openConnection().getInputStream(), "utf-8"));
            String line = null;
            StringBuffer result = new StringBuffer();
            while ((line = reader.readLine()) != null) {
                result.append(line);
            }
            reader.close();
            Map map = JSON.parseObject(result.toString(), Map.class);
            List<Map<String, String>> data = (List) map.get("data");
            return data.get(0).get("location");
        } catch (Exception e) {
            return "";
        }
    }

    /**
     * 获取访问设备
     *
     * @param request 请求
     * @return {@link UserAgent} 访问设备
     */
    public static UserAgent getUserAgent(HttpServletRequest request){
        return UserAgent.parseUserAgentString(request.getHeader("User-Agent"));
    }

}

5、统一异常处理

5.1、自定义异常处理

/**
 * @author 木字楠
 * @description 基础异常处理类
 * @version 1.0
 */
@Getter
public class BaseException extends RuntimeException {

    /**
     * 所属模块
     */
    private final String moudle;

    /**
     * 状态码
     */
    private final Integer code;

    /**
     * 报错信息
     */
    private final String message;

    /**
     * 全参构造方法
     *
     * @param moudle  所属模块
     * @param code    状态码
     * @param message 报错信息
     */
    public BaseException(String moudle, Integer code, String message) {
        this.moudle = moudle;
        this.code = code;
        this.message = message;
    }
}

5.2、全局异常处理

/**
 * @author 木字楠
 * @version 1.0
 * @description 全局异常处理
 * @date 2022/6/29
 */
@Slf4j
@RestControllerAdvice
public class GlobalException {

    /**
     * 全局异常处理
     *
     * @param e 异常信息
     * @return 错误信息
     */
    @ExceptionHandler(Exception.class)
    public ResponseResult<?> globalException(Exception e) {
        log.error("异常信息 => {}", e.getMessage());
        return ResponseResult.fail(HttpCodeEnum.OPERATOR_IS_FAILED.getMessage());
    }

    /**
     * 基础异常处理
     *
     * @param baseException 基础异常信息类
     * @return 错误结果
     */
    @ExceptionHandler(BaseException.class)
    public ResponseResult<?> baseException(BaseException baseException) {
        log.error("{}:异常信息 => {}", null == baseException.getMoudle() ? "未知" : baseException.getMoudle(), baseException.getMessage());
        return ResponseResult.fail(baseException.getMessage());
    }

}
相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
2月前
|
关系型数据库 MySQL Java
【IDEA】java后台操作mysql数据库驱动常见错误解决方案
【IDEA】java后台操作mysql数据库驱动常见错误解决方案
94 0
|
Java 关系型数据库 MySQL
JDBC连接数据库工具类
JDBC连接数据库工具类
|
2月前
|
SQL JavaScript 关系型数据库
node博客小项目:接口开发、连接mysql数据库
【10月更文挑战第14天】node博客小项目:接口开发、连接mysql数据库
|
6月前
|
Apache 数据库
杨校老师课堂之基于Apache的数据库连接池DBCP的工具类开发
杨校老师课堂之基于Apache的数据库连接池DBCP的工具类开发
28 0
|
6月前
|
druid 数据库
杨校老师课堂之基于阿里巴巴的数据库连接池Druid的工具类开发
杨校老师课堂之基于阿里巴巴的数据库连接池Druid的工具类开发
40 0
|
7月前
|
关系型数据库 MySQL 应用服务中间件
tomcat 搭建博客 及破解数据库密码
tomcat 搭建博客 及破解数据库密码
|
2月前
|
SQL druid Java
JDBC和数据库连接池-两个工具类-JDBCUtilsByDruid和BasicDAO
JDBC和数据库连接池-两个工具类-JDBCUtilsByDruid和BasicDAO
57 0
|
4月前
|
存储 SQL 数据库
【计算机三级数据库技术】第8章 数据库后台编程技术--附思维导图
本文介绍了数据库后台编程的关键技术,包括存储过程、用户定义函数、触发器和游标,并附有思维导图。
39 1
|
4月前
|
运维 前端开发 Serverless
中后台前端开发问题之降低数据库使用门槛和运维成本如何解决
中后台前端开发问题之降低数据库使用门槛和运维成本如何解决
35 0
|
7月前
|
JavaScript 前端开发 小程序
基于springBoot + Vue电影售票系统分前后台【完整源码+数据库】
基于springBoot + Vue电影售票系统分前后台【完整源码+数据库】
120 4