SpringBoot

自动装配原理:springboot是通过main方法下的SpringApplication.run方法启动的,启动的时候他会调用refshContext方法,先刷新容器,然后根据解析注解或者解析配置文件的形式祖册bean,而它是通过启动类的SpringBootApplication注解进行开始解析的,他会根据EnableAutoConfiguration开启自动化配置,里面有个核心方法ImportSelect选择性的导入,根据loadFanctoryNames根据classpash路径以MATA-INF/spring.factorces下面以什么什么EnableAutoConfiguration开头的key去加载里面所有对应的自动化配置,他并不是把这一百二十多个自动化配置全部导入,在他每个自动化配置里面都有条件判断注解,先判断是否引入相互的jar包,再判断容器是否有bean再进行注入到bean容器

一、基础入门

依赖管理特性

父项目做依赖管理

依赖管理
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.3.4.RELEASEversion>
parent>

上面项目的父项目如下:
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-dependenciesartifactId>
<version>2.3.4.RELEASEversion>
parent>
它几乎声明了所有开发中常用的依赖的版本号,自动版本仲裁机制

开发导入starter场景启动器:

  • 见到很多 spring-boot-starter-就某种场景
  • 只要引入starter,这个场景的所有常规需要的依赖我们都自动引入
  • 更多SpringBoot所有支持的场景
  • 见到的 *-spring-boot-starter: 第三方为我们提供的简化开发的场景启动器。
所有场景启动器最底层的依赖

<dependency>

<groupId>org.springframework.bootgroupId>

<artifactId>spring-boot-starterartifactId>

<version>2.3.4.RELEASEversion>

<scope>compilescope>

dependency>

无需关注版本号,自动版本仲裁

  1. 引入依赖默认都可以不写版本
  2. 引入非版本仲裁的jar,要写版本号。

可以修改默认版本号

  1. 查看spring-boot-dependencies里面规定当前依赖的版本 用的 key。
  2. 在当前项目里面重写配置,如下面的代码。
<properties>
<mysql.version>5.1.43mysql.version>
properties>

自动配置特性

  • 自动配好Tomcat

  • 引入Tomcat依赖。

  • 配置Tomcat
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-tomcatartifactId>
<version>2.3.4.RELEASEversion>
<scope>compilescope>
dependency>
  • 自动配好SpringMVC

  • 引入SpringMVC全套组件

  • 自动配好SpringMVC常用组件(功能)

  • 自动配好Web常见功能,如:字符编码问题

  • SpringBoot帮我们配置好了所有web开发的常见场景

  • 默认的包结构

  • 默认扫描主程序所在的包中的组件和下面的所有子包

    [En]

    the components in the package where the main program is located and all the subpackages below will be scanned by default*

  • 无需以前的包扫描配置
  • 想要改变扫描路径,@SpringBootApplication(scanBasePackages= “com.atguigu”)

  • 或者@ComponentScan 指定扫描路径

@SpringBootApplication等同于@SpringBootConfiguration@EnableAutoConfiguration@ComponentScan("com.atguigu.boot")
  • 各种配置拥有默认值

  • 默认配置最终都是映射到某个类上,如:MultipartProperties

  • 配置文件的值最终绑定到每个类,从而在容器中创建一个对象

    [En]

    the value of the configuration file is eventually bound to each class, which creates an object in the container*

  • 按需加载所有自动配置项

二、容器功能

2.1、组件添加

1、@Configuration

  • 基本使用
  • *Full模式与Lite模式

  • 示例

  • 最佳实战

  • 配置 类组件之间无依赖关系用Lite模式加速容器启动过程,减少判断

  • 配置类组件之间有依赖关系,方法会被调用得到之前单实例组件,用Full模式
#############################Configuration使用示例######################################################/** * 1、配置类里面使用@Bean标注在方法上给容器注册组件,默认也是单实例的 * 2、配置类本身也是组件 * 3、proxyBeanMethods:代理bean的方法 *      Full(proxyBeanMethods = true)、【保证每个@Bean方法被调用多少次返回的组件都是单实例的】 *      Lite(proxyBeanMethods = false)【每个@Bean方法被调用多少次返回的组件都是新创建的】 *      组件依赖必须使用Full模式默认。其他默认是否Lite模式 * * * */@Configuration(proxyBeanMethods = false) //告诉SpringBoot这是一个配置类 == 配置文件public class MyConfig {    /**     * Full:外部无论对配置类中的这个组件注册方法调用多少次获取的都是之前注册容器中的单实例对象     * @return     */    @Bean //给容器中添加组件。以方法名作为组件的id。返回类型就是组件类型。返回的值,就是组件在容器中的实例    public User user01(){        User zhangsan = new User("zhangsan", 18);        //user组件依赖了Pet组件        zhangsan.setPet(tomcatPet());        return zhangsan;    }    @Bean("tom")    public Pet tomcatPet(){        return new Pet("tomcat");    }}################################@Configuration测试代码如下########################################@SpringBootConfiguration@EnableAutoConfiguration@ComponentScan("com.atguigu.boot")public class MainApplication {    public static void main(String[] args) {        //1、返回我们IOC容器        ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);        //2、查看容器里面的组件        String[] names = run.getBeanDefinitionNames();        for (String name : names) {            System.out.println(name);        }        //3、从容器中获取组件        Pet tom01 = run.getBean("tom", Pet.class);        Pet tom02 = run.getBean("tom", Pet.class);        System.out.println("组件:"+(tom01 == tom02));        //4、com.atguigu.boot.config.MyConfig$$EnhancerBySpringCGLIB$$51f1e1ca@1654a892        MyConfig bean = run.getBean(MyConfig.class);        System.out.println(bean);        //如果@Configuration(proxyBeanMethods = true)代理对象调用方法。SpringBoot总会检查这个组件是否在容器中有。        //保持组件单实例        User user = bean.user01();        User user1 = bean.user01();        System.out.println(user == user1);        User user01 = run.getBean("user01", User.class);        Pet tom = run.getBean("tom", Pet.class);        System.out.println("用户的宠物:"+(user01.getPet() == tom));    }}

2、@Bean、@Component、@Controller、@Service、@Repository

3、@ComponentScan、@Import

* 4、@Import({User.class, DBHelper.class}) *      给容器中自动创建出这两个类型的组件、默认组件的名字就是全类名 * * * */@Import({User.class, DBHelper.class})@Configuration(proxyBeanMethods = false) //告诉SpringBoot这是一个配置类 == 配置文件public class MyConfig {}

@Import 高级用法: ​​https://www.bilibili.com/video/BV1gW411W7wy?p=8​

4、@Conditional

条件装配:满足Conditional指定的条件,则进行组件注入

SpringBoot
=====================测试条件装配==========================@Configuration(proxyBeanMethods = false) //告诉SpringBoot这是一个配置类 == 配置文件//@ConditionalOnBean(name = "tom")@ConditionalOnMissingBean(name = "tom")public class MyConfig {    /**     * Full:外部无论对配置类中的这个组件注册方法调用多少次获取的都是之前注册容器中的单实例对象     * @return     */    @Bean //给容器中添加组件。以方法名作为组件的id。返回类型就是组件类型。返回的值,就是组件在容器中的实例    public User user01(){        User zhangsan = new User("zhangsan", 18);        //user组件依赖了Pet组件        zhangsan.setPet(tomcatPet());        return zhangsan;    }    @Bean("tom22")    public Pet tomcatPet(){        return new Pet("tomcat");    }}public static void main(String[] args) {        //1、返回我们IOC容器        ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);        //2、查看容器里面的组件        String[] names = run.getBeanDefinitionNames();        for (String name : names) {            System.out.println(name);        }        boolean tom = run.containsBean("tom");        System.out.println("容器中Tom组件:"+tom);        boolean user01 = run.containsBean("user01");        System.out.println("容器中user01组件:"+user01);        boolean tom22 = run.containsBean("tom22");        System.out.println("容器中tom22组件:"+tom22);    }

2.2、原生配置文件引入

1、@ImportResource

======================beans.xml=========================
versinotallow="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

<bean id="haha" class="com.atguigu.boot.bean.User">
<property name="name" value="zhangsan">property>
<property name="age" value="18">property>
bean>

<bean id="hehe" class="com.atguigu.boot.bean.Pet">
<property name="name" value="tomcat">property>
bean>
beans>
@ImportResource("classpath:beans.xml")public class MyConfig {}======================测试=================        boolean haha = run.containsBean("haha");        boolean hehe = run.containsBean("hehe");        System.out.println("haha:"+haha);//true        System.out.println("hehe:"+hehe);//true

2.3、配置绑定

如何使用Java读取到properties文件中的内容,并且把它封装到JavaBean中,以供随时使用;

public class getProperties {     public static void main(String[] args) throws FileNotFoundException, IOException {         Properties pps = new Properties();         pps.load(new FileInputStream("a.properties"));         Enumeration enum1 = pps.propertyNames();//得到配置文件的名字         while(enum1.hasMoreElements()) {             String strKey = (String) enum1.nextElement();             String strValue = pps.getProperty(strKey);             System.out.println(strKey + "=" + strValue);             //封装到JavaBean。         }     } }

1、@ConfigurationProperties

/** * 只有在容器中的组件,才会拥有SpringBoot提供的强大功能 */@Component@ConfigurationProperties(prefix = "mycar")public class Car {    private String brand;    private Integer price;    public String getBrand() {        return brand;    }    public void setBrand(String brand) {        this.brand = brand;    }    public Integer getPrice() {        return price;    }    public void setPrice(Integer price) {        this.price = price;    }    @Override    public String toString() {        return "Car{" +                "brand='" + brand + '\'' +                ", price=" + price +                '}';    }}

2、@EnableConfigurationProperties + @ConfigurationProperties

3、@Component + @ConfigurationProperties

@EnableConfigurationProperties(Car.class)//1、开启Car配置绑定功能//2、把这个Car这个组件自动注册到容器中public class MyConfig {}

三、自动配置原理入门

总结:

  • SpringBoot先加载所有的自动配置类 xxxxxAutoConfiguration
  • 每个自动配置类按照条件进行生效,默认都会绑定配置文件指定的值。xxxxProperties里面拿。xxxProperties和配置文件进行了绑定
  • 生效的配置类将许多组件组装到容器中
    [En]

    configuration classes that are in effect will assemble many components into the container*

  • 只要容器中有这些组件,它们就等同于这些功能。
    [En]

    as long as there are these components in the container, they are equivalent to these functions.*

  • 定制化配置

  • 用户直接自己@Bean替换底层的组件

  • 修改组件获取的配置文件的值。
    [En]

    the user will modify the value of the configuration file obtained by the component.*

xxxxxAutoConfiguration —> 组件 —> xxxxProperties里面拿值 —-> application.properties

3.1、自动配置原理

Spring Boot自动配置的核心注解是@SpringBootApplication,该注解是spring boot的启动类注解,它是一个复合注解,里面包含:

@SpringBootConfiguration@EnableAutoConfiguration@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),    @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })public @interface SpringBootApplication{}======================

(1) @SpringBootConfiguration:

该注解上有一个 @Configuration注解,表示这个spring boot启动类是一个配置类,最终要被注入到spring容器中。

(2) @ComponentScan

指定扫描哪些,Spring注解;

(3) @EnableAutoConfiguration:

表示已启用自动配置,它也是包含以下内容的复合批注:

[En]

Indicates that automatic configuration is enabled, which is also a composite annotation that contains:

@AutoConfigurationPackage@Import(AutoConfigurationImportSelector.class)public @interface EnableAutoConfiguration {}

@AutoConfigurationPackage:

该注解上有一个@Import(AutoConfigurationPackages.Registrar.class)注解,其中 Registrar 类的作用是将启动类所在包下的所有子包的组件扫描注入到spring容器中。

这也是为什么在spring boot中,我们通常将controller、pojo、service、dao等包放在启动类同级目录下的原因。

@Import(AutoConfigurationPackages.Registrar.class)  //给容器中导入一个组件public @interface AutoConfigurationPackage {}//利用Registrar给容器中导入一系列组件//将指定的一个包下的所有组件导入进来?MainApplication 所在包下。

​②@Import(AutoConfigurationImportSelector.class):

其中AutoConfigurationImportSelector类中有一个getCandidateConfigurations()方法,该方法通过SpringFactoriesLoader.loadFactoryNames()方法查找位于META-INF/spring.factories文件中的所有自动配置类,并加载这些类。

SpringBoot

spring.factories文件是以key-value键值对的形式存储文件里,其中有一个key=EnableAutoConfiguration,它对应的value值就是一个个以AutoConfiguration结尾来命名的 xxxAutoConfiguration 自动配置类。

SpringBoot

所以spring boot在整个的启动过程中,其实就是在类路径的META-INF/spring.factories 文件中找到EnableAutoConfiguration对应的所有的自动配置类,然后将所有自动配置类加载到spring容器中。

所有自动配置类都是以AutoConfiguration结尾来命名的,而诸多的xxxAutoConfiguration 其实就是Spring容器的JavaConfig形式,它的作用就是为Spring容器导入bean。

SpringBoot

3.2、自动配置生效

前面加载的所有自动配置类并不是都生效的,每一个xxxAutoConfiguration自动配置类都是在某些特定的条件之下才会生效。这些条件限制是通过@ConditionOnxxx注解实现的。

常见的 @ConditionOnxxx注解有以下几种:

@ConditionalOnBean:当容器里存在指定bean的条件下。@ConditionalOnMissingBean:当容器里不存在指定bean的条件下。@ConditionalOnClass:当类路径下有指定类的条件下。@ConditionalOnMissingClass:当类路径下不存在指定类的条件下。@ConditionalOnProperty:指定的属性是否有指定的值,比如    @ConditionalOnProperties(prefix="xxx.xxx", value="enable", matchIfMissing=true),代表当xxx.xxx为enable时条件的布尔值为true,如果没有设置的情况下也为true。

@ConditionOnxxx注解用来指定自动配置类在哪些条件下会生效。我们要使用哪些类,就直接在spring boot项目中的pom.xml文件中导入相应的启动器即可,这样spring boot就会利用@ConditionOnxxx注解使我们需要的自动配置类生效,将该类的bean注入到spring容器中,这样就完成了整个自动配置的过程。

总结

spring boot中,每一个xxxAutoConfiguration 自动配置类,其实就是一个spring容器的JavaConfig形式,它的作用就是为spring容器注入相应的bean。而在注入bean的过程中,所有需要的属性值则是通过xxxProperties的bean来获得的。

3.3、最佳实践

  • 引入场景依赖

​https://docs.spring.io/spring-boot/docs/current/reference/html/using-spring-boot.html#using-boot-starter​

  • 检查自动配置的内容(可选)

    [En]

    check what is automatically configured (optional)*

  • 自我分析。场景引入对应的自动配置一般生效。

    [En]

    self-analysis. The automatic configuration corresponding to the introduction of the scenario generally takes effect.*

  • 配置文件中debug=true开启自动配置报告。Negative(不生效)\Positive(生效)

  • 是否需要修改

  • 参照文档修改配置项

  • ​https://docs.spring.io/spring-boot/docs/current/reference/html/appendix-application-properties.html#common-application-properties​

  • 自己分析。xxxxProperties绑定了配置文件的哪些。

  • 自定义加入或者替换组件

  • @Bean、@Component。。。

  • 自定义器 XXXXXCustomizer

  • ……

四、配置文件

4.1 文件类型

properties

同以前的properties用法

yaml

简介

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

非常适合以数据为中心的配置文件

[En]

Ideal for data-centric configuration files

基本语法

  • key: value;kv之间有空格
  • 大小写敏感
  • 使用缩进表示层级关系
  • 缩进不允许使用tab,只允许空格
  • 缩进空格的数量并不重要,只要同一级别的元素左对齐即可
    [En]

    the number of indented spaces is not important, as long as the elements at the same level are aligned to the left*

  • ‘#’表示注释
  • 字符串不需要加引号。如果要添加,‘’和‘’表示字符串的内容将被转义/不转义。
    [En]

    the string does not need to be quoted. If it is to be added,”and’ ‘indicate that the contents of the string will be escaped / not escaped.*

数据类型

  • 字面量:单个的、不可再分的值。date、boolean、string、number、null
k: v
  • 对象:键值对的集合。map、hash、set、object
行内写法:  k: {k1:v1,k2:v2,k3:v3}#或k:   k1: v1  k2: v2  k3: v3
  • 数组:一组按次序排列的值。array、list、queue
行内写法:  k: [v1,v2,v3]#或者k: - v1 - v2 - v3

1.2.4、示例

@Data
public class Person {

private String userName;
private Boolean boss;
private Date birth;
private Integer age;
private Pet pet;
private String[] interests;
private List<String> animal;
private Map<String, Object> score;
private Set<Double> salarys;
private Map<String, List<Pet>> allPets;
}

@Data
public class Pet {
private String name;
private Double weight;
}
yaml表示以上对象person:  userName: zhangsan  boss: false  birth: 2019/12/12 20:12:33  age: 18  pet:     name: tomcat    weight: 23.4  interests: [篮球,游泳]  animal:     - jerry    - mario  score:    english:       first: 30      second: 40      third: 50    math: [131,140,148]    chinese: {first: 128,second: 136}  salarys: [3999,4999.98,5999.99]  allPets:    sick:      - {name: tom}      - {name: jerry,weight: 47}    health: [{name: mario,weight: 47}]

4.2 配置提示

通常不会提示自定义类和配置文件绑定。

[En]

Custom class and profile bindings are generally not prompted.

<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-configuration-processorartifactId>
<optional>trueoptional>
dependency>


<build>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-configuration-processorartifactId>
exclude>
excludes>
configuration>
plugin>
plugins>
build>

五、数据访问

6.1 SQL

数据源的自动配置-HikariDataSource

1、导入JDBC场景

<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-data-jdbcartifactId>
dependency>

SpringBoot

数据库驱动?

为什么导入JDBC场景,官方不导入驱动?官方不知道我们接下要操作什么数据库。

数据库版本对应于驱动程序版本

[En]

The database version corresponds to the driver version

2、分析自动配置

自动配置的类:

  • DataSourceAutoConfiguration : 数据源的自动配置

  • 修改数据源相关的配置: spring.datasource

  • 数据库连接池的配置,是自己容器中没有DataSource才自动配置的
  • 底层配置好的连接池是: *HikariDataSource
@Configuration(proxyBeanMethods = false)  @Conditional(PooledDataSourceCondition.class)  @ConditionalOnMissingBean({ DataSource.class, XADataSource.class })  @Import({ DataSourceConfiguration.Hikari.class, DataSourceConfiguration.Tomcat.class,      DataSourceConfiguration.Dbcp2.class, DataSourceConfiguration.OracleUcp.class,      DataSourceConfiguration.Generic.class, DataSourceJmxConfiguration.class })  protected static class PooledDataSourceConfiguration
  • DataSourceTransactionManagerAutoConfiguration: 事务管理器的自动配置
  • JdbcTemplateAutoConfiguration: *JdbcTemplate的自动配置,可以来对数据库进行crud

  • 可以修改这个配置项@ConfigurationProperties(prefix = “spring.jdbc”) 来修改JdbcTemplate

  • @Bean@PrimaryJdbcTemplate;容器中有这个组件

  • JndiDataSourceAutoConfiguration: jndi的自动配置

  • XADataSourceAutoConfiguration: 分布式事务相关的

3、修改配置项

spring:  datasource:    url: jdbc:mysql://localhost:3306/db_account    username: root    password: 123456    driver-class-name: com.mysql.jdbc.Driver

4、测试

@Slf4j@SpringBootTestclass Boot05WebAdminApplicationTests {    @Autowired    JdbcTemplate jdbcTemplate;    @Test    void contextLoads() {//        jdbcTemplate.queryForObject("select * from account_tbl")//        jdbcTemplate.queryForList("select * from account_tbl",)        Long aLong = jdbcTemplate.queryForObject("select count(*) from account_tbl", Long.class);        log.info("记录总数:{}",aLong);    }}

使用Druid数据源

1、druid官方github地址

​https://github.com/alibaba/druid​

集成第三方技术的两种方式

[En]

Two ways to integrate third-party technology

  • 自定义
  • 找starter

2、自定义方式

1)创建数据源

<dependency>
<groupId>com.alibabagroupId>
<artifactId>druidartifactId>
<version>1.1.17version>
dependency>

<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
destroy-method="close">
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="maxActive" value="20" />
<property name="initialSize" value="1" />
<property name="maxWait" value="60000" />
<property name="minIdle" value="1" />
<property name="timeBetweenEvictionRunsMillis" value="60000" />
<property name="minEvictableIdleTimeMillis" value="300000" />
<property name="testWhileIdle" value="true" />
<property name="testOnBorrow" value="false" />
<property name="testOnReturn" value="false" />
<property name="poolPreparedStatements" value="true" />
<property name="maxOpenPreparedStatements" value="20" />

2)StatViewServlet

StatViewServlet的用途包括:

  • 提供监控信息展示的html页面
  • 提供监控信息的JSON API
<servlet>
<servlet-name>DruidStatViewservlet-name>
<servlet-class>com.alibaba.druid.support.http.StatViewServletservlet-class>
servlet>
<servlet-mapping>
<servlet-name>DruidStatViewservlet-name>
<url-pattern>/druid/*

3)StatFilter

用于统计监控信息;如SQL监控、URI监控

需要给数据源中配置如下属性;可以允许多个filter,多个用,分割;如:

<property name="filters" value="stat,slf4j" />

系统中所有filter:

别名

Filter类名

default

com.alibaba.druid.filter.stat.StatFilter

stat

com.alibaba.druid.filter.stat.StatFilter

mergeStat

com.alibaba.druid.filter.stat.MergeStatFilter

encoding

com.alibaba.druid.filter.encoding.EncodingConvertFilter

log4j

com.alibaba.druid.filter.logging.Log4jFilter

log4j2

com.alibaba.druid.filter.logging.Log4j2Filter

slf4j

com.alibaba.druid.filter.logging.Slf4jLogFilter

commonlogging

com.alibaba.druid.filter.logging.CommonsLogFilter

慢SQL记录配置:

<bean id="stat-filter" class="com.alibaba.druid.filter.stat.StatFilter">
<property name="slowSqlMillis" value="10000" />
<property name="logSlowSql" value="true" />
bean>

使用 slowSqlMillis 定义慢SQL的时长

3、使用官方starter方式

1)引入druid-starter

<dependency>
<groupId>com.alibabagroupId>
<artifactId>druid-spring-boot-starterartifactId>
<version>1.1.17version>
dependency>

2)分析自动配置

  • 扩展配置项 spring.datasource.druid
  • DruidSpringAopConfiguration. class, 监控SpringBean的;配置项: spring.datasource.druid.aop-patterns
  • DruidStatViewServletConfiguration. class, 监控页的配置: spring.datasource.druid.stat-view-servlet;默认开启
  • DruidWebStatFilterConfiguration. class, web监控配置; spring.datasource.druid.web-stat-filter;默认开启
  • DruidFilterConfiguration. class}) 所有Druid自己filter的配置
private static final String FILTER_STAT_PREFIX = "spring.datasource.druid.filter.stat";    private static final String FILTER_CONFIG_PREFIX = "spring.datasource.druid.filter.config";    private static final String FILTER_ENCODING_PREFIX = "spring.datasource.druid.filter.encoding";    private static final String FILTER_SLF4J_PREFIX = "spring.datasource.druid.filter.slf4j";    private static final String FILTER_LOG4J_PREFIX = "spring.datasource.druid.filter.log4j";    private static final String FILTER_LOG4J2_PREFIX = "spring.datasource.druid.filter.log4j2";    private static final String FILTER_COMMONS_LOG_PREFIX = "spring.datasource.druid.filter.commons-log";    private static final String FILTER_WALL_PREFIX = "spring.datasource.druid.filter.wall";

3、配置示例

spring:  datasource:    url: jdbc:mysql://localhost:3306/db_account    username: root    password: 123456    driver-class-name: com.mysql.jdbc.Driver    druid:      aop-patterns: com.atguigu.admin.*  #监控SpringBean      filters: stat,wall     # 底层开启功能,stat(sql监控),wall(防火墙)      stat-view-servlet:   # 配置监控页功能        enabled: true        login-username: admin        login-password: admin        resetEnable: false      web-stat-filter:  # 监控web        enabled: true        urlPattern: /*        exclusions: '*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*'      filter:        stat:    # 对上面filters里面的stat的详细配置          slow-sql-millis: 1000          logSlowSql: true          enabled: true        wall:          enabled: true          config:            drop-table-allow: false

SpringBoot配置示例

​https://github.com/alibaba/druid/tree/master/druid-spring-boot-starter​

配置项列表

​https://github.com/alibaba/druid/wiki/DruidDataSource%E9%85%8D%E7%BD%AE%E5%B1%9E%E6%80%A7%E5%88%97%E8%A1%A8​

整合MyBatis操作

​https://github.com/mybatis​

starter

SpringBoot官方的Starter:spring-boot-starter-*

第三方的: *-spring-boot-starter

<dependency>
<groupId>org.mybatis.spring.bootgroupId>
<artifactId>mybatis-spring-boot-starterartifactId>
<version>2.1.4version>
dependency>

SpringBoot

1、配置模式

  • 全局配置文件
  • SqlSessionFactory: 自动配置好了
  • SqlSession:自动配置了 SqlSessionTemplate 组合了SqlSession
  • @Import(AutoConfiguredMapperScannerRegistrar. class);
  • Mapper: 只要我们写的操作MyBatis的接口标准了 *@Mapper 就会被自动扫描进来
@EnableConfigurationProperties(MybatisProperties.class) : MyBatis配置项绑定类。@AutoConfigureAfter({ DataSourceAutoConfiguration.class, MybatisLanguageDriverAutoConfiguration.class })public class MybatisAutoConfiguration{}@ConfigurationProperties(prefix = "mybatis")public class MybatisProperties

可以修改配置文件中 mybatis 开始的所有;

配置mybatis规则mybatis:  config-location: classpath:mybatis/mybatis-config.xml  #全局配置文件位置  mapper-locations: classpath:mybatis/mapper/*.xml  #sql映射文件位置  Mapper接口--->绑定Xml"1.0" encoding="UTF-8" ?>        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">"com.atguigu.admin.mapper.AccountMapper">    "getAcct" resultType="com.atguigu.admin.bean.Account">        select * from  account_tbl where  id=#{id}

配置 privateConfiguration configuration; mybatis. configuration下面的所有,就是相当于改mybatis全局配置文件中的值

配置mybatis规则mybatis:#  config-location: classpath:mybatis/mybatis-config.xml  mapper-locations: classpath:mybatis/mapper/*.xml  configuration:    map-underscore-to-camel-case: true     可以不写全局;配置文件,所有全局配置文件的配置都放在configuration配置项中即可
  • 导入mybatis官方starter
  • 编写mapper接口。标准@Mapper注解
  • 编写sql映射文件并绑定mapper接口
  • 在application.yaml中指定Mapper配置文件的位置,以及指定全局配置文件的信息 (建议; 配置在mybatis.configuration

2、注解模式

@Mapperpublic interface CityMapper {    @Select("select * from city where id=#{id}")    public City getById(Long id);    public void insert(City city);}

3、混合模式

@Mapperpublic interface CityMapper {    @Select("select * from city where id=#{id}")    public City getById(Long id);    public void insert(City city);}

最佳实战:

  • 引入mybatis-starter
  • 配置application.yaml中,指定mapper-location位置即可
  • 编写Mapper接口并标注@Mapper注解
  • 简单方法直接注解方式
  • 复杂方法编写mapper.xml进行绑定映射
  • @MapperScan(“com.atguigu.admin.mapper”) 简化,其他的接口就可以不用标注@Mapper注解

整合 MyBatis-Plus 完成CRUD

1、什么是MyBatis-Plus

​MyBatis-Plus​​(简称 MP)是一个​​MyBatis​​的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。

​mybatis plus 官网​

建议安装 MybatisX插件

2、整合MyBatis-Plus

<dependency>
<groupId>com.baomidougroupId>
<artifactId>mybatis-plus-boot-starterartifactId>
<version>3.4.1version>
dependency>

自动配置

  • MybatisPlusAutoConfiguration 配置类,MybatisPlusProperties 配置项绑定。 mybatis-plus:xxx 就是对mybatis-plus的定制
  • SqlSessionFactory 自动配置好。底层是容器中默认的数据源
  • mapperLocations 自动配置好的。有默认值。classpath*:/mapper//.xml;任意包的类路径下的所有mapper文件夹下任意路径下的所有xml都是sql映射文件。 建议以后sql映射文件,放在 mapper下*
  • 容器中也自动配置好了 SqlSessionTemplate
  • @Mapper 标注的接口也会被自动扫描;建议直接@MapperScan(“com.atguigu.admin.mapper”) 批量扫描就行

优点:

  • 只需要我们的Mapper继承 BaseMapper就可以拥有crud能力

3、CRUD功能

@GetMapping("/user/delete/{id}")
public String deleteUser(@PathVariable("id") Long id,
@RequestParam(value = "pn",defaultValue = "1")Integer pn,
RedirectAttributes ra){

userService.removeById(id);

ra.addAttribute("pn",pn);
return "redirect:/dynamic_table";
}


@GetMapping("/dynamic_table")
public String dynamic_table(@RequestParam(value="pn",defaultValue = "1") Integer pn,Model model){
//表格内容的遍历
// response.sendError
// List users = Arrays.asList(new User("zhangsan", "123456"),
// new User("lisi", "123444"),
// new User("haha", "aaaaa"),
// new User("hehe ", "aaddd"));
// model.addAttribute("users",users);
//
// if(users.size()>3){
// throw new UserTooManyException();
// }
//从数据库中查出user表中的用户进行展示

//构造分页参数
Page<User> page = new Page<>(pn, 2);
//调用page进行分页
Page<User> userPage = userService.page(page, null);


// userPage.getRecords()
// userPage.getCurrent()
// userPage.getPages()


model.addAttribute("users",userPage);

return "table/dynamic_table";
}
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper,User> implements UserService {


}

public interface UserService extends IService<User> {

}

6.2 NoSQL

Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、 缓存和消息中间件。 它支持多种类型的数据结构,如​​字符串(strings)​​,​​散列(hashes)​​,​​列表(lists)​​,​​集合(sets)​​,​​有序集合(sorted sets)​​与范围查询,​​bitmaps​​,​​hyperloglogs​​和​​地理空间(geospatial)​​索引半径查询。 Redis 内置了​​复制(replication)​​,​​LUA脚本(Lua scripting)​​,​​LRU驱动事件(LRU eviction)​​,​​事务(transactions)​​和不同级别的​​磁盘持久化(persistence)​​, 并通过​​Redis哨兵(Sentinel)​​和自动​​分区(Cluster)​​提供高可用性(high availability)。

Redis自动配置

<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-data-redisartifactId>
dependency>

SpringBoot

自动配置:

  • RedisAutoConfiguration 自动配置类。RedisProperties 属性类 –> spring.redis.xxx是对redis的配置
  • 连接工厂是准备好的。 LettuceConnectionConfiguration、 JedisConnectionConfiguration
  • 自动注入了RedisTemplate< Object, Object> : xxxTemplate;
  • 自动注入了StringRedisTemplate;k:v都是String
  • key:value
  • *底层只要我们使用 StringRedisTemplate、RedisTemplate就可以操作redis

redis环境搭建

1、阿里云按量付费redis。经典网络

2、申请redis的公网连接地址

3、修改白名单 允许0.0.0.0/0 访问

RedisTemplate与Lettuce

@Test
void testRedis(){
ValueOperations<String, String> operations = redisTemplate.opsForValue();

operations.set("hello","world");

String hello = operations.get("hello");
System.out.println(hello);
}

切换至jedis

<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-data-redisartifactId>
dependency>


<dependency>
<groupId>redis.clientsgroupId>
<artifactId>jedisartifactId>
dependency>
spring:  redis:      host: r-bp1nc7reqesxisgxpipd.redis.rds.aliyuncs.com      port: 6379      password: lfy:Lfy123456      client-type: jedis      jedis:        pool:          max-active: 10

Original: https://blog.51cto.com/u_15709549/5604431
Author: 弄风的画
Title: SpringBoot

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/500617/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球