文章目录
环境搭建
0.实体类
1.业务层接口
2.业务层实现类
3.持久层接口
4.持久层实现类
5.配置文件:bean.xml
6.测试类
通过注解代替bean.xml配置文件
@Component("account")
@Value("zhangsan")
@Service("accountDao")
@Autowired
@Repository("accountDao")
@Configuration
@ComponentScan
@Bean
测试
@Import
@PropertySource
Spring整合Junit
总结
0.实体类
1.业务层接口
2.业务层实现类
3.持久层接口
4.持久层实现类
5.SpringConfig配置主类
6.jdbcConfig.properties
7.JDBCConfig配置副类
8.测试类
环境搭建
数据库:
- create table account(
- id int primary key auto_increment,
- name varchar(40),
- money float
- )character set utf8 collate utf8_general_ci;
-
- insert into account(name,money) values('aaa',1000);
- insert into account(name,money) values('bbb',1000);
- insert into account(name,money) values('ccc',1000);

项目的目录结构:

pom.xml:
- <dependencies>
-
- <dependency>
- <groupId>mysqlgroupId>
- <artifactId>mysql-connector-javaartifactId>
- <version>8.0.18version>
- dependency>
-
- <dependency>
- <groupId>org.springframeworkgroupId>
- <artifactId>spring-webmvcartifactId>
- <version>5.2.0.RELEASEversion>
- dependency>
-
- <dependency>
- <groupId>junitgroupId>
- <artifactId>junitartifactId>
- <version>4.12version>
- <scope>testscope>
- dependency>
-
- <dependency>
- <groupId>c3p0groupId>
- <artifactId>c3p0artifactId>
- <version>0.9.1.2version>
- dependency>
-
- <dependency>
- <groupId>commons-dbutilsgroupId>
- <artifactId>commons-dbutilsartifactId>
- <version>1.7version>
- dependency>
-
- <dependency>
- <groupId>junitgroupId>
- <artifactId>junitartifactId>
- <version>4.12version>
- <scope>testscope>
- dependency>
- dependencies>
0.实体类
- public class Account {
- private Integer id;
- private String name;
- private Float money;
-
- public Integer getId() {
- return id;
- }
-
- public void setId(Integer id) {
- this.id = id;
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public Float getMoney() {
- return money;
- }
-
- public void setMoney(Float money) {
- this.money = money;
- }
-
- @Override
- public String toString() {
- return "Account{" +
- "id=" + id +
- ", name='" + name + '\'' +
- ", money=" + money +
- '}';
- }
- }
1.业务层接口
- public interface AccountService {
- //查询所有
- List
findAllAccount(); - //查询一个
- Account findAccountById(Integer id);
- //保存
- void saveAccount(Account account);
- //更新
- void updateAccount(Account account);
- //删除
- void deleteAccount(Integer id);
- }
2.业务层实现类
- //业务层实现类,业务层调用持久层
- public class AccountServiceImpl implements AccountService{
- private AccountDao accountDao;
-
- public void setAccountDao(AccountDao accountDao) {
- this.accountDao = accountDao;
- }
-
- public List
findAllAccount() { - return accountDao.findAllAccount();
- }
-
- public Account findAccountById(Integer id) {
- return accountDao.findAccountById(id);
- }
-
- public void saveAccount(Account account) {
- accountDao.saveAccount(account);
- }
-
- public void updateAccount(Account account) {
- accountDao.updateAccount(account);
- }
-
- public void deleteAccount(Integer id) {
- accountDao.deleteAccount(id);
- }
- }
3.持久层接口
- //账户的持久层接口
- public interface AccountDao {
- //查询所有
- List
findAllAccount(); - //查询一个
- Account findAccountById(Integer id);
- //保存
- void saveAccount(Account account);
- //更新
- void updateAccount(Account account);
- //删除
- void deleteAccount(Integer id);
- }
4.持久层实现类
- //持久层实现类
- public class AccountDaoImpl implements AccountDao {
- private QueryRunner runner;
-
- public void setRunner(QueryRunner runner) {
- this.runner = runner;
- }
-
- public List
findAllAccount() { - try {
- return runner.query("select * from account",new BeanListHandler
(Account.class)); - } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
-
- public Account findAccountById(Integer id) {
- try {
- return runner.query("select * from account where id=?",new BeanHandler
(Account.class),id); - } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
-
- public void saveAccount(Account account) {
- try {
- runner.update("insert into account(name,money) values(?,?)",account.getName(),account.getMoney());
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
-
- public void updateAccount(Account account) {
- try {
- runner.update("update account set name=?,money=? where id=?",account.getName(),account.getMoney(),account.getId());
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
-
- public void deleteAccount(Integer id) {
- try {
- runner.update("delete from account where id=?",id);
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
- }
5.配置文件:bean.xml
- "1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- 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.xsd">
-
-
- <context:component-scan base-package="com.hh"/>
-
-
- <bean id="account" class="com.hh.domain.Account">
- <property name="name" value="zhangsan"/>
- <property name="money" value="2000"/>
- bean>
-
-
- <bean id="accountService" class="com.hh.service.AccountServiceImpl">
-
- <property name="accountDao" ref="accountDao"/>
- bean>
-
-
- <bean id="accountDao" class="com.hh.dao.AccountDaoImpl">
-
- <property name="runner" ref="queryRunner"/>
- bean>
-
-
- <bean id="queryRunner" class="org.apache.commons.dbutils.QueryRunner" scope="prototype">
-
- <constructor-arg name="ds" ref="dataSource"/>
- bean>
-
-
- <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
-
- <property name="driverClass" value="com.mysql.jdbc.Driver"/>
- <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/spring"/>
- <property name="user" value="root"/>
- <property name="password" value="123"/>
- bean>
- beans>
6.测试类
- public class MyTest {
- @Test
- public void testFindAll(){
- //获取Spring核心容器
- ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
- //得到业务层对象
- AccountService service =
- context.getBean("accountService", AccountService.class);
- List
accounts = service.findAllAccount(); - for(Account account :accounts){
- System.out.println(account);
- }
- }
-
- @Test
- public void testFindone(){
- //获取Spring核心容器
- ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
- //得到业务层对象
- AccountService service =
- context.getBean("accountService", AccountService.class);
- Account account = service.findAccountById(3);
- System.out.println(account);
- }
-
- @Test
- public void testSave(){
- //获取Spring核心容器
- ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
- //得到业务层对象
- AccountService service =
- context.getBean("accountService", AccountService.class);
- //获取Account对象
- Account account = context.getBean("account",Account.class);
- service.saveAccount(account);
- }
-
- @Test
- public void testUpdate(){
- //获取Spring核心容器
- ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
- //得到业务层对象
- AccountService service =
- context.getBean("accountService", AccountService.class);
- context.getBean("account");
- //获取Account对象
- Account account = service.findAccountById(4);
- account.setMoney(3000f);
- service.updateAccount(account);
- }
-
- @Test
- public void testDelete(){
- //获取Spring核心容器
- ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
- //得到业务层对象
- AccountService service =
- context.getBean("accountService", AccountService.class);
- context.getBean("account");
- service.deleteAccount(4);
- }
- }
通过注解代替bean.xml配置文件
- "1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- 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.xsd">
-
-
- <context:component-scan base-package="com.hh"/>
-
-
- <bean id="account" class="com.hh.domain.Account">
- <property name="name" value="zhangsan"/>
- <property name="money" value="2000"/>
- bean>
-
-
- <bean id="accountService" class="com.hh.service.AccountServiceImpl">
-
- <property name="accountDao" ref="accountDao"/>
- bean>
-
-
-
-
- <bean id="accountDao" class="com.hh.dao.AccountDaoImpl">
-
- <property name="runner" ref="queryRunner"/>
- bean>
-
-
- <bean id="queryRunner" class="org.apache.commons.dbutils.QueryRunner" scope="prototype">
-
- <constructor-arg name="ds" ref="dataSource"/>
- bean>
-
-
- <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
-
- <property name="driverClass" value="com.mysql.jdbc.Driver"/>
- <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/spring"/>
- <property name="user" value="root"/>
- <property name="password" value="123"/>
- bean>
- beans>
既然是使用注解开发,那么思考一个问题,要通过哪些注解把上面的xml文件去掉,不再使用bean.xml呢?
@Component(“account”)
使用@Component来创建Account对象,将Account对象放进IOC容器

代替bean.xml中下面的配置:
- <bean id="account" class="com.hh.domain.Account">
- bean>
@Value(“zhangsan”)
如果不想在测试类中调用setter方法初始化,可以使用注解依赖注入

代替bean.xml中下面的配置:
- <bean id="account" class="com.hh.domain.Account">
- <property name="name" value="zhangsan"/>
- <property name="money" value="2000"/>
- bean>
@Service(“accountDao”)
使用@Service来创建accountService对象

代替bean.xml中下面的配置:
- <bean id="accountService" class="com.hh.service.AccountServiceImpl">
-
- <property name="accountDao" ref="accountDao"/>
- bean>
@Autowired
由于AccountServiceImpl中有一个bean对象属性,因此可以通过@Autowired依赖注入,可以省略setter方法

@Repository(“accountDao”)
使用@Repository来创建accountDao对象

代替bean.xml中下面的配置:
- <bean id="accountDao" class="com.hh.dao.AccountDaoImpl">
-
- <property name="runner" ref="queryRunner"/>
- bean>
@Configuration
作用:指定当前类是一个配置类,作用和bean.xml相同
- //该类是一个配置类,作用和bean.xml相同
- @Configuration
- public class SpringConfig {
-
- }
@ComponentScan
作用:用于通过注解指定Spring在创建容器中要扫描的包
属性:value和bacePackages作用相同,都是指定要扫描的包
作用等同于xml中的:

使用@ComponentScan指定要扫描的包

代替bean.xml中下面的配置:
-
- <context:component-scan base-package="com.hh"/>
@Bean
作用:用于把当前方法的返回值作为bean对象存入Spring容器中
属性:name:用于指定bean的id,不写时默认为当前方法的名称
细节:当我们使用注解配置方法时,如果方法有参数,Spring框架回去容器中找有没有可用的bean对象,查找的方式和Autowired一样。


代替bean.xml中下面的配置:
- <bean id="queryRunner" class="org.apache.commons.dbutils.QueryRunner" scope="prototype">
-
- <constructor-arg name="ds" ref="dataSource"/>
- bean>
-
-
- <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
-
- <property name="driverClass" value="com.mysql.jdbc.Driver"/>
- <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/spring"/>
- <property name="user" value="root"/>
- <property name="password" value="123"/>
- bean>
-
- <bean id="account" class="com.hh.domain.Account">
- <property name="name" value="zhangsan"/>
- <property name="money" value="2000"/>
- bean>
到目前为止,我们已经把配置文件中所有的配置都去掉了,目前就是下面这个样子,同时就可以吧这个bean.xml删除了:
bean.xml:
- "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
- http://www.springframework.org/schema/context/spring-context.xsd">
- beans>
测试
下面我们需要对注解改造过的项目进行测试,那么问题来了,之前我们都是通过配置文件bean.xml来获取Spring的IOC核心容器ApplicationContext,现在注解删了,还怎么获取?
下面要通过ApplicationContext的另一个实现类:

- public class MyTest {
- @Test
- public void testSave(){
- //获取Spring核心容器
- ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
- //得到业务层对象
- AccountService service =
- context.getBean("accountService", AccountService.class);
- //获取Account对象
- Account account = context.getBean("account",Account.class);
- service.saveAccount(account);
- }

@Import
当配置类作为容器对象AnnotationConfigApplicationContext的参数时,@Configuration注解可以省略不写

配置类JDBCConfig:
- //和Spring连接数据库相关的配置类
- public class JDBCConfig {
- //用于创建一个QueryRunner对象
- @Bean(name="queryRunner")
- public QueryRunner createQueryRunner(DataSource dataSource){
- return new QueryRunner(dataSource);
- }
- //创建一个DataSource对象
- @Bean(name="dataSource")
- public DataSource createDataSource() throws PropertyVetoException {
- ComboPooledDataSource ds = new ComboPooledDataSource();
- ds.setDriverClass("com.mysql.jdbc.Driver");
- ds.setJdbcUrl("jdbc:mysql://localhost:3306/spring");
- ds.setUser("root");
- ds.setPassword("123");
- return ds;
- }
- }
如上图,重新在config包下面写一个配置类JDBCConfig,如果把这个配置类的注解@Configuration省略不写,就要把这个配置类JDBCConfig.class加到容器对象的参数中


如果在JDBCConfig类上加了@Configuration注解,那么就不需要再容器对象参数中写入JDBCConfig.class


问题来了,现在有两个配置类SpringConfig和JDBCConfig,如果我既不想在JDBCConfig类上加一个@Configuration注解,也不想在容器对象参数中加入JDBCConfig.class呢?这个时候就需要引入一个新注解@Import。把配置类JDBCConfig导入配置类SpringConfig中。
@Import作用:用于导入其他的配置类
使用Import注解后,有Import注解的类就是主配置类,导入的都是副配置类



@PropertySource
现在还有一个问题注意看SpringConfig配置类:
- //和Spring连接数据库相关的配置类
- public class JDBCConfig {
- //用于创建一个QueryRunner对象
- @Bean(name="queryRunner")
- public QueryRunner createQueryRunner(DataSource dataSource){
- return new QueryRunner(dataSource);
- }
- //创建一个DataSource对象
- @Bean(name="dataSource")
- public DataSource createDataSource() throws PropertyVetoException {
- ComboPooledDataSource ds = new ComboPooledDataSource();
- ds.setDriverClass("com.mysql.jdbc.Driver");
- ds.setJdbcUrl("jdbc:mysql://localhost:3306/spring");
- ds.setUser("root");
- ds.setPassword("123");
- return ds;
- }
- }

写一个jdbcConfig.properties配置文件:
- driver=com.mysql.jdbc.Driver
- url=jdbc:mysql://localhost:3306/spring
- username=root
- password=123
在配置类JDBCConfig中写入这几个属性,并指定值:


@PropertySource
作用:用于指定properties文件的位置
属性:value用于指定文件的名称和路径
关键字:classPath:表示类路径下

Spring整合Junit
1.导入spring整合Junit的jar包
- <dependency>
- <groupId>org.springframeworkgroupId>
- <artifactId>spring-testartifactId>
- <version>5.2.0.RELEASEversion>
- <scope>testscope>
- dependency>
2.使用Junit提供的一个注解把原有的main方法替换了,替换成spring提供的@Runwith
3.告知spring的运行器,spring的ioc的创建是基于xml的还是基于注解的,并说明位置。
@ContextConfigration
locations:指定xml文件的位置,加上classpath关键字,表示在类路径下。
classes:自定注解所在的位置
总结
0.实体类
- package com.hh.domain;
-
-
-
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.beans.factory.annotation.Value;
- import org.springframework.stereotype.Component;
-
- //实体类
- @Component("account")
- public class Account {
- private Integer id;
- @Value("zhangsan")
- private String name;
- @Value("2000f")
- private Float money;
-
-
- public void setId(Integer id) {
- this.id = id;
- }
- public void setName(String name) {
- this.name = name;
- }
- public void setMoney(Float money) {
- this.money = money;
- }
-
- public Integer getId() {
- return id;
- }
-
- public String getName() {
- return name;
- }
-
- public Float getMoney() {
- return money;
- }
-
- @Override
- public String toString() {
- return "Account{" +
- "id=" + id +
- ", name='" + name + '\'' +
- ", money=" + money +
- '}';
- }
- }
1.业务层接口
- public interface AccountService {
- //查询所有
- List
findAllAccount(); - //查询一个
- Account findAccountById(Integer id);
- //保存
- void saveAccount(Account account);
- //更新
- void updateAccount(Account account);
- //删除
- void deleteAccount(Integer id);
- }
2.业务层实现类
- @Service("accountService")
- public class AccountServiceImpl implements AccountService{
-
- @Autowired
- private AccountDao accountDao;
-
- public List
findAllAccount() { - return accountDao.findAllAccount();
- }
-
- public Account findAccountById(Integer id) {
- return accountDao.findAccountById(id);
- }
-
- public void saveAccount(Account account) {
- accountDao.saveAccount(account);
- }
-
- public void updateAccount(Account account) {
- accountDao.updateAccount(account);
- }
-
- public void deleteAccount(Integer id) {
- accountDao.deleteAccount(id);
- }
- }
3.持久层接口
- //账户的持久层接口
- public interface AccountDao {
- //查询所有
- List
findAllAccount(); - //查询一个
- Account findAccountById(Integer id);
- //保存
- void saveAccount(Account account);
- //更新
- void updateAccount(Account account);
- //删除
- void deleteAccount(Integer id);
- }
4.持久层实现类
- //持久层实现类
- @Repository("accountDao")
- public class AccountDaoImpl implements AccountDao {
- @Autowired
- private QueryRunner runner;
-
- public List
findAllAccount() { - try {
- return runner.query("select * from account",new BeanListHandler
(Account.class)); - } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
-
- public Account findAccountById(Integer id) {
- try {
- return runner.query("select * from account where id=?",new BeanHandler
(Account.class),id); - } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
-
- public void saveAccount(Account account) {
- try {
- runner.update("insert into account(name,money) values(?,?)",account.getName(),account.getMoney());
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
-
- public void updateAccount(Account account) {
- try {
- runner.update("update account set name=?,money=? where id=?",account.getName(),account.getMoney(),account.getId());
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
-
- public void deleteAccount(Integer id) {
- try {
- runner.update("delete from account where id=?",id);
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
- }
5.SpringConfig配置主类
- //该类是一个配置类,作用和bean.xml相同
- @ComponentScan("com.hh")
- @Import(JDBCConfig.class)
- @PropertySource("classpath:jdbcConfig.properties")
- public class SpringConfig {
-
- //用于创建一个QueryRunner对象
- @Bean(name="queryRunner")
- public QueryRunner createQueryRunner(DataSource dataSource){
- return new QueryRunner(dataSource);
- }
- }
6.jdbcConfig.properties
- driver=com.mysql.jdbc.Driver
- url=jdbc:mysql://localhost:3306/spring?serverTimezone=UTC
- username=root
- password=123
7.JDBCConfig配置副类
- //和Spring连接数据库相关的配置类
- public class JDBCConfig {
- @Value("${driver}")
- private String driver;
- @Value("${url}")
- private String url;
- @Value("${username}")
- private String username;
- @Value("${password}")
- private String password;
-
- //用于创建一个QueryRunner对象
- @Bean(name="queryRunner")
- public QueryRunner createQueryRunner(DataSource dataSource){
- return new QueryRunner(dataSource);
- }
- //创建一个DataSource对象
- @Bean(name="dataSource")
- public DataSource createDataSource() throws PropertyVetoException {
- ComboPooledDataSource ds = new ComboPooledDataSource();
- ds.setDriverClass(driver);
- ds.setJdbcUrl(url);
- ds.setUser(username);
- ds.setPassword(password);
- return ds;
- }
- }
8.测试类
- @RunWith(SpringJUnit4ClassRunner.class)
- @ContextConfiguration(classes = SpringConfig.class)
- public class AccountServiceTest {
- @Autowired
- private AccountService service=null;
- @Autowired
- private Account account=null;
-
- @Test
- public void testFindAll(){
- List
accounts = service.findAllAccount(); - for(Account account :accounts){
- System.out.println(account);
- }
- }
-
- @Test
- public void testFindone(){
- Account account = service.findAccountById(3);
- System.out.println(account);
- }
-
- @Test
- public void testSave(){
- service.saveAccount(account);
- }
-
- @Test
- public void testUpdate(){
- account.setMoney(3000f);
- service.updateAccount(account);
- }
-
- @Test
- public void testDelete(){
- service.deleteAccount(4);
- }
- }