1.新建springboot工程:
2.2.1
父工程配置:properties,dependencyManagement,build
pom爆红的话,先注释掉dependencyManagement,然后下载,下载好后加上dependencyManagement标签,刷新maven就好了。
yygh_parent的pom:
4.0.0
common
model
service
org.springframework.boot
spring-boot-starter-parent
2.6.9
com.fan
yygh_parent
0.0.1-SNAPSHOT
pom
yygh_parent
Demo project for Spring Boot
1.8
Hoxton.RELEASE
2.2.0.RELEASE
3.4.2
8.0.22
2.7.0
0.7.0
1.2.29
4.5.1
2.2.0-beta2
4.1.1
3.9.1
2.10.1
org.springframework.cloud
spring-cloud-dependencies
${cloud.version}
pom
import
com.alibaba.cloud
spring-cloud-alibaba-dependencies
${alibaba.version}
pom
import
com.baomidou
mybatis-plus-boot-starter
${mybatis-plus.version}
mysql
mysql-connector-java
${mysql.version}
io.springfox
springfox-swagger2
${swagger.version}
io.springfox
springfox-swagger-ui
${swagger.version}
io.jsonwebtoken
jjwt
${jwt.version}
org.apache.httpcomponents
httpclient
${httpclient.version}
com.alibaba
fastjson
${fastjson.version}
com.alibaba
easyexcel
${easyexcel.version}
com.aliyun
aliyun-java-sdk-core
${aliyun.version}
com.aliyun.oss
aliyun-sdk-oss
${oss.version}
joda-time
joda-time
${jodatime.version}
src/main/java
**/*.xml
false
搭建common 父模块:在根yygh_parent下搭建:
在父工程下创建子模块
子模块使用maven:
common
common的pom:
yygh_parent
com.fan
0.0.1-SNAPSHOT
4.0.0
common
pom
common_util
svervice_util
org.springframework.boot
spring-boot-starter-web
provided
com.baomidou
mybatis-plus-boot-starter
provided
org.projectlombok
lombok
io.springfox
springfox-swagger2
io.springfox
springfox-swagger-ui
com.alibaba
fastjson
common子模块下继续创建2个子模块:
父工程yygh_parent下创建子模块model:
model的pom:
yygh_parent
com.fan
0.0.1-SNAPSHOT
4.0.0
model
org.projectlombok
lombok
com.baomidou
mybatis-plus-boot-starter
provided
io.springfox
springfox-swagger2
provided
com.alibaba
easyexcel
provided
org.springframework.boot
spring-boot-starter-data-mongodb
provided
com.alibaba
fastjson
provided
再次在父工程yygh_parent下创建子模块service:
service的pom:
yygh_parent
com.fan
0.0.1-SNAPSHOT
4.0.0
service
pom
service_user
com.fan
model
0.0.1-SNAPSHOT
com.fan
svervice_util
0.0.1-SNAPSHOT
org.springframework.boot
spring-boot-starter-web
com.baomidou
mybatis-plus-boot-starter
mysql
mysql-connector-java
org.springframework.boot
spring-boot-devtools
true
org.springframework.cloud
spring-cloud-starter-openfeign
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-discovery
org.springframework.boot
spring-boot-maven-plugin
src/main/java
**/*.yml
**/*.properties
**/*.xml
false
src/main/resources
**/*.yml
**/*.properties
**/*.xml
false
然后删掉yygh_parent,common,service的src,因为这几个都是父模块,并且不需要写代码
复制远程地址:
VCS->Import into Version control–>Create Git Repository
第一次推送,需要填写地址
将上面项目放到远程库即可;
创建表:我这里用mysql8.0.22,客户端是navicat
sql:数据自己添加
CREATE DATABASE IF NOT EXISTS `yygh_cmn` CHARACTER SET utf8;
USE `yygh_cmn`;
CREATE TABLE `hospital_set` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '编号',
`hosname` varchar(100) DEFAULT NULL COMMENT '医院名称',
`hoscode` varchar(30) DEFAULT NULL COMMENT '医院编号',
`api_url` varchar(100) DEFAULT NULL COMMENT 'api基础路径',
`sign_key` varchar(50) DEFAULT NULL COMMENT '签名秘钥',
`contacts_name` varchar(20) DEFAULT NULL COMMENT '联系人',
`contacts_phone` varchar(11) DEFAULT NULL COMMENT '联系人手机',
`status` tinyint(3) NOT NULL DEFAULT '0' COMMENT '状态',
`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`is_deleted` tinyint(3) NOT NULL DEFAULT '0' COMMENT '逻辑删除(1:已删除,0:未删除)',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_hoscode` (`hoscode`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT='医院设置表';
创建新子模块:service下service_hosp
配置文件:
application.properties:
# 服务端口
server.port=8201
# 服务名
spring.application.name=service-hosp
# 环境设置:dev、test、prod
spring.profiles.active=dev
# mysql数据库连接
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/mybatis_plus?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=root
#返回json的全局时间格式
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=GMT+8
#spring.data.mongodb.uri=mongodb://192.168.44.165:27017/yygh_hosp
# nacos服务地址
#spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
#rabbitmq地址
#spring.rabbitmq.host=192.168.44.165
#spring.rabbitmq.port=5672
#spring.rabbitmq.username=guest
#spring.rabbitmq.password=guest
#配置mapper xml文件的路径
#mybatis-plus.mapper-locations=classpath:com/atguigu/yygh/mapper/xml/*.xml
#mybatis-plus.mapper-locations=classpath:com/atguigu/yygh/mapper/xml/*.xml
# nacos服务地址
#spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
#开启sentinel
#feign.sentinel.enabled=true
#设置sentinel地址
#spring.cloud.sentinel.transport.dashboard=http://127.0.0.1:8858
#mongodb地址
#spring.data.mongodb.host=192.168.44.163
#spring.data.mongodb.port=27017
#spring.data.mongodb.database=yygh_hosp
#rabbitmq地址
#spring.rabbitmq.host=127.0.0.1
#spring.rabbitmq.port=5672
#spring.rabbitmq.username=guest
#spring.rabbitmq.password=guest
#logging.level.root=DEBUG
现阶段不用的配置先注释掉;
手动创建这几个包和启动类:
启动类:
package com.fan.yygh.hosp;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ServiceHospApplication {
public static void main(String[] args) {
SpringApplication.run(ServiceHospApplication.class,args);
}
}
启动测试,记得注释掉service的pom中的服务调用的依赖,如下三个:
没有报错;ok;
model模块放所有的实体类:
将资料中的com文件夹整个复制到src-java下即可:
编写mapper:
创建xml文件夹和文件:
HospitalSetMapper.xml
service:
HospitalSetService接口:
package com.fan.yygh.hosp.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.fan.yygh.model.hosp.HospitalSet;
public interface HospitalSetService extends IService {
}
impl:
impl.HospitalSetServiceImpl:
package com.fan.yygh.hosp.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fan.yygh.hosp.mapper.HospitalSetMapper;
import com.fan.yygh.hosp.service.HospitalSetService;
import com.fan.yygh.model.hosp.HospitalSet;
import org.springframework.stereotype.Service;
@Service
public class HospitalSetServiceImpl extends
ServiceImpl implements
HospitalSetService {
}
controller:
package com.fan.yygh.hosp.controller;
import com.fan.yygh.hosp.service.HospitalSetService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/admin/hosp/hospitalSet")
public class HospitalSetController {
//注入service接口
@Autowired
private HospitalSetService hospitalSetService;
}
最后效果:
简单测试controller:
package com.fan.yygh.hosp.controller;
import com.fan.yygh.hosp.service.HospitalSetService;
import com.fan.yygh.model.hosp.HospitalSet;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
@RequestMapping("/admin/hosp/hospitalSet")
@Api("医院设置的控制器")
public class HospitalSetController {
//注入service接口
@Autowired
private HospitalSetService hospitalSetService;
@GetMapping("findAll")
@ApiOperation(value = "findAllHospital查找所有")
public List findAllHospital(){
List list = hospitalSetService.list();
return list;
}
}
我这里直接使用swagger:config的swagger配置类:
package com.fan.yygh.hosp.config;
import io.swagger.annotations.ApiOperation;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
/**
* @Author: zq
* @Date 2020-08-24 10:55
* @Description swagger 配置类,swagger基本信息和接口的权限
* @ClassName SwaggerConfig
* @PackageName com.zq.springboot.common.config
*/
@Configuration
@EnableSwagger2
public class SwaggerConfig {
/**
* 创建api实例
* @return
*/
@Bean
public Docket createRestAoi(){
return new Docket(DocumentationType.SWAGGER_2)
//用来创建该API的基本信息,展示在文档的页面中(自定义展示的信息)
.apiInfo(apiInfo())
//设置哪些接口暴露给Swagger展示
.select()
//扫描所有有注解的api,用这种方式更灵活,指定为ApiOperation.class
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
//构建
.build();
}
/**
* 添加摘要信息
* @return
*/
private ApiInfo apiInfo(){
//用ApiInfoBuilder进行定制,可以设置不同的属性,比较方便
return new ApiInfoBuilder()
//设置标题
.title("标题:springboot集成swagger测试")
//描述
.description("描述:用于测试集成swagger接口")
//作者信息
.contact(new Contact("zq",null,null))
//版本
.version("版本号:1.0")
//构建
.build();
}
}
1.我使用了springboot2.6.9,需要增加这个配置:
spring.mvc.pathmatch.matching-strategy=ant_path_matcher
2.注意换成自己的数据库:yygh_cmn
# 服务端口
server.port=8201
# 服务名
spring.application.name=service-hosp
# 环境设置:dev、test、prod
spring.profiles.active=dev
# mysql数据库连接
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/yygh_cmn?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=root
spring.mvc.pathmatch.matching-strategy=ant_path_matcher
#返回json的全局时间格式
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=GMT+8
#spring.data.mongodb.uri=mongodb://192.168.44.165:27017/yygh_hosp
# nacos服务地址
#spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
#rabbitmq地址
#spring.rabbitmq.host=192.168.44.165
#spring.rabbitmq.port=5672
#spring.rabbitmq.username=guest
#spring.rabbitmq.password=guest
#配置mapper xml文件的路径
#mybatis-plus.mapper-locations=classpath:com/atguigu/yygh/mapper/xml/*.xml
#mybatis-plus.mapper-locations=classpath:com/atguigu/yygh/mapper/xml/*.xml
# nacos服务地址
#spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
#开启sentinel
#feign.sentinel.enabled=true
#设置sentinel地址
#spring.cloud.sentinel.transport.dashboard=http://127.0.0.1:8858
#mongodb地址
#spring.data.mongodb.host=192.168.44.163
#spring.data.mongodb.port=27017
#spring.data.mongodb.database=yygh_hosp
#rabbitmq地址
#spring.rabbitmq.host=127.0.0.1
#spring.rabbitmq.port=5672
#spring.rabbitmq.username=guest
#spring.rabbitmq.password=guest
#logging.level.root=DEBUG
mapper可以加启动类上,也可以加在配置类上,建议放在配置类上
逻辑删除:
将swagger配置类放到service_util模块下:
com.fan.yygh.common.config.Swagger2Config:
使用资料中给的swagger配置类:
package com.fan.yygh.common.config;
import com.google.common.base.Predicates;
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.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
/**
* Swagger2配置信息
*/
@Configuration
@EnableSwagger2
public class Swagger2Config {
@Bean
public Docket webApiConfig(){
return new Docket(DocumentationType.SWAGGER_2)
.groupName("webApi")
.apiInfo(webApiInfo())
.select()
//只显示api路径下的页面
.paths(Predicates.and(PathSelectors.regex("/api/.*")))
.build();
}
@Bean
public Docket adminApiConfig(){
return new Docket(DocumentationType.SWAGGER_2)
.groupName("adminApi")
.apiInfo(adminApiInfo())
.select()
//只显示admin路径下的页面
.paths(Predicates.and(PathSelectors.regex("/admin/.*")))
.build();
}
private ApiInfo webApiInfo(){
return new ApiInfoBuilder()
.title("网站-API文档")
.description("本文档描述了网站微服务接口定义")
.version("1.1")
.contact(new Contact("fan", "http://atguigu.com", "493211102@qq.com"))
.build();
}
private ApiInfo adminApiInfo(){
return new ApiInfoBuilder()
.title("后台管理系统-API文档")
.description("本文档描述了后台管理系统微服务接口定义")
.version("1.1")
.contact(new Contact("fan", "http://atguigu.com", "49321112@qq.com"))
.build();
}
}
然后在启动类上增加@ComponentScan(basePackages = “com.fan”)
让其能扫描到swagger:
增加swagger标签:
swagger2:访问地址:http://localhost:8201/swagger-ui.htm
在使用SpringBoot项目多人开发时,返回给前端的数据类型如果不统一的话,会带来很多麻烦。这时,我们就应该规定一下约束,比如说统一返回的result结果集
改造controller中的请求方法的返回值:
//3.条件查询带分页
@PostMapping("findPageHospSet/{current}/{limit}")
public Result findPageHospSet(@PathVariable long current ,
@PathVariable long limit,
@RequestBody(required = false) HospitalSetQueryVo hospitalSetQueryVo){
//创建page对象,传递当前页,每页的记录数
Page page = new Page<>(current, limit);
//构造条件
QueryWrapper hospitalSetQueryWrapper = new QueryWrapper<>();
String hosname = hospitalSetQueryVo.getHosname();//医院名称
String hoscode = hospitalSetQueryVo.getHoscode();//医院编号
if(!StringUtils.isEmpty(hosname)){
hospitalSetQueryWrapper.like("hosname",hospitalSetQueryVo.getHosname());
}
if(!StringUtils.isEmpty(hoscode)){
hospitalSetQueryWrapper.eq("hoscode",hospitalSetQueryVo.getHoscode());
}
//调用方法实现分页查询
Page hospitalSetPage = hospitalSetService.page(page, hospitalSetQueryWrapper);
return Result.ok(hospitalSetPage);
}
添加医院设置:
测试数据:
{
"apiUrl": "http:localhost:9999",
"contactsName": "张三",
"contactsPhone": "123",
"hoscode": "1000_1",
"hosname": "深圳人民医院",
"isDeleted": 0
}
修改的参数:
删除参数:
@ControllerAdvice注解是Spring3.2中新增的注解,学名是Controller增强器,作用是给Controller控制器添加统一的操作或处理。
对于@ControllerAdvice,我们比较熟知的用法是结合@ExceptionHandler用于全局异常的处理,但其作用不止于此。ControllerAdvice拆开来就是Controller Advice,关于Advice,在Spring的AOP中,是用来封装一个切面所有属性的,包括切入点和需要织入的切面逻辑。这里ControllerAdvice也可以这么理解,
其抽象级别应该是用于对Controller进行切面环绕的,而具体的业务织入方式则是通过结合其他的注解来实现的。@ControllerAdvice是在类上声明的注解,其用法主要有三点:
1.结合方法型注解@ExceptionHandler,用于捕获Controller中抛出的指定类型的异常,从而达到不同类型的异常区别处理的目的。
2.结合方法型注解@InitBinder,用于request中自定义参数解析方式进行注册,从而达到自定义指定格式参数的目的。
3.结合方法型注解@ModelAttribute,表示其注解的方法将会在目标Controller方法执行之前执行。
从上面的讲解可以看出,@ControllerAdvice的用法基本是将其声明在某个bean上,然后在该bean的方法上使用其他的注解来指定不同的织入逻辑。不过这里@ControllerAdvice并不是使用AOP的方式来织入业务逻辑的,而是Spring内置对其各个逻辑的织入方式进行了内置支持
自定义异常:
修改这个:
模拟异常并测试:
日志xml中输出地址:修改成这样:
value=“D:\yygh_log\edu”
logback
INFO
${CONSOLE_LOG_PATTERN}
UTF-8
${log.path}/log_info.log
%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
UTF-8
${log.path}/info/log-info-%d{yyyy-MM-dd}.%i.log
100MB
15
INFO
ACCEPT
DENY
${log.path}/log_warn.log
%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
UTF-8
${log.path}/warn/log-warn-%d{yyyy-MM-dd}.%i.log
100MB
15
warn
ACCEPT
DENY
${log.path}/log_error.log
%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
UTF-8
${log.path}/error/log-error-%d{yyyy-MM-dd}.%i.log
100MB
15
ERROR
ACCEPT
DENY