Spring IOC

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>

- 使用注解提供

    * 曾經(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);
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容