Spring入门资料

来源:互联网 发布:mosh 端口 编辑:程序博客网 时间:2024/06/07 09:52

Spring 学习文档

一、    基本概念

(一)    Hello World

步骤一:

引入spring.jar包和commons-logging.jar包

步骤二:

编写如下配置文件:

<?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/beanshttp://www.springframework.org/schema/beans/spring-beans-2.0.xsd">

    <bean id="greeingService" class="sq.test.spring.test001.GreeingServiceImpl">

       <property name="greeting"value="Buenos Dias!" />

    </bean>

</beans>

步骤三:

在代码中使用spring

public class HelloWorle {

    public static void main(String[] args) {

       BeanFactory factory = new XmlBeanFactory(new FileSystemResource(

              "bin/applicationContext.xml"));

 

       GreetingService greetingService = (GreetingService) factory

              .getBean("greeingService");

 

       greetingService.sayGreeting();

    }

}

(二)    通过构造函数主任bean属性

<bean id="greeingService" class="sq.test.spring.test001.GreeingServiceImpl">

       <constructor-arg value="BuenosDias!" />

</bean>

(三)    AOP[面向切面]的基本使用方式

首先需要配置如下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:aop="http://www.springframework.org/schema/aop"

    xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-2.0.xsd

    http://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop-2.0.xsd">

    <bean id="minstrel" class="sq.test.spring.test002.Minstrel" />

    <aop:config>

       <aop:aspect ref="minstrel">

           <aop:pointcut id="questPointcut"

              expression="execution(* *.test(..)) and target(bean)"/>

           <aop:before method="singBefore"pointcut-ref="questPointcut"

              arg-names="bean" />

           <aop:after method="singAfter"pointcut-ref="questPointcut"

              arg-names="bean" />

       </aop:aspect>

    </aop:config>

</beans>

其中,红色标记部分是必须的

二、    基本Bean装配

Spring提供两种容器:

1)             Bean工厂:由org.springframework.beans.factory.BeanFactory接口定义,是最简单的容器,提供基本的依赖注入支持。

2)             应用上下文:由org.springframework.context.ApplicationContext接口定义,建立在Bean工厂基础之上,提供了系统架构服务,如:属性文件中读取文本信息,向有关的事件监听器中发布事件。

(一)    BeanFactory介绍

在Spring中,有多种BeanFactory的实现,其中最长用的是XmlBeanFactory.

要创建XmlBeanFactory需要传递一个org.springframework.core.io.Resource实例给构造函数。

  

Resource实现

   

目的

   

org.springframework.core.io.ByteArrayResource

   

定义一个内容由一组字节给定的资源

   

org.springframework.core.io.ClassPathResource

   

 

   

org.springframework.core.io.DescriptiveResource

   

 

   

org.springframework.core.io.FileSystemResource

   

 

   

org.springframework.core.io.InputStreamResource

   

 

   

org.springframework.web.portlet.context.PortletContextResource

   

 

   

org.springframework.web.context.support.ServletContextResource

   

 

   

org.springframework.core.io.UrlResource

   

 

 

 

使用方法如下:

BeanFactory factory = new XmlBeanFactory(newFileSystemResource("bin/aop_test.xml"));

 

这行代码告诉Bean工厂从XML文件中读取Bean的定义信息。但是,现在还没有实例化Bean。Bean被延迟加载到Bean工厂中的。只有在被需要的时候,才被实例化。

Minstrel minstrel =(Minstrel) factory.getBean("minstrel");

如上,当调用getBean方法的时候,工厂就会实例化Bean,这样就在Spring容器中开始了Bean的生命周期。

(二)    使用应用上下文

ApplicationContext的多种实现中,常用的有如下三种:

1)             ClassPathXmlApplicationContext:从类路中的Xml文件载入上下文定义信息,把上下文定义文件当初类路径资源

2)             FileSystemXmlApplicationContext:从文件系统中XML文件载入上下文定义信息。

3)             XmlWebApplicationContext:从WEB系统中的XML文件载入上下文定义信息

 

使用方法如下:

ApplicationContext context = new FileSystemXmlApplication(“c:/foo.xml”);

 

使用ClassPathXmlApplicationContext和FileSystemXmlApplicationContext的区别是,FileSystemXmlApplicationContext只能在指定的路径中寻找配置文件,而ClassPathXmlApplicationContext能够在整个类路径中(包括JAR文件)寻找配置文件。

 

应用上下文和Bean工厂的一个重要区别是:在对于单实例Bean的加载过程中,Bean工厂是在直到getBean方法被调用的时候才加载,而应用上下文是启动的时候,预加载所有的Bean。

 

(三)    装配集合

Spring提供4种类型的集合配置元素

  

集合元素

   

用途

   

list

   

装配一列值,运行复制

   

set

   

装配值集,确保无复制

   

map

   

装配名称—值对的集合,名称和值可以是任意类型

   

props

   

装配名称—值对的集合,名称和值都是Stirng类型

 

4种集合的使用方法如下:

1. List、Set

<bean id="testListForObj"class="sq.test.spring.test003.TestList">

       <property name="objList">

           <list>

              <ref bean="duks"/>

              <ref bean="duks"/>

              <ref bean="duks"/>

           </list>

       </property>

    </bean>

   

    <bean id="testListForString" class="sq.test.spring.test003.TestList">

       <property name="strList">

           <list>

              <value>1</value>

              <value>1</value>

              <value>1</value>

           </list>

       </property>

    </bean>

 

set的配置方式和list类似

 

2. Map

<bean id="testMapForString"class="sq.test.spring.test003.TestMap">

       <property name="testMapForString">

           <map>

              <entry key="1"value="1" />

              <entry key="2"value="2" />

              <entry key="3"value="3" />

           </map>

       </property>

    </bean>

    <bean id="testMapForObj" class="sq.test.spring.test003.TestMap">

       <property name="testMapForObj">

           <map>

              <entry key="1"value-ref="duks" />

              <entry key="2"value-ref="duks" />

              <entry key="3"value-ref="duks" />

           </map>

       </property>

    </bean>

 

map中每个entry都有一个键和值组成,包括的属性有:

key

key-ref

value

value-ref

3. props

props的使用方法如下:

<bean id="testProps"class="sq.test.spring.test003.TestMap">

       <property name="testMapForString">

           <props>

              <prop key="1">1</prop>

              <prop key="2">2</prop>

              <prop key="3">3</prop>

           </props>

       </property>

    </bean>

(四)    装配空值

<property name=”test”><null/></property>

(五)    自动装配

Spring 提供4种自动装配类型:

1、byName:通过名字自动装配。如果没有找到符合的Bean,这个属性就没有被装配上。

2、byType:通过类型自动装配。如果没有找到符合的Bean,这个属性就没有被装配上。如果找到多个,就会抛出异常

3、constructor:在容器中查找与需要自动装配的Bean的构造函数一致的一个或多个Bean。如果存在不确定Bean或构造函数,则抛出异常

4、autodetect:首先尝试使用constructor方式,然后再使用byType方式。不确定情况下的处理和constructor和byType一样。

 

使用方法如下:

<bean id="duks"class="sq.test.spring.test003.Juggler" autowire="byName">

 

可以通知配置文件,设置默认自动装配方式:

<beans  default-autowire=”byName”>

</beans>

(六)    控制bean创建

1. 控制bean的范围

默认情况下,所有SpringBean都是单一的。

 

通过设置scope=”prototype”属性,可以使得每次都产生一个新的实例

<bean id="duks"class="sq.test.spring.test003.Juggler" scope="prototype">

       <constructor-arg value="15"/>

    </bean>

 

scope的可配置值包括:

  

范围

   

说明

   

singleton

   

单例

   

prototype

   

每次使用产生一个新的bean

   

request

   

 

   

session

   

 

   

global-session

   

 

 

 

2. 通过工厂方法来创建Bean

通过配置,可以实现通过工厂方法来创建Bean

1、首先定义一个带有静态工厂方法的类:

public class TestFactoryMethod{

    private static class TestFactoryMethodHolder

    {

       static TestFactoryMethod instance =new TestFactoryMethod();

    }

   

    public static TestFactoryMethod getInstance()

    {

       return TestFactoryMethodHolder.instance;

    }

   

    public void test()

    {

       System.out.println("TestFactory Method Success !");

    }

}

2、XML配置方式如下:

<bean id="testFactoryMethod" class="sq.test.spring.test003.TestFactoryMethod"

       factory-method="getInstance"/>

 

其中,工厂方法必须是静态的。

 

3. 初始化和销毁Bean

可以在Bean中配置init-method和destory-method方法来配置在初始化和销毁bean的调用特定的方法进行处理。

 

甚至,可以在Beans节点中通过配置default-init-method和default-destory-method来配置默认的方法。

通过定义默认的初始化和销毁方法,如果在bean中找不到想要的方法名,不会报错。

 

如果不通过配置文件的方式,也可用通过使Bean实现InitializingBean和DisposableBean接口:

public class TestInitDestory implementsInitializingBean,DisposableBean{

 

    @Override

    public void afterPropertiesSet() throws Exception {

      

    }

 

    @Override

    public void destroy() throws Exception {

      

    }

}

实现InitializingBean接口要求实现afterPropertiesSet方法,该方法在设置Bean的所有指定属性之后执行。

实现DisposableBean接口要求实现destroy方法

 

三、    高级Bean装配

(一)    声明父Bean和子Bean

为了实现Bean的继承,<bean>元素提供两个特殊属性:

parent:指定Bean的id,它对bean的作用相当于extends

abstract:如果设置为true,则表示bean是抽象的,不能被实例化

1. 抽象基bean类型

使用方式如下:

<bean id="baseBean"class="sq.test.spring.test004.BaseBean"

       abstract="true">

       <property name="song"value="test song" />

       <property name="singer"value="test singer" />

    </bean>

    <bean id="song1" parent="baseBean"/>

    <bean id="song2" parent="baseBean">

       <property name="song"value="test song2" />

    </bean>

 

在代码中:

ApplicationContext ctx = new ClassPathXmlApplicationContext(

              "sq/test/spring/test004/testBaseBean.xml");

 

    BaseBean bean1 = (BaseBean) ctx.getBean("song1");

    BaseBean bean2 =(BaseBean) ctx.getBean("song2");

在定义baseBean的时候,也可以不定义abstract=”true”,照常可以使用

 

2. 抽象共同的属性

也可以单独把属性抽象出来:

<bean id="baseProperty" abstract="true">

       <property name="song"value="Somewhere Over the Rainbow" />

    </bean>

(二)    方法注入

Spring支持两种形式的方法注入:

1、  方法替换:可以在运行时用新的实现替换现有方法(抽象或具体的)。

2、  获取器注入:可以在运行时用新实现替换现有方法(抽象或具体的),从Spring上下文返回特定的Bean。

1. 方法替换

例子:

1)有一个如下类:

public class MagicBoxImpl implements MagicBox{

    public MagicBoxImpl(){}

    @Override

    public String getContents() {

       return "A beautifulassistant";

    }

}

和类:

public class TigerReplacer implements MethodReplacer{

    @Override

    public Object reimplement(Object arg0, Method arg1, Object[]arg2)

           throws Throwable {

       return "A ferocioustiger";

    }

}

2)配置文件中进行如下定义:

<bean id="magicBox" class="sq.test.spring.test005.MagicBoxImpl">

       <replaced-method name="getContents"replacer="tigerReplacer" />

</bean>

   

<bean id="tigerReplacer" class="sq.test.spring.TigerReplacer" />

 

即可实现方法替换。其中需要注意如下几点:

1、  要在spring中实现方法替换,需要增加asm和cglib包。

2、  用于替换的方法实现类必须实现MethodReplacer接口。

2. 获取器注入

例子:

1)有一个类如下:

public class Instrumentalist implements Performer {

    @Override

    public void perform() {

       System.out.println("Playing" + song + " : ");

       getInstrument().play();

    }

 

    private String song;

 

    public void setSong(String song) {

       this.song = song;

    }

 

    public Instrument getInstrument() {

       return null;

    }

}

 

public class InstrumentImpl implements Instrument{

    @Override

    public void play() {

       System.out.println("this is atest instrument");

    }

}

2)配置文件配置如下:

<bean id="stevie" class="sq.test.spring.test005.Instrumentalist">

    <lookup-method name="getInstrument" bean="testIns" />

    <property name="song" value="test song1" />

</bean>

 

<bean id="testIns"class="sq.test.spring.test005.InstrumentImpl" />

需要注意的是:

1、  其中,更常用的是将getInstrument方法定义为abstract方法。

2、  任何返回值不是void的方法都可以被<lookup-method>替换。

(三)    注入自定义属性编辑器

Spring的自定义属性编辑器基于JavaApi的java.beans.PropertyEditor接口。该接口提供了一种手段,让我们能够自定义String值如何映射到非String值。java.beans.PropertyEditorSupport是这个接口的一种简便实现方式,它有如下两个方法需要特别注意:

1、  getAsText()返回属性值的String表达式

2、  setAsText(String)把传递的String值设置给Bean的属性。

Spring提供了如下一些属性编辑器:

  

属性编辑器

   

功能

   

ClassEditor

   

 

   

CustomDateEditor

   

 

   

FileEditor

   

 

   

LocalEditor

   

 

   

StringArrayPropertyEditor

   

 

   

StringTrimmerEditor

   

 

   

URLEditor

   

 

 

 

通过扩展PropertyEditorSupport可以实现自己的属性编辑器。如下:

public class Contact {

    private PhoneNumber phoneNumber;

 

    public void setPhoneNumber(PhoneNumber phoneNumber) {

       this.phoneNumber = phoneNumber;

    }

 

    public PhoneNumber getPhoneNumber() {

       return phoneNumber;

    }

}

 

public class PhoneNumber {

    private String areaCode;

    private String prefix;

    private String number;

   

    public PhoneNumber(){}

   

    public PhoneNumber(String areaCode, String prefix, Stringnumber)

    {

       this.areaCode = areaCode;

       this.prefix = prefix;

       this.number = number;

    }

   

    @Override

    public String toString()

    {

       return this.areaCode+"-"+this.prefix+"-"+this.number;

    }

}

 

public class PhoneEditor extends PropertyEditorSupport{

    @Override

    public void setAsText(StringtextValue)

    {

       String stripped = stripNonNumber(textValue);

      

       String areaCode = stripped.substring(0, 3);

       String prefix = stripped.substring(3, 6);

       String number = stripped.substring(6);

      

       PhoneNumberphone = newPhoneNumber(areaCode, prefix, number);

      

       setValue(phone);

    }

   

    private String stripNonNumber(String original)

    {

       StringBuffer allNumberic = new StringBuffer();

      

       for(int i=0; i< original.length(); i++)

       {

           char c = original.charAt(i);

           if(Character.isDigit(c))

           {

              allNumberic.append(c);

           }

       }

      

       return allNumberic.toString();

    }

}

 

 

Xml配置如下:

<bean id="contact" class="sq.test.spring.test006.Contact">

       <property name="phoneNumber"ref="infoPhone" />

</bean>

 

<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">

       <property name="customEditors">  <!-- 固定的,必须这么写-->

           <map>

              <entry key="sq.test.spring.test006.PhoneNumber">

                  <bean id="phoneEditor"class="sq.test.spring.test006.PhoneEditor"/>

              </entry>

           </map>

       </property>

</bean>

   

<bean id="contactUseEditor"class="sq.test.spring.test006.Contact">

       <property name="phoneNumber"value="777-666-2424" />

</bean>

 

(四)    使用Spring的特殊Bean

1. 后处理Bean

例子如下:

步骤一:定义处理类

public class Fuddifier implements BeanPostProcessor{

 

    @Override

    public Object postProcessAfterInitialization(Object bean,String name)

           throws BeansException {

       if(bean != null)

       {

           Field[] fields = bean.getClass().getDeclaredFields();

          

           try

           {

              for(int i = 0; i < fields.length; i++)

              {

                  if(fields[i].getType().equals(java.lang.String.class))

                  {

                     fields[i].setAccessible(true);

                     String original = (String)fields[i].get(bean);

                      fields[i].set(bean,fuddify(original));

                  }

              }

           }

           catch(IllegalAccessException e)

           {

              e.printStackTrace();

           }

       }

       return bean;

    }

 

    @Override

    public Object postProcessBeforeInitialization(Object bean,String name)

           throws BeansException {

       return bean;

    }

   

    private Object fuddify(String orig)

    {

       if(orig == null)

           return orig;

       return orig.replaceAll("r|l", "w").replaceAll("R|L", "W");

    }

}

步骤而:编写配置文件

<bean class="sq.test.spring.test007.Fuddifier"></bean>

配置之后,容器会把Fuddifier识别为BeanPostProcessor,在每个bean被初始化之前和之后调用它的后处理器方法。例如,如下的bean:

<bean id="someClassHaveString" class="sq.test.spring.test007.SomeClassHaveStringPro">

       <property name="test1"value="rrrtest1lll" />

       <property name="test2"value="rrrtest2lll" />

</bean>

test1属性会被修改为:wwwtest1www

2. Bean工厂的后处理

如下:

public class BeanCounter implements BeanFactoryPostProcessor{

         private Logger LOGGER= Logger.getLogger(BeanCounter.class);

        

         @Override

         public voidpostProcessBeanFactory(ConfigurableListableBeanFactory factory)

                            throwsBeansException {

                   LOGGER.info("BEANCOUNT: " + factory.getBeanDefinitionCount());

         }

}

需要实现BeanFactoryPostProcessor接口,并进行如下配置:

<bean id="beanCounter"class="sq.test.spring.test007.BeanCounter" />

在全部Bean定义被加载之后,但在任何一个Bean被实例化之前(包括BeanPostProcessorBean),Spring容器会调用postProcessBeanFactory方法。

当容器发现beanCounter是个BeanPostProcessor时,会自动把它注册为Bean工厂后处理器,BeanPostProcessor不能用于基于Bean工厂容器,这个特性只能用于程序上下文。

3. 配置属性的外在化

例如,常规的数据源配置方式如下:

<bean id="dataSource"

       class="org.springframework.jdbc.datasource.DirvermanagerDataSource">

       <property name="url"value="jdbc:hsqldb:Tranining" />

       <property name="dirverClassName"value="org.hsqldb.jdbcDriver" />

       <property name="username"value="test" />

       <property name="passwork"value="test" />

</bean>

通过使用PropertyPlaceholderConfigurer,可以使用外部属性文件加载配置,首先需要定义:

<bean id="propertyConfigurer"

       class="org.springframework.beans.factor.config.PropertyPlaceholderConfigurer">

       <property name="location"value="jdbc.properties" />

</bean>

如果有多个属性文件,配置方式如下:

<bean id="propertyConfigurer"

       class="org.springframework.beans.factor.config.PropertyPlaceholderConfigurer">

       <property name="locations">

           <list>

              <value>jdbc.properties</value>

              <value>security.properties</value>

              <value>application.properties</value>

           </list>

       </property>

</bean>

然后,就可进行如下的使用方式:

<bean id="dataSource2"

       class="org.springframework.jdbc.datasource.DirvermanagerDataSource">

       <property name="url"value="${daabase.url}" />

       <property name="dirverClassName"value="${database.driver}" />

       <property name="username"value="${database.username}" />

       <property name="passwork"value="${database.password}" />

</bean>

四、    AOP:面向切面

(一)    AOP术语

1.       通知(Advice)

通知定义了切面是什么以及何时使用。除了描述切面要完成的工作,通知还解决了何时执行这个工作的问题。它应该应用在某个地方被调用之前?之后?之前和之后?或是只在方法抛出异常的时候?

2.       连接点(Joinpoint)

连接点是在程序执行过程中,能够插入切面的一个点。这个点可能是方法被调用时、异常抛出时、甚至字段被编辑时。

3.       切入点(Pointcut)

一个切面不一定是通知到程序里面所有的连接点。切入点可以缩小切面通知的连接点范围。如果说通知定义了切面的“什么”和“何时”,那么切入点定义了“何地”。

4.       切面(Aspect)

切面是通知和切入点的结合,他们共同定义了切面的全部内容——它的功能、在何时和何地完成其功能。

5.       引入(Introduction)

“引入”运行我们向现有的类添加新的方法或属性。

6.       目标(Target)

“目标”是被通知的对象

7.       代理(Proxy)

“代理”是向目标对象应用通知之后被创建的对象

8.       织入(Weaving)

“织入”是将切面应用到目标对象来创建新的代理对象的过程。切面在指定的连接点织入到目标对象。在目标对象的生命周期里有多个时机可以发生织入过程:

编译时候:切面在目标类编译时被织入。这需要特殊的编译器,AspectJ的织入编译器就以这种方式织入切面。

类加载时:切面在目标了加载到JVM时被织入。这需要特殊的ClassLoader,它可以在目标类被加载到程序之前增强类的字节代码。AspectJ的“加载时织入(LTW)”就以这种方式支持织入切面。

运行时:切面在程序运行的某个时刻被织入。一般情况下,在织入切面时,AOP容器会被动态创建一个代理对象来委托给目标对象。这就是Spring AOP织入切面的方式。

(二)    Spring对AOP的支持

 

 

五、    使用数据库

(一)    Spring的数据访问哲学

1. 异常体系

SQLException是一种针对数据访问错误的“通用”异常,也就是说任何数据访问错误都会触发这个异常,而不是每个可能的错误产生不同的异常。

Spring提供了多个数据访问异常,分别描述了触发异常的问题。同时它是与平台无关的。Spring为读取和写入数据库可能产生的任何错误都定义了相应的异常。同时它并没有与任何特定的持久化方式相关联,这意味着我们可以依赖Spring抛出一致的异常集,而不必考虑所使用的持久化方式。这样就把持久化方式与数据访问层隔离开了。

这些异常源于DataAccessException,其特殊之处在于它是免检异常,换句话说,我们不必捕获Spring抛出的任何数据访问异常(当然,捕获也是可以的)。

2. 数据访问的模板化

Spring把数据访问过程中固定与变化的部分明确地划分为两类:模板和回调。模板管理过程中固定部分;而回调处理自定义的数据访问代码。

Spring提供了多个模板,针对不同的数据访问持久化平台。如果使用的JDBC,那么可以使用JdbcTemplate,如下:Template

n  jca.cci.CciTemplate

n  jdbc.core.JdbcTemplate

n  jdbc.core.nameparam.NameParameterJdbcTemplate

n  jdbc.core.simple.SimpleJdbcTemplate

n  orm.hibernate.HibernateTemplate

n  orm.hibernate3.HibernateTemplate

n  orm.ibatis.SqlMapClientTemplate

n  orm.jdo.JdoTemplate

n  orm.jpa.JpaTemplate

n  orm.toplink.TopLinkTemplate

 

  

模板的定义如下:

   

public class DataReader

 

{

 

    private String driverClass = null;

 

    private String jdbcUrl = null;

 

    private String userName = null;

 

    private String userPswd = null;

 

   

 

    private String sql;

 

   

 

    public DataReader(String  xmlFilePath) throws DocumentException{

 

       SAXReader reader = new SAXReader();

 

       Document document =  reader.read(xmlFilePath);

 

       this.driverClass =  document.getRootElement().elementText("driverClass");

 

       this.jdbcUrl = document.getRootElement().elementText("jdbcUrl");

 

       this.userName =  document.getRootElement().elementText("userName");

 

       this.userPswd =  document.getRootElement().elementText("userPswd");

 

       this.sql = document.getRootElement().elementText("sql");

 

    }

 

   

 

    public void execute(ExecutorInDataRow executorInDataRow)throws SQLException, ClassNotFoundException{

 

       Class.forName(driverClass);

 

       Connection con = null;

 

       try{

 

           con = DriverManager.getConnection(jdbcUrl, userName, userPswd); 

 

           Statement stmt =  con.createStatement();

 

           ResultSet rs = stmt.executeQuery(sql);

 

           while(rs.next()){

 

              executorInDataRow.execute(rs);

 

           }

 

       }finally{

 

           if(null != con){

 

              con.close();

 

           }

 

       }

 

    }

 

   

 

    //定义了内部接口,用于处理数据结果

 

    public static interface  ExecutorInDataRow{

 

       public void  execute(ResultSet rs);

 

    }

 

}

 

上面的代码,使用方式如下:

DataReader dataReader = new DataReader("config/oracle_sql.xml");

dataReader.execute(new ExecutorInDataRow(){

@Override

public void execute(ResultSet rs){

   //编写实际的处理代码

}

 

3. DAO支持类

在模板/回调的基础上,Spring提供了DAO支持类,用于派生出自己的DAO类。Spring提供的DAO支持类主要有如下类型:

n  jca.cci.supportCciDaoSupport

n  jdbc.core.support.JdbcDaoSupport

n  jdbc.core.namedparame.NameParameterJdbcDaoSupport

n  jdbc.core.simple.SimpleJdbcDaoSupport

n  orm.hibernate.support.HibernateDaoSupport

n  orm.hibernate3.support.HibernateDaoSupport

n  orm.ibatis.support.SqlMapClientDaoSupport

n  orm.jdo.support.JdoDaoSupport

n  orm.jpa.support.JpaDaoSupport

n  orm.toplink.support.TopLinkDaoSupport

(二)    配置数据源

Spring提供了多个选项用于在Spring程序里面配置数据库,其中包括:

n  由JDBC驱动程序定义的数据源

n  由JNDI查询的数据源

n  连接池的数据源

对于已经准备进行发布的程序,使用从连接池获取连接的数据源更好。

1. 使用JNDI数据源

<?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:jee="http://www.springframework.org/schema/jee"

    xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-2.0.xsd

    http://www.springframework.org/schema/jee

    http://www.springframework.org/schema/jee/spring-jee-2.0.xsd">

   

    <!-- 使用这种方式,没有必要使用jee命名 -->

    <bean id="dataSource" class="org.springframework.jndi.JndiobjectFacoryBean"

       scope="singleton">

       <property name="jndiName"value="/jdbc/RantzDatasource" />

       <property name="resourceRef"value="true" />

    </bean>

   

    <!—使用这种方式,需要引入jee命名空间 -->

    <jee:jndi-lookup id="dataSource"

        jndi-name="/jdbc/RantzDatasource"

        resource-ref="true"/>

</beans>

2. 使用数据源连接池

Spring没有提供一个数据源连接池,但是DBCP项目提供了一个,使用方式如下:

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">

       <property name="driverClassName"value="org.hsqldb.jdbcDriver" />

       <property name="url"value="jdbc:hsqldb:hsql://localhost/roadrantz/roadrantz"/>

       <property name="username"value="sa" />

       <property name="password"value="" />

       <property name="initialSize"value="5" />

       <property name="maxActive"value="10" />

    </bean>

 

BasicDataSource的池配置属性主要有如下一些:

  

属性

   

说明

   

initialSize

   

 

   

maxActive

   

 

   

maxIdle

   

池里不会被释放的最多空闲连接数量,设置为0表示无限制

   

maxOpenPreparedStatements

   

同一时间能够从语句池里分配的已备语句的最大数量。设置为0表示无限制。

   

maxWait

   

在抛出异常之前,池等待连接被回收的最长时间(当没有可用连接时)。设置为-1表示无限等待。

   

minEvictableIdleTimemillis

   

连接保持空闲不被驱逐的最长时间

   

minIdle

   

在不新建连接的条件下,池中保持空闲的最少连接数

   

poolPreparedStatements

   

是否对已备语句进行池管理(布尔值)

 

 

3. 基于JDBC驱动的数据源

Spring提供了两个直接使用JDBC的数据源包

n  DriverManagerDataSource:在每个连接请求时都新建了一个连接,没有进行池管理。

n  SingleConnectionDataSource:在每个连接请求时都返回同一个连接,可以看成是只有一个连接的连接池。

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">

       <property name="driverClassName"value="org.hsqldb.jdbcDriver" />

       <property name="url"value="jdbc:hsqldb:hsql://localhost/roadrantz/roadrantz"/>

       <property name="username"value="sa" />

       <property name="password"value="" />

    </bean>

 

(三)    在Spring中使用JDBC

1. 使用JDBC模板

对于JDBC来说,Spring提供了3种模板类:

n  JdbcTemplate:Spring里面最基本的JDBC模板,利用JDBC和简单的索引参数查询提供对数据库的简单访问。

n  NamedParameterJdbcTemplate:能够在执行查询时把值绑定到SQL里的命名参数,而不是使用索引参数。

n  SimpleJdbcTemplate:利用Java 5特性,比如自动封装、通用和可变参数列表来简化JDBC模板的使用

(一)   使用JdbcTemplate访问数据

首先配置如下xml内容:

<bean id="jdbcTemplate"class="org.springframework.jdbc.core.JdbcTemplate">

       <property name="dataSource"ref="dataSource" />

    </bean>

String querySql = "select * from mytest where id = ?";

String insertSql = "insert into mytest values(?,?,?)";

//变更的方式如下:

jdbcTemplate.update(insertSql, newObject[]{"5","test5","test5"});

 

//查询的方式如下:

List<ArrayList<String>> result =jdbcTemplate.query(querySql,

                   newObject[]{"5"},

                   newRowMapper()

{

         @Override

         public ObjectmapRow(ResultSet arg0, int arg1) throws SQLException {

                   // TODOAuto-generated method stub

                   List _temp =new ArrayList();

                   _temp.add(arg0.getString(1));

                   _temp.add(arg0.getString(2));

                  _temp.add(arg0.getString(3));

                 

                  return _temp;

         }

});

(二)   使用NamedParameterJdbcTemplate访问数据

 

(三)   使用SimpleJdbcTemplate访问数据

 

2. 使用Spring对JDBC的DAO支持类

原创粉丝点击