Spring第二章-IOC

Spring第二章-IOC

一、目标

1、使用IOC完成CRUD

2、基于注解的IOC配置

3、使用注解改造CRUD(半xml半注解)

4、纯注解开发

5、spring与junit的整合

二、使用IOC完成改造CRUD
a、引入依赖
 			<!--spring的核心包(基本)-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>
        <!--dbutils-->
        <dependency>
            <groupId>commons-dbutils</groupId>
            <artifactId>commons-dbutils</artifactId>
            <version>1.4</version>
        </dependency>
        <!--c3p0数据源-->
        <dependency>
            <groupId>c3p0</groupId>
            <artifactId>c3p0</artifactId>
            <version>0.9.1.2</version>
        </dependency>
        <!--mysql驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.6</version>
        </dependency>
        <!--单元测试-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
b、创建表
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);
c、实体类
public class Account {
    private Integer id;
    private String name;
    private Float money;
}
d、持久层
1 接口
package com.sgw.dao;

import com.sgw.domain.Account;

import java.util.List;

public interface AccountDao {

    /**
     * 查询全部
     * @return
     */
    public List<Account> findAll();

    /**
     * 根据id查询
     * @param id
     * @return
     */
    public Account findById(Integer id);

    /**
     * 保存账户
     * @param account
     */
    public void save(Account account);

    /**
     * 更新账户
     * @param account
     */
    public void update(Account account);

    /**
     * 根据id删除账户
     * @param id
     */
    public void del(Integer id);
}
2. 实现类
package com.sgw.dao.impl;

import com.sgw.dao.AccountDao;
import com.sgw.domain.Account;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;

import java.sql.SQLException;
import java.util.List;

/**
 * dbUtils 操作数据库
 *  入口:QueryRunner对象
 */
public class AccountDaoImpl implements AccountDao {

    QueryRunner queryRunner;

    public void setQueryRunner(QueryRunner queryRunner) {
        this.queryRunner = queryRunner;
    }

    @Override
    public List<Account> findAll() {
        String sql = "select * from account";
        try {
            List<Account> accountList = queryRunner.query(sql, new BeanListHandler<Account>(Account.class));
            return accountList;
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public Account findById(Integer id) {
        String sql = "select * from account where id = ?";
        try {
            Account account = queryRunner.query(sql, new BeanHandler<>(Account.class), id);
            return account;
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public void save(Account account) {
        String sql = "insert into account values(null , ? , ?)";
        try {
            queryRunner.update(sql ,account.getName() ,account.getMoney());
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void update(Account account) {
        String sql = "update account set name = ? ,money = ? where id = ?";
        try {
            queryRunner.update(sql ,account.getName(),account.getMoney(),account.getId());
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void del(Integer id) {
        String sql = "delete from account where id = ?";
        try {
            queryRunner.update(sql ,id);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

e、业务层
1. 接口
package com.sgw.service;

import com.sgw.domain.Account;

import java.util.List;

public interface AccountService {
    /**
     * 查询全部
     * @return
     */
    public List<Account> findAll();

    /**
     * 根据id查询
     * @param id
     * @return
     */
    public Account findById(Integer id);

    /**
     * 保存账户
     * @param account
     */
    public void save(Account account);

    /**
     * 更新账户
     * @param account
     */
    public void update(Account account);

    /**
     * 根据id删除账户
     * @param id
     */
    public void del(Integer id);
}

2. 实现类
package com.sgw.service.impl;

import com.sgw.dao.AccountDao;
import com.sgw.domain.Account;
import com.sgw.service.AccountService;

import java.util.List;

public class AccountServiceImpl implements AccountService {

    private  AccountDao accountDao;

    public void setAccountDao(AccountDao accountDao) {
        this.accountDao = accountDao;
    }

    @Override
    public List<Account> findAll() {
        return accountDao.findAll();
    }

    @Override
    public Account findById(Integer id) {
        return accountDao.findById(id);
    }

    @Override
    public void save(Account account) {
        accountDao.save(account);
    }

    @Override
    public void update(Account account) {
        accountDao.update(account);
    }

    @Override
    public void del(Integer id) {
        accountDao.del(id);
    }
}

f、配置文件
<?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对象,创建service对象-->
    <bean id="accountService" class="com.sgw.service.impl.AccountServiceImpl">
        <property name="accountDao" ref="accountDao" ></property>
    </bean>
    <!--在AccountService中需要AccountDao对象-->
    <bean id="accountDao" class="com.sgw.dao.impl.AccountDaoImpl">
        <property name="queryRunner" ref="queryRunner"></property>
    </bean>
    <!--在AccountDao中需要QueryRunner对象,创建对象-->
    <bean id="queryRunner" class="org.apache.commons.dbutils.QueryRunner">
        <!--按照类型在构造方法注入数据源对象-->
        <constructor-arg type="javax.sql.DataSource" ref="dataSource"></constructor-arg>
    </bean>
    <!--在QueryRunner对象中需要DataSource对象-->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
        <!--通过set方法注入必要的四个属性-->
        <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/spring_sgw"></property>
        <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
        <property name="user" value="root"></property>
        <property name="password" value="root"></property>
    </bean>
</beans>
g、测试类
package com.sgw;

import com.sgw.domain.Account;
import com.sgw.service.AccountService;
import com.sgw.service.impl.AccountServiceImpl;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.util.List;

public class TestCRUD {

    @Test
    public void testFindAll(){
        //创建容器
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
        //创建service对象
        AccountService accountService = ac.getBean("accountService",AccountService.class);
        List<Account> accountList = accountService.findAll();
        for (Account account : accountList) {
            System.out.println(account);
        }
    }

    @Test
    public void testFindById(){
        //创建service对象
        AccountService accountService = new AccountServiceImpl();
        Account account = accountService.findById(1);
        System.out.println(account);
    }
    @Test
    public void testSave(){
        //创建service对象
        AccountService accountService = new AccountServiceImpl();

        Account account = new Account();
        account.setName("ddd");
        account.setMoney(1111F);

        accountService.save(account);
    }


    @Test
    public void testUpdate(){
        //创建service对象
        AccountService accountService = new AccountServiceImpl();

        Account account = new Account();
        account.setId(4);
        account.setName("eeee");
        account.setMoney(1222F);

        accountService.update(account);
    }

    @Test
    public void testDel(){
        AccountService accountService = new AccountServiceImpl();
        accountService.del(4);
    }
}

三、常用的注解
a. 注解开发入门流程
	1.引入依赖
  	<!--引入spring的核心包-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>
        <!--引入单元测试-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
   2. 配置文件:applicationContext.xml
   <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.xsd
        http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
        ">
    <!--
        开启注解,指定扫描的包 : context:component-scan
        引入context名称空间-引入约束
        base-package:指定要扫描的包, 扫描的是包及其子包
    -->
    <context:component-scan base-package="com.sgw"></context:component-scan>
    <!--
                context:include-filter :指定包含过滤
                type="annotation": 按照类型过滤
                expression: 过滤的表达式
                    只扫描标记了Controller注解的类
        -->
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"></context:include-filter>
        <!--
                context:exclude-filter:指定排除过滤
                type="annotation": 按照类型过滤
                expression:过滤的表达式
                        排除标记了Controller的注解都会扫描
        -->
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
	</beans>
	3. 在需要创建对象的类上添加注解
		@Component
	4. 测试
		 		//创建容器对象
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
        //获取对象
        UserDao userDao = ac.getBean(UserDao.class);
        System.out.println(userDao);

        UserService userService = ac.getBean(UserService.class);
        System.out.println(userService);
b. @Component -- 标记在类上,不能用在方法上
		作用:创建对象, 只要标记了,扫描了该包,对象就会创建
		衍生了三个子注解
			@Controller 一般用于web(控制层)层
			@Service    一般用于业务层
			@Repository 一般用于持久层
		相当于xml	
			<bean id="" class="全限类名"></bean>
		属性:value="userDao" 相当于xml的 id="userDao"
		如果没有指定value属性,默认的名称是 简单类名,首字母小写
			UserDaoImpl -- userDaoImpl
			UserServiceImpl -- userServiceImpl
c.  @Autowired  -- 自动注入
	可以标记在属性和set方法上,如果标记在属性上,可以没有set方法
	特点:默认自动按照类型注入
	流程:当属性|set方法标记了@Autowired ,会自动在容器中查询该属性类型的对象,如果有且只有一个,则注入
	@Qualifier	:必须与@Autowired结合使用
		作用:如果自动注入按照类型注入失败,则按照指定的名称注入
	如果没有@Qualifier,类型注入失败,则按照属性名按照名称注入
d. @Resource -- 自动注入
	流程:当属性|set方法标记了@Resource,会自动按照名称注入, 如果名称没有找到,则根据类型注入,如果类型有多个,则抛出异常
e. @Autowired :默认按照类型注入,如果类型有多个,则按照名称注入  -- spring提供的
	@Resource : 默认按照名称注入,没有名称没有找到,按照类型注入  -- jdk提供的
	
	++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

f. @Configuration : 标记该类为配置文件类
	可以替换 applicationContext.xml
g. @ComponentSacn("com.sgw")
	相当于:<context:component-scan base-package="com.sgw">
h. @Import: 引入其他配置文件
	<import resource="classpath:applicationContext-dao.xml"></import>
i. @Bean -- 通过方法创建对象,一般用于创建别人提供的类
	相当于:<bean  > 
j. @Scope("singleton|prototype")
	配置对象的范围:相当于:bean标签中的属性  scope="singleton|prototype"
k. 生命周期
	@PostConstruct:相当于bean标签的属性 init-method,指定初始化方法
	@PreDestroy:相当于bean标签的属性:destroy-method, 指定对象的销毁方法
l. @Value 给属性赋值 -- 只能赋值简单类型
m. PropertySource : 引入外部属性文件
	 相当于:<context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
四、使用注解改造账户CRUD
a、实体类
public class Account {
    private Integer id;
    private String name;
    private Float money;
}
b、持久层
package com.sgw.dao.impl;

import com.sgw.dao.AccountDao;
import com.sgw.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;

/**
 * dbUtils 操作数据库
 *  入口:QueryRunner对象
 */
@Repository("accountDao")
public class AccountDaoImpl implements AccountDao {

    @Autowired
    QueryRunner queryRunner;
    @Override
    public List<Account> findAll() {
        String sql = "select * from account";
        try {
            List<Account> accountList = queryRunner.query(sql, new BeanListHandler<Account>(Account.class));
            return accountList;
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public Account findById(Integer id) {
        String sql = "select * from account where id = ?";
        try {
            Account account = queryRunner.query(sql, new BeanHandler<>(Account.class), id);
            return account;
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public void save(Account account) {
        String sql = "insert into account values(null , ? , ?)";
        try {
            queryRunner.update(sql ,account.getName() ,account.getMoney());
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void update(Account account) {
        String sql = "update account set name = ? ,money = ? where id = ?";
        try {
            queryRunner.update(sql ,account.getName(),account.getMoney(),account.getId());
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void del(Integer id) {
        String sql = "delete from account where id = ?";
        try {
            queryRunner.update(sql ,id);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

c、业务层
package com.sgw.service.impl;

import com.sgw.dao.AccountDao;
import com.sgw.domain.Account;
import com.sgw.service.AccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service("accountService")
public class AccountServiceImpl implements AccountService {

    @Autowired
    private  AccountDao accountDao;

    @Override
    public List<Account> findAll() {
        return accountDao.findAll();
    }

    @Override
    public Account findById(Integer id) {
        return accountDao.findById(id);
    }

    @Override
    public void save(Account account) {
        accountDao.save(account);
    }

    @Override
    public void update(Account account) {
        accountDao.update(account);
    }

    @Override
    public void del(Integer id) {
        accountDao.del(id);
    }
}

d、配置文件
<?xml version="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">

    <!--开启注解,扫描包-->
    <context:component-scan base-package="com.sgw"></context:component-scan>

    <!--创建queryRunner对象, 需要数据源对象,创建数据源对象,通过构造方法注入-->
    <bean id="queryRunner" class="org.apache.commons.dbutils.QueryRunner">
        <!--通过构造方法参数类型注入-->
        <constructor-arg type="javax.sql.DataSource" ref="dataSource"></constructor-arg>
    </bean>
    <!--创建数据源对象:需要注入四个参数-->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <!--通过set方法注入-->
        <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
        <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/spring_331"></property>
        <property name="user" value="root"></property>
        <property name="password" value="root"></property>
    </bean>
</beans>
e、测试
package com.sgw;

import com.sgw.domain.Account;
import com.sgw.service.AccountService;
import com.sgw.service.impl.AccountServiceImpl;
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;

/**
 * 1. 替换Junit的运行器: 为spring与junit整合后的运行器
 * 2. 指定配置文件路径, 会自动创建容器对象
 *      @ContextConfiguration({"classpath:applicationContext.xml"})
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:applicationContext.xml"})
public class TestCRUD {
//    ApplicationContext ac;
//    @Before
//    public void init(){
//        //创建容器
//        ac = new ClassPathXmlApplicationContext("applicationContext.xml");
//
//    }
    @Autowired
    AccountService accountService;
    @Test
    public void testFindAll(){

        //创建service对象
        List<Account> accountList = accountService.findAll();
        for (Account account : accountList) {
            System.out.println(account);
        }
    }

    @Test
    public void testFindById(){
        //创建service对象
        Account account = accountService.findById(1);
        System.out.println(account);
    }
    @Test
    public void testSave(){
        //创建service对象
        AccountService accountService = new AccountServiceImpl();

        Account account = new Account();
        account.setName("ddd");
        account.setMoney(1111F);

        accountService.save(account);
    }


    @Test
    public void testUpdate(){
        //创建service对象
        AccountService accountService = new AccountServiceImpl();

        Account account = new Account();
        account.setId(4);
        account.setName("eeee");
        account.setMoney(1222F);

        accountService.update(account);
    }

    @Test
    public void testDel(){
        AccountService accountService = new AccountServiceImpl();
        accountService.del(4);
    }
}

五、纯注解开发
1. SpringConfiguration.java
/**
 * 1. 标记该类为配置文件类  @Configuration
 * 2. 指定注解扫描的包路径  @ComponentScan({"com.sgw"})
 * 3. 引入其他配置文件类    @Import({JDBCConfiguration.class})
 */
@Configuration
@ComponentScan({"com.sgw"})
@Import({JDBCConfiguration.class})
public class SpringConfiguration {
}
2. JDBCConfiguration.java
/**
 * 配置持久层的对象
 * @Configuration :可以省略的
 *
 * @Bean("name") 用在方法上,用来指定方法创建的对象存到容器中
 *                  "name": 就是在容器的名称
 */
@Configuration
public class JDBCConfiguration {
    @Bean("queryRunner")
    public QueryRunner createQueryRunner(DataSource dataSource){
//        需用通过构造方法注入dataSource
        QueryRunner queryRunner = new QueryRunner(dataSource);
        return queryRunner;
    }
    /**
     * 创建数据源对象:dataSource
     * @return
     */
    @Bean("dataSource")
    public DataSource createDataSource(){
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/spring_331");
        dataSource.setUser("root");
        dataSource.setPassword("root");
        try {
            dataSource.setDriverClass("com.mysql.jdbc.Driver");
        } catch (PropertyVetoException e) {
            e.printStackTrace();
        }
        return dataSource;
    }
}
3. 测试
	 //纯注解创建容器对象
        ApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfiguration.class);
        //创建service对象
        AccountService accountService = ac.getBean("accountService",AccountService.class);

六、spring与junit的整合
1. 引入依赖
			<!--单元测试-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
        <!--引入spring-5 的测试包: 必须引用相应的junit包, junit的版本必须是4.12以上-->
        <!--引入spring-4 的测试包: 必须引用相应的junit包, junit的版本必须是4.9以上-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>
2.1 配置测试环境-- xml
	a. 替换Junit的运行器: 为spring与junit整合后的运行器
	@RunWith(SpringJUnit4ClassRunner.class)
	b. 指定配置文件路径, 会自动创建容器对象, 必须添加classpath
	@ContextConfiguration({"classpath:applicationContext.xml"})
2.2 配置测试环境-- ann
	a. 替换Junit的运行器: 为spring与junit整合后的运行器
	@RunWith(SpringJUnit4ClassRunner.class)
	b. 指定配置文件路径, 会自动创建容器对象, 必须添加classpath
	@ContextConfiguration(classes = {SpringConfiguration.class})
3. 测试:从容器可以获取某类型的对象
	@Autowired
	AccountService accountService;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值