SpringBoot 学习笔记

SpringBoot 学习笔记

一、Spring工作流程

SpringBoot流程

二、分层说明

Controller:

​ 注意在此层中将包含Config配置和拦截器/过滤器,负责与前端进行交互,下属各个方法也需要@GetMapping等等注解

注解
@Controller 处理http请求*
@Controller
public class HelloController {

    @RequestMapping(value="/hello",method= RequestMethod.GET)
    public String sayHello(){
        return "hello";
    }
}
//@Controller必须配合模版来使用。spring-boot 支持多种模版引擎包括:
//1,FreeMarker
//2,Groovy
//3,Thymeleaf (Spring 官网使用这个)
//4,Velocity
//5,JSP 
@ResponseBody
/*@ResponseBody的作用其实是将java对象转为json格式的数据。

@responseBody注解的作用是将controller的方法返回的对象通过适当的转换器转换为指定的格式之后,写入到response对象的body区,通常用来返回JSON数据或者是XML数据。
注意:在使用此注解之后不会再走视图处理器,而是直接将数据写入到输入流中,他的效果等同于通过response对象输出指定格式的数据。*/

@RequestMapping("/login.do")
@ResponseBody
public Object login(String name, String password, HttpSession session) {
	user = userService.checkLogin(name, password);
	session.setAttribute("user", user);
	return new JsonResult(user);
}


@RequestBody AND @RequestParam()
/*@RequestBody主要用来接收前端传递给后端的json字符串中的数据的(请求体中的数据的);GET方式无请求体,所以使用@RequestBody接收数据时,前端不能使用GET方式提交数据,而是用POST方式进行提交.

在后端的同一个接收方法里,@RequestBody 与@RequestParam()可以同时使用,@RequestBody最多只能有一个,而@RequestParam()可以有多个。

注:一个请求,只有一个RequestBody;一个请求,可以有多个RequestParam

注:当同时使用@RequestParam()和@RequestBody时,@RequestParam()指定的参数可以是普通元素、数组、集合、对象等等(即:当,@RequestBody 与@RequestParam()可以同时使用时,原SpringMVC接收参数的机制不变,只不过RequestBody 接收的是请求体里面的数据;而RequestParam接收的是key-value里面的参数,所以它会被切面进行处理从而可以用普通元素、数组、集合、对象等接收)。*/

//@RequestBody 
@RequestMapping(value = "/something", method = RequestMethod.PUT)  
public void handle(@RequestBody String body, Writer writer) throws IOException {  
  writer.write(body);  
}
//@RequestParam()
@GetMapping(value = "/login")
public ResultVO login(@RequestParam("username") String name,
 				      @RequestParam(value = "password",defaultValue = "111111") String pwd){
     return userService.checkLogin(name,pwd);
}
*@RestController
//@RestController注解相当于@Controller + @ResponseBody 合在一起的作用。
@RequestMapping 配置url映射关系
/*
1.value
用于设置方法或者类的映射路径,可以直接写路径,即@RequestMapping("/Student");==@RequestMapping(value="/Student");

2.method
用于指定请求的方法,可以设置单个或多个,如果请求方法不满足条件则会请求失败。
3.headers
headers这个参数,让人有种望文生义的感觉。看着这个单词就大概可以猜到,他是和请求头部有关,而事实上也确实是这样。用于指定请求的headers,必须要含有这个headers才可以请求。

4.可以在@RequestMapping注解中用{}来表明URL的变量部分,例如:
@RequestMapping("/users/{username}")
*/
@RequestMapping(value = "/something", method = RequestMethod.PUT)  
public void handle(@RequestBody String body, Writer writer) throws IOException {  
  writer.write(body);  
}

@RequestMapping("/goods")
public class GoodsController {

    @PostMapping(value = "/add")
    public ResultVO addGoods(){
        return null;
    }

    @DeleteMapping(value = "/{id}")
    public ResultVO deleteGoods(@PathVariable("gid") int goodsId){
        System.out.println("------"+goodsId);
        return new ResultVO(10000,"delete success",null);
    }

    @PutMapping(value = "/{id}")
    public ResultVO updateGoods(int goodsId){
        return null;
    }
}
@PathVariable 获取url中的数据
/*
在路由中定义变量规则后,通常我们需要在处理方法(也就是@RequestMapping注解的方法)中获取这个URL的具体值,并根据这个值(例如用户名)做相应的操作,SpringMVC提供的@PathVariable可以帮助我们:
*/
@GetMapping("/detail-params/{pid}")
public ResultVO getProductParams(@PathVariable("pid") String pid){

    return productService.getProductParamsById(pid);
}
@GetMapping 组合

同样有PostMapping等
@GetMapping是一个组合注解,是@RequestMapping(method = RequestMethod.GET)的缩写。该注解将HTTP Get 映射到 特定的处理方法上。

即可以使用@GetMapping(value = “/hello”)来代替@RequestMapping(value=”/hello”,method= RequestMethod.GET)。即可以让我们精简代码。

@GetMapping("/detail-commontscount/{pid}")
public ResultVO getProductCommentsCount(@PathVariable("pid") String pid){

    return productCommentsService.getCommentsCountByProductId(pid);
}

@CrossOrigin

设置可以访问跨域

Beans层或Entity层

注解
@Entity

@Entity:表明User是一个实体类,它默认对应数据库中的表名是user,你也可以指定@Entity(name = “t_users”),或者@Table(name=“t_users”)
@Id注释指定表的主键@GeneratedValue(strategy = GenerationType.IDENTITY)自增长主键生成策略
@Column注释定义了将成员属性映射到关系表中的哪一列和该列的结构信息,如@Column(name="reg_date"),将实体类regDate对应数据库中的reg_date。

@ManyToOne:多(User)对一(Address)

@Table(name = "product_params")
public class ProductParams {
    /**
     * 商品参数id
     */
    @Id
    @Column(name = "param_id")
    private String paramId;
    }

Mapper层

注解
@Mapper

整合Mybatis更为好用

@Mapper
public interface DemoMapper {  
    @Insert("insert into Demo(name) values(#{name})")  
    @Options(keyProperty="id",keyColumn="id",useGeneratedKeys=true)  
    public void save(Demo demo);  
}  

@MapperScan注解

​ 通过使用@MapperScan可以指定要扫描的Mapper类的包的路径,比如:

@SpringBootApplication  
@MapperScan("com.kfit.*.mapper")  
public class App {  
    public static void main(String[] args) {  
       SpringApplication.run(App.class, args);  
    }  
}  

Service层

注解

@service

对于 service 层的类,在类上用 @Service 注解声明

//实现类
@Service
public class shoppingCartServiceImpl implements shoppingCartService {
    @Autowired
    private ShoppingCartMapper shoppingCartMapper;

    private SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");


    @Override
    public ResultVO addShopppingCart(ShoppingCart cart) {
        cart.setCartTime(simpleDateFormat.format(new Date()));
        int i = shoppingCartMapper.insert(cart);
        if (i>0){
            return new ResultVO(ResStatus.OK,"SUCCESS",null);
        }else {
            return new ResultVO(ResStatus.NO,"FAIL",null);
        }
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    public ResultVO listShoppingCartByUserId(int userId) {
        List<ShoppingCartVO> list = shoppingCartMapper.selectShopcartByUserId(userId);
        return new ResultVO(ResStatus.OK,"SUCCESS",list);

    }
}

//接口

public interface shoppingCartService {
    public ResultVO addShopppingCart(ShoppingCart cart);
    public ResultVO listShoppingCartByUserId(int userId);
}
事务

事务(transaction)是指业务逻辑上对数据库进行的一系列持久化操作,要么全部成功,要么全部失败。

二、特性和实现

1、事务的四个基本性质(ACID)

1)原子性(Atomicity)

      事务的原子性指事务是一个不可分割的工作单位,这组操作要么全部执行,要么全部不发生。

      就拿银行转账来说,原子性指的是从A账户扣款和转账到B账户两件事一起发生,不能只发生其中一样。

2)一致性(Consistency)

      在事务开始的前后,被操作的数据的完整性都处于一致性的状态。

      还是银行转账的例子,一致性指的是在转账的前后A和B两个账户的总金额是不变的,始终保持一致。

3)隔离性(Isolation)

      多个事务并发时,事务之间是隔离的,每个事务都有自己的完整数据空间,不会影响到其他事物的运行效果。

      事务隔离性的四种隔离级别和实现原理这里就不作阐述,感兴趣的可以看以下两篇博客:

            四种隔离级别      https://blog.csdn.net/qq_33290787/article/details/51924963

            实现原理            https://blog.csdn.net/matt8/article/details/53096405

4)持久性(Durability)

      事务提交后,该事务对数据所做的修改将持久地保存在数据库,并不会回滚。

事务的原子性、一致性和持久性是通过数据库的redo/undo日志文件实现的。redo log处理系统故障,undo log处理事务回滚。如果在事务提交之后出现数据库崩溃(断电)的情况,在恢复供电时,数据库会根据重写日志对数据进行前滚。

2、事务的实现

    在Spring中,事务有两种实现方式,分别是编程式事务和声明式事务。

    编程式事务:编程式事务管理使用Transaction Template或者直接使用底层的Platform TransactionManager。对于编程式事务,Spring推荐使用Transaction Template。TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();

    声明式事务:声明式事务基于AOP,其本质是对方法前后进行拦截,在方法开始前创建或加入一个事务,再根据目标方法执行的结果决定提交还是回滚事务。只需要在类、方法加上@Transactional注解就可以使用事务,没有入侵性,简单粗暴。


一、如何改变默认规则:

1 让checked例外也回滚:在整个方法前加上 @Transactional(rollbackFor=Exception.class)

2 让unchecked例外不回滚: @Transactional(notRollbackFor=RunTimeException.class)

3 不需要事务管理的(只查询的)方法:@Transactional(propagation=Propagation.NOT_SUPPORTED)

二、spring事务传播属性

PROPAGATION_REQUIRED – 支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
PROPAGATION_SUPPORTS – 支持当前事务,如果当前没有事务,就以非事务方式执行。
PROPAGATION_MANDATORY – 支持当前事务,如果当前没有事务,就抛出异常。
PROPAGATION_REQUIRES_NEW – 新建事务,如果当前存在事务,把当前事务挂起。
PROPAGATION_NOT_SUPPORTED – 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
PROPAGATION_NEVER – 以非事务方式执行,如果当前存在事务,则抛出异常。
PROPAGATION_NESTED – 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与PROPAGATION_REQUIRED类似的操作。

三、SpringBoot 所需依赖

spring-boot-starter-parent

这个依赖是最常见的,通常用作父模块的依赖,来构建一个包含多个子模块的SpringBoot应用。在官网的解释中,它提供Springboot的默认配置,和一棵完整的SpringBoot依赖树,还包括maven的打包插件。

通过spring-boot-starter-parent依赖,在各个子模块中,我们引申的各个SpringBoot依赖甚至连版本号都可以省略,只需要指定spring-boot-starter-parent的依赖。此时,子模块的各个SpringBoot依赖会默认为父依赖中的版本。

<parent>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-parent</artifactId>
	<version>1.5.2.RELEASE</version>
</parent>

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>

spring-boot-starter-web

以spring-boot-starter-web:2.0.1.RELEASE版本为例子,它包含的依赖如下:

spring-boot-starter:2.0.1.RELEASE
Spring Boot的核心启动器,包含了自动配置、日志和YAML

spring-boot-starter-json:2.0.1.RELEASE
Spring Boot 提供了 Jackson 的自动配置,而JackJson来源于 spring-boot-starter-json这个包

spring-boot-starter-tomcat:2.0.1.RELEASE
SpringBoot封装了Tomcat,并把它作为默认的容器,当然,我们也可以进行修改为jetty,两者都是作为servlet容器,据说jetty在长连接上比较具有优势:

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jetty</artifactId>
        </dependency>
</dependencies>

hibernate-validator:6.0.9.Final

一个验证器,它可以帮我们验证一些参数的格式,譬如是否为空,是否为手机格式。

spring-web:5.0.5.RELEASE
从给出的文档中,我们可以知道,该模块会进行IOC容器的初始化工作,而且提供了其他的Web框架和HTTP技术。

spring-webmvc:5.0.5.RELEASE
spring-webmvc则是在spring-web上的进一步延伸,其实从依赖也可以看出,两者引入的依赖有重复的部分,spring-webmvc是Spring MVC的实现,如果我们不想用springMVC而只是用到其他web相关的技术,那我们可以在引入的时候将这个依赖排除。

四、SpringBoot 配置文件

配置文件

SpringBoot使用一个全局的配置文件 , 配置文件名称是固定的

application.properties
语法结构 :

key=value
application.yml
语法结构 :key:空格 value
配置文件的作用 :修改SpringBoot自动配置的默认值,因为SpringBoot在底层都自动配置好了;

YAML
YAML是 “YAML Ain’t a Markup Language” (YAML不是一种标记语言)的递归缩写。
在开发的这种语言时,YAML 的意思其实是:“Yet Another Markup Language”(仍是一种标记语言)
YAML A Markup Language :是一个标记语言
YAML isnot Markup Language :不是一个标记语言

spring:
  datasource:
    druid:
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://rm-2ze8v2149pild9r0fbo.mysql.rds.aliyuncs.com:3306/vueblog?useUnicode=true&useSSL=false&characterEncoding=utf8&serverTimezone=Asia/Shanghai
      username: root
      password: POiu0987


mybatis:
  mapper-locations: classpath:mappers/*Mapper.xml
  type-aliases-package: com.qfedu.fmmall.entity
  

五、SpringBoot整合框架

六、SpringBoot 使用Lombok 插件

Lombok 是一个可以通过简单的注解的形式来帮助我们简化消除一些必须有但显得很臃肿的 Java 代码的工具,在我们项目开发中经常使用model,entity等类,绝大部分数据类类中都需要get、set、toString等方法,一般我们需要手动的添加这些属性, 但是如果我们受到业务的变更,字段的添加,修改等操作,我们需要更改实体类,但是使用了Lombok插件,只要我们定义了变量,例如使用@Data属性,lombok会在编译的时候,自动加上get set方法。

2、Lombok 常用注解
@Data:注解在类上,相当于同时使用了@Setter+@Getter+@EqualsAndHashCode+@NoArgsConstructor+@ToString,对于POJO类十分有用
@NonNull:注解在属性/方法参数上,如果方法内对该参数进行是否为空的校验,如果为null值,则抛出NPE(NullPointerException)
@Cleanup:自动管理资源,用在局部变量之前,在当前变量范围内即将执行完毕退出之前会自动清理资源,自动生成try-finally这样的代码来关闭流
@Getter/@Setter:注解在属性上,自动生成生成setter/getter方法,final变量不包含,还可以指定访问范围
@ToString:注解在类上,可以自动覆写toString方法,当然还可以加其他参数,例如@ToString(exclude=”id”)排除id属性,或者@ToString(callSuper=true, includeFieldNames=true)调用父类的toString方法,包含所有属性
@EqualsAndHashCode:注解在类上,自动生成equals()方法和hashCode方法
@NoArgsConstructor:注解在类上,自动生成空参构造方法
@AllArgsConstructor:注解在类上,自动生成全部参数构造方法
@RequiredArgsConstructor:注解在类上,将标记为@NoNull的属性自动生成构造方法(如果运行中标记为@NoNull的属性为null,会抛出空指针异常)
@Data:注解在类上,相当于同时使用了@ToString、@EqualsAndHashCode、@Getter、@Setter和@RequiredArgsConstrutor这些注解,对于POJO类十分有用
@Value:注解在类上,是@Data的不可变形式, 两个主要区别就是如果变量不加@NonFinal ,@Value会给所有的弄成final的。当然如果是final的话,就没有set方法了。用于注解final类
@Builder:用在类、构造器、方法上,为你提供复杂的builder APIs,让你可以像如下方式一样调用Person.builder().name(“name”).city(“shanghai”).build();更多说明参考Builder
@SneakyThrows:自动抛受检异常,而无需显式在方法上使用throws语句。自动调用close方法关闭资源。
@Synchronized:用在方法上,将方法声明为同步的,并自动加锁,而锁对象是一个私有的属性 l o c k 或 lock或 lockLOCK,而java中的synchronized关键字锁对象是this,锁在this或者自己的类对象上存在副作用,就是你不能阻止非受控代码去锁this或者类对象,这可能会导致竞争条件或者其它线程错误
@Getter(lazy=true):可以替代经典的Double Check Lock样板代码
@Log:注解在类上,根据不同的注解生成不同类型的log对象,但是实例名称都是log,有六种可选实现类
@CommonsLog Creates log = org.apache.commons.logging.LogFactory.getLog(LogExample.class);
@Log Creates log = java.util.logging.Logger.getLogger(LogExample.class.getName());
@Log4j Creates log = org.apache.log4j.Logger.getLogger(LogExample.class);
@Log4j2 Creates log = org.apache.logging.log4j.LogManager.getLogger(LogExample.class);
@Slf4j Creates log = org.slf4j.LoggerFactory.getLogger(LogExample.class);
@XSlf4j Creates log = org.slf4j.ext.XLoggerFactory.getXLogger(LogExample.class);

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

whr133464

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值