一、新建工程
1.确定maven版本。目前使用的是3.6.1
2.新建empty project
3.点击文件下拉菜单里面project structure或者点击右上角的project structure图标,进入project structure
4.module导航点击+,new module,选择spring initializr.,选择module sdk(1.8);选择initializr service url。网速实在慢就用https://start.aliyun.com。后面初始化的界面不一样,阿里的最新的还是2.4.1,默认的已经2.6.x以上了;另外阿里云创建的和直接官网创建的pom文件稍微不一样,一个有parent,一个直接导入了dependencyManagement。需要联网,下一步。
另外也可以直接进入https://start.spring.io/,在这个UI界面进行工程的创建,创建完成生成压缩包,导入到Idea就可以了。
5.initializr setting界面,设置spring的gav坐标(group,artifact和version),注意修改package,name和description不重要。next。artifact设置为springboot_01_01_quickstart。
6. springboot版本选择稳定版。snapshot是快照版。selected dependencies只选择springweb,下一步,下一步。ok。创建导入完成后,点击右侧的maven的刷新按钮。
还可以直接创建maven工程。在pom.xml文件里面需要添加
7. 创建controller类。
/ Rest模式
@RestController
@RequestMapping("/books")
public class BookController {
@GetMapping
public String getById(){
System.out.println("springboot running");
return "springboot is running";
}
}
直接运行,http://localhost:8080/books 已经有内容了。
配置:不想看到某些类型的文件可以进入:setting-搜索file type,找到editors里面的File Types,里面的ignore files and folders,添加对应的文件类型。
概念:starter
◆SpringBoot中常见项目名称, 定义了当前项目使用的所有依赖坐标,以达到减少依赖配置的目的
parent
◆所有SpringBoot项目 要继承的项目,定义了若干个坐标版本号(依赖管理,而非依赖),以达到减少依赖冲突的目的
◆spring-boot-starter-parent各版本间存在着诸多坐标版本不同
实际开发
◆使用任意坐标时, 仅书写GAV中的G和A, V由SpringBoot提供, 除非SpringBoot 未提供对应版本V
如发生坐标错误,再指定Version (要小心版本冲突)
⑴开发SpringBoot程 序需要导入坐标时通常导入对应的starter
⑵每个不同的starter根据功能不同,通常包含多个依赖坐标
⑶使用starter可以实现快速配置的效果,达到简化配置的目的
⑷SpringBoot工程提供引导类用来启动程序:SpringBoot的引导类是Boot工程的执行入口,运行main方法就可以启动项目
⑸SpringBoot工程启动后创建并初始化Spring容器:SpringBoot工程运行后初始化Spring容器,扫描引导类所在包加载bean
通过exclution可以变更依赖包里面的项
内置服务器有tomcat、jetty(更轻量,负载相比低一点)、undertow
内嵌Tomcat服务器是SpringBoot辅助功能之一,内嵌Tomcat工作原理是将Tomcat服务器作为对象运行,并将该对象交给Spring容器管理,变更内嵌服务器思想是去除现有服务器,添加全新的服务器
RestFull形式:使用Rest风格进行访问资源
@RequestMapping:方法注解,位于sprinmvc控制器方法的上方,用来设置当前控制器方法的请求访问路径。书属性包括value(请求访问路径),method(http请求动作)
@PathVariable:形参注解,位于SpringMVC控制器方法形参定义前面,用来绑定路径参数与处理器方法形参之间的关系吗,要求路径参数名和形参名一致。
Rest风格常用注解:
@RequestBody:用于接收Json数据;
@RequestParam:用于接收URL地址传参或表单传参;
@PathValiable:用于接收路径参数,使用(参数名称)描述路径参数、
@RestController:类注解,位于基于SpringMVC的Restful开发控制器类定义上方,用来设置当前控制器类为Restful风格,等同于@Controller与@ResponseBody两个注解的组合。
@GetMapping/PostMapping/PutMapping/DeleteMapping:方法注解,位于基于SpringMVC的Restful开发控制器方法定义上方,用于设置当前控制器方法访问路径与请求动作,每种对应一个请求动作,例如@GetMapping对应Get请求,是RestMapping以及method的简化。
复制模块:目标工程,修改工程文件夹名字,再修改pom.xml的artifactId属性为工程文件夹名字,删除name和description。删除除了src和pom.xml外的其他文件。一个可复制模块模块好了。
修改配置:application.properties (官方文档入口Common Application Properties ctrl+f搜索)
端口:server.port = 8090;banner:spring.banner.image.location=logo.png
日志:logging.level.root = error #默认是info,debug最多。
关闭banner:spring.main.banner.mode = off
配置方式:application.properties ,application.yml,application.yaml,生效的优先级也是这个顺序。
如果yml不显示为配置文件,进入project structure-facets-选择工程-点击配置文件图标,再点击添加按钮,将yml文件加入即可。
其他数组格式,添加- a或者 [a]、[{},{}]这样.
server:
port: 8090
users:
-
name: yongfor
nickname: '永华'
-
name: xiali
nickname: '夏力'
department: [{name: '团长',level: 5},{name: '首席',level: 6},{name: '专家',level: 7}]
使用yml定义的数据:
@Value("${users[1].name}")
private String name;
@Value("${department[1].level}")
private String level;
yml里面使用字符串需要转义,用双引号包括,不用引号不会被转义。
在yml里面也可以使用${属性名}引用yml已定义的数据,比如BaseUrl。
springboot使用Enviroment对象封装全部配置信息,使用@Autowired自动装配数据到Environment对象。
自定义对象封装指定数据:yml定义好数据对象,封装一个spring类,添加指定数据的注解,使用时注入就可以了。
整合Junit:
如果测试类存在于引导类所在的包或者子包则无需指定引导类;如果不在则需要通过classes属性指定引导类。
整合Mybatis:导入mybatis对应的starter,yml添加配置信息,在数据库SQL类上添加@Mapper注解能顾被spring容器识别。
如果使用的低版本的springboot,高版本的mysql8.0 ,可改成下方配置,url添加serverTimezone设定/或者修改Mysql数据库配置(略),驱动类改成com.mysql.cj.jdbc.Driver/
整合Mybatis-plus:
⑴手动添加SpringBoot整合Mybatis-plus的坐标,可以通过https://mvnrepository.com/ 查找
⑵定义数据层接口与映射配置,继承BaseMapper
@Mapper
public interface UserDao extends BaseMapper{}
⑶yml文件添加同样的datasource信息,另外
mybatis-plus:
global-config:
db-config:
table-prefix: tpl_
id-type: auto
整合Druid:
⑴导入Druid的starter;⑵添加Druid的配置
简单案例
Lombok:提供了一套注解,简化了pojo的开发。需要在Idea的sertting-plugin里面安装插件(lombok)。@Data不提供构造函数,需要添加注解@NoArgsConstructor或者@AllArgsConstructor
Autowired:注入Mapper会提示Could not autowire,No Beans of “xxx”,需要在mapper类上添加@component或者@Repository 申明这个类是Beans
MP日志:输出到终端面板上,正式上线要关了。
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
分页:
使用到的快捷键:CTRL+Alt+v就可以自动补全左侧语句代码;ctrl+h可查看类的继承关系。
使用mybatis-plus的selectPage,设定分页对象:
IPage page = new Page(1,5);
bookDao.selectPage(page,null);
添加拦截器,内部动态的拼接sql语句。否则limit不会起效。
@Configuration
public class MPConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
return interceptor;
}
}
IPage对象封装了分页操作里面的所有数据:数据、当前页码值、每页数据总量、最大页码值、数据总量.
查询条件
使用QuerySwapper/LambdaQuerySwapper对象封装查询条件
void testGetBy2(){
String name = null;
LambdaQueryWrapper lqw = new LambdaQueryWrapper<>();
lqw.like(name!=null,Book::getName,name);
bookDao.selectList(lqw);
}
业务层快速开发方案:
使用MyBatisPlus提供有业务层通用接口(IService
// IBookService.java
public interface IBookService extends IService {
}
// BookServiceImpl.java
@Service
public class BookServiceImpl extends ServiceImpl implements IBookService{
}
// ServiceTest.java
// page的写法
@Test
void testGetpage(){
IPage page = bookService.getPage(2,3);
System.out.println(page);
}
另外可在通用类基础上做功能重载或功能追加,注意正在重载时不要覆盖原始操作,避免原始童工的功能丢失(通过@override验证是否覆盖),以后企业级开发大多就是追加的功能的开发。
表现层开发:
基于Restful制作表现层接口:新增-post,删除-delete,修改-put,查询-get
接收参数:大量数据等实体数据@RequesBody,路径变量:@PathValiable
// BookServiceImpl.java
@Override
public IPage getPage(int currentPage, int pageSize) {
IPage page = new Page<> (currentPage,pageSize);
bookDao.selectPage (page,null);
return page;
}
// BookController.java
@RestController
@RequestMapping("/books")
public class BookController {
@Autowired
private IBookService bookService;
@GetMapping("{id}")
public Book getById(@PathVariable Integer id){
return bookService.getById (id);
}
@GetMapping("{currentPage}/{pageSize}")
public IPage getPage(@PathVariable Integer currentPage,@PathVariable Integer pageSize){
return bookService.getPage (currentPage,pageSize);
}
}
表现层消息一致性处理
设计统一的返回值结果类型便于前端开发读取数据;返回值结果可以根据需求自行设定,没有固定格式;返回值结果模型类用于后端和前端进行数据格式统一,也称作前端数据协议。
// 返回值类 controller/utils/R.java
@Data
public class R {
private Boolean flag;
private Object data;
public R(){}
public R(Boolean flag){
this.flag = flag;
}
public R(Boolean flag,Object data){
this.flag = flag;
this.data = data;
}
}
// BookController.java使用返回值类
@DeleteMapping
public R delete(Integer id){
return new R(bookService.delete (id));
}
@GetMapping("{id}")
public R getById(@PathVariable Integer id){
return new R(true,bookService.getById (id));
}
异常处理器
新建一个SpringMVC异常处理器拦截异常,用来处理发生异常导致的数据返回格式不一致。
// 异常处理器 controller/utils/ProjectExceptionAdvice.java
@RestControllerAdvice
public class ProjectExceptionAdvice {
@ExceptionHandler(Exception.class)
public R doException(Exception ex){
ex.printStackTrace();
return new R("error");
}
}
// 在返回值类里面添加对应的构造函数 controller/utils/R.java
// 表现层返回结果的模型类里面添加消息属性,用来传递消息到页面(即提示消息由后台统一管理)
public R(Boolean flag,String msg){
this.flag = flag;
this.msg = msg;
}
// 异常处理器所需的构造函数
public R(String msg){
this.flag = false;
this.msg = msg;
}
分页bug简单处理
多发生于最后一页只有一条数据,删除操作导致的页面显示问题
@GetMapping("{currentPage}/{pageSize}")
public R getPage(@PathVariable Integer currentPage,@PathVariable Integer pageSize){
// 如果当前页码值大于总页数,那么在执行查询操作,使用最大页码作为当前页码值
IPage page = bookService.getPage(currentPage,pageSize);
if(currentPage > page.getPages()){
page = bookService.getPage((int)page.getPages(),pageSize);
};
return new R(true,page);
}
条件查询
修改加载数据的js,添加参数数据,修改后端的controller和service
getAll() {
//组织参数,拼接url请求地址
// console.log(this.pagination.type);
param = "?type="+this.pagination.type;
param +="&name="+this.pagination.name;
param +="&description="+this.pagination.description;
// console.log(param);
//发送异步请求
axios.get("/books/"+this.pagination.currentPage+"/"+this.pagination.pageSize+param).then((res)=>{
this.pagination.pageSize = res.data.data.size;
this.pagination.currentPage = res.data.data.current;
this.pagination.total = res.data.data.total;
this.dataList = res.data.data.records;
});
},
后端controller方法里面通过book接收参数
@GetMapping("{currentPage}/{pageSize}")
public R getPage(@PathVariable Integer currentPage,@PathVariable Integer pageSize,Book book){
// 如果当前页码值大于总页数,那么在执行查询操作,使用最大页码作为当前页码值
IPage page = bookService.getPage(currentPage,pageSize,book);
if(currentPage > page.getPages()){
page = bookService.getPage((int)page.getPages(),pageSize,book);
};
return new R(true,page);
}
service里面创建一个接收参数的方法
public IPage getPage(Integer currentPage, Integer pageSize, Book book) {
LambdaQueryWrapper lqw = new LambdaQueryWrapper<>();
lqw.like(Strings.isNotEmpty(book.getType()),Book::getType,book.getType());
lqw.like(Strings.isNotEmpty(book.getName()),Book::getName,book.getName());
lqw.like(Strings.isNotEmpty(book.getDescription()),Book::getDescription,book.getDescription());
IPage page = new Page<> (currentPage,pageSize);
bookDao.selectPage (page,null);
return page;
}
打包和运行
首先确保pom.xml存在maven插件
org.springframework.boot
spring-boot-maven-plugin
1.打包
IDEA右侧maven-lifecycle-clean,清除target文件夹;选定lifecycle-test,点击上方的skip按钮
跳过test,防止打包之前自动执行一遍test;选择package,双击开始打包,生成新的target文件夹。
2. windows系统上运行
右键target,选择show in explore,进入target文件夹。地址栏输入cmd,运行java -jar xxx.jar
3.端口占用查询
4.linux运行
使用MobaXterm1_CHS1将jar包上传linux系统。注意配置mysql。(未安装虚拟机,再补充。)
一个是设置后台运行,一个是需要技术,通过kill -p指令操作。
5.临时属性
(1)使用jar命令启动springboot工程时可以使用临时属性替代配置文件里面的属性。临时属性的添加方式:java -jar xxx.jar --属性名=新值;多个临时属性之间使用空格分割;临时属性必须是当前boot工程支持的属性,否则设置无效。
(2)进入configuration进入config页面,添加参数测试指令是否可用。
也可在xxxapplication.java里面通过编程形式带参数启动springboot程序,为程序添加运行参数。
不携带参数,外部指令就无法使用了。
(3)配置文件权限级别
与jar同级的config级别最好,工程文件里面的yml最低。多层级配置文件属性采用叠加并覆盖的形式生效。
(4)想要修改使用的配置文件名,需在configuration的Program arguments项里面添加--spring.config.name='xxx,或spring.config.location=classpath:/xxx.yml然后xxx.yml就可以生效。
后面的权限更高。
多环境开发(yml)
(1)都放在一个yml里面
spring.profile提示过时,可采用spring:config:activate:on-profile:xxx格式。
(2)拆分成多个文件
主配置文件设置公共配置,环境分类配置文件设置冲突属性。
properties文件多环境配置只支持多文件格式。不支持单一文件格式。
当主环境dev与其它环境有相同属性时,主环境生效;其它环境有相同属性时,最后加载的环境属性生效。
从springboot2.4开始使用group属性替代include属性,降低了配置书写量,使用group属性定义多种主环境与自环境的包含关系。
也可在pom里面由Maven设置多环境属性。
当Maven与Springboot同时多环境进行控制,以Maven为主,springboot使用@..@占位符读取Maven对应的配置属性值;基于Springboot读取maven配置属性的前提下,如果在Idea下测试工程时pom.xml每次更新都需要手动compile方可生效。
日志
可用过设置日志组,控制指定包对应的日志输出级别,也可直接控制指定包对应的日志输出级别
logging:
# 设置日志组
group:
# 自定义组名,设置当前组包含的包
ebank: com.itheima.controller,com.itheima.service
level:
root: warn
# 为对应组设置日志级别
ebank: debug
# 为对应包设置日志级别
com.itheima.controller: debug
日志级别共有6种,常用的包括4种,分别是info,warn,debug,error
日志使用:
private static final logger log = loggerFactory.getLogger(BookController.class)
log.debug("debug。。。")
为防止每次都要定义logger对象,可定义一个baseclass,包含logger对象,其他类继承。也可使用@Slf4j注解。
Idea日志输出格式控制:
logging:
pattern:
console: "%d - %m%n"
# %d : 日期,%m: 消息, %n: 换行
-------------------------------
logging:
pattern:
console: "%d %clr(%p)" --- [%16t] %clr(%-40.40c){cyan} : %m %n
日志保存文件
logging:
file:
name: server.log # 单个文件
................................
logback: # 滚动的日志文件
rollingpolicy:
max-file-size: 4kB
file-name-pattern: server.%d(yyyy-MM-dd).%i.log # server.2022.01.01.1.log
接下来是开发实用篇,----《springboot学习2》