Java54spring:IOC完成账户的CRUD,基于注解的IOC配置

Posted 码农编程录

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java54spring:IOC完成账户的CRUD,基于注解的IOC配置相关的知识,希望对你有一定的参考价值。


1.配置文件

暂不写servlet,只写service和dao,service要提供增删改查的方法,并且每个service里调用相应的dao实现对数据库真正的增删改查操作。service和dao层之间依赖的调用通过spring配置方式调用,包括service和dao层对象的创建交给spring去做,不是我们之前new的方式了。new一个maven工程。
在这里插入图片描述

//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.itheima</groupId>
    <artifactId>spring_day02_01</artifactId>
    <version>1.0-SNAPSHOT</version>
    <build>
        <plugins>
            <!-- java编译插件 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.2</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
    <dependencies>
        <!-- ioc相关 spring版本一致-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.0.6.RELEASE</version>
        </dependency>
        <!-- jdbcTemplate spring版本一致-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.0.6.RELEASE</version>
        </dependency>
        <!-- mysql驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.38</version>
        </dependency>
        <!-- 德鲁伊连接池 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.0.9</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
    </dependencies>
</project>
//applicationContext.xml
<?xml version="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">
    <!-- 装配service对象到spring容器 -->
    <bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl">
        <property name="accountDao" ref="accountDao"></property>
    </bean>

    <!-- 装配dao对象到spring容器 -->
    <bean id="accountDao" class="com.itheima.dao.impl.AccountDaoImpl">
        <property name="jdbcTemplate" ref="jdbcTemplate"></property>
    </bean>

    <!--
        JdbcTemplate jdbcTemplate = new JdbcTemplate(JdbcUtils.getDataSource());
        采用构造方式注入连接池对象,
     -->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <constructor-arg name="dataSource" ref="dataSource"></constructor-arg>
    </bean>

    <!-- 装配德鲁伊连接池对象
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName();
        dataSource.setUrl();
        dataSource.setUsername();
        dataSource.setPassword();
        根据以前如上写的java代码,我们此处可以使用set注入方式,给属性赋值
     -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="password" value="root"></property>
        <property name="username" value="root"></property>
        <property name="url" value="jdbc:mysql://localhost:3306/spring_day02"></property>
        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
    </bean>
</beans>

2.service

package com.itheima.service;
import com.itheima.domain.Account;

public interface AccountService {
    public void add(Account account);
    public void deleteById(int id);
    public void update(Account account);
    public Account findAccountById(int id);
}
package com.itheima.service.impl;
import com.itheima.dao.AccountDao;
import com.itheima.domain.Account;
import com.itheima.service.AccountService;

public class AccountServiceImpl implements AccountService {
    private AccountDao accountDao ;  //只声明,没有new,spring创建AccountServiceImpl时应给accountDao赋值,依赖注入提供set方法
    public AccountDao getAccountDao() {
        return accountDao;
    }
    public void setAccountDao(AccountDao accountDao) {
        this.accountDao = accountDao;
    }
    @Override
    public void add(Account account) {
        accountDao.add(account);
    }
    @Override
    public void deleteById(int id) {
        accountDao.deleteById(id);
    }
    @Override
    public void update(Account account) {
        accountDao.update(account);
    }
    @Override
    public Account findAccountById(int id) {
        Account account = accountDao.findAccountById(id);
        return account;
    }
}

3.dao

package com.itheima.dao;
import com.itheima.domain.Account;

public interface AccountDao {
    void add(Account account);
    void deleteById(int id);
    void update(Account account);
    Account findAccountById(int id);
}
package com.itheima.dao.impl;
import com.alibaba.druid.pool.DruidDataSource;
import com.itheima.dao.AccountDao;
import com.itheima.domain.Account;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import javax.annotation.PostConstruct;

public class AccountDaoImpl implements AccountDao {
    private JdbcTemplate jdbcTemplate ; //也要spring注入,加入set方法
    public JdbcTemplate getJdbcTemplate() {
        return jdbcTemplate;
    }
    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }
    @Override
    public void add(Account account) {
        String sql = "insert into account values(?,?,?)"; //mybatis才用#
        jdbcTemplate.update(sql,account.getId(),account.getName(),account.getMoney());

    }
    @Override
    public void deleteById(int id) {
        String sql = "delete from account where id = ?";
        jdbcTemplate.update(sql,id);
    }
    @Override
    public void update(Account account) {
        String sql = "update account set money = ? where id = ?";
        jdbcTemplate.update(sql,account.getMoney(),account.getId());
    }
    @Override
    public Account findAccountById(int id) {
        String sql = "select * from account where id = ?";
        Account account = null;
        try {
            account = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<>(Account.class), id);
        } catch (DataAccessException e) {
            e.printStackTrace();
        }
        return account;
    }
}

4.test

package com.itheima.service;
import com.itheima.domain.Account;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AccountServiceTest {
    private AccountService accountService;
    @Before
    public void setUp() throws Exception {
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
        accountService = (AccountService) ac.getBean("accountService");
    }
    @Test
    public void add() {
        Account account = new Account();
        account.setId(4);
        account.setName("wuyifan");
        account.setMoney(250);
        accountService.add(account); //数据库中增加一行
    }
    @Test
    public void deleteById() {
    }
    @Test
    public void update() {
    }
    @Test
    public void findAccountById() {
        Account account = accountService.findAccountById(1);
        System.out.println(account);
    }
}

findAccountById执行结果如下
在这里插入图片描述

5.使用注解的方式装配bean:component-scan

以前xml方式通过bean标签装配bean。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
Component:相当于xml配置的< bean > < bean />标签。注解的value属性值相当于bean标签的id属性。
在这里插入图片描述

6.常用注解:Autowired

6.1 用于创建对象的

在这里插入图片描述
在这里插入图片描述
如下都在applicationContext.xml中。
在这里插入图片描述
在这里插入图片描述
如下4个注解都一样。
在这里插入图片描述

6.2 用于注入数据的

如下在AccountServiceImpl.java中。
在这里插入图片描述

6.3 用于改变作用范围的

在这里插入图片描述
在这里插入图片描述

7.纯注解开发:Configuration

要删除applicationContext.xml,需要一个.java文件即配置类替代下面三个功能。
在这里插入图片描述
用SpringConfig.java和JdbcConfig.java替换了applicationContext.xml。

package com.itheima.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.PropertySource;
/*
 *   纯注解开发的步骤: 1.需要一个配置类存放xml中的配置
            		   2.配置注解扫描的包
      			       3.引入外部配置文件
       			       4.创建jdbcTemplate和DataSource数据源
 */
@Configuration  //声明当前类是一个配置类,用来替代xml配置。
@ComponentScan("com.itheima") //配置ioc注解的包扫描
@Import(JdbcConfig.class) //导入其他的配置类,JdbcConfig上面不用写@Configuration了
public class SpringConfig {
}
package com.itheima.config;
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Autowired;
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.PropertySource;
import org.springframework.jdbc.core.JdbcTemplate;
import javax.sql.DataSource;

@PropertySource("classpath:jdbc.properties") //加载外部的配置文件
public class JdbcConfig {
    /**
     *   1.给基本属性注入值,@Value 注解
     *     值应该读取配置文件中的内容, ${jdbc.url}
     */
    @Value("${jdbc.url}")
    private String url;
    @Value("${jdbc.driverClass}")
    private String driverClass;
    @Value("${jdbc.username}")
    private String username;
    @Value("${jdbc.password}")
    private String password;
    /**
     *  @Bean: 将方法的返回值作为对象,装配到spring容器
     *       里面value属性就是bean的id
     *       如果不写value属性,那么默认方法名作为bean的唯一标识
     */
    @Bean
    public DataSource dataSource1(){
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        dataSource.setUrl(url);
        dataSource.setDriverClassName(driverClass);
        return dataSource;
    }
    // @Qualifier: 可以单独使用在方法的变量上,也可以省略
    @Bean("jdbcTemplate")
    public JdbcTemplate jdbcTemplate( DataSource dataSource){
        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
        return jdbcTemplate;
    }
}

在这里插入图片描述

8.spring整合junit:两个注解

1、应用程序的入口
main方法

2、junit单元测试中,没有main方法也能执行
junit集成了一个main方法
该方法就会判断当前测试类中有哪些@Test注解
junit就让有Test注解的方法执行

3、junit不会管我们是否采用spring框架
在执行测试方法时,junit根本不知道我们是不是使用了spring框架
所以也就不会为我们读取配置文件/配置类创建spring核心容器

4、由以上三点可知
当测试方法执行时,没有Ioc容器,就算写了Autowired注解,也无法实现注入

在这里插入图片描述

package com.itheima.service;
import com.itheima.config.SpringConfig;
import com.itheima.domain.Account;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org

以上是关于Java54spring:IOC完成账户的CRUD,基于注解的IOC配置的主要内容,如果未能解决你的问题,请参考以下文章

Spring 从入门到精通系列 07——基于XML与注解方式的IOC案例编写

SSM框架01:Spring的IoC和DI,以及手把手带你创建Spring核心配置文件

java框架篇---spring IOC 实现原理

spring ioc原理

Spring07_纯注解实战及Spring整合Junit

Spring07_纯注解实战及Spring整合Junit