springboot笔记整理(超详细,手把手教程!)

(建议配合哔哩哔哩狂神说springboot食用,有问题一起来交流吧🐧:504863638)

微服务阶段

javase:OOP

mysql:持久化

html+css+js+jquery+框架:视图

javaweb:独立开发MVC三层架构的网站:原始

ssm:框架:简化了开发流程,配置也开始较为复杂

war包:tomcat运行
spring再简化:springboot-jar:内嵌tomcat;微服务架构

服务越来越多:springcould

新服务架构:服务网格!

约定大于配置

springboot

  • 开箱即用
  • 内嵌式容器简化web项目
  • 没有冗余代码生成和XML配置的要求

微服务是一种架构风格

高内聚低耦合

第一个springboot

环境:

  • jdk1.8
  • maven 3.6.1
  • springboot:最新版
  • IDEA

配置springboot 启动彩蛋

springboot banner网站:https://www.bootschool.net/ascii

在resource中新建文件banner.txt 给文件的内容则为启动彩蛋

修改端口号

在resource文件夹中的application.properties文件中添加:

server.port=xxxx

原理初探

自动装配:

pom.xml

  • spring-boot-dependencies:核心依赖在父工程中

  • <dependency>
    	<groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
    </dependency>
    
  • 启动器:SpringBoot的启动场景

  • 如spring-boot-starter-web,会自动导入web环境所有的依赖

  • springboot会将所有的功能场景,都变成一个个启动器

  • 想要使用什么功能,就只需要找到对应的启动器 starter

主程序
@SpringBootApplication:标注这个类是一个SpringBoot的应用
@SpringBootApplication
public class SpringbootApplication {

    public static void main(String[] args) {
   //将SpringBoot应用启动
        SpringApplication.run(SpringbootApplication.class, args);
    }
}

  • 注解

    • 补:注解和反射

    • //定义该注解在那个位置可以生效
      @Target(value = {ElementType.MEthod,ElementType.TYPE})//标识注解什么时候还有效runtime>class>source
      @Retention(value = RetentionPolicy.RUNTIME)
      //表示是否将该注解生成在JAVAdoc中
      @Documented
      //子类可以继承父类的注解
      @inherited
      
    • @SpringBootConfiguration:springboot的配置
          @Configuration:spring配置类
          @Component:说明这也是一个spring组件
      
      @EnableAutoConfiguration:自动配置
          @AutoConfigurationPackage:自动配置包
              @Import({Registrar.class}) :自动配置`包注册`
          @Import({AutoConfigurationImportSelector.class}):自动配置导入选择
              
      //获取所有的配置
      List<String>configurations=this.getCandidateConfigurations(annotationMetadata, attributes);
      
      • 获取候选的配置

        protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
                List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());
                Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.");
                return configurations;
            }
        
      • META-INF/spring.factories:自动配置的核心文件[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cE6IQv8y-1617241215055)(C:\Users\advancer\AppData\Roaming\Typora\typora-user-images\image-20210225232052715.png)]

    • Properties properties = PropertiesLoaderUtils.loadProperties(resource);
      
    • 结论:springboot所有自动装配都是在启动的时候扫描并加载:spring.factories所有的自动配置类都在这里面,但是不一定生效,要判断条件是否成立,只要导入了对应的start,就有对应的启动器了,有了启动器,自动装配就会生效,然后配置成功。

      1. springboot在启动的时候,从类路径下/META-INF/spring.factories获取指定的值;
      2. 将这些自动配置的类导入容器,自动配置就会生效,进行自动配置!
      3. 以前我们需要自动配置的东西,springboot帮我们做了
      4. 整合javaEE,解决方案和自动配置的东西都在spring-boot-autoconfigure-2.2.0.RELEASE.jar这个包下
      5. 他会把所有需要导入的组件,一类名的方式返回,这些组件就会被添加到容器
      6. 容器中也会存在非常多的xxxAutoCofiguration的文件(@Bean),就是这些类给容器中导入了这个场景所需要的所有组件,并自动配置。@Configuration,JavaConfig
      7. 有了自动配置类,免去了我们手动编写配置文件的工作
  • run

    • JavaConfig @Configuration(配置) @Bean(组件)

Docker:进程

关于springboot的理解:

  1. 自动装配
  2. run();(重构才会用到)

springCloud 全面接管springMVC的配置

SpringBoot配置

使用yaml文件

#对空格要求高

#k = v
#普通的 k-v
name: root

#对象
student1:
  name: root
  age: 21

#行内写法(对象用{},数组用[])
student2: {name: root,age: 21}

#数组
pets1:
  - cat
  - dog
  - pig

pets2: [cat, dog, pig]

yaml可以给实体类赋值

package com.ljq.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @author advancer
 * @create 2021-02-26   23:44
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@Component
//@PropertySource(value = "classpath:properties.properties")
@ConfigurationProperties(prefix = "person")
public class Person {
    /**
     * SPEL表达式,取出配置文件的值
     */
//    @Value(value = "${name}")
    private String name;
    private Integer age;
    private Boolean happy;
    private Date birth;
    private Map<String, Object> maps;
    private List<Object> lists;
    private Dog dog;
}

application.yaml

其中还可以使用SPEL表达式获取值

person:
  name: ljq${random.uuid}
  age: 21
  happy: false
  birth: 1999/12/17
  maps: {k1: v1, k2: v2}
#  hello: asd
  lists:
    - code
    - music
    - girl
  dog:
    name: ${person.hello:happy}_旺财
    age: 3

不局限于pojo类 例如mysql的配置就可以使用

使用properties文件

package com.ljq.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @author advancer
 * @create 2021-02-26   23:44
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@Component
//加载是定的配置文件
@PropertySource(value = "classpath:properties.properties")
//@ConfigurationProperties(prefix = "person")
public class Person {
    /**
     * SPEL表达式,取出配置文件的值
     */
    @Value(value = "${name}")
    private String name;
    private Integer age;
    private Boolean happy;
    private Date birth;
    private Map<String, Object> maps;
    private List<Object> lists;
    private Dog dog;
}
name = abc

javaConfig可以采用以上两种方式,绑定配置文件的值

**配置文件读取顺序:yml -> yaml -> properties,所以,如果都配置了同名的配置,以properties为准,因为后读取的会覆盖前面的。优先级:properties>yaml >yml **

对比

img

小结

1、@ConfigurationProperties只需要写一次即可 , @Value则需要每个字段都添加

2、松散绑定:这个什么意思呢? 比如我的yml中写的last-name,这个和lastName是一样的, - 后面跟着的字母默认是大写的。这就是松散绑定。可以测试一下

3、JSR303数据校验 , 这个就是我们可以在字段是增加一层过滤器验证 , 可以保证数据的合法性

4、复杂类型封装,yml中可以封装对象 , 使用value就不支持

结论:

配置yml和配置properties都可以获取到值 , 强烈推荐 yml;

如果我们在某个业务中,只需要获取配置文件中的某个值,可以使用一下 @value;

如果说,我们专门编写了一个JavaBean来和配置文件进行一一映射,就直接@configurationProperties,不要犹豫!

JSR303
@Validated  //数据校验,需要添加数据校验启动器
  1. 常见参数
@NotNull(message="名字不能为空")
private String userName;
@Max(value=120,message="年龄最大不能查过120")
private int age;
@Email(message="邮箱格式错误")
private String email;

空检查
@Null       验证对象是否为null
@NotNull    验证对象是否不为null, 无法查检长度为0的字符串
@NotBlank   检查约束字符串是不是Null还有被Trim的长度是否大于0,只对字符串,且会去掉前后空格.
@NotEmpty   检查约束元素是否为NULL或者是EMPTY.
    
Booelan检查
@AssertTrue     验证 Boolean 对象是否为 true  
@AssertFalse    验证 Boolean 对象是否为 false  
    
长度检查
@Size(min=, max=) 验证对象(Array,Collection,Map,String)长度是否在给定的范围之内  
@Length(min=, max=) string is between min and max included.

日期检查
@Past       验证 Date 和 Calendar 对象是否在当前时间之前  
@Future     验证 Date 和 Calendar 对象是否在当前时间之后  
@Pattern    验证 String 对象是否符合正则表达式的规则

.......等等
除此以外,我们还可以自定义一些数据校验规则

多环境配置以及文件位置

多环境

开发环境dev 测试环境test 生产环境pro

properties配置文件

我们在主配置文件编写的时候,文件名可以是 application-{profile}.properties/yml , 用来指定多个环境版本;

例如:

application-test.properties 代表测试环境配置

application-dev.properties 代表开发环境配置

但是Springboot并不会直接启动这些配置文件,它默认使用application.properties主配置文件

我们需要通过一个配置来选择需要激活的环境:

#比如在配置文件中指定使用dev环境,我们可以通过设置不同的端口号进行测试;
#我们启动SpringBoot,就可以看到已经切换到dev下的配置了;
spring.profiles.active=dev

yaml的多文档块

和properties配置文件中一样,但是使用yml去实现不需要创建多个配置文件,更加方便了 !

server:
  port: 8081
#选择要激活那个环境块
spring:
  profiles:
    active: prod

---
server:
  port: 8083
spring:
  profiles: dev #配置环境的名称


---

server:
  port: 8084
spring:
  profiles: prod  #配置环境的名称

注意:如果yml和properties同时都配置了端口,并且没有激活其他环境 , 默认会使用properties配置文件的!

文件位置

配置文件可以放到以下四个位置 并且有优先级区分

优先级:file:./config > file: ./ > classpath./config > classpath./

自动配置原理

xxxAutoConfiguration中的注解
//表示这是一个配置类,和以前编写的配置文件一样,也可以给容器中添加组件;
@Configuration 

//启动指定类的ConfigurationProperties功能;
  //进入这个HttpProperties查看,将配置文件中对应的值和HttpProperties绑定起来;
  //并把HttpProperties加入到ioc容器中
@EnableConfigurationProperties({HttpProperties.class}) 

//Spring底层@Conditional注解
  //根据不同的条件判断,如果满足指定的条件,整个配置类里面的配置就会生效;
  //这里的意思就是判断当前应用是否是web应用,如果是,当前配置类生效
@ConditionalOnWebApplication(
    type = Type.SERVLET
)

//判断当前项目有没有这个类CharacterEncodingFilter;SpringMVC中进行乱码解决的过滤器;
@ConditionalOnClass({CharacterEncodingFilter.class})

//判断配置文件中是否存在某个配置:spring.http.encoding.enabled;
  //如果不存在,判断也是成立的
  //即使我们配置文件中不配置pring.http.encoding.enabled=true,也是默认生效的;
@ConditionalOnProperty(
    prefix = "spring.http.encoding",
    value = {"enabled"},
    matchIfMissing = true
)

定义bean

下面是@Configuration里的一个例子

//@Bean是一个方法级别上的注解,主要用在@Configuration注解的类里,也可以用在@Component注解的类里。添加的bean的id为方法名
@Configuration
public class AppConfig {

    @Bean
    public TransferService transferService() {
        return new TransferServiceImpl();
    }

}

这个配置就等同于之前在xml里的配置

<beans>
    <bean id="transferService" class="com.acme.TransferServiceImpl"/>
</beans>

根据当前不同的条件判断,决定这个配置类是否生效!

  • 一但这个配置类生效;这个配置类就会给容器中添加各种组件;
  • 这些组件的属性是从对应的properties类中获取的,这些类里面的每一个属性又是和配置文件绑定的;
  • 所有在配置文件中能配置的属性都是在xxxxProperties类中封装着;
  • 配置文件能配置什么就可以参照某个功能对应的这个属性类
//从配置文件中获取指定的值和bean的属性进行绑定
@ConfigurationProperties(prefix = "spring.http") 
public class HttpProperties {
    // .....
}

总结

1、SpringBoot启动会加载大量的自动配置类

2、我们看我们需要的功能有没有在SpringBoot默认写好的自动配置类当中;

3、我们再来看这个自动配置类中到底配置了哪些组件;(只要我们要用的组件存在在其中,我们就不需要再手动配置了)

4、给容器中自动配置类添加组件的时候,会从properties类中获取某些属性。我们只需要在配置文件中指定这些属性的值即可;

**xxxxAutoConfigurartion:自动配置类;**给容器中添加组件

xxxxProperties:封装配置文件中相关属性;

了解:@Conditional

了解完自动装配的原理后,我们来关注一个细节问题,自动配置类必须在一定的条件下才能生效;

@Conditional派生注解(Spring注解版原生的@Conditional作用)

作用:必须是@Conditional指定的条件成立,才给容器中添加组件,配置配里面的所有内容才生效;

img

那么多的自动配置类,必须在一定的条件下才能生效;也就是说,我们加载了这么多的配置类,但不是所有的都生效了。

我们怎么知道哪些自动配置类生效?

我们可以通过启用 debug=true属性;来让控制台打印自动配置报告,这样我们就可以很方便的知道哪些自动配置类生效;

#开启springboot的调试类
debug=true

Positive matches:(自动配置类启用的:正匹配)

Negative matches:(没有启动,没有匹配成功的自动配置类:负匹配)

Unconditional classes: (没有条件的类)

如果没有生效就需要导入所需要类的启动器

SpringBoot Web开发

前端:

模板:

别人写好的,我们拿来改成自己需要的

框架:

组件:自己动手组装拼接! bootstrap,Layui,semantic-ui

  • 栅格系统
  • 导航栏
  • 侧边栏
  • 表单

写一个网页大体步骤

  1. 前端:页面长什么样子:数据
  2. 设计数据库(数据库设计,难点!)
  3. 前端独立运行,独立化工程
  4. 数据决口如何对接:json,对象 all in one!
  5. 前后端联调测试!

1、开发一套自己的后台模板:工作必要!

2、前端界面:至少能够通过前端框架,组合出来一个网站页面

  • index
  • about
  • blog
  • post
  • user

3、让这个网站能够独立运行

导入静态资源

存放文件夹

在文件夹resources下可以再建resouces static public三种文件夹来存放静态文件

访问优先级

  • 首先访问public文件夹下的,其次访问static下的,最后访问resources下的
  • 所以优先级顺序为resouces>static>public

小结:

  1. 在springboot下可以使用以下方式处理静态资源
    • webjars(不常用) localhost:8080/webjars/
    • public, static, /**, resource localhost:8080/
  2. 优先级:
    • resouces>static(默认)>public

首页

​ 在静态资源文件夹中添加index.html就可以自动进行访问

jsp, 使用模板引擎Thymeleaf

​ jsp成为过去流行技术,不利于前后端分离

使用模板引擎可以将静态页面进行动态结合

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ClN0s1os-1617241215059)(C:\Users\advancer\AppData\Roaming\Typora\typora-user-images\image-20210305130448942.png)]

添加thymeleaf启动器

需要注意版本是否出错

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

标准表达式

简单表达
  变量表达式: ${…}
  选择变量表达式: *{…}
  消息表达式: #{…}
  链接网址表达式: @{…}
  片段表达式: ~{…}

字面
  文本文字:‘one text’,‘Another one!’,…
  号码文字:0,34,3.0,12.3,…
  布尔文字:true,false
  空字面: null
  文字标记:one,sometext,main,…
  文字操作:
  字符串连接: +
  文字替换: |The name is ${name}|

算术运算
  二元运算符:+,-,*,/,%
  减号(一元运算符): -

布尔运算
  二元运算符:and,or
  布尔否定(一元运算符): !,not

比较和平等
  比较:>,<,>=,<=(gt,lt,ge,le)
  等值运算符:==,!=(eq,ne)

条件运算符
  if-then: (if) ? (then)
  if-then-else: (if) ? (then) : (else)
  default: (value) ?: (defaultvalue)

特殊特征符
  无操作: _

所有这些功能都可以组合和嵌套,例:
  'User is of type ’ + (user.isAdmin()?′Administrator′:(user.isAdmin()?′Administrator′😦{user.type} ?: ‘Unknown’))

例子
//设置model   
public String hello(Model model) {
    model.addAttribute("a", "this is a message!");
    return "test";
}
<!-- 引入命名空间,避免校验错误 -->
<html xmlns:th="http://www.thymeleaf.org">
<!-- 使用方法th:text="${}" -->
<h3 th:text="${a}"></h3>

img

小结

只需要使用thymeleaf,只需要导入依赖即可。我们将html放入templates目录下即可!

public static final String DEFAULT_PREFIX = "classpath:/templates/";

	public static final String DEFAULT_SUFFIX = ".html";

装配扩展SpringMVC

修改springboot的默认设置

方式一:

通过webmvc的自动配置原理分析,通过源码探究,得出结论。springboot在自动配置很多组件的时候,先看容器中有没有自己配置的(如果用户自己配置@Bean),如果有就用用户配置的,如果没有就用自动配置的;如果有些组件可以存在多个,比如视图解析器,就将用户配置和自己默认的组合起来。

拓展springmvc dispatchservlet如果想自定义一些定制化功能,只要写这个组件,然后将他交给springboot,springboot会帮我们自动装配

/**
 * 拓展springmvc  dispatchservlet
 * 如果想自定义一些定制化功能,只要写这个组件,然后将他交给springboot,springboot会帮我们自动装配
 */

@Configuration
public class MyConfig implements WebMvcConfigurer {
    /**
     * ViewResolver 实现了视图解析器接口的类,我们就可以把他看作视图解析器
     */
    public ViewResolver myViewResolver(){
        return new MyViewResolver();
    }

    /**
     * 自定义视图解析器,该视图解析器与默认视图解析器共存
     */
    public static class MyViewResolver implements ViewResolver{
        @Override
        public View resolveViewName(String viewName, Locale locale) throws Exception {
            return null;
        }
    }
}
方式二:

编写一个@Configuration注解类,并且类型要为WebMvcConfigurer(接口),而且不能标注@EnableWebMvc注解

如果我们要扩展springmvc,官方建议我们这样做

@Configuration
public class MyConfig implements WebMvcConfigurer {
    /**
     * 视图跳转
     */
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
       registry.addViewController("/ljq").setViewName("test");
    }
}

如果标注了@EnableWebMvc注解,其中WebMvcAutoConfiguration.java中的@ConditionalOnMissingBean注解将会导致该类失效。

小结:

在springboot中,有非常多的xxxConfiguration帮助我们进行扩展配置,只要看见了这个东西,我们就要注意了!

拦截器

实现HandlerInterceptor接口

重写preHandle方法
public class LoginHandlerInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //使用request获取session再获取属性
        //通过属性进行一些列判断
        return false/true;
    }
}
在MyConfig中配置
registry.addInterceptor(new LoginHandlerInterceptor())//新建对象,配置
                .addPathPatterns("/**")//添加拦截对象
                .excludePathPatterns("/", "/login", "/login.html", "/user/login", "/css/*",
                        "/images/*", "/js/*", "/plugins/*", "/scss/*");//排除放行对象

是否从/static开始,是否静态资源自动被放过

国际化

创建配置文件

  1. 创建国际化文件夹:i18n

  2. 新建配置文件:xxx.properties, xxx_en_US.properties, xxx_zh_CN.properties

  3. 创建第二个文件时自动合并为Resource Bundle ‘xxx’

  4. 两种方式设置

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WwSd5Igm-1617241215061)(C:\Users\ advancer\AppData\Roaming\Typora\typora-user-images\image-20210311210424741.png)]

html文件设置

<input type="text" th:placeholder="#{login.username}" class="border p-3 w-100 my-2">
<input type="password" th:placeholder="#{login.password}" class="border p-3 w-100 my-2">
<div class="loggedin-forgot">
     <input type="checkbox" id="keep-me-logged-in">
     <label for="keep-me-logged-in" class="pt-3 pb-2" th:value="#{login.rememberme}">
         Keep me loggedin</label>
</div>
  • 使用thymeleaf获取配置文件中的国际化配置

  • 语法:th:placeholder="#{login.username}"
    [[#{login.username}]]
    

在html文件中添加中英文切换按钮

<a th:href="@{login.html(l='zh_CN')}">中文</a>
/
<a th:href="@{login.html(l='en_US')}">English</a>

创建类实现LocaleResolver接口

默认AcceptHeaderLocaleResolver实现了LocaleResolve接口,可以根据这个类中重写的resolveLocale()方法中找到一定的逻辑。

重写接口中的方法resolveLocale(HttpServletRequest request)
  @Override
  public Locale resolveLocale(HttpServletRequest request) {
      //获取请求中的语言参数
      String la	nguage = request.getParameter("l");

      Locale locale = Locale.getDefault();

      //判断是否为国际化请求
      if (!StringUtils.isEmpty(language)){

          System.out.println(language);

          //获取国家/地区
          String[] split = language.split("_");

          locale = new Locale(split[0], split[1]);
          System.out.println("split:" + split[0] + "      |||||split[0]:" + split[1]);
      }

      return locale;
  }

在配置类中将这个类放入bean中

    @Bean
    public LocaleResolver localeResolver(){
        return new MylocaleResolve();
    }

增删改查

提取公共页面
  • 提取
    • th:fragment=“sidebar”
  • 使用
    1. th:replace="~{commons/common::sidebar} 替换元素
    2. th:insert="~{commons/common::sidebar(active=‘main’)} 在元素中插入
    3. 如果要传参数,可以直接使用()传参,接受判断即可
列表循环展示
  • th:each=“emp:${allEmps}” 循环取值
  • 取属性

  1. 可以使用GetMapping进入到曾加页面
  2. 再通过PostMapping处理从前端获取到的信息

404界面

  1. 再templates下创建一个新文件夹error
  2. 将404页面、500页面放入该文件夹中,springboot会自动配置进去

JDBC

项目导入了如下的启动器:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>

编写yaml配置文件连接数据库

spring:
  datasource:
    username: root
    password: 123456
    #?serverTimezone=UTC解决时区的报错
    url: jdbc:mysql://localhost:3306/springboot?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
    driver-class-name: com.mysql.cj.jdbc.Driver

直接使用

输出当前datasource类:HikariDataSource

HikariDataSource 号称 Java WEB 当前速度最快的数据源,相比于传统的 C3P0 、DBCP、Tomcat jdbc 等连接池更加优秀;

@RestController
@RequestMapping("/jdbc")
public class JdbcController {
    /**
     * Spring Boot 默认提供了数据源,默认提供了 org.springframework.jdbc.core.JdbcTemplate
     * JdbcTemplate 中会自己注入数据源,用于简化 JDBC操作
     * 还能避免一些常见的错误,使用起来也不用再自己来关闭数据库连接
     */
    @Autowired
    JdbcTemplate jdbcTemplate;
    //查询employee表中所有数据
    //List 中的1个 Map 对应数据库的 1行数据
    //Map 中的 key 对应数据库的字段名,value 对应数据库的字段值
    @GetMapping("/list")
    public List<Map<String, Object>> userList(){
        String sql = "select * from employee";
        List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql);
        return maps;
    }

Druid(重点)

在配置好jdbc的基础上

导入依赖

 <!--log4j-->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>

        <!-- druid -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.5</version>
        </dependency>

配置yml配置

现在这些配置还不能生效

    #Spring Boot 默认是不注入这些属性值的,需要自己绑定
    #druid 数据源专有配置
    initialSize: 5
    minIdle: 5
    maxActive: 20
    maxWait: 60000
    timeBetweenEvictionRunsMillis: 60000
    minEvictableIdleTimeMillis: 300000
    validationQuery: SELECT 1 FROM DUAL
    testWhileIdle: true
    testOnBorrow: false
    testOnReturn: false
    poolPreparedStatements: true

    #配置监控统计拦截的filters,stat:监控统计、log4j:日志记录、wall:防御sql注入
    #如果允许时报错  java.lang.ClassNotFoundException: org.apache.log4j.Priority
    #则导入 log4j 依赖即可,Maven
    filters: stat,wall,log4j
    maxPoolPreparedStatementPerConnectionSize: 20
    useGlobalDataSourceStat: true
    connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500

配置DruidConfig.java

配置这些之后可以使yml文件的上述配置生效

@Configuration//配置文件标识哦!
public class DruidConfig {
    /*
       将自定义的 Druid数据源添加到容器中,不再让 Spring Boot 自动创建
       绑定全局配置文件中的 druid 数据源属性到 com.alibaba.druid.pool.DruidDataSource从而让它们生效
       @ConfigurationProperties(prefix = "spring.datasource"):作用就是将 全局配置文件中
       前缀为 spring.datasource的属性值注入到 com.alibaba.druid.pool.DruidDataSource 的同名参数中
     */
    @ConfigurationProperties(prefix = "spring.datasource")
    @Bean
    public DataSource druidDataSource(){
        return new DruidDataSource();
    }
    //后台监控(固定模式) 相当于web.xml, ServletRegistrationBean
    //因为springBoot内置了servlet容器,所以没有web.xml,替代方法:ServletRegistrationBean
    @Bean
    public ServletRegistrationBean statViewServlet(){
        ServletRegistrationBean<StatViewServlet> bean = new ServletRegistrationBean<>(new StatViewServlet(), "/druid/*");

        //后台需要有人登录,账号密码配置
        HashMap<String, String> initParameters = new HashMap<>();
        //增加配置
        initParameters.put("loginUsername", "admin");
        initParameters.put("loginPassword", "1234");

        //允许谁能访问
        initParameters.put("allow", "");
        //禁止谁能访问initParameters.put("user1", "192.168.xx.xxx");

        bean.setInitParameters(initParameters);//初始化参数
        return bean;
    }
    //配置过滤器
    public FilterRegistrationBean webStatFilter() {
        FilterRegistrationBean<Filter> bean = new FilterRegistrationBean<>();

        bean.setFilter(new WebStatFilter());

        //可以过滤的请求
        Map<String, String> initParameters = new HashMap<>();

        //这些东西不进行统计
        initParameters.put("exclusions", "*.js, *.css, /druid/*");

        bean.setInitParameters(initParameters);

        return bean;
    }
}

可以登录http://localhost:8080/druid/login.html来进行后台管理

Mybatis(重点)

导入相关依赖

<!-- mybatis-spring-boot-starter -->
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.1.4</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>

在有实体类pojo的前提下

映射接口与映射文件

创建接口

在com.ljq.mapper中创建BookMapper.java

@Repository
@Mapper//表示这是一个mybatis的mapper类
public interface BookMapper {
    List<Book> queryBooks();
}
创建映射配置文件

在resource文件夹下BookMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ljq.mapper.BookMapper">
    <select id="queryBooks" resultType="com.ljq.pojo.Book"><!--在配置完mybatis:mapper-locations后可以直接写为 resultType="Book"-->
        select * from book
    </select>
</mapper>

整合mybatis

在配置文件application.yml中添加语句

#整合mybatis
mybatis:
#配置文件所在位置
  mapper-locations: classpath:mybatis/mapper/*.xml
#使用type-aliases-package中指定entity扫描包类让mybatis自定扫描到自定义的entity。
  type-aliases-package: com.ljq.pojo 

调用dao层

BookController.java

@RestController
public class BookController {
    @Autowired
    BookMapper bookMapper;

    //查询数据库的所有信息
    @GetMapping("/list")
    public List<Book> bookList() {
        List<Book> maps = bookMapper.queryBooks();
        return maps;
    }
}
评论 2 您还未登录,请先 登录 后发表或查看评论

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:游动-白 设计师:我叫白小胖 返回首页

打赏作者

adwaiter

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

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

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

打赏作者

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

抵扣说明:

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

余额充值