Springboot--黑马程序员《基础篇》
一、入门案例
SpringBoot是Pivotal团队提供的全新框架,其设计目的是用来简化Spring应用的初始搭建以及开发过程
1.1 Idea联网版
//Rest模式
@RestController
@RequestMapping("/books")
public class BookController {@GetMappingpublic String getById(){System.out.println("springboot is running ...");return "springboot is running";}}
1.2 官网创建版(Idea不能联网时用)


1. 打开SpringBoot官网,选择Quickstart Your Project
2.创建工程,并保存项目
3.解压项目,通过IDE导入项目
小技巧:

1.3 入门案例解析
1.3.1 SpringBoot程序优点:
起步依赖(简化依赖配置)
自动配置(简化常用工程相关配置)
辅助功能(内置服务器,……)
1.3.2 parent
1.开发SpringBoot程序要继承spring-boot-starter-parent
2.spring-boot-starter-parent中定义了若干个依赖管理
3.继承parent模块可以避免多个依赖使用相同技术时出现依赖版本冲突
4.继承parent的形式也可以采用引入依赖的形式实现效果
org.springframework.boot spring-boot-starter-parent 3.0.0
点进去:(Ctrl+B)
org.springframework.boot spring-boot-dependencies 3.0.0
再点进去:(Ctrl+B)
会发现定义了很多版本控制以及依赖


1.3.3 starter
SpringBoot中常见项目名称,定义了当前项目使用的所有依赖坐标,以达到减少依赖配置的目的
和parent比较:
parent:所有Springboot项目要继承的项目,定义了若干个坐标版本号(依赖管理,而非依赖),以达到减少依赖冲突的目的
spring-boot-starter-parent各版本间存在着诸多坐标版本不同
starter小结:
1.开发springboot程序需要导入坐标时通常导入对应的starter
2.每个不同的starter根据功能不同,通常包含多个依赖坐标
3.使用starter可以实现快速配置的效果,达到简化配置的目的
1.3.4 引导类
1.SpringBoot工程提供引导类用来启动程序
2.SpringBoot工程启动后创建并初始化Spring容器
@SpringBootApplication
public class Demo1Application {public static void main(String[] args) {SpringApplication.run(Demo1Application.class, args);}}
SpringBoot的引导类是Boot工程的执行入口,运行main方法就可以启动项目
SpringBoot工程运行后初始化Spring容器,扫描引导类所在包加载bean
1.3.5 内嵌tomcat
内嵌tomcat工作原理是将tomcat服务器作为对象运行,并将该对象交给Spring容器管理
org.springframework.boot spring-boot-starter-tomcat 3.0.0 compile
点进去,有内嵌的tomcat服务器:
org.apache.tomcat.embed tomcat-embed-core 10.1.1 compile tomcat-annotations-api org.apache.tomcat

springboot内置服务器:
tomcat(默认):apache出品,粉丝多,应用面广,负载了若干较重的组件
jetty:更轻量级,负载性能远不及tomcat
undertow:负载性能勉强能跑赢tomcat
二、知识加油站 ---REST开发
2.1 REST简介
REST:表现形式状态转换
传统风格资源描述形式:
http://localhost/user/getById?id=1
http://localhost/user/saveUser
REST风格描述形式:
http://localhost/user/1
http://localhost/user
优点:
1.隐藏资源的访问行为,无法通过地址得知对资源是何种操作
2.书写简化

2.2 入门案例
@RequestBody @RequestParam @PathVariable
区别:
@RequestParam用于接收url地址传参或表单传参
@RequestBody用于接收json数据
@PathVariable用于接收路径参数,使用{参数名称}描述路径参数
应用:
后期开发中,发送请求参数超过1个时,以json格式为主,@RequestBody应用较广
如果发送非json格式数据,选用@RequestParam接受请求参数
采用RESTful进行开发时,当参数数量较少时,例如1个,可以采用@PathVariable接收请求路径变量,通常用于传递id值
package com.itheima.controller;import com.itheima.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;//Rest模式
@Controller
@ResponseBody
public class UserController {@RequestMapping(value="/users",method= RequestMethod.POST)public String save(){System.out.println("user save");return "user save";}@RequestMapping(value="/users/{id}",method=RequestMethod.DELETE)public String delete(@PathVariable Integer id){System.out.println(" user delete "+id);return "user delete";}@RequestMapping(value="/users",method=RequestMethod.PUT)public String update(@RequestBody User user){System.out.println("user update..."+user);return "user update";}@RequestMapping(value="/users/{id}",method=RequestMethod.GET)public String getById(@PathVariable Integer id){System.out.println("user getById"+id);return "getById";}@RequestMapping(value="/users",method=RequestMethod.GET)public String getUsers(){System.out.println("users");return "getUsers";}}
2.3 RESTful快速开发
对入门案例简化开发
package com.itheima.controller;import com.itheima.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;//Rest模式
@RestController
@RequestMapping("/users")
public class UserController {@PostMappingpublic String save(){System.out.println("user save");return "user save";}@DeleteMapping("/{id}")public String delete(@PathVariable Integer id){System.out.println(" user delete "+id);return "user delete";}@PutMappingpublic String update(@RequestBody User user){System.out.println("user update..."+user);return "user update";}@GetMapping("/{id}")public String getById(@PathVariable Integer id){System.out.println("user getById"+id);return "getById";}@GetMappingpublic String getUsers(){System.out.println("users");return "getUsers";}}
三、基础配置
3.1 复制工程
原则:
保留工程基础结构
抹掉原始工程痕迹
①复制一份副本文件
②删掉除了src和pom.xml以外的文件

③进入idea,导入一个新模块

记得勾选maven项目:

小结:

3.2 属性配置
修改服务器端口
SpringBoot默认配置文件application.properties,通过键值对配置对应属性
# 服务器端口配置
server.port=80
更多配置:
# 服务器端口配置
server.port=80#修改banner
#spring.main.banner-mode=off#日志
#logging.level.root=debug
#logging.level.root=error
3.3 3种配置文件类型
SpringBoot提供了多种属性配置方式
application.properties
application.yml (主流格式)
application.yaml
3.4 配置文件加载优先级
优先级:.properties>.yml>.yaml
不同那个配置文件中相同配置按照加载优先级相互覆盖,不同配置文件中不同配置全部保留
3.5 yaml数据格式
YAML:一种数据序列化格式
优点:
容易阅读
容易与脚本语言交互
以数据为核心,重数据轻格式
YAML文件扩展名:
.yml(主流)
.yaml
yml语法规则
①大小写敏感
②属性层级关系使用多行描述,每行结尾时用冒号结束
③属性值前面添加空格(属性名与属性值之间使用冒号+空格作为分隔)
④#表示注释
⑤使用缩进标识层级关系,同层级左侧对齐,只允许使用空格(不允许使用Tab键)
country: chinaprovince: beijingcity: beijingarea: haidianport: 8080party: truebirthday: 1949-10-1user:name: itcastage: 16likes:- game- music- sleeplikes2: [game,music,sleep]users:- name: zhangsanage: 18- name: lisiage: 17users2:-name: zhangsiage: 19-name: lisanage: 25users3: [{name:zhangsan,age:lisi},{name:lisi,age:17}]


3.6 读取yaml数据
3.6.1 读取yaml单一属性数据
使用@Value配合SpEL读取单个数据
如果数据存在多层级,依次书写层级名称即可
//Rest模式
@RestController
@RequestMapping("/users")
public class UserController {@Value("${country}")private String country;@Value("${user1.name}")private String name;@Value("${likes[2]}")private String likes1;@Value("${users[1].age}")private int age;@GetMappingpublic String getCountry(){System.out.println("country--->"+country);System.out.println("name--->"+name);System.out.println("likes1--->"+likes1);System.out.println("age--->"+age);return "springboot``";}}

3.6.2 yaml文件中的变量引用
在配置文件中可以使用${属性名}方式引用属性值
如果属性中出现特殊字符,可以使用双引号包裹起来作为字符解析
baseDir: c:\windows
tempDir: ${baseDir}\temp
3.6.3 读取yaml全部属性数据
使用Environment对象封装全部配置信息
使用@Autowired自动装配数据到Environment对象中
//使用自动装配将所有的数据封装到一个对象Environment中@Autowiredprivate Environment env;@GetMapping("/env")public String getEnv(){System.out.println(env.getProperty("country"));return "env";}
3.6.4 读取yaml引用类型属性数据
1.使用@ConfigurationProperties注解绑定配置信息到封装类中
2.封装类需要定义为Spring管理的bean,否则无法进行属性注入

#创建类,用于封装下面的数据
#由spring帮我们去加载数据到对象中,一定要告诉spring加载这组信息
#使用的时候从spring中直接获取信息使用datasource:driver: com.myswl.cj.jdbc.Driverurl: jdbc:mysql://localhost/db_springbootusername: rootpassword: root
package com.itheima;import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;//1.定义数据模型封装yaml文件中对应的数据
//2.定义为spring管控的bean
@Component
//3.指定加载的数据
@ConfigurationProperties(prefix="datasource")
public class MyDataSource {private String driver;private String url;private String username;private String password;public MyDataSource(){}public MyDataSource(String driver, String url, String username, String password) {this.driver = driver;this.url = url;this.username = username;this.password = password;}public String getDriver() {return driver;}public void setDriver(String driver) {this.driver = driver;}public String getUrl() {return url;}public void setUrl(String url) {this.url = url;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}@Overridepublic String toString() {return "MyDataSource{" +"driver='" + driver + '\'' +", url='" + url + '\'' +", username='" + username + '\'' +", password='" + password + '\'' +'}';}
}
测试:
@Autowiredprivate MyDataSource myDataSource;@GetMapping("/datasource")public String getMyDatasource(){System.out.println(myDataSource);return "source";}

四、 各种整合
4.1 整合JUnit

①简单的junit使用小案例
1.导入测试对应的starter
2.测试类使用@SpringBootTest修饰
3.使用自动装配的形式添加要测试的对象
public interface BookDao {public void save();}
@Repository
public class BookDaoImpl implements BookDao {@Overridepublic void save(){System.out.println("book dao is running...");}
}
@SpringBootTest
class SpringbootJunitApplicationTests {//1.注入你要测试的对象//2.执行要测试的对象对应的方法@Autowiredprivate BookDao bookDao;@Testvoid testSave(){bookDao.save();}@Testvoid contextLoads() {System.out.println("test...");}}
②问题:当测试类不在引导类所在包及其子包下,测试无法通过
解决方法:
a)用@SpringBootTest 显式的写出引导类
@SpringBootTest(classes= SpringbootJunitApplication.class)
class SpringbootJunitApplicationTests {//1.注入你要测试的对象//2.执行要测试的对象对应的方法@Autowiredprivate BookDao bookDao;@Testvoid testSave(){bookDao.save();}@Testvoid contextLoads() {System.out.println("test...");}}
b)使用@ContextConfiguration
@SpringBootTest
@ContextConfiguration(classes=SpringbootJunitApplication.class)
class SpringbootJunitApplicationTests {//1.注入你要测试的对象//2.执行要测试的对象对应的方法@Autowiredprivate BookDao bookDao;@Testvoid testSave(){bookDao.save();}@Testvoid contextLoads() {System.out.println("test...");}}
4.2 整合MyBatis
核心配置:数据库连接相关信息(连什么、连谁、什么权限)
映射配置:SQL映射(XML/注解)
①整合MyBatis需要在创建模块/工程的时候在SQL中勾选:
MySQL Driver
MyBatis Framework
=====>导入对应的stater
org.mybatis.spring.boot mybatis-spring-boot-starter 3.0.0 com.mysql mysql-connector-j runtime
②设置数据源参数
#2.配置相关信息
spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/db_springbootusername: rootpassword: root
③创建实体类
public class Book {private Integer id;private String type;private String name;private String description;
……
}
④创建dao(定义数据层接口与映射配置)
数据库SQL映射需要添加@Mapper被容器识别到
@Mapper
public interface BookDao {@Select("select * from tb_book where id=#{id}")public Book getById(Integer id);}
⑤测试
@SpringBootTest
class MybatisDemoApplicationTests {@Autowiredprivate BookDao bookDao;@Testpublic void testBookDao(){Book book = bookDao.getById(1);System.out.println(book);}}
测试结果:


可能遇到的问题

4.3 整合MyBatis-Plus
MyBatis-Plus与MyBatis区别:
导入坐标不同
数据层实现简化
①创建模块的时候修改服务器URL

②选择关系型数据库,添加依赖

如果不想执行上述①②步,也可以直接手动导入坐标
com.baomidou mybatis-plus-boot-starter 3.4.2
同时去掉坐标:
org.springframework.boot spring-boot-starter
③配置数据源
spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/db_springbootusername: rootpassword: root
mybatis-plus:global-config:db-config:table-prefix: tb_
④配置实体类(和MyBatis一样)
⑤dao层
@Mapper
public interface BookDao extends BaseMapper {}
⑤测试
@SpringBootTest
class MybatisPlusApplicationTests {@Autowiredprivate BookDao bookDao;@Testvoid contextLoads() {System.out.println(bookDao.selectById(2));}}
4.4 整合Druid
①自行导入Druid的坐标
com.alibaba druid 1.2.11
②配置数据源
spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/db_springbootusername: rootpassword: 0529Lovetype: com.alibaba.druid.pool.DruidDataSource
测试:
@SpringBootTest
class MybatisDemoApplicationTests {@Autowiredprivate BookDao bookDao;@Testpublic void testBookDao(){Book book = bookDao.getById(2);System.out.println(book);}}
测试通过~
五、基于SpringBoot的SSMP整合案例


5.1 创建模块
1.勾选SpringMVC与MySQL坐标
2.修改配置文件为yml格式
3.设置端口为80方便访问
需要手动导入添加的依赖:
com.baomidou mybatis-plus-boot-starter 3.4.2 com.alibaba druid-spring-boot-starter 1.1.9 org.projectlombok lombok
5.2 创建实体类
注解@Data:
为当前实体类在编译期设置对应的get/set方法,toString方法,hashCode方法,equals方法等
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Book {@TableId(type= IdType.AUTO)private Integer id;private String type;private String name;private String description;}
5.3 数据层开发
5.3.1 applicaton.yml
server:port: 80spring:datasource:druid:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/db_springboot?serverTimezone=UTCusername: rootpassword: rootmybatis-plus:global-config:db-config:table-prefix: tb_
5.3.2 建库建表
create table tb_book(id int primary key auto_increment,type varchar(30) not null,name varchar(30) not null,description varchar(255)
)auto_increment=1;insert into tb_book(type,name,description) values
('计算机理论','Spring实战 第五版','Spring入门经典教程,深入理解Spring原理技术内幕');insert into tb_book(type,name,description) values
('计算机理论','Spring实战 核心原理','Spring入门经典教程,深入理解Spring原理技术内幕');insert into tb_book(type,name,description) values
('计算机理论','Spring实战 设计模式','Spring入门经典教程,深入理解Spring原理技术内幕');insert into tb_book(type,name,description) values
('计算机理论','Spring实战 入门到开发','Spring入门经典教程,深入理解Spring原理技术内幕');insert into tb_book(type,name,description) values
('计算机理论','Java核心技术卷','Spring入门经典教程,深入理解Spring原理技术内幕');
5.3.3 开启MP运行日志
使用配置方式开启日志,设置日志输出方式为标准输出
mybatis-plus:configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
效果:

5.3.4 分页
分页操作需要设定分页对象IPage
IPage对象中封装了分页操作中的所有数据
数据值
当前页码值
每页数据总量
最大页码值(总页码值)
数据总量
配置类:
@Configuration
public class MPConfig {@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor(){MybatisPlusInterceptor interceptor=new MybatisPlusInterceptor();interceptor.addInnerInterceptor(new PaginationInnerInterceptor());return interceptor;}}
测试实例:
@Testvoid testGetPage(){IPage page=new Page(1,3);bookDao.selectPage(page,null);}

解释:
bookDao.selectPage(page,null);调用结束后返回的仍然是IPage对象的实例,有如下方法:

分别打印输出可得:
@Testvoid testGetPage(){IPage page=new Page(1,3);bookDao.selectPage(page,null);System.out.println(page.getCurrent());System.out.println(page.getSize());System.out.println(page.getTotal());System.out.println(page.getPages());System.out.println(page.getRecords());}

5.3.5 条件查询
1.使用QueryWrapper对象封装查询条件
2.推荐使用LambdaQueryWrapper对象
3.所有查询操作封装成方法调用
4.查询条件支持动态条件拼接
@Testvoid testLambdaQueryWrapper(){LambdaQueryWrapper wrapper=new LambdaQueryWrapper<>();wrapper.like(Book::getName,"Spring");bookDao.selectList(wrapper);}
如果传入的判断条件为null,sql会直接将null认为是字符串直接拼接,所以需要做处理:
如果不满足条件,则不会进行此次like xxx拼接
@Testvoid testLambdaQueryWrapper(){String name=null;LambdaQueryWrapper wrapper=new LambdaQueryWrapper<>();wrapper.like(name!=null,Book::getName,name);bookDao.selectList(wrapper);}
5.4 业务层开发
Service层接口定义与数据层接口定义具有较大的区别,不要混用
selectByUserNameAndPassword(String username,String password);
login(String username,String password);
1.Service接口名称定义为业务名称,并与Dao接口名称进行区分
2.制作测试类测试Service功能是否有效
5.4.1 定义业务层接口
public interface BookService {boolean save(Book book);boolean update(Book book);boolean delete(Integer id);Book getById(Integer id);List getAll();IPage getPage(int currentPage,int pageSize);}
5.4.2 定义业务层实现类
@Service
public class bookServiceImpl implements BookService {@Autowiredprivate BookDao bookDao;@Overridepublic boolean save(Book book) {return bookDao.insert(book)>0;}@Overridepublic boolean update(Book book) {return bookDao.updateById(book)>0;}@Overridepublic boolean delete(Integer id) {return bookDao.deleteById(id)>0;}@Overridepublic Book getById(Integer id) {return bookDao.selectById(id);}@Overridepublic List getAll() {return bookDao.selectList(null);}@Overridepublic IPage getPage(int currentPage, int pageSize) {IPage page=new Page<>(currentPage,pageSize);return bookDao.selectPage(page,null);}
}
5.4.3 制作测试类
@SpringBootTest
public class BookServiceCase {@Autowiredprivate BookService bookService;@Testvoid testGetById(){System.out.println(bookService.getById(4));}@Testvoid testSave(){Book book=new Book(null,"悬疑","盗墓笔记","南派三叔匠心制作");System.out.println(bookService.save(book));}@Testvoid update(){Book book=new Book();book.setId(4);book.setDescription("入门神作");bookService.update(book);}@Testvoid testGetPage(){IPage page=bookService.getPage(2,2);System.out.println(page.getTotal());System.out.println(page.getSize());System.out.println(page.getPages());System.out.println(page.getCurrent());System.out.println(page.getRecords());}
5.4.4 业务层快速开发
快速开发方案:
使用MyBatisPlus提供有业务层通用接口(IService
)与业务层通用实现类(ServiceImpl )) 在通用类基础上做功能重载或功能追加
注意重载时不要覆盖原始操作,避免原始提供的功能丢失
业务层接口:
public interface IBookService extends IService {
}
业务层实现类:
@Service
public class BookServiceImpl extends ServiceImpl implements IBookService {
}
测试用例:
@SpringBootTest
public class BookServiceTest {@Autowiredprivate IBookService iBookService;@Testvoid testSave(){Book book=new Book(null,"游戏","全职高手","人生有梦,各自精彩");iBookService.save(book);}@Testvoid testUpdate(){Book book=new Book();book.setId(8);book.setDescription("这一次回国,我会夺回属于我的一切");iBookService.updateById(book);}@Testvoid testDelete(){iBookService.removeById(8);}@Testvoid testGetAll(){List list = iBookService.list();list.forEach(System.out::println);}@Testvoid testGetPage(){IPage page=new Page<>(2,3);iBookService.page(page);System.out.println(page.getRecords());}}
5.5 表现层开发
基于Restful进行表现层接口开发
新增:POST
删除:DELETE
修改:PUT
查询:GET
基于Postman测试表现层接口功能
实体数据:@RequestBody
路径变量:@PathVariable
@RestController
@RequestMapping("/books")
public class BookController {@Autowiredprivate IBookService bookService;@GetMappingpublic List getAll(){return bookService.list();}@PostMappingpublic Boolean save(@RequestBody Book book){return bookService.save(book);}@PutMappingpublic Boolean update(@RequestBody Book book){return bookService.updateById(book);}@DeleteMapping("/{id}")public Boolean delete(@PathVariable("id") Integer id){return bookService.removeById(id);}@GetMapping("/{id}")public Book getById(@PathVariable("id") Integer id){return bookService.getById(id);}}
getPage功能:
IBookService.java
public interface IBookService extends IService {IPage getPage(int currentPage,int pageSize);
}
BookServiceImpl.java
@Service
public class BookServiceImpl extends ServiceImpl implements IBookService {@Autowiredprivate BookDao bookDao;@Overridepublic IPage getPage(int currentPage, int pageSize) {IPage page=new Page<>(currentPage,pageSize);bookDao.selectPage(page,null);return page;}
}
BookController.java
@GetMapping("/{currentPage}/{pageSize}")public IPage getPage(@PathVariable int currentPage,@PathVariable int pageSize){return bookService.getPage(currentPage, pageSize);}
5.6 表现层消息一致性处理(R对象)
设计表现层返回结果的模型类,用于后端与前端进行数据格式统一,也称为前后端数据协议
@Data
@NoArgsConstructor
@AllArgsConstructor
public class R {private Boolean flag;private Object data;public R(Boolean flag){this.flag=flag;}
}
BookController.java
@RestController
@RequestMapping("/books")
public class BookController {@Autowiredprivate IBookService bookService;@GetMappingpublic R getAll(){return new R(true,bookService.list());}@PostMappingpublic R save(@RequestBody Book book){return new R(bookService.save(book));}@PutMappingpublic R update(@RequestBody Book book){return new R(bookService.updateById(book));}@DeleteMapping("/{id}")public R delete(@PathVariable("id") Integer id){return new R(bookService.removeById(id));}@GetMapping("/{id}")public R getById(@PathVariable("id") Integer id){return new R(true,bookService.getById(id));}@GetMapping("/{currentPage}/{pageSize}")public R getPage(@PathVariable int currentPage,@PathVariable int pageSize){return new R(true,bookService.getPage(currentPage,pageSize));}}
5.7 前后端协议联调
前后端分离结构设计中页面归属前端服务器
单体工程中页面放置在resources目录下的static目录中(建议执行clean)
前端没学,不会,TBC……
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
