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等版本,否则出现如下异常:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/27334.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

sigmoid ReLU 等激活函数总结

sigmoid ReLU sigoid和ReLU对比 1.sigmoid有梯度消失问题&#xff1a;当sigmoid的输出非常接近0或者1时&#xff0c;区域的梯度几乎为0&#xff0c;而ReLU在正区间的梯度总为1。如果Sigmoid没有正确初始化&#xff0c;它可能在正区间得到几乎为0的梯度。使模型无法有效训练。 …

TCP和UDP

目录 TCP和UDP是什么&#xff1f; TCP和UDP有什么区别? 三次握手和四次挥手 TCP维护可靠的通信方式 拥塞控制 滑动窗口的原理 什么是粘包以及粘包的原因 粘包的处理方式 TCP和UDP使用场景 TCP和UDP是什么&#xff1f; TCP&#xff1a; 传输控制协议&#xff08;TCP&am…

HarmonyOS元服务开发实践:桌面卡片字典

一、项目说明 1.DEMO创意为卡片字典。 2.不同卡片显示不同内容&#xff1a;微卡、小卡、中卡、大卡&#xff0c;根据不同卡片特征显示同一个字的不同内容&#xff0c;基于用户习惯可选择喜欢的卡片。 3.万能卡片刷新&#xff1a;用户点击卡片刷新按钮查看新内容&#xff0c;同时…

Java课题笔记~ AspectJ 的开发环境(掌握)

AspectJ 的开发环境(掌握) &#xff08;1&#xff09; maven 依赖 <dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></depe…

深度学习和OpenCV的对象检测(MobileNet SSD图像识别)

基于深度学习的对象检测时,我们主要分享以下三种主要的对象检测方法: Faster R-CNN(后期会来学习分享)你只看一次(YOLO,最新版本YOLO3,后期我们会分享)单发探测器(SSD,本节介绍,若你的电脑配置比较低,此方法比较适合R-CNN是使用深度学习进行物体检测的训练模型; 然而,…

项目实战 — 消息队列(4){消息持久化}

目录 一、消息存储格式设计 &#x1f345; 1、queue_data.txt&#xff1a;保存消息的内容 &#x1f345; 2、queue_stat.txt&#xff1a;保存消息的统计信息 二、消息序列化 三、自定义异常类 四、创建MessageFileManger类 &#x1f345; 1、约定消息文件所在的目录和文件名…

探索CSS计数器:优雅管理网页元素的计数与序号

113. 探索CSS计数器&#xff1a;优雅管理网页元素的计数与序号 在前端开发中&#xff0c;我们经常需要对网页元素进行计数与序号&#xff0c;如有序列表、表格行号、步骤指示等。为了优雅地管理这些计数与序号&#xff0c;CSS提供了一种强大的功能&#xff1a;CSS计数器&#…

掌握 JVM 调优命令

常用命令 1、jps查看当前 java 进程2、jinfo实时查看和调整 JVM 配置参数3、jstat查看虚拟机统计信息4、jstack查看线程堆栈信息5、jmap查看堆内存的快照信息 JVM 日常调优总结起来就是&#xff1a;首先通过 jps 命令查看当前进程&#xff0c;然后根据 pid 通过 jinfo 命令查看…

MemFire教程|FastAPI+MemFire Cloud+LangChain开发ChatGPT应用-Part2

基本介绍 上篇文章我们讲解了使用FastAPIMemFire CloudLangChain进行GPT知识库开发的基本原理和关键路径的代码实现。目前完整的实现代码已经上传到了github&#xff0c;感兴趣的可以自己玩一下&#xff1a; https://github.com/MemFire-Cloud/memfirecloud-qa 目前代码主要…

ffmpeg源码编译成功,但是引用生成的静态库(.a)报错,报错位置在xxx_list.c,报错信息为某变量未定义

背景&#xff1a;本文是对上一个文章的补充&#xff0c;在源码编译之前&#xff0c;项目是有完整的ffmpeg编译脚本的&#xff0c;只不过新增了断点调试ffmpeg&#xff0c;所以产生的上面的文章&#xff0c;也就是说&#xff0c;我在用make编译成功后&#xff0c;再去做的源码编…

Jenkins+Nginx+vue

安装nodejs 在这里插入图片描述 echo off xcopy C:\ProgramData\Jenkins\.jenkins\workspace\super_manage_vue\dist F:\java\www\super_manage_vue\ /s /e /y echo 复制文件完成 exit安装niginx 配置文件如下 #user nobody; worker_processes 1;#error_log logs/error.lo…

4、长度最小的子数组

找到一个数组中&#xff0c;有多少个连续元素的和小于某个值&#xff0c;求出连续元素的长度的最小值。 滑动窗口法&#xff1a; 其本质也是快慢指针&#xff0c;一个指针指向窗口的起始位置&#xff0c;另一个指针指向窗口的终止位置。 1.定义快慢指针&#xff1a; 2.更新慢指…

排序算法(二)

1.希尔排序-Shell Sort 1.算法原理 将未排序序列按照增量gap的不同分割为若干个子序列&#xff0c;然后分别进行插入排序&#xff0c;得到若干组排好序的序列&#xff1b; 缩小增量gap&#xff0c;并对分割为的子序列进行插入排序&#xff1b;最后一次的gap1&#xff0c;即整个…

【Linux操作系统】GCC编译与静态库、动态库制作详解

GCC是一款广泛使用的开源编译器&#xff0c;它支持多种编程语言&#xff0c;并且具有强大的编译能力。在软件开发中&#xff0c;我们经常需要将代码编译成可执行文件或者库文件。本文将详细介绍GCC编译过程以及如何制作静态库和动态库。 文章目录 一、GCC编译过程1. 预处理阶段…

打破传统直播,最新数字化升级3DVR全景直播

导语&#xff1a; 近年来&#xff0c;随着科技的不断创新和发展&#xff0c;传媒领域也正经历着一场前所未有的变革。在这个数字化时代&#xff0c;直播已经不再仅仅是在屏幕上看到一些人的视频&#xff0c;而是将观众带入一个真实世界的全新体验。其中&#xff0c;3DVR全景直…

架构训练营学习笔记:6-1 微服务

序 这部分是了解的。传统企业使用soa较多。很多企业银行、电信对于Oracle 依赖大&#xff0c;强调稳定性。各个项目侧重外包&#xff0c;技术栈不统一。 soa 历史 这个之前电信的BOSS系统就是这种架构&#xff0c;不知道现在呢&#xff0c;核心计费系统billing是运行在tuxduo…

【Linux】操作系统与冯诺依曼体系——深度解析(软硬件层面)

​ 前言 大家好吖&#xff0c;欢迎来到 YY 滴 Linux系列 &#xff0c;热烈欢迎&#xff01; 本章主要内容面向接触过Linux的老铁&#xff0c;从软硬件层面向大家介绍操作系统与冯诺依曼体系&#xff0c; 主要内容含&#xff1a; 欢迎订阅 YY滴Linux专栏&#xff01;更多干货持…

el-table那些事

el-table那些事 获取el-table所有勾选的行数据 用于记录工作和日常学习遇到的坑&#xff0c;需求。 vue3element-plusts 获取el-table所有勾选的行数据 1、需要先声明一个ref变量&#xff0c;并赋值给el-table 2、通过el-table提供的getSelectionRows()函数获取选中的"行…

【iPhone】手机还有容量,拍视频却提示 iPhone 储存空间已满

文章目录 前言解决方案 结语 前言 今天在用 iPhone 录像的时候突然提醒我 iPhone储存空间已满 你没有足够的储存空间来录制视频” 可我明明还有 20G 的容量 我非常疑惑&#xff0c;因为我之前还剩1个G都能录像&#xff0c;现在20G反而不行了&#xff0c;于是重启了手机&#…

伦敦金费用有哪几方面?

通常在网上开设伦敦金投资账户是没有成本的&#xff0c;而它交易的费用&#xff0c;主要是由点差和过夜利息&#xff08;仓息&#xff09;构成。如果伦敦金投资者只是做短线的日内交易&#xff0c;做一手完整的100盎司的标准合约&#xff0c;需要支付大约50美元点差费用&#x…