1.Springboot整合JUnit

1.1介绍下Spring的整合JUnit的制作方式(了解就好)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//加载spring整合junit专用的类运行器
@RunWith(SpringJUnit4ClassRunner.class)
//指定对应的配置信息
@ContextConfiguration(classes = SpringConfig.class)
public class AccountServiceTestCase {
//注入你要测试的对象
@Autowired
private AccountService accountService;
@Test
public void testGetById(){
//执行要测试的对象对应的方法
System.out.println(accountService.findById(2));
}
}

​ 其中核心代码是前两个注解,第一个注解@RunWith是设置Spring专用于测试的类运行器,简单说就是Spring程序执行程序有自己的一套独立的运行程序的方式,不能使用JUnit提供的类运行方式了,必须指定一下,但是格式是固定的,琢磨一下,每次都指定一样的东西,这个东西写起来没有技术含量啊,第二个注解@ContextConfiguration是用来设置Spring核心配置文件或配置类的,简单说就是加载Spring的环境你要告诉Spring具体的环境配置是在哪里写的,虽然每次加载的文件都有可能不同,但是仔细想想,如果文件名是固定的,这个貌似也是一个固定格式。似然有可能是固定格式,那就有可能每次都写一样的东西,也是一个没有技术含量的内容书写

SpringBoot就抓住上述两条没有技术含量的内容书写进行开发简化,能走默认值的走默认值,能不写的就不写,具体格式如下

1.2SpringBoot的整合JUnit的制作方式(重点)

1
2
3
4
5
6
7
8
9
10
11
12
@SpringBootTest
class Springboot04JunitApplicationTests {
//注入你要测试的对象
@Autowired
private BookDao bookDao;
@Test
void contextLoads() {
//执行要测试的对象对应的方法
bookDao.save();
System.out.println("two...");
}
}

重点在:@SpringBoot注解

看看这次简化成什么样了,一个注解就搞定了,而且还没有参数,再体会SpringBoot整合其他技术的优势在哪里,就两个字——简化。使用一个注解@SpringBootTest替换了前面两个注解。至于内部是怎么回事?和之前一样,只不过都走默认值。

这个时候有人就问了,你加载的配置类或者配置文件是哪一个?就是我们前面启动程序使用的引导类。如果想手工指定引导类有两种方式,第一种方式使用属性的形式进行,在注解@SpringBootTest中添加classes属性指定配置类

1
2
3
4
5
6
7
8
9
10
11
12
@SpringBootTest(classes = Springboot04JunitApplication.class)
class Springboot04JunitApplicationTests {
//注入你要测试的对象
@Autowired
private BookDao bookDao;
@Test
void contextLoads() {
//执行要测试的对象对应的方法
bookDao.save();
System.out.println("two...");
}
}

​ 第二种方式回归原始配置方式,仍然使用@ContextConfiguration注解进行,效果是一样的

1
2
3
4
5
6
7
8
9
10
11
12
13
@SpringBootTest
@ContextConfiguration(classes = Springboot04JunitApplication.class)
class Springboot04JunitApplicationTests {
//注入你要测试的对象
@Autowired
private BookDao bookDao;
@Test
void contextLoads() {
//执行要测试的对象对应的方法
bookDao.save();
System.out.println("two...");
}
}

image-20220807195621813

温馨提示

使用SpringBoot整合JUnit需要保障导入test对应的starter,由于初始化项目时此项是默认导入的,所以此处没有提及,其实和之前学习的内容一样,用什么技术导入对应的starter即可。

总结

  1. 导入测试对应的starter
  2. 测试类使用@SpringBootTest修饰
  3. 使用自动装配的形式添加要测试的对象
  4. 测试类如果存在于引导类所在包或子包中无需指定引导类
  5. 测试类如果不存在于引导类所在的包或子包中需要通过classes属性指定引导类(这个主要针对找不到测试类,测试类乱放)

1.3介绍下注解开发定义bean

1.使用@Component定义bean

1
2
3
4
5
@Component

public class BookDaoImpl implants BookDao{

}

2.核心配置文件通过组件扫描加载bean

1
<context:compant-scan base-package="com.itheima"/>

Spring提供@Component注解的三个衍生注解

  • Controller:用于表现层bean定义
  • Service:用于业务层bean定义
  • Pepository:用于数据层bean定义

这三个就等于@Component

1.4@Autowired 注解用法()

  • 应用于构造函数
  • 应用于setter方法
  • 应用于具有任意名称和多个参数的方法
  • 应用于字段,或者将其与构造函数混合
  • 将 @Autowired 注释添加到需要该类型数组的字段或方法,则 Spring 会从ApplicationContext 中搜寻符合指定类型的所有 bean

@Autowired 注解的作用(依赖注入)

这个注解是属于 Spring 的容器配置的一个注解,与它同属容器配置的注解还有:@Required, @Primary, @Qualifier 等等。@Autowired 注解是一个用于容器(container)配置的注解。

直接从字面意思来看,@autowired 注解来源于英文单词 autowire,这个单词的意思是自动装配的意思。自动装配又是什么意思?这个词语本来的意思是指的一些工业上的用机器代替人口,自动将一些需要完成的组装任务,或者别的一些任务完成。而在 Spring 的世界当中,自动装配指的就是使用将 Spring 容器中的 bean 自动的和我们需要这个 bean 的类组装在一起。

@Autowired 注解的实现

Java 的注解实现的核心技术是反射;
在 Spring 源代码当中,Autowired 注解位于包 org.springframework.beans.factory.annotation 之中, Spring 对 autowire 注解的实现逻辑位于该包下的类:AutowiredAnnotationBeanPostProcessor 之中;
使用 @Autowired 注入的 bean 对于目标类来说,从代码结构上来讲也就是一个普通的成员变量,@Autowired 和 Spring 一起工作,通过反射为这个成员变量赋值,也就是将其赋为期望的类实例。

2.整合MyBatis

2.1核心:用啥勾啥(在sql里找扫Mybatis和Mysql Driver驱动就好了)

创建模块时勾选要使用的技术,MyBatis,由于要操作数据库,还要勾选对应数据库

image-20220807200717882

或者手工导入对应技术的starter,和对应数据库的坐标(了解即可)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<dependencies>
<!--1.导入对应的starter-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.0</version>
</dependency>

<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>

</dependencies>

2.2配置数据源相关信息,没有这个信息你连接哪个数据库都不知道(在yml里做)–(可以当个模版)

1
2
3
4
5
6
7
#2.配置相关信息
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/db1
username: root
password: f1961455267

完了,就这么多,没了。有人就很纳闷,这就结束了?对,这就结束了,SpringBoot把配置中所有可能出现的通用配置都简化了。下面就可以写一下MyBatis程序运行需要的Dao(或者Mapper)就可以运行了

2.3测试结果

实体类

1
2
3
4
5
6
public class Book {
private Integer id;
private String type;
private String name;
private String description;
}

映射接口(Dao)

1
2
3
4
5
@Mapper
public interface BookDao {
@Select("select * from tbl_book where id = #{id}")
public Book getById(Integer id);
}

重要:想要连接这个表必须要连接数据源。不然不知道表名

image-20220807211449262

测试类

1
2
3
4
5
6
7
8
9
@SpringBootTest
class Springboot05MybatisApplicationTests {
@Autowired
private BookDao bookDao;
@Test
void contextLoads() {
System.out.println(bookDao.getById(1));
}
}

完美,开发从此变的就这么简单。再体会一下SpringBoot如何进行第三方技术整合的,是不是很优秀?具体内部的原理到原理篇再展开讲解

注意:当前使用的SpringBoot版本是2.5.4,对应的坐标设置中Mysql驱动使用的是8x版本。当SpringBoot2.4.3(不含)版本之前会出现一个小BUG,就是MySQL驱动升级到8以后要求强制配置时区,如果不设置会出问题。解决方案很简单,驱动url上面添加上对应设置就行了

1
2
3
4
5
6
7
#2.配置相关信息
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/ssm_db?serverTimezone=UTC
username: root
password: root

这里设置的UTC是全球标准时间,你也可以理解为是英国时间,中国处在东八区,需要在这个基础上加上8小时,这样才能和中国地区的时间对应的,也可以修改配置不写UTC,写Asia/Shanghai也可以解决这个问题。

1
2
3
4
5
6
7
#2.配置相关信息
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/ssm_db?serverTimezone=Asia/Shanghai
username: root
password: root

如果不想每次都设置这个东西,也可以去修改mysql中的配置文件mysql.ini,在mysqld项中添加default-time-zone=+8:00也可以解决这个问题。其实方式方法很多,这里就说这么多吧。

此外在运行程序时还会给出一个提示,说数据库驱动过时的警告,根据提示修改配置即可,弃用com.mysql.jdbc.Driver,换用com.mysql.cj.jdbc.Driver。前面的例子中已经更换了驱动了,在此说明一下。

1
Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new driver class is `com.mysql.cj.jdbc.Driver'. The driver is automatically registered via the SPI and manual loading of the driver class is generally unnecessary.

总结

  1. 整合操作需要勾选MyBatis技术,也就是导入MyBatis对应的starter

  2. 数据库连接相关信息转换成配置

  3. 数据库SQL映射需要添加@Mapper被容器识别到

  4. MySQL 8.X驱动强制要求设置时区(没提示就不改)

    • 修改url,添加serverTimezone设定
    • 修改MySQL数据库配置
  5. 驱动类过时,提醒更换为com.mysql.cj.jdbc.Driver

  6. 一定要连接数据源

3.整合MyBatis-Plus(简称MP)SSMP的就是这个

做完了两种技术的整合了,各位小伙伴要学会总结,我们做这个整合究竟哪些是核心?总结下来就两句话

  • 导入对应技术的starter坐标
  • 根据对应技术的要求做配置

image-20220807211824952

3.1导入对应的starter

mybatis勾选了两个,所以第一个MysqlDriver可以勾选,但是不像mybatis可以都勾选,MP是国人开发的,idea没有(懂得都懂),所以我们自己创建对应的starter。

1
2
3
4
5
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.2</version>
</dependency>

这个坐标的名字书写比较特殊,是第三方技术名称在前,boot和starter在后。此处简单提一下命名规范。(了解即可)

starter所属 命名规则 示例
官方提供 spring-boot-starter-技术名称 spring-boot-starter-web
spring-boot-starter-test
第三方提供 第三方技术名称-spring-boot-starter druid-spring-boot-starter
第三方提供 第三方技术名称-boot-starter(第三方技术名称过长,简化命名) mybatis-plus-boot-starter

3.2配置数据源相关信息

1
2
3
4
5
6
7
#2.配置相关信息
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/ssm_db
username: root
password: root

没了,就这么多,剩下的就是写MyBaitsPlus的程序了

3.2.1映射接口(Dao)

1
2
3
@Mapper
public interface BookDao extends BaseMapper<Book> {
}

核心在于Dao接口继承了一个BaseMapper的接口,这个接口中帮助开发者预定了若干个常用的API接口,简化了通用API接口的开发工作。

image-20220807224555999

下面就可以写一个测试类进行测试了,此处省略。

温馨提示

目前数据库的表名定义规则是tbl_模块名称,为了能和实体类相对应,需要做一个配置,相关知识各位小伙伴可以到MyBatisPlus课程中去学习,此处仅给出解决方案。配置application.yml文件,添加如下配置即可,设置所有表名的通用前缀名

1
2
3
4
mybatis-plus:
global-config:
db-config:
table-prefix: tbl_ #设置所有表的通用前缀名称为tbl_

总结

  1. 手工添加MyBatis-Plus对应的starter
  2. 数据层接口使用BaseMapper简化开发
  3. 需要使用的第三方技术无法通过勾选确定时,需要手工添加坐标

3.整合Druid

使用SpringBoot整合了3个技术了,发现套路基本相同,导入对应的starter,然后做配置,各位小伙伴需要一直强化这套思想。下面再整合一个技术,继续深入强化此思想。前面整合MyBatis和MP的时候,使用的数据源对象都是SpringBoot默认的数据源对象,下面我们手工控制一下,自己指定了一个数据源对象,Druid。

3.1导入对应的starter

因为这是个数据库的,所以还要勾选对应的mysql和mybatis

然后配置对应的starter

1
2
3
4
5
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.11</version>
</dependency>

3.2修改配置(专用)

1
2
3
4
5
6
7
spring:
datasource:
druid:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/ssm_db?serverTimezone=UTC
username: root
password: root

注意观察,配置项中,在datasource下面并不是直接配置url这些属性的,而是先配置了一个druid节点,然后再配置的url这些东西。言外之意,url这个属性时druid下面的属性,那你能想到吗?除了这4个常规配置外,还有druid专用的其他配置。通过提示功能可以打开druid相关的配置查阅

4.结论

导入对应starter,使用对应配置。没了,SpringBoot整合其他技术就这么简单粗暴。