- Java锁的逻辑(结合对象头和ObjectMonitor)
- 还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)⛵
- 自动注册实体类到EntityFrameworkCore上下文,并适配ABP及ABPVNext
- 基于Sklearn机器学习代码实战
上一小节中我们从0到1 使用Vite搭建了一个Vue3项目,并集成了Element Plus 实现了一个简单的增删改查页面.
这一篇中我们将使用IDEA快速搭建一个SpringBoot3.x的项目.
1、File->new->project 。
2、选择“Spring Initializr”,点击next; 。
3、选择spring boot版本及添加相关依赖 。
这一步我们需要选择springboot版本,及Dependencies信息,当然了Dependencies 不是必须选择的。可以在项目建好之后需要什么添加什么.
简要说明:我们这里选择了四个Dependencies 。
4、创建好的项目结构 。
5、配置Maven 。
在这里配置本地Maven本地路径、Maven仓库。在本地Maven的settings.xml中会配置maven的镜像资源等信息 。
6、 下载相关依赖 。
在这里我们下载之前配置好的依赖,一般项目创建后会默认下载 。
在实际开发中,我们一般都会有好几套运行环境。比如①开发环境 ②测试环境 ③ 生产环境等等 。
我们不可能每次都去修改一个配置文件,这就显得很麻烦。下面我们主要说一说怎么配置多环境 。
① 修改application.properties 配置文件 。
idea创建的springboot项目,默认的配置文件是application.properties。我们这里将application.properties修改成application.yml.
为什么这么修改呢?因为yml文件配置起来比较方便,可以省略好多冗余内容,当然了你不改也是没啥问题的.
修改后的applicatio.yml文件如下,通过active:属性来切换环境 。
spring:
application:
name: springbootdemo
profiles:
active: dev
②添加开发环境配置 。
新建application-dev.yml 文件,在这里我们就可以配置开发环境下的端口,数据库连接等信息,具体内容如下 。
server.port
属性,指定应用程序在服务器上监听的端口号。这里设置为8080 spring.datasource
属性,配置应用程序与数据库的连接
driver-class-name
指定数据库驱动程序的类名 url
指定数据库的连接地址,这里是本地MySQL数据库的地址和端口号以及数据库名称 username
和 password
分别指定连接数据库所需的用户名和密码 spring.mybatis.mapper-locations
属性,指定MyBatis映射器XML文件的位置。这里配置为 classpath:mapper/*.xml ,表示映射器文件位于classpath下的mapper目录中
server:
port: 8080 # 配置端口为8080
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3308/test?useUnicode=true&characterEncoding=utf-8&useSSL=false
username: root
password: 123456
mybatis:
mapper-locations: classpath:mapper/*.xml
③ 添加生产环境配置 。
新建application-prod.yml文件,这里配置的是生产环境。具体内容如下,配置一样的,只是各种换成了生产的 。
server:
port: 8989
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://www.xiezhrspace.cn:3308/mybatisdemo?useUnicode=true&characterEncoding=utf-8&useSSL=false
username: root
password: 123456
mybatis:
mapper-locations: classpath:mapper/*.xml
以上配置好之后,我们就可以启动springboot项目 。
浏览器输入: http://localhost:8080 后出现如下内容,说明项目启动成功 。
通过之前的步骤,我们的springboot项目已经可以正常运行起来了,接下来我们就从数据库中获取数据并通过json格式返回前台 。
DROP TABLE IF EXISTS `sys_user`;
CREATE TABLE `sys_user` (
`id` int(0) NOT NULL AUTO_INCREMENT COMMENT '主键id',
`username` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '用户名',
`nickname` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '用户昵称',
`password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '用户密码',
`sex` enum('1','2') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '用户性别',
`birthday` date NULL DEFAULT NULL COMMENT '用户生日',
`email` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '用户邮箱',
`phone` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '用户电话',
`addr` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '用户地址',
`stop_flag` enum('1','0') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '用户启用标志',
`create_time` datetime(0) NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '用户创建时间',
`update_time` datetime(0) NULL DEFAULT NULL COMMENT '用户更新时间',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
INSERT INTO `sys_user` VALUES (1, 'xiezhr', '程序员小凡', '12345678', '1', '1999-09-19', 'xiezhr@qq.com', '13288888888', '云南省昆明市', '0', '2023-09-04 21:08:32', NULL);
INSERT INTO `sys_user` VALUES (2, 'xiaoqi', '程序员晓柒', '123456', '1', '2020-10-04', 'xiaoqi@163.com', '13288888888', '云南文山', '0', '2023-09-04 21:09:42', NULL);
INSERT INTO `sys_user` VALUES (3, 'xiaodeng', '财务小邓', '123456', '2', '2019-09-04', 'xiaodeng@qq.com', '13588888888', '云南文山', '0', '2023-09-04 21:10:43', NULL);
创建与表结构一致的实体类SysUser 。
@Data 是Lombok依赖的注解,使用它我们就不用写get、set方法了 。
@Data
public class SysUser implements Serializable {
private static final long serialVersionUID = 526934774547561999L;
/**
* 主键id
*/
private Integer id;
/**
* 用户名
*/
private String username;
/**
* 用户昵称
*/
private String nickname;
/**
* 用户密码
*/
private String password;
/**
* 用户性别
*/
private String sex;
/**
* 用户生日
*/
private Date birthday;
/**
* 用户邮箱
*/
private String email;
/**
* 用户电话
*/
private String phone;
/**
* 用户地址
*/
private String addr;
/**
* 用户启用标志
*/
private String stopFlag;
/**
* 用户创建时间
*/
private Date createTime;
/**
* 用户更新时间
*/
private Date updateTime;
}
数据访问对象,是MVC架构中负责与数据库进行交互的组件。它封装了数据库的访问操作,提供给Service层调用。Dao层通常包含一系列方法,用于对数据库进行增删改查操作,以及与数据库的连接、事务管理等.
@Mapper 表示这个接口是一个MyBatis的Mapper接口,用于定义数据库操作的方法 。
@Mapper
public interface SysUserMapper {
List<SysUser> querySyserList();
}
MyBatis的映射文件(mapper),用于操作数据库中的sys_user表。其中定义了一个resultMap用于映射查询结果到SysUser对象,还定义了一个select语句用于查询sys_user表中的所有用户信息。 id="querySyserList" 必须与mapper接口中方法名一致 。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xiezhr.mapper.SysUserMapper">
<resultMap type="com.xiezhr.model.entity.SysUser" id="SysUserMap">
<result property="id" column="id" jdbcType="INTEGER"/>
<result property="username" column="username" jdbcType="VARCHAR"/>
<result property="nickname" column="nickname" jdbcType="VARCHAR"/>
<result property="password" column="password" jdbcType="VARCHAR"/>
<result property="sex" column="sex" jdbcType="VARCHAR"/>
<result property="birthday" column="birthday" jdbcType="TIMESTAMP"/>
<result property="email" column="email" jdbcType="VARCHAR"/>
<result property="phone" column="phone" jdbcType="VARCHAR"/>
<result property="addr" column="addr" jdbcType="VARCHAR"/>
<result property="stopFlag" column="stop_flag" jdbcType="VARCHAR"/>
<result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
<result property="updateTime" column="update_time" jdbcType="TIMESTAMP"/>
</resultMap>
<!--查询所有用户信息-->
<select id="querySyserList" resultMap="SysUserMap">
select * from sys_user
</select>
</mapper>
Service是MVC架构中负责处理业务逻辑的组件。它封装了业务逻辑的实现细节,提供给Controller调用。Service层通常包含一系列方法,用于处理各种业务需求,如数据处理、事务管理、业务规则校验等.
SysUserService 。
public interface SysUserService {
List<SysUser> querySyserList();
}
SysUserServiceImpl 。
@Service
public class SysUserServiceImpl implements SysUserService {
@Resource
private SysUserMapper userMapper;
@Override
public List<SysUser> querySyserList() {
return userMapper.querySyserList();
}
}
Controller是MVC架构中负责接收用户请求并处理的组件。它接收来自用户的请求,并根据请求的内容调用相应的Service方法进行业务处理,然后返回结果给用户。Controller通常负责路由请求、参数验证、调用Service等操作 。
SysUserController 。
@RestController
@RequestMapping("/sysUser")
public class SysUserController {
@Autowired
private SysUserService sysUserService;
@RequestMapping(value = "/querySysUser",method = RequestMethod.GET)
public List<SysUser> querySysUser(){
return sysUserService.querySyserList();
}
}
到此我们三大组件的代码都写完了,接下来我们来看看我们写好的接口 。
浏览器地址栏输入: http://localhost:8080/sysUser/querySysUser 。
为了保证所有接口返回的数据格式一致,减少重复代码编写。我们将对返回结果进行统一处理.
具体返回结果格式如下 。
{
"code": 200, // 状态码,表示请求的处理结果
"message": "请求成功", // 状态消息,对请求结果的简要描述
"data": { // 数据对象,用于存储具体的返回数据
"key1": "value1",
"key2": "value2"
}
}
code
:表示请求的处理结果,一般采用HTTP状态码或自定义的业务状态码 message
:对请求结果的简要描述,通常是一个字符串 data
:用于存储具体的返回数据,可以是一个对象、数组或其他类型的数据 IResultCode
的接口 它位于 com.xiezhr.common.result 包中,可以由不同的类来实现,实现一致且统一的结果码和消息的处理和返回 。
package com.xiezhr.common.result;
public interface IResultCode {
String getCode();
String getMsg();
}
getCode()
: 这个方法返回一个 String
类型的结果码 getMsg()
: 这个方法返回一个 String
类型的结果消息 ResultCode
定义了一个枚举类 ResultCode ,它实现了 IResultCode 接口,并包含了一些常见的响应码和对应的消息.
@AllArgsConstructor
@NoArgsConstructor
public enum ResultCode implements IResultCode, Serializable {
SUCCESS("200","成功"),
NOT_FOUND("404","未找到"),
INTERNAL_SERVER_ERROR("500","服务器内部错误"),
;
private String code;
private String msg;
@Override
public String getCode() {
return code;
}
@Override
public String getMsg() {
return msg;
}
}
定义系统中常见的响应码和对应的消息,用于表示不同的业务场景或操作的执行结果 。
每个枚举常量都包含一个 code 和一个 msg ,分别表示响应码和消息内容 。
枚举常量包括了一些常见的响应码,如 SUCCESS 表示成功, INTERNAL_SERVER_ERROR 服务器内部错误, NOT_FOUND 表示未找到 。
定义了一个名为 Result 的类,用于表示统一的响应结构体 。
@Data
public class Result<T> implements Serializable {
private static final long serialVersionUID = 1L;
private String code;
private String msg;
private T data;
public static<T> Result<T> success() {
return success(null);
}
public static<T> Result<T> success(T data) {
Result result = new Result<>();
result.setCode(ResultCode.SUCCESS.getCode());
result.setMsg(ResultCode.SUCCESS.getMsg());
result.setData(data);
return result;
}
public static <T> Result<T> error(String msg) {
Result<T> result = new Result<>();
result.setCode(ResultCode.ERROR.getCode());
result.setMsg(ResultCode.ERROR.getMsg());
return result;
}
}
到此,统一响应返回我们已经封装好了,我们来改造一下Controller中的代码看看效果 。
SysUserController 未改之前 。
@RequestMapping(value = "/querySysUser",method = RequestMethod.GET)
public List<SysUser> querySysUser(){
return sysUserService.querySyserList();
}
SysUserController 修改之后 。
@RequestMapping(value = "/querySysUser",method = RequestMethod.GET)
public Result querySysUser(){
return Result.success(sysUserService.querySyserList());
}
前端返回结果 。
从上面的返回结果,我们会发现将密码等敏感信息返回到了前端,这是非常不可取的 。
这时,我们就需要根据前端的需求,灵活地选择需要展示的数据字段 。
如果你还傻傻分不清PO BO VO DTO POJO DAO DO 这些概念,可以看看知乎的这篇文章,个人觉得还是说的比较清楚的了 。
https://www.zhihu.com/question/39651928/answer/2490565983 。
定义一个需要返回前端的VO 。
@Data
public class UserInfoVO {
/**
* 用户名
*/
private String username;
/**
* 用户昵称
*/
private String nickname;
/**
* 用户性别
*/
private String sex;
/**
* 用户生日
*/
private Date birthday;
/**
* 用户邮箱
*/
private String email;
/**
* 用户电话
*/
private String phone;
/**
* 用户地址
*/
private String addr;
}
interface SysUserService 改造前 。
public interface SysUserService {
List<SysUser> querySyserList();
}
interface SysUserService 改造后 。
public interface SysUserService {
List<UserInfoVO> querySyserList();
}
SysUserServiceImpl 改造前 。
@Service
public class SysUserServiceImpl implements SysUserService {
@Resource
private SysUserMapper userMapper;
@Override
public List<SysUser> querySyserList() {
return userMapper.querySyserList();
}
}
SysUserServiceImpl 改造后 。
@Service
public class SysUserServiceImpl implements SysUserService {
@Resource
private SysUserMapper userMapper;
@Override
public List<UserInfoVO> querySyserList() {
List<UserInfoVO> userInfoVOList = new ArrayList<UserInfoVO>();
List<SysUser> sysUserList= userMapper.querySyserList();
for (SysUser sysUser : sysUserList) {
UserInfoVO userInfoVO = new UserInfoVO();
BeanUtils.copyProperties(sysUser,userInfoVO);
userInfoVOList.add(userInfoVO);
}
return userInfoVOList;
}
}
service 返回由原来的SysUser -->变成UserInfoVO 。
浏览器地址栏输入: http://localhost:8080/sysUser/querySysUser 。
这时返回前端的json数据中已经没有密码了 。
认真看文章的小伙伴可能已经发现了,前面返回的json数据中,日期是 "birthday" : "1999-09-18T16:00:00.000+00:00" 这样的 。
这样的日期可读性非常差,有没有什么方法可以格式化下日期呢?
其实呢,日期格式化非常简单,我们只需要在之前定义好的 UserInfoVO 的日期属性上加上一个注解即可 。
import com.fasterxml.jackson.annotation.JsonFormat;
@JsonFormat(pattern = "yyyy-MM-dd")
private Date birthday;
我们来测试一下 。
通过格式化的日期就是我们习惯的日期格式了 。
日常开发中,我们处理异常一般都会用到 try-catch 、 throw 和 throws 的方式抛出异常.
这种方式不仅仅程序员处理麻烦,对用户来说也不太友好 。
我们都希望不用写过多的重复代码处理异常,又能提升用户体验.
这时候 全局异常处理 就显得很便捷很重要了 。
小伙伴们如果对异常还不熟悉的可以看看这篇文章 。
https://blog.csdn.net/rong09_13/article/details/128090748 。
Springboot对于异常的处理也做了不错的支持,它提供两个注解供我们使用 。
@ControllerAdvice
public class MyExceptionHandler {
@ExceptionHandler(value =Exception.class)
public String exceptionHandler(Exception e){
System.out.println("发生了一个异常"+e);
return e.getMessage();
}
}
我们在 Result 类中添加如下两个方法来处理自定义异常和其他异常返回结果 。
//自定义异常返回的结果
public static <T> Result<T> bussinessErr(BusinessException e) {
Result<T> result = new Result<>();
result.setCode(e.getErrorCode());
result.setMsg(e.getErrorMsg());
result.setData(null);
return result;
}
//其他异常处理方法返回的结果
public static <T> Result<T> otherErr(ResultCode resultCode) {
Result<T> result = new Result<>();
result.setCode(resultCode.getCode());
result.setMsg(resultCode.getMsg());
result.setData(null);
return result;
}
新建com.xiezhr.exception包,并自定义异常类 。
public class BusinessException extends RuntimeException{
private String errorCode;
private String errorMsg;
public BusinessException() {
}
public BusinessException(String errorCode, String errorMsg) {
this.errorCode = errorCode;
this.errorMsg = errorMsg;
}
public String getErrorCode() {
return errorCode;
}
public void setErrorCode(String errorCode) {
this.errorCode = errorCode;
}
public String getErrorMsg() {
return errorMsg;
}
public void setErrorMsg(String errorMsg) {
this.errorMsg = errorMsg;
}
}
我们自定义一个全局异常处理类,来处理各种异常,包括 自己定义的异常 和 内部异常 .
这样可以简化不少代码,不用自己对每个异常都使用try,catch的方式来实现 。
我们在 com.xiezhr.exception 包下面添加全局异常处理类 GlobalExceptionHandler 。
@RestControllerAdvice
public class GlobalExceptionHandler {
/**
* 处理自定义异常
*
*/
@ExceptionHandler(value = BusinessException.class)
@ResponseBody
public<T> Result<T> bizExceptionHandler(BusinessException e) {
return Result.bussinessErr(e);
}
/**
* 处理其他异常
*
*/
@ExceptionHandler(value = Exception.class)
@ResponseBody
public Result exceptionHandler(Exception e) {
return Result.otherErr(ResultCode.INTERNAL_SERVER_ERROR);
}
}
我们在SysUserController 中添加如下代码来测试下异常,看看能不能捕获到 。
@RequestMapping("/getBusinessException")
public Result DeException(){
throw new BusinessException("400","我出错了");
}
@RequestMapping("/getException")
public Result Exception(){
Result result = new Result();
int a=1/0;
return result;
}
日志记录应用程序的运行状态,通过日志开发者可以更好的了解应用程序的运行情况 。
当系统出现bug时,也能通过日志快速定位问题和解决问题 。
① 常用日志框架 。
JUL、JCL、Jboss-logging、logback、log4j、log4j2、slf4j… 。
② 日志框架之间的关系 。
日志框架的设计类似于JDBC-数据库驱动的设计,提供了统一的接口抽象层,然后再由各个数据库厂商去实现它, 。
从而实现连接不同数据库(Oracle、MySQL、PostgreSQL、MongoD...) 。
日志门面(日志抽象层) | 日志实现 |
---|---|
JCL SLF4j jboss-logging |
Log4j JUL(java.util.logging) Log4j2 Logback |
我们需要需要选择一个日志门面 和日志实现 。
springboot 默认选用 SLF4j 和 Logback 。
① 日志输出分析 。
② 日志级别 。
日志级别由低到高如下 。
TRACE < DEBUG< INFO< WARN < ERROR
如果设置为 WARN ,则低于 WARN 的信息都不会输出 Spring Boot 中默认配置 ERROR 、 WARN 和 INFO 级别的日志输出到控制台 。
怎么调整日志级别呢?
logging.level.root=DEBUG
java -jar your-application.jar --logging.level.root=DEBUG
③ 日志写到文件中 。
需在application.properties或application.yml配置文件中设置 logging.file 或 logging.path 属性 。
logging.file
,设置文件,可以是绝对路径,也可以是相对路径。如: logging.file=my.log
logging.path
,设置目录,会在该目录下创建 spring.log
文件,并写入日志内容,如: logging.path=/var/log
如果只配置 logging.file ,会在项目的当前路径下生成一个 xxx.log 日志文件。 如果只配置 logging.path ,在 /var/log 文件夹生成一个日志文件为 spring.log 。
注 :二者不能同时使用,如若同时使用,则只有 logging.file 生效 。
默认情况下,日志文件的大小达到 10MB 时会切分一次,产生新的日志文件,默认级别为: ERROR、WARN、INFO 。
①第一种方法 。
我们参照官网: https://www.slf4j.org/manual.html 的例子即可 。
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class HelloWorld {
public static void main(String[] args) {
Logger logger = LoggerFactory.getLogger(HelloWorld.class);
logger.info("Hello World");
}
}
②第二种方法 。
第一种方法中,每次使用都要创建了一个名为 logger 的Logger对象,使用起来有点繁琐。这里我们引入注解方式实现 。
使用注解@Slf4j 需要安装 lombok 插件 。
可以用 {} 占位符来拼接字符串,而不需要使用 + 来连接字符串.
@SpringBootTest
@Slf4j
class SpringbootdemoApplicationTests {
@Test
void testLog() {
String name = "xiezhr";
int age = 20;
log.info("name:{},age:{}", name, age);
}
}
日志输出如下:
2023-09-16T12:27:57.014+08:00 INFO 53792 --- [ main] c.x.s.SpringbootdemoApplicationTests : name:xiezhr,age:20
前面几节说的都是springboot基本日志配置,如果这些都不能满足我们的需求,我们就需要添加 logback-spring.xml 官方推荐的配置文件进行配置 。
logback-spring.xml 中 配置了两个 分别是①输出到控制台②将日志写到文件中 并且使用 指定开发/生产环境配置 。
大家可以参考下面配置 。
<?xml version="1.0" encoding="UTF-8"?>
<!-- 日志级别从低到高分为TRACE < DEBUG < INFO < WARN < ERROR < FATAL,如果设置为WARN,则低于WARN的信息都不会输出 -->
<configuration>
<!-- SpringBoot默认logback的配置 -->
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
<springProperty scope="context" name="APP_NAME" source="spring.application.name"/>
<property name="LOG_HOME" value="/logs/${APP_NAME}"/>
<!--1. 输出到控制台-->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<!-- <withJansi>true</withJansi>-->
<!--此日志appender是为开发使用,只配置最低级别,控制台输出的日志级别是大于或等于此级别的日志信息-->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>DEBUG</level>
</filter>
<encoder>
<Pattern>${CONSOLE_LOG_PATTERN}</Pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<!-- 2. 输出到文件 -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 当前记录的日志文档完整路径 -->
<file>${LOG_HOME}/log.log</file>
<!--日志文档输出格式-->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} -%5level ---[%15.15thread] %-40.40logger{39} : %msg%n%n</pattern>
<charset>UTF-8</charset> <!-- 此处设置字符集 -->
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_HOME}/%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>10MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!--日志文档保留天数-->
<maxHistory>15</maxHistory>
</rollingPolicy>
<!-- 临界值过滤器,输出大于INFO级别日志 -->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter>
</appender>
<!-- 开发环境输出至控制台 -->
<springProfile name="dev">
<root level="INFO">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE"/>
</root>
</springProfile>
<!-- 生产环境输出至文件 -->
<springProfile name="prod">
<root level="INFO">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE"/>
</root>
</springProfile>
</configuration>
看到这,大家如果对日志还不太清楚的可以看看下面雷神讲的视频, 。
https://www.bilibili.com/video/BV1sb411H7Po 。
最终完整项目结构如下 。
本篇文章我们手把手创建了一个SpringBoot项目,并整合Mybatis实现了将数据库中数据通过json返回前端.
对返回json结果进行统一封装,异常的统一处理,日期时间的处理、开发/生产环境配置以及系统日志配置.
以上都是基于日常工作开发中的实际案例,希望对你有所帮助.
本期内容到此九结束了,希望对你有所帮助。我们下期再见~ (●'◡'●) 。
最后此篇关于快速搭建SpringBoot3.x项目的文章就讲到这里了,如果你想了解更多关于快速搭建SpringBoot3.x项目的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我正在使用 NetBeans 开发 Java 中的 WebService,并使用 gradle 作为依赖管理。 我找到了this article关于使用 gradle 开发 Web 项目。它使用 Gr
我正在将旧项目从 ant 迁移到 gradle(以使用其依赖项管理和构建功能),并且在生成 时遇到问题>eclipse 项目。今天的大问题是因为该项目有一些子项目被拆分成 war 和 jar 包部署到
我已经为这个错误苦苦挣扎了很长时间。如果有帮助的话,我会提供一些问题的快照。请指导我该怎么办????在我看来,它看起来一团糟。 *** glibc detected *** /home/shivam/
我在 Ubuntu 12.10 上运行 NetBeans 7.3。我正在学习 Java Web 开发类(class),因此我有一个名为 jsage8 的项目,其中包含我为该类(class)所做的工作。
我想知道 Codeplex、GitHub 等中是否有任何突出的项目是 C# 和 ASP.NET,甚至只是 C# API 与功能测试 (NUnit) 和模拟(RhinoMocks、NMock 等)。 重
我创建了一个 Maven 项目,包装类型为“jar”,名为“Y”我已经完成了“Maven 安装”,并且可以在我的本地存储库中找到它.. 然后,我创建了另一个项目,包装类型为“war”,称为“X”。在这
我一直在关注the instructions用于将 facebook SDK 集成到我的应用程序中。除了“helloFacebookSample”之外,我已经成功地编译并运行了所有给定的示例应用程序。
我想知道,为什么我们(Java 社区)需要 Apache Harmony 项目,而已经有了 OpenJDK 项目。两者不是都是在开源许可下发布的吗? 最佳答案 事实恰恰相反。 Harmony 的成立是
我正在尝试使用 Jsoup HTML Parser 从网站获取缩略图 URL我需要提取所有以 60x60.jpg(或 png)结尾的 URL(所有缩略图 URL 都以此 URL 结尾) 问题是我让它在
我无法构建 gradle 项目,即使我编辑 gradle 属性,我也会收到以下错误: Error:(22, 1) A problem occurred evaluating root project
我有这个代码: var NToDel:NSArray = [] var addInNToDelArray = "Test1 \ Test2" 如何在 NToDel:NSArray 中添加 addInN
如何在单击显示更多(按钮)后将主题列表限制为 5 个(项目)。 还有 3(项目),依此类推到列表末尾,然后它会显示显示更少(按钮)。 例如:在 Udemy 过滤器选项中,当您点击查看更多按钮时,它仅显
如何将现有的 Flutter 项目导入为 gradle 项目? “导入项目”向导要求 Gradle 主路径。 我有 gradle,安装在我的系统中。但是这里需要设置什么(哪条路径)。 这是我正在尝试的
我有一个关于 Bitbucket 的项目。只有源被提交。为了将项目检索到新机器上,我在 IntelliJ 中使用了 Version Control > Checkout from Ve
所以,我想更改我公司的一个项目,以使用一些与 IDE 无关的设置。我在使用 Tomcat 设置 Java 应用程序方面有非常少的经验(我几乎不记得它是如何工作的)。 因此,为了帮助制作独立于 IDE
我有 2 个独立的项目,一个在 Cocos2dx v3.6 中,一个在 Swift 中。我想从 Swift 项目开始游戏。我该怎么做? 我已经将整个 cocos2dx 项目复制到我的 Swift 项目
Cordova 绝对是新手。这些是我完成的步骤: checkout 现有项目 运行cordova build ios 以上生成此构建错误: (node:10242) UnhandledPromiseR
我正在使用 JQuery 隐藏/显示 li。我的要求是,当我点击任何 li 时,它应该显示但隐藏所有其他 li 项目。当我将鼠标悬停在文本上时 'show all list item but don
我想将我所有的java 项目(223 个项目)迁移到gradle 项目。我正在使用由 SpringSource STS 团队开发的 Gradle Eclipse 插件。 目前,我所有的 java 项目
我下载this Eclipse Luna ,对于 Java EE 开发人员,如描述中所见,它支持 Web 应用程序。我找不到 file -> new -> other -> web projects
我是一名优秀的程序员,十分优秀!