当前位置: 首页 > news >正文

DAY02_Spring—第三方资源配置管理Spring容器Spring注解开发Spring整合Mybatis和Junit

目录

  • 一 第三方资源配置管理
    • 1 管理DataSource连接池对象
      • 问题导入
      • 1.1 管理Druid连接池
      • 1.2 管理c3p0连接池
    • 2 加载properties属性文件
      • 问题导入
      • 2.1 基本用法
      • 2.2 配置不加载系统属性
      • 2.3 加载properties文件写法
  • 二 Spring容器
    • 1 Spring核心容器介绍
      • 问题导入
      • 1.1 创建容器
      • 1.2 获取bean对象
      • 1.3 容器类层次结构
      • 1.4 BeanFactory
    • 2 Spring核心容器总结
      • 2.1 容器相关
        • 2.2 bean相关
        • 2.3 依赖注入相关
  • 三 Spring注解开发
    • 1 注解开发定义Bean对象
      • 问题导入
      • 1.1 基本使用
      • 1.2 @Component三个衍生注解
    • 2 纯注解开发模式
      • 问题导入
      • 2.1 纯注解开发模式介绍
      • 2.2 代码演示
    • 3 注解开发Bean作用范围和生命周期管理
      • 问题导入
      • 3.1 bean作用范围注解配置
      • 3.2 bean生命周期注解配置
    • 4 注解开发依赖注入
      • 问题导入
      • 4.1 使用@Autowired注解开启自动装配模式(按类型)
      • 4.2 使用@Qualifier注解指定要装配的bean名称
      • 4.3 使用@Value实现简单类型注入
    • 5 注解开发管理第三方Bean
      • 问题导入
      • 【第一步】单独定义配置类
      • 【第二步】将独立的配置类加入核心配置
        • 方式1:@Import注解导入式
        • 方式2:@ComponentScan扫描式
    • 6 注解开发为第三方Bean注入资源
      • 问题导入
      • 6.1 简单类型依赖注入
      • 6.2 引用类型依赖注入
    • 7 注解开发总结
  • 四 Spring整合其他技术
    • 1 Spring整合mybatis
      • 1.1 思路分析
        • 问题导入
        • 1.1.1 MyBatis程序核心对象分析
        • 1.1.2 整合MyBatis
      • 1.2 代码实现
        • 问题导入
        • 【前置工作】
          • 【第一步】导入Spring整合Mybatis依赖
          • 【第二步】创建JdbcConfig配置DataSource数据源
          • 【第三步】创建MybatisConfig整合mybatis
          • 【第四步】创建SpringConfig主配置类进行包扫描和加载其他配置类
          • 【第五步】定义测试类进行测试
    • 2 Spring整合Junit单元测试
      • 问题导入
        • 【第一步】导入整合的依赖坐标spring-test
        • 【第二步】使用Spring整合Junit专用的类加载器
        • 【第三步】加载配置文件或者配置类

一 第三方资源配置管理

说明:以管理DataSource连接池对象为例讲解第三方资源配置管理

1 管理DataSource连接池对象

问题导入

配置数据库连接参数时,注入驱动类名是用driverClassName还是driver?

1.1 管理Druid连接池

数据库准备

create database if not exists spring_db character set utf8;
use spring_db;
create table if not exists tbl_account(id int primary key auto_increment,name varchar(20),money double
);
insert into tbl_account values(null,'Tom',1000);
insert into tbl_account values(null,'Jerry',1000);

【第一步】添加Druid连接池依赖

<dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.2.8</version>
</dependency>
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.20</version>
</dependency>

注意:除了添加以上两个依赖之外,别忘了添加spring-context依赖。

【第二步】配置DruidDataSource连接池Bean对象

<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"><property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/spring_db?characterEncoding=utf8&amp;useSSL=false&amp;serverTimezone=Asia/Shanghai&amp;rewriteBatchedStatements=true"/><property name="username" value="root"/><property name="password" value="root"/>
</bean>

【第三步】在测试类中从IOC容器中获取连接池对象并打印

public class App {public static void main(String[] args) {ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");DataSource dataSource = (DataSource) ctx.getBean("dataSource");System.out.println(dataSource);}
}

打印结果
在这里插入图片描述

1.2 管理c3p0连接池

【第一步】添加c3p0连接池依赖

<dependency><groupId>c3p0</groupId><artifactId>c3p0</artifactId><version>0.9.1.2</version>
</dependency>

【第二步】配置c3p0连接池Bean对象

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"><property name="driverClass" value="com.mysql.cj.jdbc.Driver"/><property name="jdbcUrl" value="jdbc:mysql://localhost:3306/spring_db?characterEncoding=utf8&amp;useSSL=false&amp;serverTimezone=Asia/Shanghai&amp;rewriteBatchedStatements=true"/><property name="user" value="root"/><property name="password" value="root"/></bean>

注意:同一个Spring容器中不能有两个id="dataSource"的连接池。

【第三步】在测试类中从IOC容器中获取连接池对象并打印

public class App {public static void main(String[] args) {ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");DataSource dataSource = (DataSource) ctx.getBean("dataSource");System.out.println(dataSource);}
}

运行结果:

com.mchange.v2.c3p0.ComboPooledDataSource [ acquireIncrement -> 3, acquireRetryAttempts -> 30, acquireRetryDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 0, connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, dataSourceName -> 1hge0yzax1fmo0yo1qse2m7|4f7d0008, debugUnreturnedConnectionStackTraces -> false, description -> null, driverClass -> com.mysql.cj.jdbc.Driver, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, identityToken -> 1hge0yzax1fmo0yo1qse2m7|4f7d0008, idleConnectionTestPeriod -> 0, initialPoolSize -> 3, jdbcUrl -> jdbc:mysql://localhost:3306/spring_db?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true, maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 0, maxIdleTimeExcessConnections -> 0, maxPoolSize -> 15, maxStatements -> 0, maxStatementsPerConnection -> 0, minPoolSize -> 3, numHelperThreads -> 3, numThreadsAwaitingCheckoutDefaultUser -> 0, preferredTestQuery -> null, properties -> {user=******, password=******}, propertyCycle -> 0, testConnectionOnCheckin -> false, testConnectionOnCheckout -> false, unreturnedConnectionTimeout -> 0, usesTraditionalReflectiveProxies -> false ]

2 加载properties属性文件

目的:将数据库的连接参数抽取到一个单独的文件中,与Spring配置文件解耦。

问题导入

问题1:如何解决使用EL表达式读取属性文件中的值结果读取到了系统属性问题?
问题2:加载properties文件写法标准写法该怎么写?

2.1 基本用法

【第一步】编写jdbc.properties属性文件

jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/spring_db?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true
jdbc.username=root
jdbc.password=root

【第二步】在applicationContext.xml中开启开启context命名空间,加载jdbc.properties属性文件
在这里插入图片描述
小技巧:如果同学们觉得上述复制粘贴方式不好改或者容易改错,其实idea是有提示功能的,注意不要选错就行了。有些版本的idea没有这个提示,那么就按照上面复制粘贴的方式改,改完之后可以做成live template模板,后期直接用。
在这里插入图片描述

<context:property-placeholder location="jdbc.properties"/>

【第三步】在配置连接池Bean的地方使用EL表达式获取jdbc.properties属性文件中的值

<bean class="com.alibaba.druid.pool.DruidDataSource"><property name="driverClassName" value="${jdbc.driver}"/><property name="url" value="${jdbc.url}"/><property name="username" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/>
</bean>

配置完成之后,运行之前的获取Druid连接池代码,可以获取到连接池对象就表示配置成功。

2.2 配置不加载系统属性

问题

如果属性文件中配置的不是jdbc.username,而是username=root666,那么使用${username}获取到的不是root666,而是计算机的名称。

原因

系统属性的优先级比我们属性文件中的高,替换了我们的username=root666。

解决

解决1:换一个名称,例如不叫username,叫jdbc.username。

解决2:使用system-properties-mode="NEVER"属性表示不使用系统属性。

<context:property-placeholder location="jdbc.properties" system-properties-mode="NEVER"/>

2.3 加载properties文件写法

  • 不加载系统属性
<context:property-placeholder location="jdbc.properties" system-properties-mode="NEVER"/>
  • 加载多个properties文件
<context:property-placeholder location="jdbc.properties,msg.properties"/>
  • 加载所有properties文件
<context:property-placeholder location="*.properties"/>
  • 加载properties文件 标准格式
<context:property-placeholder location="classpath:*.properties"/>
  • 从路径或jar包中搜索并加载properties文件
<context:property-placeholder location="classpath*:*.properties"/>

二 Spring容器

1 Spring核心容器介绍

问题导入

问题:按照Bean名称获取Bean有什么弊端,按照Bean类型获取Bean有什么弊端?

1.1 创建容器

  • 方式一:类路径加载配置文件
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
  • 方式二:文件路径加载配置文件
ApplicationContext ctx = new FileSystemXmlApplicationContext("D:\\applicationContext.xml");
  • 加载多个配置文件
ApplicationContext ctx = new ClassPathXmlApplicationContext("bean1.xml", "bean2.xml");

1.2 获取bean对象

  • 方式一:使用bean名称获取
    • 需要自己强制类型转换
BookDao bookDao = (BookDao) ctx.getBean("bookDao");
  • 方式二:使用bean名称获取并指定类型
    • 推荐使用
BookDao bookDao = ctx.getBean("bookDao", BookDao.class);
  • 方式三:使用bean类型获取
    • 如果IOC容器中同类型的Bean对象有多个,此处获取会报错
BookDao bookDao = ctx.getBean(BookDao.class);

1.3 容器类层次结构

在这里插入图片描述

1.4 BeanFactory

  • 类路径加载配置文件
Resource resources = new ClassPathResource("applicationContext.xml");
BeanFactory bf = new XmlBeanFactory(resources);
BookDao bookDao = bf.getBean("bookDao", BookDao.class);
bookDao.save();
  • BeanFactory创建完毕后,所有的Bean均为延迟加载,也就是说我们调用getBean()方法获取Bean对象时才创建Bean对象并返回给我们

2 Spring核心容器总结

2.1 容器相关

  • BeanFactory是IoC容器的顶层接口,初始化BeanFactory对象时,加载的bean延迟加载
  • ApplicationContext接口是Spring容器的核心接口,初始化时bean立即加载
  • ApplicationContext接口提供基础的bean操作相关方法,通过其他接口扩展其功能
  • ApplicationContext接口常用初始化类
    • ClassPathXmlApplicationContext(常用)
    • FileSystemXmlApplicationContext

2.2 bean相关

在这里插入图片描述

2.3 依赖注入相关

在这里插入图片描述

三 Spring注解开发

1 注解开发定义Bean对象

目的:xml配置Bean对象有些繁琐,使用注解简化Bean对象的定义

问题导入

问题1:使用什么标签进行Spring注解包扫描?
问题2:@Component注解和@Controller、@Service、@Repository三个衍生注解有什么区别?

1.1 基本使用

【第一步】在applicationContext.xml中开启Spring注解包扫描

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><!--扫描com.itheima包及其子包下的类中注解--><context:component-scan base-package="com.itheima"/>
</beans>

【第二步】在类上使用@Component注解定义Bean。

//@Component定义bean
@Component("bookDao")
public class BookDaoImpl implements BookDao {public void save() {System.out.println("book dao save ...");}
}
@Component
public class BookServiceImpl implements BookService {private BookDao bookDao;public void setBookDao(BookDao bookDao) {this.bookDao = bookDao;}public void save() {System.out.println("book service save ...");bookDao.save();}
}

补充说明:如果@Component注解没有使用参数指定Bean的名称,那么类名首字母小写就是Bean在IOC容器中的默认名称。例如:BookServiceImpl对象在IOC容器中的名称是bookServiceImpl。

【第三步】在测试类中获取Bean对象

public class AppForAnnotation {public static void main(String[] args) {ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");BookDao bookDao = (BookDao) ctx.getBean("bookDao");System.out.println(bookDao);//按类型获取beanBookService bookService = ctx.getBean(BookService.class);System.out.println(bookService);}
}

注意:在测试类中不要调用bookService的save方法,因为还没有给BookServiceImpl中的bookDao赋值,调用bookService的save方法会出现空指针异常。

运行结果
在这里插入图片描述

1.2 @Component三个衍生注解

说明:加粗的注解为常用注解

  • Spring提供 @Component 注解的三个衍生注解
    • @Controller:用于表现层bean定义
    • @Service:用于业务层bean定义
    • @Repository:用于数据层bean定义
@Repository("bookDao")
public class BookDaoImpl implements BookDao {
}@Service
public class BookServiceImpl implements BookService {
}

2 纯注解开发模式

问题导入

问题1:配置类上使用什么注解表示该类是一个配置类?
问题2:配置类上使用什么注解进行Spring注解包扫描?

2.1 纯注解开发模式介绍

  • Spring3.0开启了纯注解开发模式,使用Java类替代配置文件,开启了Spring快速开发赛道
  • Java类代替Spring核心配置文件
    在这里插入图片描述
  • @Configuration注解用于设定当前类为配置类
  • @ComponentScan注解用于设定扫描路径,此注解只能添加一次,多个数据请用数组格式
@ComponentScan({com.itheima.service","com.itheima.dao"})
  • 读取Spring核心配置文件初始化容器对象切换为读取Java配置类初始化容器对象
//加载配置文件初始化容器
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
//加载配置类初始化容器
ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);

2.2 代码演示

【第一步】定义配置类代替配置文件

//声明当前类为Spring配置类
@Configuration
//Spring注解扫描,相当于<context:component-scan base-package="com.itheima"/>
@ComponentScan("com.itheima")
//设置bean扫描路径,多个路径书写为字符串数组格式
//@ComponentScan({"com.itheima.service","com.itheima.dao"})
public class SpringConfig {
}

【第二步】在测试类中加载配置类,获取Bean对象并使用

public class AppForAnnotation {public static void main(String[] args) {//AnnotationConfigApplicationContext加载Spring配置类初始化Spring容器ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);BookDao bookDao = (BookDao) ctx.getBean("bookDao");System.out.println(bookDao);//按类型获取beanBookService bookService = ctx.getBean(BookService.class);System.out.println(bookService);}
}

3 注解开发Bean作用范围和生命周期管理

问题导入

在类上使用什么注解定义Bean的作用范围?

3.1 bean作用范围注解配置

  • 使用@Scope定义bean作用范围
    • 单例模式:@Scope(“singleton”)
    • 非单例模式:@Scope(“prototype”)
@Repository
@Scope("singleton")
public class BookDaoImpl implements BookDao {
}

3.2 bean生命周期注解配置

  • 使用@PostConstruct
    • 设置bean的初始化方法
  • @PreDestroy
    • 设置bean的销毁方法
@Repository
@Scope("singleton")
public class BookDaoImpl implements BookDao {public BookDaoImpl() {System.out.println("book dao constructor ...");}@PostConstructpublic void init(){System.out.println("book init ...");}@PreDestroypublic void destroy(){System.out.println("book destory ...");}
}
public class AppForAnnotation {public static void main(String[] args) {//AnnotationConfigApplicationContext加载Spring配置类初始化Spring容器AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);BookDao bookDao1 =ctx.getBean(BookDao.class);BookDao bookDao2 =ctx.getBean(BookDao.class);System.out.println(bookDao1);System.out.println(bookDao2);ctx.close();

注意:@PostConstruct和@PreDestroy注解是jdk中提供的注解,从jdk9开始,jdk中的javax.annotation包被移除了,也就是说这两个注解就用不了了,可以额外导入一下依赖解决这个问题。

<dependency><groupId>javax.annotation</groupId><artifactId>javax.annotation-api</artifactId><version>1.3.2</version>
</dependency>

4 注解开发依赖注入

问题导入

问题1:请描述@Autowired注解是如何进行自动装配的?
问题2:请描述@Qualifier注解的作用

4.1 使用@Autowired注解开启自动装配模式(按类型)

@Service
public class BookServiceImpl implements BookService {//@Autowired:注入引用类型,自动装配模式,默认按类型装配@Autowiredprivate BookDao bookDao;public void save() {System.out.println("book service save ...");bookDao.save();}
}

说明:不管是使用配置文件还是配置类,都必须进行对应的Spring注解包扫描才可以使用。@Autowired默认按照类型自动装配,如果IOC容器中同类的Bean有多个,那么默认按照变量名和Bean的名称匹配,建议使用@Qualifier注解指定要装配的bean名称

注意:自动装配基于反射设计创建对象并暴力反射对应属性为私有属性初始化数据,因此无需提供setter方法。

4.2 使用@Qualifier注解指定要装配的bean名称

目的:解决IOC容器中同类型Bean有多个装配哪一个的问题

@Service
public class BookServiceImpl implements BookService {//@Autowired:注入引用类型,自动装配模式,默认按类型装配@Autowired//@Qualifier:自动装配bean时按bean名称装配@Qualifier("bookDao")private BookDao bookDao;public void save() {System.out.println("book service save ...");bookDao.save();}
}

注意:@Qualifier注解无法单独使用,必须配合@Autowired注解使用

4.3 使用@Value实现简单类型注入

@Repository("bookDao")
public class BookDaoImpl implements BookDao {//@Value:注入简单类型(无需提供set方法)@Value("${name}")private String name;public void save() {System.out.println("book dao save ..." + name);}
}

以上@Value注解中使用${name}从属性文件中读取name值,那么就需要在配置类或者配置文件中加载属性文件。

@Configuration
@ComponentScan("com.itheima")
//@PropertySource加载properties配置文件
@PropertySource({"classpath:jdbc.properties"}) //{}可以省略不写
public class SpringConfig {
}

注意:@PropertySource()中加载多文件请使用数组格式配置,不允许使用通配符*

5 注解开发管理第三方Bean

问题导入

导入自己定义的配置类有几种方式?

【第一步】单独定义配置类

public class JdbcConfig {//@Bean:表示当前方法的返回值是一个bean对象,添加到IOC容器中@Beanpublic DataSource dataSource(){DruidDataSource ds = new DruidDataSource();ds.setDriverClassName("com.mysql.cj.jdbc.Driver");ds.setUrl("mysql://localhost:3306/spring_db?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true");ds.setUsername("root");ds.setPassword("root");return ds;}
}

【第二步】将独立的配置类加入核心配置

方式1:@Import注解导入式

@Configuration
@ComponentScan("com.itheima")
//@Import:导入配置信息
@Import({JdbcConfig.class})
public class SpringConfig {
}

方式2:@ComponentScan扫描式

@Configuration
@ComponentScan({"com.itheima.config","com.itheima.service","com.itheima.dao"})  //只要com.itheima.config包扫到了就行,三个包可以合并写成com.itheima
public class SpringConfig {
}

6 注解开发为第三方Bean注入资源

问题导入

配置类中如何注入简单类型数据,如何注入引用类型数据?

6.1 简单类型依赖注入

public class JdbcConfig {//1.定义一个方法获得要管理的对象@Value("com.mysql.cj.jdbc.Driver")private String driver;@Value("jdbc:mysql://localhost:3306/spring_db?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true")private String url;@Value("root")private String userName;@Value("root")private String password;//2.@Bean:表示当前方法的返回值是一个bean对象,添加到IOC容器中@Beanpublic DataSource dataSource(){DruidDataSource ds = new DruidDataSource();ds.setDriverClassName(driver);ds.setUrl(url);ds.setUsername(userName);ds.setPassword(password);return ds;}
}

说明:如果@Value()中使用了EL表达式读取properties属性文件中的内容,那么就需要加载properties属性文件。

6.2 引用类型依赖注入

//Spring会自动从IOC容器中找到BookDao对象赋值给参数bookDao变量,如果没有就会报错。
@Bean 
public DataSource dataSource(BookDao bookDao){System.out.println(bookDao);DruidDataSource ds = new DruidDataSource();ds.setDriverClassName(driver);ds.setUrl(url);ds.setUsername(userName);ds.setPassword(password);return ds;
}

说明:引用类型注入只需要为bean定义方法设置形参即可,容器会根据类型自动装配对象

7 注解开发总结

在这里插入图片描述

四 Spring整合其他技术

1 Spring整合mybatis

1.1 思路分析

问题导入

mybatis进行数据层操作的核心对象是谁?

1.1.1 MyBatis程序核心对象分析

在这里插入图片描述

1.1.2 整合MyBatis

在这里插入图片描述

  • 使用SqlSessionFactoryBean封装SqlSessionFactory需要的环境信息
    在这里插入图片描述
  • 使用MapperScannerConfigurer加载Dao接口,创建代理对象保存到IOC容器中
    在这里插入图片描述

1.2 代码实现

问题导入

问题1:Spring整合mybatis的依赖叫什么?
问题2:Spring整合mybatis需要管理配置哪两个Bean,这两个Bean作用分别是什么?

【前置工作】

  1. 在pom.xml中添加spring-context、druid、mybatis、mysql-connector-java等基础依赖。
  2. 准备service和dao层基础代码
public interface AccountService {void save(Account account);void delete(Integer id);void update(Account account);List<Account> findAll();Account findById(Integer id);}
@Service
public class AccountServiceImpl implements AccountService {@Autowiredprivate AccountDao accountDao;public void save(Account account) {accountDao.save(account);}public void update(Account account){accountDao.update(account);}public void delete(Integer id) {accountDao.delete(id);}public Account findById(Integer id) {return accountDao.findById(id);}public List<Account> findAll() {return accountDao.findAll();}
}
public interface AccountDao {@Insert("insert into tbl_account(name,money)values(#{name},#{money})")void save(Account account);@Delete("delete from tbl_account where id = #{id} ")void delete(Integer id);@Update("update tbl_account set name = #{name} , money = #{money} where id = #{id} ")void update(Account account);@Select("select * from tbl_account")List<Account> findAll();@Select("select * from tbl_account where id = #{id} ")Account findById(Integer id);
}
【第一步】导入Spring整合Mybatis依赖
<dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.3.18</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.2.8</version></dependency><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.6</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.20</version></dependency><dependency><groupId>org.mybatis</groupId><artifactId>mybatis-spring</artifactId><version>2.0.6</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>5.3.18</version></dependency></dependencies>
【第二步】创建JdbcConfig配置DataSource数据源
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/spring_db?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true
jdbc.username=root
jdbc.password=root
public class JdbcConfig {@Value("${jdbc.driver}")private String driver;@Value("${jdbc.url}")private String url;@Value("${jdbc.username}")private String userName;@Value("${jdbc.password}")private String password;@Beanpublic DataSource dataSource(){DruidDataSource ds = new DruidDataSource();ds.setDriverClassName(driver);ds.setUrl(url);ds.setUsername(userName);ds.setPassword(password);return ds;}
}
【第三步】创建MybatisConfig整合mybatis
public class MybatisConfig {//定义bean,SqlSessionFactoryBean,用于产生SqlSessionFactory对象@Beanpublic SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource){SqlSessionFactoryBean ssfb = new SqlSessionFactoryBean();ssfb.setTypeAliasesPackage("com.itheima.domain");ssfb.setDataSource(dataSource);return ssfb;}//定义bean,返回MapperScannerConfigurer对象@Beanpublic MapperScannerConfigurer mapperScannerConfigurer(){MapperScannerConfigurer msc = new MapperScannerConfigurer();msc.setBasePackage("com.itheima.dao");return msc;}
}
【第四步】创建SpringConfig主配置类进行包扫描和加载其他配置类
@Configuration
@ComponentScan("com.itheima")
//@PropertySource:加载类路径jdbc.properties文件
@PropertySource("classpath:jdbc.properties")
@Import({JdbcConfig.class,MybatisConfig.class})
public class SpringConfig {
}
【第五步】定义测试类进行测试
public class App {public static void main(String[] args) {ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);AccountService accountService = ctx.getBean(AccountService.class);Account ac = accountService.findById(1);System.out.println(ac);}
}

2 Spring整合Junit单元测试

问题导入

Spring整合Junit的两个注解作用分别是什么?

【第一步】导入整合的依赖坐标spring-test

<dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.3.18</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>5.3.18</version></dependency><!--spring整合junit--><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>5.3.18</version><scope>test</scope></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.2.8</version></dependency><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.6</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.20</version></dependency><dependency><groupId>org.mybatis</groupId><artifactId>mybatis-spring</artifactId><version>2.0.6</version></dependency><!--junit--><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13.2</version><scope>test</scope></dependency></dependencies>

【第二步】使用Spring整合Junit专用的类加载器

【第三步】加载配置文件或者配置类

//【第二步】使用Spring整合Junit专用的类加载器
@RunWith(SpringJUnit4ClassRunner.class)
//【第三步】加载配置文件或者配置类
@ContextConfiguration(classes = {SpringConfiguration.class}) //加载配置类
//@ContextConfiguration(locations={"classpath:applicationContext.xml"})//加载配置文件
public class AccountServiceTest {//支持自动装配注入bean@Autowiredprivate AccountService accountService;@Testpublic void testFindById(){System.out.println(accountService.findById(1));}@Testpublic void testFindAll(){System.out.println(accountService.findAll());}
}

注意:junit的依赖至少要是4.12版本,可以是4.13等版本,否则出现如下异常:
在这里插入图片描述

相关文章:

DAY02_Spring—第三方资源配置管理Spring容器Spring注解开发Spring整合Mybatis和Junit

目录 一 第三方资源配置管理1 管理DataSource连接池对象问题导入1.1 管理Druid连接池1.2 管理c3p0连接池 2 加载properties属性文件问题导入2.1 基本用法2.2 配置不加载系统属性2.3 加载properties文件写法 二 Spring容器1 Spring核心容器介绍问题导入1.1 创建容器1.2 获取bean…...

Icon图标有哪些在线设计的工具推荐

虽然icon图标相对较小&#xff0c;但icon图标在设计中非常重要。高质量的icon图标通常可以决定设计工作的质量。高质量的在线生产icon工具可以提高设计师图标设计的效率。此外&#xff0c;优秀的图标设计师还可以让设计师快速开始图标设计工作。本文为您选择了五种在线生成icon…...

深度学习环境安装依赖时常见错误解决

1.pydantic 安装pydantic时报以下错误&#xff1a; ImportError: cannot import name Annotated from pydantic.typing (C:\Users\duole\anaconda3\envs\vrh\lib\site-packages\pydantic\typing.py) 这个是版本错误&#xff0c;删除装好的版本&#xff0c;重新指定版本安装就…...

opencv基础47 查找图像轮廓cv2.findContours()详解

什么是图像轮廓&#xff1f; 图像轮廓是指图像中物体边缘的连续性曲线。在计算机视觉和图像处理中&#xff0c;轮廓通常被用于检测物体、分割图像以及提取物体特征。 图像轮廓是由一系列连续的像素点组成&#xff0c;这些像素点位于物体边界上。轮廓的特点是在物体和背景之间的…...

Splunk Enterprise for mac(可视化数据分析软件)详细安装教程

Splunk Enterprise for Mac是一款可视化数据分析软件&#xff0c;为你提供强大的搜索、 分析和可视化功能&#xff0c;可以帮助您获得有价值的业务情报&#xff0c;从你机器生成的数据。还在等什么&#xff1f;有需要的朋友&#xff0c;欢迎前来下载&#xff01; 实时监测和搜…...

如何实现环卫项目运营的数字化管理,达到企业降本增效的目的?

数字环卫是指利用数字技术和数据驱动的方法来改善环卫流程和管理。数字环卫的底层逻辑在于利用技术来优化运营、提高效率并降低环卫项目管理成本。如何实现环卫工程运营数字化管理&#xff0c;达到降本增效的目标&#xff1a; 1.数据收集和分析&#xff1a;实施数据收集机制&a…...

React Native连接Zebra斑马打印机通过发送CPCL指令打印(Android 和 iOS通用)

自 2015 年发布以来&#xff0c;React Native 已成为用于构建数千个移动应用程序的流行跨平台移动开发框架之一。通常&#xff0c;我们有开发人员询问如何将 Link-OS SDK 与 React Native 应用程序集成&#xff0c;以便在 Zebra 打印机上打印标签。在本教程中&#xff0c;我们将…...

使用 Simulink 进行 STM32 编程

目录 介绍 所需材料 步骤 1&#xff1a;在MATLAB中设置STM32-MAT软件路径步骤 2&#xff1a;在STM32CubeMX中创建一个项目步骤 3&#xff1a;配置时钟和 GPIO 引脚步骤 4&#xff1a;项目经理并生成代码步骤 5&#xff1a;在 Simulink 中创建模型步骤 6&#xff1a;在模型中插…...

走出迷宫的最少步数and第一条出路

题面 题目描述 一个迷宫由 R 行 C 列格子组成&#xff0c;有的格子里有障碍物&#xff0c;不能走&#xff1b;有的格子是空地&#xff0c;可以走。 给定一个迷宫&#xff0c;求从左上角走到右下角最少需要走多少步(数据保证一定能走到)。只能在水平方向或垂直方向走&#xff0c…...

MediaCodec创建对应解码器

媒体编解码API使用示例 //获取相关格式文件的内容信息&#xff0c;如轨道数量、获取MIME信息、视频的高度与宽度、语言格式、播放总时长等 MediaExtractor mediaExtractor new MediaExtractor(); try {mediaExtractor.setDataSource(path); // 设置数据源 } catch (IOExcept…...

使用eXosip+ffmpeg、ffplay命令行实现sip客户端

文章目录 前言一、关键实现1、主要流程2、解决端口冲突&#xff08;1&#xff09;、出现原因&#xff08;2&#xff09;、解决方法 3、解析sdp&#xff08;1&#xff09;、定义实体&#xff08;2&#xff09;、解析视频&#xff08;3&#xff09;、解析音频 4、命令行推拉流&am…...

dotNet 之网络TCP

**硬件支持型号 点击 查看 硬件支持 详情** DTU701 产品详情 DTU702 产品详情 DTU801 产品详情 DTU802 产品详情 DTU902 产品详情 G5501 产品详情 ARM dotnet 编程 dotNet使用TCP&#xff0c;可以使用Socket和TcpClient 、TcpListener类 2种&#xff0c;对于高级用户&…...

python基础面试题汇总(持续更新),冲击offer

目录 1.概念理解题python内置数据结构&#xff0c;哪些是不可变的python新式类和经典类的区别is和有什么区别Python中变量查找顺序python函数的参数是值传递还是引用传递python垃圾回收机制什么是闭包什么是装饰器&#xff0c;开发中用到举例如何实现只读属性Python中类方法、实…...

Java课题笔记~ AOP编程术语(掌握)

&#xff08;1&#xff09; 切面&#xff08;Aspect&#xff09; 切面泛指交叉业务逻辑。上例中的事务处理、日志处理就可以理解为切面。常用的切面是通知&#xff08;Advice&#xff09;。实际就是对主业务逻辑的一种增强。 &#xff08;2&#xff09; 连接点&#xff08;Jo…...

暑假刷题第23天--8/6

3748. 递增子串 - AcWing题库 #include<iostream> #include<string> const int N200005; int a[N]; using namespace std; int main(){int t;cin>>t;for(int q1;q<t;q){int n;cin>>n;string s;cin>>s;int cnt1;a[1]1;for(int i2;i<n;i){i…...

ArcGIS API for JavaScript 4.x 教程(一) 显示一张地图

了解如何创建和显示带有基本地图图层的地图。 地图包含地理数据层。地图包含一个基本地图层&#xff0c;以及一个或多个数据层&#xff08;可选&#xff09;。可以使用地图视图显示地图的特定区域&#xff0c;并设置位置和缩放级别。 本教程将向您展示如何使用地形底图层创建和…...

Python-OpenCV中的图像处理

Python-OpenCV中的图像处理 颜色空间转换物体跟踪获取HSV的值几何变换图像缩放图像平移图像旋转仿射变换透视变换 图像阈值单阈值自适应阈值Otsus二值化 颜色空间转换 在 OpenCV 中有超过 150 中进行颜色空间转换的方法。但是你以后就会 发现我们经常用到的也就两种&#xff1…...

分清性能测试,负载测试,压力测试这三个的区别

做测试一年多来&#xff0c;虽然平时的工作都能很好的完成&#xff0c;但最近突然发现自己在关于测试的整体知识体系上面的了解很是欠缺&#xff0c;所以&#xff0c;在工作之余也做了一些测试方面的知识的补充。不足之处&#xff0c;还请大家多多交流&#xff0c;互相学习。 …...

前端架构师岗位的工作职责(合集)

前端架构师岗位的工作职责1 职责&#xff1a; 1.制定前端的标准和规范&#xff0c;并推广和应用&#xff0c;提高团队的开发效率; 2.前端架构的框架或核心模块的设计与实现; 3.在前端架构、设计与开发上对团队进行足够的指导; 4.在日常的系统设计与优化上与服务端团队紧密合…...

使用 Amazon ECS Anywhere 在边缘部署 Amazon IoT Greengrass

1.概述 亚马逊云科技提供了完备的IoT服务能力&#xff0c;涵盖设备服务、连接和控制服务以及云端分析服务&#xff0c;是快速构建安全可靠、可扩展的 IoT 平台的常见选择。Amazon IoT Greengrass 边缘运行时和云服务&#xff0c;可帮助您在设备上构建、部署和管理 IoT 应用。A…...

大数据学习栈记——Neo4j的安装与使用

本文介绍图数据库Neofj的安装与使用&#xff0c;操作系统&#xff1a;Ubuntu24.04&#xff0c;Neofj版本&#xff1a;2025.04.0。 Apt安装 Neofj可以进行官网安装&#xff1a;Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...

遍历 Map 类型集合的方法汇总

1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...

可靠性+灵活性:电力载波技术在楼宇自控中的核心价值

可靠性灵活性&#xff1a;电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中&#xff0c;电力载波技术&#xff08;PLC&#xff09;凭借其独特的优势&#xff0c;正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据&#xff0c;无需额外布…...

Objective-C常用命名规范总结

【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名&#xff08;Class Name)2.协议名&#xff08;Protocol Name)3.方法名&#xff08;Method Name)4.属性名&#xff08;Property Name&#xff09;5.局部变量/实例变量&#xff08;Local / Instance Variables&…...

VTK如何让部分单位不可见

最近遇到一个需求&#xff0c;需要让一个vtkDataSet中的部分单元不可见&#xff0c;查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行&#xff0c;是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示&#xff0c;主要是最后一个参数&#xff0c;透明度…...

UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)

UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中&#xff0c;UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化&#xf…...

Caliper 配置文件解析:config.yaml

Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...

tree 树组件大数据卡顿问题优化

问题背景 项目中有用到树组件用来做文件目录&#xff0c;但是由于这个树组件的节点越来越多&#xff0c;导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多&#xff0c;导致的浏览器卡顿&#xff0c;这里很明显就需要用到虚拟列表的技术&…...

Kafka入门-生产者

生产者 生产者发送流程&#xff1a; 延迟时间为0ms时&#xff0c;也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于&#xff1a;异步发送不需要等待结果&#xff0c;同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...

JavaScript 数据类型详解

JavaScript 数据类型详解 JavaScript 数据类型分为 原始类型&#xff08;Primitive&#xff09; 和 对象类型&#xff08;Object&#xff09; 两大类&#xff0c;共 8 种&#xff08;ES11&#xff09;&#xff1a; 一、原始类型&#xff08;7种&#xff09; 1. undefined 定…...