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.bootspring-boot-starter-parent3.0.0 

点进去:(Ctrl+B)

  org.springframework.bootspring-boot-dependencies3.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.bootspring-boot-starter-tomcat3.0.0compile

点进去,有内嵌的tomcat服务器:

     org.apache.tomcat.embedtomcat-embed-core10.1.1compiletomcat-annotations-apiorg.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.bootmybatis-spring-boot-starter3.0.0com.mysqlmysql-connector-jruntime

②设置数据源参数

#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.baomidoumybatis-plus-boot-starter3.4.2

同时去掉坐标:

org.springframework.bootspring-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.alibabadruid1.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.baomidoumybatis-plus-boot-starter3.4.2com.alibabadruid-spring-boot-starter1.1.9org.projectlomboklombok

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……


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部