Spring4天-第一天IOC

别等时光非礼了梦想. 提交于 2020-01-31 08:15:33

1.什么是Spring

Spring 分层的Java  SE/EE 应用轻量级框架,以IOC ( Inversion  of   Controll控制反转)

和AOP(Aspect oriented Programming,面向切面编程,本质是动态代理,不修改源码的情况下进行功能增强)为内核 。

提供了

2.Spring 体系结构

3.耦合性问题:

* 耦合性:程序之间的依赖性。
  * 编译期依赖:编译时必须提供依赖的类,否则编译不通过。应当避免编译期依赖
  * 运行期依赖:运行时必须提供依赖的类,否则不能运行
* 耦合性越强,维护成本就越高
* 开发时要求:高内聚,低耦合

4.耦合性问题现象

* 在web开发中,服务端通常分为三层:web层、service层、dao层
  * web层调用service层完成功能:需要new一个Service对象
  * service层调用dao层操作数据库:需要new一个dao对象
* 三层之间的耦合性比较强:存在编译期依赖
  * service里写死了创建某一个dao对象:一旦dao对象换了,就需要修改service的源码
  * web里写死了创建某一个service对象:一旦service对象换了,就需要修改web的源码

5.解耦思路

方法1:可以使用反射技术,代替`new`创建对象,避免编译期依赖。
Class clazz = Class.forName("全限定类名");
Object obj = clazz.newInstance();
方法2:再把全限定类名提取到配置文件中(xml或properties),读取配置文件信息来反射创建对象
//读取配置文件,得到要创建对象的全限定类名;再通过反射技术创建对象
String className = ...;
Class clazz = Class.forName(className);
Object obj = clazz.newInstance();

6.使用工厂模式解耦

 

<dependencies>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>
</dependencies>

dao层: 

public interface UserDao {
    void save();
}
public class UserDaoImpl implements UserDao {
    @Override
    public void save() {
        System.out.println("UserDaoImpl.save......");
    }
}

 service层:

public interface UserService {
    void save();
}
public class UserServiceImpl implements UserService {

    /**
     * 存在编译期依赖:如果没有UserDaoImpl,代码编译是不通过的。
     * 要避免编译期依赖,减少运行期依赖
     * 解决思路:
     * 1. 使用反射技术代替new
     * 2. 提取配置文件
     */
    //private UserDao userDao = new UserDaoImpl();
    private UserDao userDao = (UserDao) BeanFactory.getBean("userDao");

    @Override
    public void save() {
        userDao.save();
    }
}

配置文件beans.properties

userDao=com.zengjx.dao.impl.UserDaoImpl

工厂类BeanFactory

public class BeanFactory {

    private static Map<String, Object> map = new HashMap<>();

    static {
        //类加载时,读取properties文件,把其中所有的bean都创建对象,放到一个容器里
        //当需要使用时,直接从容器中获取即可

        try {
            //1.读取配置文件
            ResourceBundle bundle = ResourceBundle.getBundle("beans");
            Enumeration<String> keys = bundle.getKeys();
            while (keys.hasMoreElements()) {
                String id = keys.nextElement();
                String className = bundle.getString(id);
                Class clazz = Class.forName(className);
                Object object = clazz.newInstance();

                map.put(id, object);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static Object getBean(String id){

        return map.get(id);
    }
}
总结:
* 解耦的思路:解决编译期依赖
  1. 生成对象时,使用反射代替`new`
  2. 配置信息放到配置文件里
* bean容器:
  * BeanFactory里增加了一个Map,把第个bean对象都放到Map里。
  * 需要使用时,只要直接从Map里获取即可,不需要每次都创建
* Spring解耦的时候:
  * 我们需要做的事情:
    * 编写Service、dao类(bean)
    * 编写配置文件(xml)
  * Spring做的事情:
    * 提供工厂类,我们直接调用Spring的工厂,获取bean对象,而不用自己创建

7.IOC 思想

* `IoC`:Inversion of Control,控制反转。是指  把创建对象的控制权交给框架:要想得到一个对象,由原来的主动创建对象,变成自己被动接收 框架创建的对象。
* `IoC`是Spring的核心思想之一
* 作用:用于降低程序间的耦合性(耦合性不能彻底解除,只能降低)

8. 控制反转入门

#### 1. 需求描述

* 有`UserDao`接口和`UserDaoImpl`实现类
* 通过Spring容器得到`UserDaoImpl`的实例对象(IoC方式)

#### 2. 开发步骤

1. 创建Maven项目,导入依赖坐标:Spring的依赖坐标
2. 编写dao接口`UserDao`及实现`UserDaoImpl`
3. 创建Spring核心配置文件,并配置`UserDaoImpl`
4. 使用Spring的API,获取Bean实例对象

maven 坐标

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.1.2.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>
</dependencies>

dao 层:

public interface UserDao {
    void save();
}
public class UserDaoImpl implements UserDao {
    @Override
    public void save() {
        System.out.println("UserDaoImpl.save......");
    }
}

创建Spring核心配置文件,并配置UserDaoImpl

配置文件名称,通常叫`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">

    <!-- 配置UserDaoImpl -->
    <bean id="userDao" class="com.zengjx.dao.impl.UserDaoImpl"></bean>
</beans>

使用Spring的API ,获得Bean 实例对象

public class SpringIocQuickStartTest {
    @Test
    public void test(){
        ApplicationContext context = 
            new ClassPathXmlApplicationContext("applicationContext.xml");
        UserDao userDao = context.getBean("userDao", UserDao.class);
        userDao.save();
    }
}

 

步骤总结:
1. 创建Maven项目,导入依赖:`spring-context`

2. 创建dao接口和实现类

3. 创建配置文件:通常是`applicationContext.xml`

   ```xml
   <bean id="唯一标识" class="全限定类名"></bean>
   ```

4. 测试:从Spring容器里获取bean对象
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");

Object bean = app.getBean("bean的唯一标识");

9.配置文件解释

  • 用于配置:把对象交给Spring进行控制

  • 默认情况下,Spring是调用类的无参构造来创建对象的;如果没有无参构造,则不能创建成功

<bean id="userDao" class="com.zengjx.dao.impl.UserDaoImpl"></bean>

 

* `id`:唯一标识
* `class`:bean的全限定类名

> 了解:bean的id和name的区别
>
> 1. 一个bean只能有一个id;一个bean可以有多个name
> 2. bean的name值:多个name之间以`,` `;` `空格 ` 隔开,第1个name作为id,其它作为别名

 

bean 标签的作用范围
<bean id="userDao" class="com.zengjx.dao.impl.UserDaoImpl" scope="singleton"></bean>
* scope属性取值如下:

| 取值            | 说明                                                         |
| --------------- | ------------------------------------------------------------ |
| `singleton`     | 默认,表示单例的,一个Spring容器里,只有一个该bean对象       |
| `prototype`     | 多例的,一个Spring容器里,有多个该bean对象                   |
| `request`       | web项目里,Spring创建的bean对象将放到`request`域中           |
| `session`       | web项目里,Spring创建的bean对象将放到`session`域中           |
| `globalSession` | web项目里,应用在Portlet环境/集群环境;如果没有Portlet/集群环境,那么globalSession相当于session(新版本中已删除) |

 10.不同scope的bean,生命周期

* singleton:bean的生命周期和Spring容器的生命周期相同
  * 整个Spring容器中,只有一个bean对象
  * 何时创建:加载Spring配置文件,初始化Spring容器时,bean对象创建
  * 何时销毁:Spring容器销毁时,bean对象销毁
* prototype:bean的生命周期和Spring容器无关。Spring创建bean对象之后,交给JVM管理了
  * 整个Spring容器中,有多个bean对象
  * 何时创建:调用`getBean`方法获取bean对象时,bean对象创建
  * 何时销毁:对象长时间不用时,垃圾回收

11.bean的生命周期相关方法的配置(了解)

<bean id="userDao" class="com.zenjgx.dao.impl.UserDaoImpl" 
      init-method="" destroy-method=""></bean>
* `init-method`:指定类中初始化方法名称,该方法将在bean对象被创建时执行

* `destroy-method`:指定类中销毁方法名称,该方法将在bean对象被销毁时执行

  > 注意:在单元测试里,Spring容器显式关闭时,才会执行destroy-method指定的方法
 ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

 UserDao userDao = context.getBean("userDao", UserDao.class);
//显式的关闭Spring容器
 ((ClassPathXmlApplicationContext)context).close();

12.bean实例化的三种方式

DataSource dataSource = DruidDataSourceFactory.createDataSource();

  • 无参构造方法实例化:默认的,让Spring调用bean的无参构造,生成bean实例对象

  • 工厂静态方法实例化:让Spring调用一个工厂类的静态方法,得到一个bean实例对象

  • 工厂非静态方法实例化(实例化方法):让Spring调用一个工厂对象的非静态方法,得到一个bean实例对象

###### 2.1 无参构造方法实例化

```xml
<bean id="userDao" class="com.zengjx.dao.impl.UserDaoImpl"></bean>
```

###### 2.2 工厂静态方法实例化

* 工厂类如下:`com.zengjx.factory.StaticFactory`

```java
public class StaticFactory{
    public static UserDao createUserDao(){
        return new UserDaoImpl();
    }
}
```

* 配置如下:

```xml
<bean id="userDao" class="com.zengjx.factory.StaticFactory" 
      factory-method="createUserDao"></bean>
```

###### 2.3 工厂非静态方法实例化

* 工厂类如下:`com.zengjx.factory.InstanceFactory`

```java
public class InstanceFactory{
    public UserDao createUserDao(){
        return new UserDaoImpl();
    }
}
```

* 配置如下:

```xml
<!-- 先配置工厂 -->
<bean id="instanceFactory" class="com.zengjx.factory.InstanceFactory"></bean>

<!-- 再配置UserDao -->
<bean id="userDao" factory-bean="instanceFactory" factory-method="createUserDao"></bean>
```

13. IOC总结

### IoC小结

* IoC:用于解耦的,控制反转

  * 如果我们需要一个对象,Spring会帮我们创建对象,交给我们使用

* bean的配置:告诉Spring创建什么样的对象

  * 基本配置:`<bean id="唯一标识" class="全限定类名"/>`

  * 作用范围:`<bean id="唯一标识" class="全限定类名" scope="作用范围"/>`

    * `singleton`:单例模式。一个Spring容器里只有一个该bean的对象
      * 何时创建:Spring容器初始化时,创建的
      * 何时销毁:Spring容器关闭时,销毁的
    * `prototype`:多例模式。一个Spring容器里有多个该bean的对象(Spring创建完,交给JVM管理)
      * 何时创建:获取bean对象时,创建的
      * 何时销毁:长时间不用,垃圾回收

  * 生命周期的方法:`<bean id="唯一标识" class="全限定类名" init-method="初始化方法" destroy-method="销毁方法"/>`

    * `init-method`:把一个方法设置为初始化方法,这个方法会在bean对象被创建时执行一次

    * `destroy-method`:把一个 方法设置为销毁方法,这个方法会在bean对象被销毁时执行一次

      > 如果bean是多例的,对象销毁进也不会执行destroy-method

* bean实例化的三种方式:告诉Spring如何创建对象

  * 默认的无参构造:Spring调用无参构造,生成bean的实例对象
  * 静态工厂方式:Spring调用工厂类的静态方法,生成bean的实例对象
  * 实例化工厂方式:Spring对象工厂对象的非静态方法,生成bean的实例对象

14.依赖注入

* 依赖注入:`Dependency Injection`,是Spring的Ioc核心的具体实现。

  * 类里依赖什么,由Spring注入(提供)什么

* 我们需要进行配置:告诉Spring,依赖什么

  我们通过Ioc把bean对象交给了Spring容器进行管理,降低了耦合性。

  但是耦合性不能彻底消除,bean之间还是有一些依赖关系。比如:业务层userService要依赖于持久层userDao。

  这样的依赖关系,可以交给Spring帮我们进行依赖的注入,而不用我们自己注入依赖
###  快速入门

#### 1. 需求描述

* 有dao层:`UserDao`和`UserDaoImpl`
* 有service层:`UserService`和`UserServiceImpl`
* `UserServiceImpl`中的方法依赖于`UserDaoImpl`
* 使用Spring,把`UserDaoImpl`注入给`UserServiceImpl`

#### 2. 开发步骤

1. 创建Maven项目,导入依赖坐标
2. 编写dao层`UserDao`及`UserDaoImpl`、service层`UserService`和`UserServiceImpl`
3. 创建Spring核心配置文件,并配置bean和依赖注入
4. 使用Spring的API,测试

#### 3. 需求实现

##### 1. 创建Maven项目,导入依赖

```xml
<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.1.2.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>
</dependencies>
```

##### 2. 编写dao层和service层代码

* dao层接口`UserDao`

```java
public interface UserDao {
    void save();
}
```

* dao层实现类`UserDaoImpl`

```java
public class UserDaoImpl implements UserDao {
    @Override
    public void save() {
        System.out.println("UserDaoImpl.save......");
    }
}
```

* service层接口`UserService`

```java
public interface UserService {
    void save();
}
```

* service层实现类`UserServiceImpl`

```java
public class UserServiceImpl implements UserService {
    //依赖于dao层的UserDao,定义一个成员变量
    private UserDao userDao;

    @Override
    public void save() {
        userDao.save();
    }
    
    //提供userDao的get/set方法
    public UserDao getUserDao() {
        return userDao;
    }

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
}
```

##### 3. 创建Spring核心配置文件,并配置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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--配置UserDao-->
    <bean id="userDao" class="com.zengjx.dao.impl.UserDaoImpl"></bean>
    <!--配置UserService-->
    <bean id="userService" class="com.zengjx.service.impl.UserServiceImpl">
        <!--把userDao注入给userService的属性-->
        <property name="userDao" ref="userDao"/>
    </bean>
</beans>
```

##### 4. 使用Spring的API,测试

```java
public class UserTest {
    public static void main(String[] args) {
        ApplicationContext context = 
            new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService userService = context.getBean("userService", UserService.class);
        userService.save();
    }
}
```

#### 4. 小结

1. 创建Maven项目,导入依赖:`spring-context`

2. 创建类:`UserService`和`UserDao`   接口及实现类

   * Service依赖于dao,要求:Service里有dao的引用、set方法

3. 创建配置文件:声明bean之间的依赖关联

   ```xml
   <bean>
   	<property name="属性名称" ref="要注入的bean对象的id"/>
   </bean>
   ```

4. 测试

15.三种注入方式

#### 2.1 set方法注入

##### 1) 介绍

在类中提供需要注入的成员(依赖项)的set方法,在配置文件中注入属性的值

```xml
<bean id="" class="">
	<property name="属性名" value="属性值"></property>
    <property name="属性名" ref="bean的id"></property>
</bean>
```

* `property`标签:用在bean标签内部,表示要给某一属性注入数据
  * `name`:属性名称
  * `value`:要注入的属性值,注入简单类型值
  * `ref`:要注入的属性值,注入其它bean对象

> 优势:创建bean对象时没有明确的限制,可以使用无参构造直接创建
>
> 缺点:如果某个成员必须有值,则获取对象时,有可能set方法未执行
2.2 构造方法注入
##### 1) 介绍

在类中提供构造方法,构造方法的每个参数就是一个依赖项,通过构造方法给依赖项注入值。

```xml
<bean id="" class="">
	<constructor-arg name="构造参数名称" value="构造参数的值"></constructor-arg>
    <constructor-arg name="构造参数名称" ref="bean的id"></constructor-arg>
</bean>
```

* `name`:构造参数的名称
* `type`:构造参数的类型
* `index`:构造参数的索引
* `value`:要注入的值,注入简单类型值
* `ref`:要注入的值,注入其它bean对象

> 优势:在获取bean对象时,注入数据是必须的操作,否则无法创建成功。
>
> 缺点:改变了bean对象的实例化方式,如果在创建对象时用不到这些数据,也必须要提供
 <!--
        2. 构造方法注入
            要求:bean类里提供有参构造,每个构造参数就是一个依赖项
            配置:使用constructor-arg标签,注入值
                name:构造参数名称
                value:注入的简单值
                ref:注入的其它bean对象

            优点:必须的依赖项,必须注入。否则会报错
            缺点:不太灵活。如果有些依赖项是非必须的,也必须注入
    -->
    <!--<bean id="userService" class="com.zengjx.service.impl.UserServiceImpl">
        <constructor-arg name="userDao" ref="userDao"/>
        <constructor-arg name="name" value="jerry"/>
    </bean>-->

 

#### 2.3 p名称空间注入(本质仍然是set方法)

##### 1) 介绍

依赖项要提供set方法, 在xml中引入p名称空间的约束

然后通过`p:属性名称=""`来注入简单数据、使用`p:属性名称-ref=""`注入其它bean对象,它的本质仍然是set方法注入


<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd">
    
    <bean id="" class="" p:属性名="简单值" p:属性名-ref="bean的id"></bean>
    
</beans>
<?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:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">
 <!--
        3. p名称空间注入
            要求:bean类里依赖项必须提供set方法; XML里必须增加 p名称空间引入
    -->
    <!--<bean id="userService" class="com.itheima.service.impl.UserServiceImpl" p:userDao-ref="userDao" p:name="jack"></bean>-->

16.集合注入给数组、List、Set、Map等注入数据

public class UserDaoImpl implements UserDao {
    private String[] arr;
    private List<String> list;
    private Set<String> set;
    private Map<String,String> map;
    private Properties properties;

    
    public String[] getArr() {
        return arr;
    }

    public void setArr(String[] arr) {
        this.arr = arr;
    }

    public List<String> getList() {
        return list;
    }

    public void setList(List<String> list) {
        this.list = list;
    }

    public Set<String> getSet() {
        return set;
    }

    public void setSet(Set<String> set) {
        this.set = set;
    }

    public Map<String, String> getMap() {
        return map;
    }

    public void setMap(Map<String, String> map) {
        this.map = map;
    }

    public Properties getProperties() {
        return properties;
    }

    public void setProperties(Properties properties) {
        this.properties = properties;
    }

    public void show(){
        System.out.println(Arrays.toString(this.arr));
        System.out.println(this.list);
        System.out.println(this.set);
        System.out.println(this.map);
        System.out.println(this.properties);
    }
}

配置注入数据

  • 注入数组:array

  • 注入List:list

  • 注入Set:set

  • 注入Map:map

  • 注入Properties:props

<bean id="userDao" class="com.zengjx.dao.impl.UserDaoImpl">
    <!--给数组注入数据-->
    <property name="arr">
        <array>
            <value>a</value>
            <value>b</value>
            <value>c</value>
        </array>
    </property>
    <!--给list注入数据-->
    <property name="list">
        <list>
            <value>a1</value>
            <value>b1</value>
            <value>c1</value>
        </list>
    </property>
    <!--给set注入数据-->
    <property name="set">
        <set>
            <value>a2</value>
            <value>b2</value>
            <value>c2</value>
        </set>
    </property>
    <!--给map注入数据-->
    <property name="map">
        <map>
            <entry key="a3" value="a3"/>
            <entry key="b3" value="b3"/>
            <entry key="c3" value="c3"/>
        </map>
    </property>
    <!--给properties注入数据-->
    <property name="properties">
        <props>
            <prop key="a4">a4</prop>
            <prop key="b4">b4</prop>
            <prop key="c4">c4</prop>
        </props>
    </property>
</bean>

所有单列结构的数据集合,标签可以互换使用。例如:List、Set、数组等

所有键值对结构的数据集合,标签可以互换使用。例如:Map、Properties等

17.ApplicationContext的继承体系

ApplicationContext:接口,代表应用上下文,可以通过其实例对象获取Spring容器中的bean对象 

18.ApplicationContext 实现类

### 2. `ApplicationContext`的实现类

#### 2.1 `ClassPathXmlApplicationContext`

* 是从类加载路径里,加载xml配置文件的
* 什么是类加载路径:代码编译之后的那个classes文件夹,
  * 开发中可以认为Maven项目的:Java文件夹、resources文件夹,都是类加载路径

#### 2.2 `FileSystemXmlApplicationContext`

* 从磁盘路径里,加载xml配置文件的

#### 2.3 `AnnotationConfigApplicationContext`

* 用注解配置Spring时,通过此类加载配置类创建Spring容器,它用于读取类上的注解配置

### 3. `getBean()`方法

* ApplicationContext提供了多种getBean方法的重载,常用的如下:

| 方法                                    | 参数            | 返回值             |
| --------------------------------------- | --------------- | ------------------ |
| `getBean(String beanId)`                | bean的id        | `Object`,bean对象 |
| `getBean(String beanId,Class beanType)` | bean的Class类型 | bean对象           |
| `getBean(Class beanType)`               |                 | bean对象           |

 

 

19.练习

写一个curd的功能,要使用Spring的IoC的方式进行解耦

* 建表语句:account.sql

* 项目需要导入的jar包依赖:

  mysql驱动, 连接池,JdbcTemplate(QueryRunner),spring,单元测试

* 在dao层,需要有一个JdbcTemplate对象:dao层有一个依赖需要注入

  *  配置service对象,依赖一个dao对象:注入dao对象
  *  配置dao对象,依赖一个JdbcTemplate对象:注入JdbcTemplate对象
  *  配置JdbcTemplate对象,依赖一个连接池对象:注入连接池对象
  *  配置连接池对象,依赖于四个简单值:驱动类名、地址、用户名、密码,注入简单值
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);

  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>day37_spring2_curd_xml</artifactId>
    <version>1.0-SNAPSHOT</version>
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>
        <dependency>
            <groupId>com.mchange</groupId>
            <artifactId>c3p0</artifactId>
            <version>0.9.5.4</version>
        </dependency>
        <dependency>
            <groupId>commons-dbutils</groupId>
            <artifactId>commons-dbutils</artifactId>
            <version>1.7</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
    </dependencies>
</project>

  resource 路径下:

   jdbc.properties:

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql:///spring1
jdbc.username=root
jdbc.password=root
applicationContext-dao.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">
    <!--AccountDao-->
    <bean id="accountDao" class="com.zengjx.dao.impl.AccountDaoImpl">
        <property name="runner" ref="runner"/>
    </bean>
    <!--QueryRunner-->
    <bean id="runner" class="org.apache.commons.dbutils.QueryRunner">
        <constructor-arg name="ds" ref="dataSource"/>
    </bean>
    <!--连接池-->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="${jdbc.driver}"/>
        <property name="jdbcUrl" value="${jdbc.url}"/>
        <property name="user" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>
</beans>
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"
       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">

    <!--引入外部的properties文件-->
    <context:property-placeholder location="classpath:jdbc.properties"/>

    <!--使用import引入模块的配置文件-->
    <import resource="classpath:applicationContext-dao.xml"/>

    <!--AccountService-->
    <bean id="accountService" class="com.zengjx.service.impl.AccountServiceImpl">
        <property name="accountDao" ref="accountDao"/>
    </bean>

</beans>

dao层:

package com.zengjx.dao;

import com.zengjx.domain.Account;

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

public interface AccountDao {
    List<Account> queryAll() throws SQLException;

    Account findById(Integer id) throws SQLException;

    void save(Account account) throws SQLException;

    void edit(Account account) throws SQLException;

    void delete(Integer id) throws SQLException;
}
package com.zengjx.dao.impl;

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

public class AccountDaoImpl implements AccountDao {

    private QueryRunner runner;

    public void setRunner(QueryRunner runner) {
        this.runner = runner;
    }

    @Override
    public List<Account> queryAll() throws SQLException {
        return runner.query("select * from account", new BeanListHandler<>(Account.class));
    }

    @Override
    public Account findById(Integer id) throws SQLException {
        return runner.query("select * from account where id = ?", new BeanHandler<>(Account.class), id);
    }

    @Override
    public void save(Account account) throws SQLException {
        runner.update("insert into account (id,name,money) values(?,?,?)", account.getId(), account.getName(), account.getMoney());
    }

    @Override
    public void edit(Account account) throws SQLException {
        runner.update("update account set name = ?, money = ? where id = ?", account.getName(), account.getMoney(), account.getId());
    }

    @Override
    public void delete(Integer id) throws SQLException {
        runner.update("delete from account where id = ?", id);
    }
}

domain:映射数据库 

package com.zengjx.domain;

public class Account {
    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 +
                '}';
    }
}

 service:

package com.zengjx.service;

import com.zengjx.domain.Account;

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

public interface AccountService {
    List<Account> queryAll() throws SQLException;

    Account findById(Integer id) throws SQLException;

    void save(Account account) throws SQLException;

    void edit(Account account) throws SQLException;

    void delete(Integer id) throws SQLException;
}
package com.zengjx.service.impl;

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

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

public class AccountServiceImpl implements AccountService {
    private AccountDao accountDao;

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

    @Override
    public List<Account> queryAll() throws SQLException {
        return accountDao.queryAll();
    }

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

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

    @Override
    public void edit(Account account) throws SQLException {
        accountDao.edit(account);
    }

    @Override
    public void delete(Integer id) throws SQLException {
        accountDao.delete(id);
    }
}
package com.zengjx.test;

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

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

public class SpringCurdTest {

    private AccountService accountService;

    @Test
    public void testQueryAll() throws SQLException {
        List<Account> accounts = accountService.queryAll();
        for (Account account : accounts) {
            System.out.println(account);
        }
    }

    @Test
    public void testFindById() throws SQLException {
        Account account = accountService.findById(4);
        System.out.println(account);
    }

    @Test
    public void testSave() throws SQLException {
        Account account = new Account();
        account.setName("rose");
        account.setMoney(100f);

        accountService.save(account);
    }

    @Test
    public void testEdit() throws SQLException {
        Account account = accountService.findById(4);
        account.setMoney(0f);
        accountService.edit(account);

    }

    @Test
    public void testDelete() throws SQLException {
        accountService.delete(4);

    }

    @Before
    public void init(){
        ApplicationContext app = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
        accountService = app.getBean("accountService", AccountService.class);
    }
}

测试结果:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 表示层Spring MVC

  • 持久层Spring JDBCTemplate

  • 业务层事务管理等

  • 耦合性:程序之间的依赖性。

    • 编译期依赖:编译时必须提供依赖的类,否则编译不通过。应当避免编译期依赖

    • 运行期依赖:运行时必须提供依赖的类,否则不能运行

  • 耦合性越强,维护成本就越高

  • 开发时要求:高内聚,低耦合

  •  

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!