Spring使用纯注解实现的小案例+Spring-Junit整合

Spring使用纯注解实现的小案例

项目结构

在这里插入图片描述

数据库

在这里插入图片描述

配置文件

  1. pom.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>com.xiaoge</groupId>
        <artifactId>account_annoioc_withoutxml</artifactId>
        <version>1.0-SNAPSHOT</version>
        <packaging>jar</packaging>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>5.0.2.RELEASE</version>
            </dependency>
    
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-test</artifactId>
                <version>5.0.2.RELEASE</version>
            </dependency>
    
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>8.0.13</version>
            </dependency>
    
            <dependency>
                <groupId>commons-dbutils</groupId>
                <artifactId>commons-dbutils</artifactId>
                <version>1.4</version>
            </dependency>
    
            <dependency>
                <groupId>c3p0</groupId>
                <artifactId>c3p0</artifactId>
                <version>0.9.1.2</version>
            </dependency>
    
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.12</version>
            </dependency>
        </dependencies>
    
    </project>
    
  2. jdbcConfig.properties

    jdbc.driver = com.mysql.cj.jdbc.Driver
    jdbc.url = jdbc:mysql://localhost:3306/eesy
    jdbc.user = root
    jdbc.password = 123456
    

实体类

  1. Account

    package com.xiaoge.domain;
    
    import java.io.Serializable;
    
    /**
     * @Author: 潇哥
     * @DateTime: 2020/4/7 下午10:16
     * @Description: 账户实体类
     */
    public class Account implements Serializable {
    
        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. Account接口

    package com.xiaoge.dao;
    
    import com.xiaoge.domain.Account;
    
    import java.util.List;
    
    /**
     * @Author: 潇哥
     * @DateTime: 2020/4/7 下午10:25
     * @Description: 账户的持久层接口
     */
    public interface AccountDao {
    
        /**
         * 查询所有
         * @return
         */
        public List<Account> findAllAccount();
    
        /**
         * 查询一个
         * @return
         */
        public Account findAccountById(Integer id);
    
        /**
         * 保存
         */
        public void saveAccount(Account account);
    
        /**
         * 更新
         * @param account
         */
        public void updateAccount(Account account);
    
        /**
         * 删除
         * @param id
         */
        public void deleteAccount(Integer id);
    
    }
    
    
  2. AccountDaoImpl实现类

    package com.xiaoge.dao.impl;
    
    import com.xiaoge.dao.AccountDao;
    import com.xiaoge.domain.Account;
    import org.apache.commons.dbutils.QueryRunner;
    import org.apache.commons.dbutils.handlers.BeanHandler;
    import org.apache.commons.dbutils.handlers.BeanListHandler;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Repository;
    
    import java.sql.SQLException;
    import java.util.List;
    
    /**
     * @Author: 潇哥
     * @DateTime: 2020/4/7 下午10:25
     * @Description: 账户的持久层实现类
     */
    @Repository("accountDao")
    public class AccountDaoImpl implements AccountDao {
    
        @Autowired
        private QueryRunner runner;
    
        public List<Account> findAllAccount() {
            try {
                return runner.query("select * from account", new BeanListHandler<Account>(Account.class));
            } catch (SQLException e) {
                throw  new RuntimeException(e);
            }
        }
    
        public Account findAccountById(Integer id) {
            try {
                return runner.query("select * from account where id = ? ", new BeanHandler<Account>(Account.class), id);
            } catch (SQLException e) {
                throw  new RuntimeException(e);
            }
        }
    
        public void saveAccount(Account account) {
            try {
                runner.update("insert into account(name, money) values(?, ?)", account.getName(), account.getMoney());
            } catch (SQLException 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 (SQLException e) {
                throw  new RuntimeException(e);
            }
        }
    
        public void deleteAccount(Integer id) {
            try {
                runner.update("delete from account where id = ? ", id);
            } catch (SQLException e) {
                throw  new RuntimeException(e);
            }
        }
    }
    
    

业务层

  1. AccountService接口

    package com.xiaoge.service;
    
    import com.xiaoge.domain.Account;
    
    import java.util.List;
    
    /**
     * @Author: 潇哥
     * @DateTime: 2020/4/7 下午10:14
     * @Description: 账户的业务层接口
     */
    public interface AccountService {
    
        /**
         * 查询所有
         * @return
         */
        public List<Account> findAllAccount();
    
        /**
         * 查询一个
         * @return
         */
        public Account findAccountById(Integer id);
    
        /**
         * 保存
         */
        public void saveAccount(Account account);
    
        /**
         * 更新
         * @param account
         */
        public void updateAccount(Account account);
    
        /**
         * 删除
         * @param id
         */
        public void deleteAccount(Integer id);
    }
    
    
  2. AccountServiceImpl实现类

    package com.xiaoge.service.impl;
    
    import com.xiaoge.dao.AccountDao;
    import com.xiaoge.domain.Account;
    import com.xiaoge.service.AccountService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    import java.util.List;
    
    /**
     * @Author: 潇哥
     * @DateTime: 2020/4/7 下午10:14
     * @Description: 账户的业务层实现类
     */
    @Service("accountService")
    public class AccountServiceImpl implements AccountService {
    
        @Autowired // 由于是唯一的所以  可以直接用Autowired注解, 用注解注入时  set方法可以不写
        private AccountDao accountDao;
    
        public List<Account> 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);
        }
    }
    
    

配置类

  1. SpringConfiguration主配置类(重点注释)

    package config;
    
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Import;
    import org.springframework.context.annotation.PropertySource;
    
    /**
     * @Author: 潇哥
     * @DateTime: 2020/4/8 下午10:56
     * @Description: 该类是一个配置类, 它的作用和bean.xml是一样的
     *
     *
     * spring中的新注解
     *      Configuration
     *          作用: 指定当前类是一个配置类
     *          细节: 当配置类作为AnnotationConfigApplicationContext对象创建的参数时, 该注解可以不写.
     *
     *
     *      ComponentScan
     *          作用: 用于通过注解指定spring在创建容器时要扫描的包
     *          属性:
     *              value: 它和basePackages的作用是一样的, 都是用于指定创建容器时要扫描的包.
     *                     我们使用此注解就等同于在xml中配置了:
     *                          <context:component-scan base-package="com.xiaoge"></context:component-scan>
     *      Bean
     *          作用: 用于把当前方法的返回值作为bean对象存入spring的ioc容器中
     *          属性:
     *              name: 用于指定bean的id. 当不写时, 默认是当前方法的名称
     *          细节:
     *              当我们使用注解配置方法时, 如果方法有参数, spring框架会去容器中查找有没有可用的bean对象.
     *              查找的方式和Autowired注解的作用是一样的
     *
     *      Import
     *          作用: 用于导入其他的配置类
     *          属性:
     *              value: 用于指定其他配置类的字节码.
     *                     当我们使用Import的注解之后, 有Import注解的类就是父配置类, 而导入的都是子配置类
     *
     *      PropertySource
     *          作用: 用于指定properties文件的位置
     *          属性:
     *              value: 指定文件的名称和路径.
     *                     关键字: classpath, 表示类路径下
     *                     列:
     *                       没有包, 直接写文件名:
     *                          classpath:jdbcConfig.properties
     *                       有包, 就是包路径 + 文件名
     *                          classpath: com/xiaoge/jdbcConfig.properties
     */
    // @Configuration
    @ComponentScan(basePackages = {"com.xiaoge"})
    @Import(JdbcConfig.class)
    @PropertySource("classpath:jdbcConfig.properties")
    public class SpringConfiguration {
    
    
    
    }
    
    
  2. JdbcConfig子配置类(重点注释)

    package config;
    
    import com.mchange.v2.c3p0.ComboPooledDataSource;
    import org.apache.commons.dbutils.QueryRunner;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Scope;
    
    import javax.sql.DataSource;
    
    /**
     * @Author: 潇哥
     * @DateTime: 2020/4/9 下午11:12
     * @Description: 和spring连接数据库相关的配置类
     *
     *
     * @Value
     *      作用: 用于注入基本类型和String类型的数据
     *      属性:
     *          value: 用于指定数据的值. 它可以使用spring中SpEL(也就是spring的el表达式)
     *          SpEL的写法: ${表达式}
     *
     *@Qualifier:(不能独立使用, 依赖@Autowired)
     *         作用: 在按照类中注入的基础之上在按照名称注入. 它在给类成员注入时不能单独使用. 但是在给方法参数注入时可以
     *         属性:
     *             value: 用于指定注入bean的id.
     *
     */
    // @Configuration
    public class JdbcConfig {
    
        @Value("${jdbc.driver}")
        private String driver;
    
        @Value("${jdbc.url}")
        private String url;
    
        @Value("${jdbc.user}")
        private String username;
    
        @Value("${jdbc.password}")
        private String password;
    
    
        /**
         * 用于创建 QueryRunner
         * @param dataSource
         * @return
         */
        @Bean(name = "runner")
        @Scope("prototype") // 这里用Qualifier注解是防止有多个bean对象都满足时, 报错, 这里给指定一个id, 根据id来找bean对象
        public QueryRunner createQueryRunner(@Qualifier("dataSource") DataSource dataSource){
            return new QueryRunner(dataSource);
        }
    
    
        /**
         * 创建爱你数据源对象
         * @return
         */
        @Bean(name = "dataSource")
        public DataSource createDataSource(){
            try{
                ComboPooledDataSource ds = new ComboPooledDataSource();
                ds.setDriverClass(driver);
                ds.setJdbcUrl(url);
                ds.setUser(username);
                ds.setPassword(password);
                return ds;
            } catch(Exception e) {
                throw new RuntimeException(e);
            }
    
        }
    
    }
    
    

测试层

  1. AccountServiceTest测试类(重点注释)

    package com.xiaoge.test;
    
    import com.xiaoge.domain.Account;
    import com.xiaoge.service.AccountService;
    import config.SpringConfiguration;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.test.context.ContextConfiguration;
    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    
    import java.util.List;
    
    /**
     * @Author: 潇哥
     * @DateTime: 2020/4/7 下午10:52
     * @Description: 使用Junit单元测试, 测试我们的配置
     *
     * Spring整合junit的配置
     *      1. 导入spring整合junit的jar(坐标)
     *      2. 使用junit提供的一个注解把原有的main方法替换了, 替换成spring提供的
     *          @Runwith
     *      3. 告知spring的运行器, spring和ioc的创建基于xml还是注解的, 并且说明位置
     *          @ContextConfiguration
     *              locations: 指定xml文件的位置, 加上classpath关键字, 表示在类路径下
     *              classes: 指定注解类所在的位置
     *
     * 当我们使用spring 5.x版本的时候, 要求junit的jar必须是4.12及以上版本
     *
     */
    
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(classes = SpringConfiguration.class)
    public class AccountServiceTest {
    
        @Autowired
        private AccountService accountService;
    
        @Test
        public void findAllTest() {
            // 1. 执行方法
            List<Account> allAccount = accountService.findAllAccount();
    
            for (Account account : allAccount) {
                System.out.println(account);
            }
    
        }
    
        @Test
        public void findOneTest() {
            // 1. 执行方法
            Account account = accountService.findAccountById(1);
    
            System.out.println(account);
    
        }
    
        @Test
        public void saveAccountTest() {
            // 1. 构造对象
            Account account = new Account();
            account.setName("ddd");
            account.setMoney(2000f);
    
            // 2. 执行方法
            accountService.saveAccount(account);
    
        }
    
        @Test
        public void updateAccountTest() {
            // 1. 构造对象
            Account account = new Account();
            account.setId(3);
            account.setName("ddd");
            account.setMoney(2000f);
    
            // 2. 执行方法
            accountService.updateAccount(account);
    
        }
    
        @Test
        public void deleteAccountTest() {
            // 1. 执行方法
            accountService.deleteAccount(3);
    
        }
    }
    
    
发布了323 篇原创文章 · 获赞 104 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/zsx1314lovezyf/article/details/105445108