目录
- Spring IOC
- IOC是什么
- IOC可以做什么
- 依赖注入
- IOC和DI
- IOC容器
- Bean
- 配置IOC容器
- spring ioc 依赖
- XML配置
- 实例化容器
- 使用容器
- xml配置详解
- spring对bean的管理
- 1、创建bean的三种方式
- 2、bean对象的作用范围
- 3、bean对象的生命周期
- 构造函数依赖注入
- Setter方法依赖注入
- 注解配置
- 使用xml和注解配置
- xml配置
- @Component、@Controller、@Service、@Repository
- 用于注入数据的注解
- @Autowired
- @Qualifier
- @Resource
- 关于@Autowired、@Qualifier、@Resource
- @Value
- 用于指定作用范围的注解 @Scope
- 与生命周期相关的注解 @PreDestroy、@PostConstruct
- 使用注解配置
- 使用@Configuration
- @ComponentScan
- @Bean
- @Import
- @PropertySource
- 注解配置案例
- Maven 依赖
- domain
- 配置类
- 主配置类
- 子配置类
- jdbc.properties
- 持久层
- IAccountDao
- IAccountDaoimpl
- 业务层
- IAccountService
- IAccountServiceimpl
- 测试类
Spring IOC
IOC是什么
IOC是 Inversion of Control 的缩写,即控制反转。
上层模块不应该依赖于下层模块,它们共同依赖于一个抽象
抽象不能依赖于具体实现,具体实现依赖于抽象
IoC 不是什么技术,而是一种设计思想。在 Java 开发中,IoC 意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制。如何理解 Ioc 呢?理解 Ioc 的关键是要明确“谁控制谁,控制什么,为何是反转(有反转就应该有正转了),哪些方面反转了”,那我们来深入分析一下:
谁控制谁,控制什么:传统 JavaSE 程序设计,我们直接在对象内部通过 new 进行创建对象,是程序主动去创建依赖对象;而 IoC 是有专门一个容器来创建这些对象,即由 IoC 容器来控制对象的创建;谁控制谁?当然是 IoC 容器控制了对象;控制什么?那就是主要控制了外部资源获取(不只是对象包括比如文件等)。
为何是反转,哪些方面反转了:有反转就有正转,传统应用程序是由我们自己在对象中主动控制去直接获取依赖对象,也就是正转;而反转则是由容器来帮忙创建及注入依赖对象;为何是反转?因为由容器帮我们查找及注入依赖对象,对象只是被动的接受依赖对象,所以是反转;哪些方面反转了?依赖对象的获取被反转了。
----转载自github的一篇博客。
未使用IOC容器前
使用IOC容器后
IOC可以做什么
IoC 不是一种技术,只是一种思想,一个重要的面向对象编程的法则,它能指导我们如何设计出松耦合、更优良的程序。传统应用程序都是由我们在类内部主动创建依赖对象,从而导致类与类之间高耦合,难于测试;有了 IoC 容器后,把创建和查找依赖对象的控制权交给了容器,由容器进行注入组合对象,所以对象与对象之间是松散耦合,这样也方便测试,利于功能复用,更重要的是使得程序的整个体系结构变得非常灵活。
其实 IoC 对编程带来的最大改变不是从代码上,而是从思想上,发生了“主从换位”的变化。应用程序原本是老大,要获取什么资源都是主动出击,但是在 IoC/DI 思想中,应用程序就变成被动的了,被动的等待 IoC 容器来创建并注入它所需要的资源了。
IoC 很好的体现了面向对象设计法则之一—— 好莱坞法则:“别找我们,我们找你”;即由 IoC 容器帮对象找相应的依赖对象并注入,而不是由对象主动去找。
----转载自github的一篇博客。
依赖注入
DI,是 Dependency Injection 的缩写,即依赖注入。
依赖注入是 IoC 的最常见形式。
容器全权负责的组件的装配,它会把符合依赖关系的对象通过 JavaBean 属性或者构造函数传递给需要的对象。
DI 是组件之间依赖关系由容器在运行期决定,形象的说,即由容器动态的将某个依赖关系注入到组件之中。依赖注入的目的并非为软件系统带来更多功能,而是为了提升组件重用的频率,并为系统搭建一个灵活、可扩展的平台。通过依赖注入机制,我们只需要通过简单的配置,而无需任何代码就可指定目标需要的资源,完成自身的业务逻辑,而不需要关心具体的资源来自何处,由谁实现。
理解 DI 的关键是:“谁依赖谁,为什么需要依赖,谁注入谁,注入了什么”,那我们来深入分析一下:
谁依赖于谁:当然是应用程序依赖于 IoC 容器;
为什么需要依赖:应用程序需要 IoC 容器来提供对象需要的外部资源;
谁注入谁:很明显是 IoC 容器注入应用程序某个对象,应用程序依赖的对象;
注入了什么:就是注入某个对象所需要的外部资源(包括对象、资源、常量数据)。
IOC和DI
其实它们是同一个概念的不同角度描述,由于控制反转概念比较含糊(可能只是理解为容器控制对象这一个层面,很难让人想到谁来维护对象关系),所以 2004 年大师级人物 Martin Fowler 又给出了一个新的名字:“依赖注入”,相对 IoC 而言,“依赖注入”明确描述了“被注入对象依赖 IoC 容器配置依赖对象”。
IOC容器
其实它们是同一个概念的不同角度描述,由于控制反转概念比较含糊(可能只是理解为容器控制对象这一个层面,很难让人想到谁来维护对象关系),所以 2004 年大师级人物 Martin Fowler 又给出了一个新的名字:“依赖注入”,相对 IoC 而言,“依赖注入”明确描述了“被注入对象依赖 IoC 容器配置依赖对象”。
Bean
JavaBean 是一种 JAVA 语言写成的可重用组件。为写成 JavaBean,类必须是具体的和公共的,并且具有无参数的构造器。JavaBean 对外部通过提供 getter / setter 方法来访问其成员。
由 IoC 容器管理的那些组成你应用程序的对象我们就叫它 Bean。Bean 就是由 Spring 容器初始化、装配及管理的对象,除此之外,bean 就与应用程序中的其他对象没有什么区别了。那 IoC 怎样确定如何实例化 Bean、管理 Bean 之间的依赖关系以及管理 Bean 呢?这就需要配置元数据,在 Spring 中由 BeanDefinition 代表,后边会详细介绍,配置元数据指定如何实例化 Bean、如何组装 Bean 等。
配置IOC容器
IoC 容器的配置有三种方式:
- 基于 xml 配置
- 基于注解配置
- 基于 Java 配置
spring ioc 依赖
首先我们先导入maven的spring ioc依赖
<dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.2.0.RELEASE</version></dependency>
</dependencies>
XML配置
首先创建一个spring ioc 的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/beanshttps://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<bean id="UserService" class="com.service.Impl.IUserServiceimpl"> </bean><import resource="bean2.xml" />
</beans>
标签说明:
<beans>
是 Spring 配置文件的根节点。<bean>
用来定义一个 JavaBean。id
属性是它的标识,在文件中必须唯一;class
属性是它关联的类。<import />
用来导入其他配置文件的 Bean 定义。这是为了加载多个配置文件。
实例化容器
核心容器的两个接口
- ApplicationContext: 单例对象适用
它在构建核心容器时,创建对象采取的策略是采用立即加载的方式。也就是说,只要一读取完配置文件马上就创建配置文件中配置的对象 - BeanFactory: 多例对象适用
它在构建核心容器时,创建对象采取的策略是采用延时加载的方式。也就是说,只有通过id获取对象时,才真正的创建对象
实例化容器的过程: 定位资源(XML 配置文件) 读取配置信息(Resource) 转化为 Spring 可识别的数据形式(BeanDefinition)。
ApplicationContext context =new ClassPathXmlApplicationContext(new String[] {"bean1.xml", "bean2.xml"});
组合 xml 配置文件 配置的 Bean 功能各不相同,都放在一个 xml 文件中,不便管理。 Java 设计模式讲究职责单一原则。配置其实也是如此,功能不同的 JavaBean 应该被组织在不同的 xml 文件中。然后使用 import 标签把它们统一导入。
ApplicationContext
是一个接口 有常用的三个实现类
- 1、
ClassPathXmlApplicationContext
- 它可以加载类路径下的配置文件,要求配置文件必须要在类路径下。
ApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"bean1.xml", "bean2.xml"});
- 2、
FileSystemXmlApplicationContext
- 它可以加载磁盘任意路径下的配置文件(前提是必须有访问权限)
- 3、
AnnotationConfigApplicationContext
- 它用于读取注解创建容器的。
new AnnotationConfigApplicationContext(Class<?> ... config);
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringConfiguration.class);
使用容器
使用容器的方式就是通过getBean获取 IoC 容器中的 JavaBean。
第一种 getBean(String id)
第二种 getBean(String id, Class<?> object)
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");IUserService iUserService1 = (IUserServiceimpl) applicationContext.getBean("IUserService");IUserService iUserService2 = applicationContext.getBean("IUserService", IUserService.class);
xml配置详解
spring对bean的管理
1、创建bean的三种方式
-
使用默认构造函数(无参)创建对象
- 在使用spring配置文件中使用bean标签时,配以id和class属性之后并且没有其他属性和标签时,采用的就是默认构造函数创建bean对象,此时如果类中没有默认构造函数,则对象无法创建。
-
使用普通工厂中的方法创建对象(使用某个类中的方法创建对象,并存入spring容器)
- id为需要创建的对象的id(需要为目标对象配bean),
factory-bean
属性为工厂类的id(先给工厂类配bean),factory-method
属性为工厂类创建目标对象的方法(该方法不能为static)
- id为需要创建的对象的id(需要为目标对象配bean),
-
使用普通工厂中的静态(static)方法创建对象(使用某个类中的静态(static)方法创建对象,并存入spring容器)
- class属性为工厂的全限定类名,这也代表着bean创建的id对应的是工厂类, 但是设置factory-method属性为工厂类创建目标对象的静态(static)方法,这样就会默认调用该方法,返回的就是目标对象。
使用默认构造函数(无参)创建对象
<bean id="UserService" class="com.service.Impl.IUserServiceimpl"> </bean>
使用普通工厂中的方法创建对象
<bean id="instanceFactory" class="com.factory.InstanceFactory"></bean><bean id="IUserService" factory-bean="instanceFactory" factory-method="getIUserSevice" ></bean>
使用普通工厂中的静态(static)方法创建对象
<bean id="IUserService" class="com.factory.staticFactory" factory-method="getIUserSevice"></bean>
2、bean对象的作用范围
默认情况下 bean对象只创建一次————————单例对象。我们可以通过bean
标签的scope
属性设置bean对象的作用范围。
scope
属性:
- 作用:用于指定bean的作用范围
- 取值:
- singleton:单例的(默认值)
- prototype:多例的
- request:作用于web应用的请求范围
- session:作用于web应用的会话范围
- global-session:作用于集群环境的会话范围(全局会话范围)。当不是集群环境时,与session等同
3、bean对象的生命周期
1、单例对象:
- 出生:当容器创建时对象出生
- 活着:只要容器没有销毁,对象一直活着
- 死亡:当容器销毁,对象跟着死亡
- 总结:单例对象的生命周期与容器相同
2、多例对象:
- 出生:当我们使用对象时spring框架为我们创建
- 活着:对象只要在使用过程中就一直活着
- 死亡:当对象长时间未使用且没有其他对象引用时,java垃圾回收机制会自动回收对象
我们可以借助bean标签的init-method属性调用初始化方法和destroy-method调用销毁方法
//init 和 destroy 是类IUserServiceimpl 定义的方法
<bean id="IUserService" class="com.service.Impl.IUserServiceimpl" scope="singleton" init-method="init" destroy-method="destroy"></bean>
构造函数依赖注入
- 使用的标签:
<constructor-arg></constructor-arg>
- 标签出现的位置:bean标签内部
- 标签的属性:
- name:用于指定给构造函数中指定名称的参数赋值
- index:用于指定需要注入的数据给构造函数中指定索引位置的参数赋值
- type:用于指定需要注入的数据类型,该数据类型也是构造函数中某个或者某些参数的类型
- value:用于指定基本类型和String类型的数据
- ref:用于指定其他bean类型数据。它指的就是在Spring的ioc核心容器中出现过的bean对象
<bean id="IUserService" class="com.service.Impl.IUserServiceimpl" ><constructor-arg name="name" value="xiuyuandashen"></constructor-arg><constructor-arg name="age" value="18"></constructor-arg><constructor-arg name="birthday" ref="birthday"></constructor-arg>
</bean>
<bean id="birthday" class="java.util.Date"></bean>
对应的构造函数
public IUserServiceimpl(String name, Date birthday, Integer age) {this.name = name;this.birthday = birthday;this.age = age;}
Setter方法依赖注入
首先该对象得Setter方法
- 使用的标签:property
- 标签出现的位置:bean标签内部
- 标签的属性:
- name:用于指定给set方法名称
- value:用于指定基本类型和String类型的数据
- ref:用于指定其他bean类型数据。它指的就是在Spring的ioc核心容器中出现过的bean对象
复杂类型的注入或者集合结构类型的注入
- 使用的标签:property
- 标签出现的位置:bean标签内部
- 用于给list结构集合注入的标签:
<array>
<list>
<set>
- 注意,结构相同标签可以互换
- 用于给map结构集合注入的标签
<map>
<props>
- 注意,结构相同标签可以互换
<bean id="fuzajiegou" class="com.domain.fuzajiegou"><property name="myArr"><array><value>hello</value><value>world</value><value>java</value><value>javaScript</value></array></property><property name="myList"><list><value>list——a</value><value>list——b</value><value>list——c</value><value>list——e</value><value>list——f</value></list></property><property name="mySet"><set><value>set——a</value><value>set——b</value><value>set——c</value><value>set——e</value><value>set——f</value></set></property><property name="myMap"><map><entry key="map1" value="1"></entry><entry key="map2" value="2"></entry><entry key="map3" value="3"></entry><entry key="map4"><value>4</value></entry></map></property><property name="myPro"><props><prop key="Properties1">1</prop><prop key="Properties2">2</prop><prop key="Properties3">3</prop><prop key="Properties4">4</prop></props></property></bean>
对应的bean类
public class fuzajiegou {private String[] myArr;private List myList;private Set mySet;private Properties myPro;private Map<String,String> myMap;public void setMyArr(String[] myArr) {this.myArr = myArr;}public void setMyList(List myList) {this.myList = myList;}public void setMySet(Set mySet) {this.mySet = mySet;}public void setMyPro(Properties myPro) {this.myPro = myPro;}public void setMyMap(Map<String, String> myMap) {this.myMap = myMap;}
}
public static void main(String[] args) {ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");final fuzajiegou fuzajiegou = applicationContext.getBean("fuzajiegou", fuzajiegou.class);System.out.println(fuzajiegou);}
注解配置
使用xml和注解配置
xml配置
Spring 默认是不启用注解的。如果想使用注解,需要先在 xml 中启动注解。 启动方式:在 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"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttps://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"><context:component-scan base-package="com"/></beans>
标签说明:
<context:component-scan base-package="com"/>
标签- 属性
base-package
表示扫描的位置
- 属性
@Component、@Controller、@Service、@Repository
@Component 注解
- 作用:用于将当前类对象存入spring容器
- 属性:
value
:用于指定<bean>
的id
。当我们不写时默认为当前类名,且首字母小写
@Controller、@Service、@Repository 注解
- 以上这三种的作用和属性与
@Component
一样,用这三种注解使三层结构对象更清晰。 @Controller
表示表现层@Service
表示业务层@Repository
表示持久层
用于注入数据的注解
他们的作用就和xml配置文件中的bean标签中写一个<property></property>
标签的作用是一样的
@Autowired
@Autowired
- 作用:自动按照类型注入。只需要容器中有唯一的一个bean对象类型和要注入的变量匹配,就可以注入成功。 如果ioc容器中没有任何bean的类型与要注入的变量类型匹配,则报错。
- 细节:
- 如果ioc容器中有多个类型匹配时:先按照变量类型找出所有,然后将变量名称作为id进行查找对应的对象/值。
@Qualifier
- 作用:在按照类型注入的基础(
@Autowired
)上再按照名称注入。 - 细节:
- 它在给类成员注入时不能单独使用。
- 但是在给方法参数注入时可以单独使用。
- 属性:
value
:用于指定注入bean的id。
@Resource
- 作用:直接按照bean的id注入。它可以单独使用。
- 属性:
- name:用于指定bean的id
关于@Autowired、@Qualifier、@Resource
以上三种注解(@Autowired、@Qualifier、@Resource
)都只能注入其他bean类型的数据,而基本类型和String类型无法使用上述三种注解实现
@Value
- 作用:用于注入基本类型和String类型的数据
- 属性:
- value:用于指定数据的值。它可以使用spring中的el表达式(spEL)。spEl的写法:${表达式}
用于指定作用范围的注解 @Scope
他们的作用就和bean标签中使用scope属性实现的功能一致。
@Scope
- 作用:用于指定bean的作用范围
- 属性:
- value:指定范围的取值。常用取值:singleton(单例),prototype(多例)…
与生命周期相关的注解 @PreDestroy、@PostConstruct
他们的作用就和bean标签中使用scope属性实现的功能一致。
@PreDestroy
- 作用:用于指定销毁方法
@PostConstruct
- 作用:用于指定初始化方法
使用注解配置
首先使用注解配置需要解决xml配置文件中注解对<context:component-scan base-package="com"/>
的依赖
我们可以使用@ComponentScan
注解来代替<context:component-scan base-package="com"/>
使用@Configuration
@Configuration
- 作用:指定当前类是一个配置类
- 细节:当该配置类作为
AnnotationConfigApplicationContext
对象创建的参数时,该注解可以不写。
@ComponentScan
@ComponentScan
- 作用:用于通过注解指定spring在创建容器时要扫描的包
- 属性:
- basePackages:它和value的作用是一致的,都是用于指定创建容器时需要扫描的包,我们使用此注解就等同于在xml配置了:
<context:component-scan base-package=""/>
. - value:与basePackages一样
- 以上两个属性的值都是一个String[]数组。数组的每个值表示要扫描的包名。
- basePackages:它和value的作用是一致的,都是用于指定创建容器时需要扫描的包,我们使用此注解就等同于在xml配置了:
- 细节:
- 被扫描的包中的类需要被扫描到的话需要加上 @Configuration 注解。
@Bean
- 作用:用于将当前方法的返回值作为bean对象存入spring的IOC容器中。
- 属性:
- name:用于指定bean的id。当不写name时,默认值为当前方法的名称。
- 细节:
- 当我们使用注解配置方法时,如果方法有参数,spring框架会去容器中查找有没有可用的bean对象。 查找的方式和
@Autowired
注解的作用是一致的。使用@Bean注解默认是单例的,需要加个@Scope("prototype")
指明为多例对象
- 当我们使用注解配置方法时,如果方法有参数,spring框架会去容器中查找有没有可用的bean对象。 查找的方式和
@Import
- 作用:用于导入其他的配置类。
- 属性:
Class []value
:该数组的值就是需要引入的其他配置类的字节码文件。
- 细节:
- 当类被其他类用
@Import
注解引入时,该类就不需要用@Configuration
来指明是配置类.相当于,使用@Import
的配置类为父配置类,引入的类就是子配置类.在使用AnnotationConfigApplicationContext
对象创建IOC容器时只需要引入父配置类即可。
@PropertySource
- 作用:用于指定Properties文件的位置
- 属性:
- String []value:指定文件的路径和名称。关键词:
classpath
表示类路径下。例如@PropertySource("classpath:jdbc.properties")
- String []value:指定文件的路径和名称。关键词:
注解配置案例
这是一个单表CRUD的案例。
项目结构
Maven 依赖
<dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.2.5.RELEASE</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.14</version></dependency><dependency><groupId>commons-dbutils</groupId><artifactId>commons-dbutils</artifactId><version>1.6</version></dependency><dependency><groupId>c3p0</groupId><artifactId>c3p0</artifactId><version>0.9.1</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13</version><scope>test</scope></dependency></dependencies>
domain
package com.domain;public class Account {private Integer id;private String name;private double money;public Account() {}public Account(String name, double money) {this.name = name;this.money = money;}@Overridepublic String toString() {return "Account{" +"id=" + id +", name='" + name + '\'' +", money=" + 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 double getMoney() {return money;}public void setMoney(double money) {this.money = money;}
}
配置类
主配置类
package com.config;import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.apache.commons.dbutils.QueryRunner;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.context.annotation.*;import javax.sql.DataSource;
@Configuration
@ComponentScan(basePackages = {"com.Dao","com.service"})
@Import({jdbcConfig.class})
@PropertySource({"classpath:jdbc.properties"})
public class SpringConfiguration {}
子配置类
package com.config;import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.apache.commons.dbutils.QueryRunner;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Scope;import javax.sql.DataSource;public class jdbcConfig {@Value("${jdbc.driver}")private String driver;@Value("${jdbc.jdbcUrl}")private String jdbcUrl;@Value("${jdbc.username}")private String username;@Value("${jdbc.password}")private String password;/*** dbUtils* @param dataSource* @return*/@Bean(name = "runner")@Scope("prototype")public QueryRunner createQueryRunner(DataSource dataSource) {return new QueryRunner(dataSource);}/*** 配置数据源* @return*/@Bean(name = "dataSource")public DataSource createDataSource() {try {ComboPooledDataSource ds = new ComboPooledDataSource();ds.setDriverClass(driver);ds.setJdbcUrl(jdbcUrl);ds.setUser(username);ds.setPassword(password);return ds;} catch (Exception e) {throw new RuntimeException(e);}}}
jdbc.properties
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.jdbcUrl=jdbc:mysql://localhost:3306/zlf?serverTimezone=UTC
jdbc.username=root
jdbc.password=feng10.10
持久层
IAccountDao
package com.Dao;import com.domain.Account;import java.util.List;/***账户的持久层接口**/
public interface IAccountDao {/*** 查询所有* @return*/List<Account> selAll();/*** 查询一个* @param id* @return*/Account findAccountbyid(int id);/*** 保存* @param account*/void saveAccount(Account account);/***更新* @param account*/void updateAccount(Account account);/*** 删除* @param id*/void deleteAccount(int id) throws Exception;
}
IAccountDaoimpl
package com.Dao.Impl;import com.Dao.IAccountDao;
import com.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.util.List;/*** 账户的持久层实现类*/
@Repository("IAccountDao")
public class IAccountDaoimpl implements IAccountDao {@Autowiredprivate QueryRunner runner;public void setRunner(QueryRunner runner) {this.runner = runner;}public List<Account> selAll() {try{return runner.query("select *from account",new BeanListHandler<Account>(Account.class));}catch (Exception e){throw new RuntimeException(e);}}public Account findAccountbyid(int id) {try{return runner.query("select *from account where id=?",new BeanHandler<Account>(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(int id) {try {runner.update("delete from account where id=?",id);}catch (Exception e){throw new RuntimeException(e);}}
}
业务层
IAccountService
package com.service;import com.domain.Account;import java.util.List;/*** 账户的业务层接口*/
public interface IAccountService {/*** 查询所有* @return*/List<Account> selAll();/*** 查询一个* @param id* @return*/Account findAccountbyid(int id);/*** 保存* @param account*/void saveAccount(Account account);/***更新* @param account*/void updateAccount(Account account);/*** 删除* @param id*/void deleteAccount(int id) throws Exception;}
IAccountServiceimpl
package com.service.Impl;import com.Dao.IAccountDao;
import com.Dao.Impl.IAccountDaoimpl;
import com.domain.Account;
import com.service.IAccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.util.List;
@Service("IAccountService")
public class IAccountServiceimpl implements IAccountService {@Autowiredprivate IAccountDao iAccountDao;public List<Account> selAll() {return iAccountDao.selAll();}public Account findAccountbyid(int id) {return iAccountDao.findAccountbyid(id);}public void saveAccount(Account account) {iAccountDao.saveAccount(account);}public void updateAccount(Account account) {iAccountDao.updateAccount(account);}public void deleteAccount(int id) throws Exception {iAccountDao.deleteAccount(id);}public void setiAccountDao(IAccountDaoimpl iAccountDao) {this.iAccountDao=iAccountDao;}
}
测试类
package com.test;import com.config.SpringConfiguration;
import com.domain.Account;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import com.service.IAccountService;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;import javax.sql.DataSource;
import java.util.List;public class accountServiceTest {IAccountService iAccountService = null;@Beforepublic void init() throws Exception {final ApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringConfiguration.class);iAccountService = applicationContext.getBean("IAccountService", IAccountService.class);}/*** 查询所有*/@Testpublic void findAll() {System.out.println(iAccountService.selAll());}/*** 查询一位*/@Testpublic void findOne() {System.out.println(iAccountService.findAccountbyid(2));}/*** 保存*/@Testpublic void TestSave() {iAccountService.saveAccount(new Account("小明", 1002.5));}/*** 更新*/@Testpublic void TestUpadata() {final Account account = iAccountService.findAccountbyid(4);account.setMoney(100002.5);iAccountService.updateAccount(account);}/*** 删除** @throws Exception*/@Testpublic void Testdalete() throws Exception {iAccountService.deleteAccount(4);}}