IOC
概念
通常情況下,應(yīng)用直接跟資源聯(lián)系,這樣兩者就產(chǎn)生了必要的聯(lián)系,這樣應(yīng)用和資源的耦合度就變得很高了,而spring中的ioc則是斷開了應(yīng)用和資源的聯(lián)系,而是通過(guò)一個(gè)工廠向應(yīng)用提供資源,與資源取得聯(lián)系,將應(yīng)用所需要的資源通過(guò)工廠轉(zhuǎn)發(fā),從而解除了資源和應(yīng)用之間的必然關(guān)系。
控制反轉(zhuǎn)(IOC)
把創(chuàng)建對(duì)象的權(quán)力交給框架,也可以說(shuō)將自身控制資源的權(quán)力交給spring工廠來(lái)控制,從而降低程序間的依賴關(guān)系。包括:依賴注入和依賴查找。
作用
降低程序之間的耦合
Spring中IOC的使用
Spring基于xml的IOC開發(fā)環(huán)境和入門
- 導(dǎo)入spring依賴
<!--sprig依賴包-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
- 創(chuàng)建bean.xml配置文件
<?xml version="1.0" encoding="UTF-8"?><!--導(dǎo)入約束-->
<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">
<!--把對(duì)象的創(chuàng)建交給spring來(lái)管理-->
<!--bean標(biāo)簽中 id為獲取對(duì)象時(shí)的唯一標(biāo)識(shí) class為反射需要?jiǎng)?chuàng)建的全限定類名-->
<bean id="accountService" class="com.itheima.spring.service.impl.AccountServiceImpl"></bean>
<bean id="accountDao" class="com.itheima.spring.dao.impl.AccountDaoImpl"></bean>
</beans>
- Controller層進(jìn)行測(cè)試
/**
* 模擬一個(gè)表現(xiàn)層,用于調(diào)用業(yè)務(wù)層
*/
public class ControllerTest {
/**
* 獲取sprig ioc容器,并根據(jù)id獲取對(duì)象
* @param args
*/
public static void main(String[] args) {
//1.獲取核心容器
ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
//2.根據(jù)id獲取Bean對(duì)象 兩種方式
AccountService accountService = (AccountService) context.getBean("accountService");//直接獲取在進(jìn)行強(qiáng)轉(zhuǎn)
AccountDao accountDao = context.getBean("accountDao", AccountDao.class);//根據(jù)字節(jié)碼進(jìn)行強(qiáng)轉(zhuǎn)
System.out.println(accountService);//com.itheima.spring.service.impl.AccountServiceImpl@46d56d67
System.out.println(accountDao);//com.itheima.spring.dao.impl.AccountDaoImpl@d8355a8
//AccountService accountService = new AccountServiceImpl();
//accountService.saveAccount();
}
}
ApplicationContext接口的三個(gè)常用實(shí)現(xiàn)類
//可以加載類路徑下的配置文件,要求配置文件必須在類路徑下,不在的話,加載不了
ApplicationContext context1 = new ClassPathXmlApplicationContext("bean.xml");
//可以加載磁盤任意路徑下的配置文件(必須有訪問(wèn)權(quán)限)bean.xml的全路徑名
ApplicationContext context2 = new FileSystemXmlApplicationContext("D:\\gyf\\my_spring\\spring_ioc_xml\\src\\main\\resources\\bean.xml");
//可以讀取注解創(chuàng)建的容器
ApplicationContext context2 = new AnnotationConfigApplicationContext();
ApplicationContext和BeanFactory的區(qū)別
-
ApplicationContext:(單例對(duì)象適用)一般使用ApplicationContext
它在構(gòu)建核心容器時(shí),創(chuàng)建對(duì)象采取的策略是立即加載的方式,也就是說(shuō),只要一讀取完配置文件馬上就創(chuàng)建配置文件中配置的對(duì)象。
-
BeanFactory:(多例對(duì)象適用)
它在構(gòu)建核心容器時(shí),創(chuàng)建對(duì)象采取的策略是采用延遲加載的方式,也就是說(shuō),什么時(shí)候根據(jù)id獲取對(duì)象,什么時(shí)候才真正創(chuàng)造對(duì)象。
Spring創(chuàng)建Bean的三種方式
- 第一種:使用默認(rèn)構(gòu)造函數(shù)創(chuàng)建,在配置文件中使用bean標(biāo)簽配以id和class屬性之后,沒(méi)有其他屬性和標(biāo)簽時(shí)。如果類中沒(méi)有構(gòu)造函數(shù),則對(duì)象無(wú)法創(chuàng)建。
<!--bean標(biāo)簽中 id為獲取對(duì)象時(shí)的唯一標(biāo)識(shí) class為反射需要?jiǎng)?chuàng)建的全限定類名-->
<bean id="accountService" class="com.itheima.spring.service.impl.AccountServiceImpl"></bean>
- 第二種:使用普通工廠中的方法創(chuàng)建對(duì)象(使用某個(gè)類中的方法創(chuàng)建對(duì)象,并存入spring容器)
/**
* 模擬一個(gè)工廠類,該類可能存在于jar包中,我們無(wú)法通過(guò)修改源碼的方式來(lái)提供默認(rèn)構(gòu)造方法
*/
public class InstanceFactory {
public AccountService getAccountService(){
return new AccountServiceImpl();
}
}
~~~xml
<!--factory-bean指定創(chuàng)建這個(gè)類的對(duì)象的工廠 factory-method指定哪個(gè)方法獲取這個(gè)對(duì)象-->
<bean id="instanceFactory" class="com.itheima.spring.factory.InstanceFactory"></bean>
<bean id="accountService" factory-bean="instanceFactory" factory-method="getAccountService"></bean>
- 第三種:使用工廠中的靜態(tài)方法創(chuàng)建對(duì)象(使用某個(gè)類中的靜態(tài)方法創(chuàng)建對(duì)象,并存入spring容器)
/**
* 模擬工廠類里面是一個(gè)靜態(tài)方法
*/
public class StaticFactory {
public static AccountService getAccountService(){
return new AccountServiceImpl();
}
}
<bean id="accountService" class="com.itheima.spring.factory.StaticFactory" factory-method="getAccountService"></bean>
Bean的作用范圍
Bean標(biāo)簽的scope屬性
作用:用于指定Bean的作用范圍
-
取值:一般使用單例和多例
- singleton:?jiǎn)卫模J(rèn))
<bean id="accountService" class="com.itheima.spring.factory.StaticFactory" factory-method="getAccountService" scope="singleton"></bean>- prototype:多例
<bean id="accountService" class="com.itheima.spring.factory.StaticFactory" factory-method="getAccountService" scope="prototype"></bean>- request:作用于web應(yīng)用的請(qǐng)求范圍
- session:作用于web應(yīng)用的會(huì)話范圍
- global-session:作用于集群環(huán)境的會(huì)話范圍(全局會(huì)話范圍)
Bean對(duì)象的生命周期
單例對(duì)象
- 出生:當(dāng)容器創(chuàng)建時(shí)對(duì)象出生
- 活著:只要容器還在,對(duì)象一直活著
- 死亡:容器銷毀,對(duì)象銷毀
總結(jié):?jiǎn)卫龑?duì)象的生命周期和容器相同
多例對(duì)象
- 出生:當(dāng)使用對(duì)象時(shí)spring為我們創(chuàng)建
- 活著:對(duì)象只要在使用時(shí)就一直活著
- 死亡:當(dāng)對(duì)象長(zhǎng)時(shí)間不用且沒(méi)有別的對(duì)象引用時(shí)由java的垃圾回收機(jī)制回收
spring中的依賴注入
依賴注入:Dependency Injection
IOC的作用:
降低程序間的耦合(依賴關(guān)系)-
概念:
依賴關(guān)系的管理,都交給spring來(lái)維護(hù),在當(dāng)前類需要用到其他類的對(duì)象,由spring為我們提供,我們只需要在配置文件中說(shuō)明。 -
能注入的三種方式:
- 基本數(shù)據(jù)類型和String
- 其他bean類型(在配置文件中或者注解配置過(guò)的bean)
- 復(fù)雜類型/集合類型
-
注入的三種方式:
- 使用構(gòu)造函數(shù)提供
- 使用的標(biāo)簽:constructor-arg
- 標(biāo)簽出現(xiàn)的位置:bean標(biāo)簽的內(nèi)部
- 標(biāo)簽屬性:
- type:用于指定要注入的數(shù)據(jù)的數(shù)據(jù)類型,該數(shù)據(jù)類型也是構(gòu)造函數(shù)中某個(gè)或某些參數(shù)的類型。
- index:用于指定要注入的數(shù)據(jù)給構(gòu)造函數(shù)中指定索引位置的參數(shù)賦值,索引的位置是從0開始。
- (主要使用)name:用于指定給構(gòu)造函數(shù)中指定名稱的參數(shù)賦值
- value:用于提供基本數(shù)據(jù)類型和String類型的數(shù)據(jù)
- ref:用于指定其他bean類型,指的就是在springIOC核心容器中出現(xiàn)的bean對(duì)象
<!--spring的依賴注入--> <bean id="accountService" class="com.itheima.spring.service.impl.AccountServiceImpl"> <!--標(biāo)簽constructor-arg:根據(jù)構(gòu)造函數(shù)注入;name標(biāo)簽:用于構(gòu)造函數(shù)中指定的參數(shù)賦值;value:用于提供基本數(shù)據(jù)類型和String類型的數(shù)據(jù);ref:用于指定其他bean類型--> <constructor-arg name="name" value="zhangsan" ></constructor-arg> <constructor-arg name="age" value="18" ></constructor-arg> <constructor-arg name="birthday" ref="new" ></constructor-arg> </bean> <!--配置一個(gè)日期類--> <bean id="new" class="java.util.Date"></bean>public class AccountServiceImpl implements AccountService { //如果經(jīng)常發(fā)生變化的數(shù)據(jù),并不適合注入的方式 private String name; private Integer age; private Date birthday; public AccountServiceImpl(String name, Integer age, Date birthday) { this.name = name; this.age = age; this.birthday = birthday; } public void saveAccount() { System.out.println("service中的saveAccount方法執(zhí)行了。。。"+name+","+age+","+birthday); //service中的saveAccount方法執(zhí)行了。。。zhangsan,18,Wed Nov 04 03:59:44 CST 2020 } }優(yōu)勢(shì):在獲取bean對(duì)象時(shí),注入數(shù)據(jù)是必須操作,否則對(duì)象無(wú)法創(chuàng)建成功 弊端:改變了bean對(duì)象的實(shí)例化方式,使我們?cè)趧?chuàng)建對(duì)象時(shí),如果用不到這些數(shù)據(jù),也必須提供。- 使用set方法提供(更常用)
- 使用的標(biāo)簽:property
- 標(biāo)簽出現(xiàn)的位置:bean標(biāo)簽的內(nèi)部
- 標(biāo)簽屬性:
- name:用于指定注入時(shí)所調(diào)用的set方法名稱
- value:用于提供基本數(shù)據(jù)類型和String類型的數(shù)據(jù)
- ref:用于指定其他bean類型,指的就是在springIOC核心容器中出現(xiàn)的bean對(duì)象
<!--配置一個(gè)日期類--> <bean id="new" class="java.util.Date"></bean> <!--spring的依賴注入基于set方法--> <!--property標(biāo)簽:根據(jù)set方法注入 name標(biāo)簽:用于注入時(shí)所調(diào)用的set方法名稱--> <bean id="accountService2" class="com.itheima.spring.service.impl.AccountServiceImpl2"> <property name="name" value="lisi"></property> <property name="age" value="21"></property> <property name="birthday" ref="new"></property> </bean>public class AccountServiceImpl2 implements AccountService { //如果經(jīng)常發(fā)生變化的數(shù)據(jù),并不適合注入的方式 private String name; private Integer age; private Date birthday; public void setName(String name) { this.name = name; } public void setAge(Integer age) { this.age = age; } public void setBirthday(Date birthday) { this.birthday = birthday; } public void saveAccount() { System.out.println("service中的saveAccount方法執(zhí)行了。。。"+name+","+age+","+birthday); } }優(yōu)勢(shì):創(chuàng)建對(duì)象時(shí)沒(méi)有明確限制,可以直接使用默認(rèn)構(gòu)造函數(shù) 弊端:如果有某個(gè)成員必須有值,則獲取對(duì)象是有可能set方法沒(méi)有執(zhí)行-
使用set方法注入集合數(shù)據(jù)
用于給List結(jié)構(gòu)集合注入的標(biāo)簽:list,array,set
用于給map結(jié)構(gòu)集合注入的標(biāo)簽:map,props
結(jié)構(gòu)相同的的標(biāo)簽可以互換
public class AccountServiceImpl3 implements AccountService { //如果經(jīng)常發(fā)生變化的數(shù)據(jù),并不適合注入的方式 private String[] myStrs; private List<String> myList; private Set<String> mySet; private Map<String,String> myMap; private Properties properties; public void saveAccount() { System.out.println(Arrays.toString(myStrs)); System.out.println(myList); System.out.println(mySet); System.out.println(myMap); System.out.println(properties); //省略set方法 }<!--使用set方法注入集合數(shù)據(jù)--> <bean id="accountService3" class="com.itheima.spring.service.impl.AccountServiceImpl3"> <property name="myStrs"> <array><!--注入數(shù)組--> <value>aaa</value> <value>bbb</value> <value>ccc</value> </array> </property> <property name="myList"> <list><!--注入list--> <value>aaa</value> <value>aaa</value> <value>ccc</value> </list> </property> <property name="mySet"> <set><!--注入set--> <value>aaa</value> <value>bbb</value> <value>ccc</value> </set> </property> <property name="myMap"> <map><!--兩種方式注入map--> <entry key="1" value="aaa"></entry> <entry key="2" > <value>bbb</value> </entry> <entry key="3" value="ccc"></entry> </map> </property> <property name="properties"> <props> <prop key="1">aaa</prop> <prop key="2">bbb</prop> <prop key="3">ccc</prop> </props> </property>
</bean>
- 使用構(gòu)造函數(shù)提供
- 使用注解提供
* 曾經(jīng)的xml配置
~~~xml
<bean id="accountService" class="com.itheima.spring.service.impl.AccountServiceImpl" scope="" init-method="" destory-method="">
<property name="" value=""/ref=""></property>
</bean>
~~~
- 用于創(chuàng)建對(duì)象的注解
他們的作用就是和在xml配置文件中編寫的<bean>標(biāo)簽實(shí)現(xiàn)的功能一樣。
@Component
作用:用于把當(dāng)前類對(duì)象存入到spring容器中
屬性:
value:用于指定bean標(biāo)簽的id,當(dāng)前不指定value值,默認(rèn)是當(dāng)前類名,且首字母小寫。
~~~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/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">
<!--告訴spring容器在創(chuàng)建容器時(shí)要掃描的包,配置所需要的標(biāo)簽不是在beans的約束中,而一個(gè)名稱為context名稱空間和約束-->
<!--掃描包xml配置-->
<context:component-scan base-package="com.itheima"></context:component-scan>
</beans>
~~~
~~~java
//業(yè)務(wù)層
@Component
public class AccountServiceImpl implements AccountService {
private AccountDao accountDao = new AccountDaoImpl();
public void saveAccount() {
accountDao.saveAccount();
}
}
/**
* 模擬一個(gè)表現(xiàn)層,用于調(diào)用業(yè)務(wù)層
*/
public class ControllerTest {
public static void main(String[] args) {
//1.獲取核心容器
ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
//2.根據(jù)id獲取Bean對(duì)象 兩種方式
AccountService accountService = (AccountService) context.getBean("accountServiceImpl");
System.out.println(accountService);
}
}
~~~
@Service:用于業(yè)務(wù)層
@Controller:用于表現(xiàn)層
@Repository:用于持久層
以上三個(gè)注解他們的作用和屬性于@Component是一模一樣,他們?nèi)齻€(gè)是spring框架為我們提供明確的三層使用的注解,使我們的三層對(duì)象更加清晰
- 用于注入數(shù)據(jù)的
他們的作用就是和在xml配置文件中編寫的<bean>標(biāo)簽中寫一個(gè) <property>的作用一樣的
@Autowired:
作用:自動(dòng)按照類型注入,只要容器中唯一的一個(gè)bean對(duì)象類型和要注入的變量類型匹配,就可以注入成功。如果ioc容器中沒(méi)有任何bean類型和要注入的變量類型匹配,則報(bào)錯(cuò)。如果ioc容器中有多個(gè)類型匹配時(shí),首先會(huì)根據(jù)類型查找,然后再根據(jù)唯一表示找,如果都不匹配則報(bào)錯(cuò),如果有兩個(gè)以上匹配也報(bào)錯(cuò)。
出現(xiàn)位置:可以是變量,也可以是方法。
細(xì)節(jié):在使用注解注入時(shí),set方法就不是必須得了。
@Qualifier:
作用:按照類中注入的基礎(chǔ)之上再按照名稱注入。它在給類成員注入時(shí)不能單獨(dú)使用,但在給方法參數(shù)注入時(shí)可以。
屬性:
value:用于指定注入bean的id
@Resource:
作用:直接按照Bean的id注入。它可以獨(dú)立使用。
屬性:
name:用于指定bean的。
以上三個(gè)注入都只能注入其他bean類型的數(shù)據(jù),而基本類型和String類型無(wú)法使用上述注解實(shí)現(xiàn)。另外集合類型的注入只能通過(guò)xml來(lái)實(shí)現(xiàn)。
@Value:
作用:用于注入基本數(shù)據(jù)類型和String類型的數(shù)據(jù)。
屬性:
value:用于指定數(shù)據(jù)的值,它可以使用spring中的el表達(dá)式的寫法,SpEL的寫法:${表達(dá)式}
- 用于改變作用范圍的
他們的作用就是和在xml配置文件中編寫的<bean>標(biāo)簽使用scope屬性實(shí)現(xiàn)的功能是一樣的
@Scope:
作用:用于指定bean的作用范圍
屬性:
value:指定范圍的取值,常用取值:singLeton prototype
- 和生命周期相關(guān)的
他們的作用就是和在xml配置文件中編寫的<bean>標(biāo)簽使用init-method和destory-methods的作用一樣
@PreDestroy:
作用:用于指定銷毀方法
@PostConstruct
作用:用于指定初始化方法
基于xml實(shí)現(xiàn)IOC
配置文件bean.xml
<?xml version="1.0" encoding="UTF-8"?><!--導(dǎo)入約束-->
<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對(duì)象-->
<bean id="accountService" class="com.itgyf.service.impl.AccountServiceImpl">
<!--注入dao對(duì)象-->
<property name="accountDao" ref="accountDao"></property>
</bean>
<!--配置dao對(duì)象-->
<bean id="accountDao" class="com.itgyf.dao.impl.AccountDaoImpl">
<!--注入QueryRunner-->
<property name="runner" ref="runner"></property>
</bean>
<!--配置QueryRunner-->
<bean id="runner" class="org.apache.commons.dbutils.QueryRunner" scope="prototype">
<!--注入數(shù)據(jù)源-->
<constructor-arg name="ds" ref="dataSource"></constructor-arg>
</bean>
<!--配置數(shù)據(jù)源-->
<bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<!--連接數(shù)據(jù)庫(kù)的必備信息-->
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/my_spring"></property>
<property name="user" value="root"></property>
<property name="password" value="root"></property>
</bean>
</beans>
dao層
/**
* 持久層接口
*/
public interface AccountDao {
/**
* 查詢所有
* @return
*/
List<Account> findAllAccount();
/**
* 查詢一個(gè)
* @return
*/
Account findAccountById(Integer accountId);
/**
* 保存
* @param account
*/
void saveAccount(Account account);
/**
* 修改
* @param account
*/
void updateAccount(Account account);
/**
* 刪除
* @param accountId
*/
void deleteAccount(Integer accountId);
}
/**
* 持久層實(shí)現(xiàn)類
*/
public class AccountDaoImpl implements AccountDao {
private QueryRunner runner;
public void setRunner(QueryRunner runner) {
this.runner = 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 accountId) {
try {
return runner.query("select * from account where id = ?",new BeanHandler<Account>(Account.class),accountId);
} 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 accountId) {
try {
runner.update("delete from account where id = ?",accountId);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
service層
/**
* 賬戶業(yè)務(wù)層接口
*/
public interface AccountService {
/**
* 查詢所有
* @return
*/
List<Account> findAllAccount();
/**
* 查詢一個(gè)
* @return
*/
Account findAccountById(Integer accountId);
/**
* 保存
* @param account
*/
void saveAccount(Account account);
/**
* 修改
* @param account
*/
void updateAccount(Account account);
/**
* 刪除
* @param accountId
*/
void deleteAccount(Integer accountId);
}
/**
* 業(yè)務(wù)層實(shí)現(xiàn)類
*/
public class AccountServiceImpl implements AccountService {
private AccountDao accountDao;
public void setAccountDao(AccountDao accountDao) {
this.accountDao = accountDao;
}
/**
* 查詢所有
* @return
*/
public List<Account> findAllAccount() {
List<Account> accounts = accountDao.findAllAccount();
return accounts;
}
/**
* 查詢一個(gè)
* @param accountId
* @return
*/
public Account findAccountById(Integer accountId) {
Account account = accountDao.findAccountById(accountId);
return account;
}
/**
* 保存
* @param account
*/
public void saveAccount(Account account) {
accountDao.saveAccount(account);
}
/**
* 修改
* @param account
*/
public void updateAccount(Account account) {
accountDao.updateAccount(account);
}
/**
* 刪除
* @param accountId
*/
public void deleteAccount(Integer accountId) {
accountDao.deleteAccount(accountId);
}
}
實(shí)體類
/**
* 實(shí)體類
* 實(shí)現(xiàn)Serializable是實(shí)體類的序列化
*/
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 +
'}';
}
}
測(cè)試類
/**
* junit單元測(cè)試
*/
public class AccountServiceTest {
//獲取容器
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
//得到業(yè)務(wù)層對(duì)象
AccountService accountService = ac.getBean("accountService", AccountService.class);
//查詢所有
@Test
public void findAll() {
List<Account> accounts = accountService.findAllAccount();
for (Account account : accounts) {
System.out.println(account);
}
}
//根據(jù)id查詢
@Test
public void findById() {
Account account = accountService.findAccountById(3);
System.out.println(account);
}
//保存
@Test
public void save() {
Account account = new Account();
account.setName("test");
account.setMoney(2000f);
accountService.saveAccount(account);
}
//修改
@Test
public void update() {
Account account = new Account();
account.setId(4);
account.setName("test");
account.setMoney(4000f);
accountService.updateAccount(account);
}
//刪除
@Test
public void delete() {
accountService.deleteAccount(4);
}
}
基于注解實(shí)現(xiàn)IOC
配置文件bean.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/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">
<!--告知spring在創(chuàng)建容器時(shí)需要掃描的包-->
<context:component-scan base-package="com.itgyf"></context:component-scan>
<!--配置QueryRunner-->
<bean id="runner" class="org.apache.commons.dbutils.QueryRunner" scope="prototype">
<!--注入數(shù)據(jù)源-->
<constructor-arg name="ds" ref="dataSource"></constructor-arg>
</bean>
<!--配置數(shù)據(jù)源-->
<bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<!--連接數(shù)據(jù)庫(kù)的必備信息-->
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/my_spring"></property>
<property name="user" value="root"></property>
<property name="password" value="root"></property>
</bean>
</beans>
dao層
/**
* 持久層接口
*/
public interface AccountDao {
/**
* 查詢所有
* @return
*/
List<Account> findAllAccount();
/**
* 查詢一個(gè)
* @return
*/
Account findAccountById(Integer accountId);
/**
* 保存
* @param account
*/
void saveAccount(Account account);
/**
* 修改
* @param account
*/
void updateAccount(Account account);
/**
* 刪除
* @param accountId
*/
void deleteAccount(Integer accountId);
}
/**
* 基于注解持久層實(shí)現(xiàn)類
*/
@Repository("accountDao")
public class AccountDaoImpl implements AccountDao {
//將對(duì)象注入 省去set方法
@Autowired
private QueryRunner runner;
/**
* 保存
* @return
*/
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 accountId) {
try {
return runner.query("select * from account where id = ?",new BeanHandler<Account>(Account.class),accountId);
} 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 accountId) {
try {
runner.update("delete from account where id = ?",accountId);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
Service層
/**
* 賬戶業(yè)務(wù)層接口
*/
public interface AccountService {
/**
* 查詢所有
* @return
*/
List<Account> findAllAccount();
/**
* 查詢一個(gè)
* @return
*/
Account findAccountById(Integer accountId);
/**
* 保存
* @param account
*/
void saveAccount(Account account);
/**
* 修改
* @param account
*/
void updateAccount(Account account);
/**
* 刪除
* @param accountId
*/
void deleteAccount(Integer accountId);
}
/**
* 基于注解業(yè)務(wù)層實(shí)現(xiàn)類
*/
@Service("accountService")
public class AccountServiceImpl implements AccountService {
//將對(duì)象注入 省去set方法
@Autowired
private AccountDao accountDao;
/**
* 查詢所有
* @return
*/
public List<Account> findAllAccount() {
List<Account> accounts = accountDao.findAllAccount();
return accounts;
}
/**
* 查詢一個(gè)
* @param accountId
* @return
*/
public Account findAccountById(Integer accountId) {
Account account = accountDao.findAccountById(accountId);
return account;
}
/**
* 保存
* @param account
*/
public void saveAccount(Account account) {
accountDao.saveAccount(account);
}
/**
* 修改
* @param account
*/
public void updateAccount(Account account) {
accountDao.updateAccount(account);
}
/**
* 刪除
* @param accountId
*/
public void deleteAccount(Integer accountId) {
accountDao.deleteAccount(accountId);
}
}