• spring(16)------spring的数据源配置


    在spring中,通过XML的形式实现数据源的注入有三种形式。

    一。使用spring自带的DriverManagerDataSource

    使用DriverManagerDataSource配置数据源与直接使用jdbc在效率上没有多大的差别,使用DriverManagerDataSource配置数据源

    的代码实比例如以下,这里重点研究spring的数据源配置。就採用spring编程式事务处理来来研究数据源的配置。

    所须要的jar包和spring编程式配置:http://blog.csdn.net/yhl_jxy/article/details/51167351

    (1)HelloDAO类:

    package com.lanhuigu.spring.dao;
    
    import javax.sql.DataSource;
    
    import org.springframework.dao.DataAccessException;
    import org.springframework.jdbc.core.JdbcTemplate;
    import org.springframework.transaction.PlatformTransactionManager;
    import org.springframework.transaction.TransactionStatus;
    import org.springframework.transaction.support.DefaultTransactionDefinition;
    import org.springframework.transaction.support.TransactionCallback;
    import org.springframework.transaction.support.TransactionCallbackWithoutResult;
    import org.springframework.transaction.support.TransactionTemplate;
    
    
    public class HelloDAO {
    	private DataSource dataSource;
    	private PlatformTransactionManager transactionManager;
    	//通过set方式注入
    	public void setDataSource(DataSource dataSource) {
    		this.dataSource = dataSource;
    	}
    	
    	public void setTransactionManager(PlatformTransactionManager transactionManager) {
    		this.transactionManager = transactionManager;
    	}
    	//=============编程式事务处理的3种编写形式====================
    	//第一种编写
    	public int create(String msg) {
    		System.out.println(msg+"開始!

    "); //使用TransactionTemplate进行事务处理编程 TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager); //调用TransactionTemplate的execute方法 Object result = transactionTemplate.execute( new TransactionCallback() { //覆盖TransactionCallback的doInTransaction()方法 @Override public Object doInTransaction(TransactionStatus status) { // TODO Auto-generated method stub //在该方法内对数据库进行添加操作 System.out.println("加入对象进行"); JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); //第一次运行不打开,第二次运行打开 //jdbcTemplate.update("insert into t_user_main values(2,'test',24)"); jdbcTemplate.update("insert into t_user_main values(1,'test',24)"); System.out.println("加入对象结束"); return null; } } ); return 0; } //另外一种编写 /*public int create(String msg) { System.out.println(msg+"開始!"); DefaultTransactionDefinition dtd = new DefaultTransactionDefinition(); TransactionStatus status = transactionManager.getTransaction(dtd); try { //使用JdbcTemplate与数据库进行交互 System.out.println("加入对象进行"); JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); jdbcTemplate.update("insert into t_user_main values(1,'test',24)"); } catch (DataAccessException ex) { // TODO: handle exception transactionManager.rollback(status); throw ex; } finally { transactionManager.commit(status); } return 0; }*/ //第三种编写 /*public int create(String msg) { System.out.println(msg+"開始。"); TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager); transactionTemplate.execute(new TransactionCallbackWithoutResult() { @Override protected void doInTransactionWithoutResult(TransactionStatus status) { // TODO Auto-generated method stub JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); jdbcTemplate.update("insert into t_user_main values(1,'test',24)"); } }); return 0; }*/ /*//============声明式事务编程============ public int create(String msg) { System.out.println(msg+"開始"); JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); //新增数据 jdbcTemplate.update("insert into t_user_main values(1,'test',24)"); System.out.println(msg+"结束"); return 0; }*/ }

    (2)使用spring自带的DataSourceTransactionManager配置数据源:

    <?xml version="1.0" encoding="UTF-8"?>
    
    <!--
      - Application context definition for JPetStore's business layer.
      - Contains bean references to the transaction manager and to the DAOs in
      - dataAccessContext-local/jta.xml (see web.xml's "contextConfigLocation").
      -->
    <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"
    		xmlns:tx="http://www.springframework.org/schema/tx"
    		xsi:schemaLocation="
    			http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
    			http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
    			http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
    	<!-- spring编程式事务配置 -->
    	<!-- 1.配置数据源(dataSource) -->
    	<bean id="dataSource" 
    		class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    		<!-- oracle数据库驱动 -->
    		<property name="driverClassName">
    			<value>oracle.jdbc.driver.OracleDriver</value>
    		</property>
    		<!-- 数据库连接 -->
    		<property name="url">
    			<value>jdbc:oracle:thin:@localhost:1521/XE</value>
    		</property>
    		<!-- 数据库用户名 -->
    		<property name="username">
    			<value>system</value>
    		</property>
    		<!-- 数据库密码 -->
    		<property name="password">
    			<value>123456</value>
    		</property>
    	</bean>
    	<!-- 2.设定transactionManager -->
    	<bean id="transactionManager" 
    		class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    		<!-- 这里配置的dataSource是DataSourceTransactionManager类中的属性,
    			在类中有着属性的定义:private DataSource dataSource; 
    			跟以下配置的HelloDAO中的dataSource不是用在一个地方。是一个东西用在两个地方-->
    		<property name="dataSource">
    			<ref bean="dataSource"/>
    		</property>
    	</bean>
    	<!-- 3.配置事务管理目标类 -->
    	<bean id="helloDAO" 
    		class="com.lanhuigu.spring.dao.HelloDAO">
    		<!-- dataSource属性 -->
    		<property name="dataSource">
    			<ref bean="dataSource"/>
    		</property>
    		<!-- transactionManager属性 -->
    		<property name="transactionManager">
    			<ref bean="transactionManager"/>
    		</property> 
    	</bean>
    	
    </beans>
    
    (3)測试程序:

    package com.lanhuigu.spring.test;
    
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    import com.lanhuigu.spring.dao.HelloDAO;
    import com.lanhuigu.spring.impl.IUser;
    
    public class TestJDBCTemplate {
    	@Test
    	public void testJDBCTemplate(){
    		//1.创建spring容器
    		ApplicationContext actx =
    				new ClassPathXmlApplicationContext("/applicationContext.xml");
    		//2.编程式測试
    		HelloDAO helloDAO = (HelloDAO) actx.getBean("helloDAO");
    		helloDAO.create("加入对象");
    	}
    }
    
    (4)总结:

    之所以说使用这样的方式跟jdbc直接操作数据库效率上没有多大差别,是由于DriverManagerDataSource建立连接是仅仅要有连接就新建一个connection,

    根本没有连接池的作用,这样做的话,数据库一直开连接,数据库崩掉是早晚的事。


    二。使用DBCP配置连接池

    须要添加jar包例如以下:

    在目录spring-framework-2.5.6libjakarta-commons下的commons-collections.jar,commons-dbcp.jar,commons-pool.jar。

    改动上面使用上面DriverManagerDataSource配置数据源的配置文件,改动为DBCP配置数据源的方式,改动后的xml例如以下。其它不变:

    <?xml version="1.0" encoding="UTF-8"?>
    
    <!--
      - Application context definition for JPetStore's business layer.
      - Contains bean references to the transaction manager and to the DAOs in
      - dataAccessContext-local/jta.xml (see web.xml's "contextConfigLocation").
      -->
    <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"
    		xmlns:tx="http://www.springframework.org/schema/tx"
    		xsi:schemaLocation="
    			http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
    			http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
    			http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
    	<!-- spring编程式事务配置 -->
    	<!-- 1.配置数据源(dataSource) -->
    	<bean id="dataSource" 
    		class="org.apache.commons.dbcp.BasicDataSource"
                    destroy-method="close">
    		<!-- oracle数据库驱动 -->
    		<property name="driverClassName">
    			<value>oracle.jdbc.driver.OracleDriver</value>
    		</property>
    		<!-- 数据库连接 -->
    		<property name="url">
    			<value>jdbc:oracle:thin:@localhost:1521/XE</value>
    		</property>
    		<!-- 数据库用户名 -->
    		<property name="username">
    			<value>system</value>
    		</property>
    		<!-- 数据库密码 -->
    		<property name="password">
    			<value>123456</value>
    		</property>
    		<!-- 最大连接数据库连接数,设置为0时。表示没有限制 -->
    		<property name="maxActive">
    			<value>255</value>
    		</property>
    		<!-- 最大等待连接中的数量,设置为0时,表示没有限制 -->
    		<property name="maxIdle">
    			<value>2</value>
    		</property>
    		<!-- 最大等待秒数,单位为毫秒。 超过时间会报出错误信息 -->
    		<property name="maxWait">
    			<value>50000</value>
    		</property>
    	</bean>
    	<!-- 2.设定transactionManager -->
    	<bean id="transactionManager" 
    		class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    		<!-- 这里配置的dataSource是DataSourceTransactionManager类中的属性。
    			在类中有着属性的定义:private DataSource dataSource; 
    			跟以下配置的HelloDAO中的dataSource不是用在一个地方。是一个东西用在两个地方-->
    		<property name="dataSource">
    			<ref bean="dataSource"/>
    		</property>
    	</bean>
    	<!-- 3.配置事务管理目标类 -->
    	<bean id="helloDAO" 
    		class="com.lanhuigu.spring.dao.HelloDAO">
    		<!-- dataSource属性 -->
    		<property name="dataSource">
    			<ref bean="dataSource"/>
    		</property>
    		<!-- transactionManager属性 -->
    		<property name="transactionManager">
    			<ref bean="transactionManager"/>
    		</property> 
    	</bean>
    	
    </beans>
    
    注意:当你执行程序时,报错的话,是HelloDAO中

    jdbcTemplate.update("insert into t_user_main values(1,'test',24)");插入数据id反复导致的,

    换个id或删掉数据库表的数据。然后再执行。

    关于DBCP的总结:

    1. 首先得了解配置文件里的属性:

    BasicDataSource提供close()方法关闭数据源。一定记得设置destroy-method=”close”。以便spring容器关闭时。

    数据源可以得到正常的关闭。还有非常多经常使用的property属性例如以下:

    defaultAutoCommit:设置从数据源中返回的连接是否採用自己主动提交的机制,默觉得true;

    defaultReadOnly:设置数据源是否仅能运行仅仅读操作,默觉得false;

    maxActive:最大连接数据库连接数,设置为0时,表示没有限制;

    mmaxIdle:最大等待连接中的数量,设置为0时,表示没有限制;

    maxWait:最大等待秒数。单位为毫秒。超时报错;

    validationQuery:用于验证连接是否成功的查询SQL语句。SQL语句必须至少要返回一行数据;

    removeAbandoned:是否自我中断,默认是false;

    removeAbandonedTimout:几秒后数据库连接会自己主动断开,在removeAbandoned为true,提供该值;

    logAbandoned:是否记录中断事件,默觉得false;

    2.使用连接池
    使用这样的方式的优点在于数据库连接时建立了连接池。连接池的优点就是当你建立连接时。从连接池中找。找到就使用已有连接,

    找不到新建连接,类推到最大连接数时,假设没有空暇可用连接,就等待。用完就释放到连接池。做到资源使用最大化。不会

    无限制的建立连接。把数据库搞崩了。

    三,使用C3P0连接数据源

    须要增加c3p0的jar包,这里使用c3p0-0.9.1.2.jar,改动spring数据源配置文件。

    <?xml version="1.0" encoding="UTF-8"?

    > <!-- - Application context definition for JPetStore's business layer. - Contains bean references to the transaction manager and to the DAOs in - dataAccessContext-local/jta.xml (see web.xml's "contextConfigLocation"). --> <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" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"> <!-- spring编程式事务配置 --> <!-- 1.配置数据源(dataSource) --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> <!-- oracle数据库驱动 --> <property name="driverClass"> <value>oracle.jdbc.driver.OracleDriver</value> </property> <!-- 数据库连接 --> <property name="jdbcUrl"> <value>jdbc:oracle:thin:@localhost:1521/XE</value> </property> <!-- 数据库username --> <property name="user"> <value>system</value> </property> <!-- 数据库密码 --> <property name="password"> <value>123456</value> </property> </bean> <!-- 2.设定transactionManager --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <!-- 这里配置的dataSource是DataSourceTransactionManager类中的属性, 在类中有着属性的定义:private DataSource dataSource; 跟以下配置的HelloDAO中的dataSource不是用在一个地方,是一个东西用在两个地方--> <property name="dataSource"> <ref bean="dataSource"/> </property> </bean> <!-- 3.配置事务管理目标类 --> <bean id="helloDAO" class="com.lanhuigu.spring.dao.HelloDAO"> <!-- dataSource属性 --> <property name="dataSource"> <ref bean="dataSource"/> </property> <!-- transactionManager属性 --> <property name="transactionManager"> <ref bean="transactionManager"/> </property> </bean> </beans>

    使用总结:

    ComboPooledDataSource和BasicDataSource一样都提供一个当spring容器关闭时用于数据源正确关闭的close()方法。

    C3P0拥有比DBCP更丰富的配置属性,通过这些属性,能够对数据源进行各种有效的控制: 
    acquireIncrement:当连接池中的连接用完时,C3P0一次性创建新连接的数目; 
    acquireRetryAttempts:定义在从数据库获取新连接失败后反复尝试获取的次数。默觉得30;

    acquireRetryDelay:两次连接中间隔时间,单位毫秒,默觉得1000; 
    autoCommitOnClose:连接关闭时默认将全部未提交的操作回滚。默觉得false; 
    automaticTestTable: C3P0将建一张名为Test的空表,并使用其自带的查询语句进行測试。

    假设定义了这个參数,那么属性preferredTestQuery将被忽略。

    你不能在这张Test表上进行不论什么操作,它将中为C3P0測试所用,默觉得null; 
     breakAfterAcquireFailure:获取连接失败将会引起全部等待获取连接的线程抛出异常。

    可是数据源仍有效保留。

    并在下次调   用getConnection()的时候继续尝试获取连接。

    假设设为true,那么在尝试获取连接失败后该数据源将申明已断开并永久关闭。默觉得 false; 
    checkoutTimeout:当连接池用完时client调用getConnection()后等待获取新连接的时间,超时后将抛出SQLException,

    如设为0则无限期等待。单位毫秒,默觉得0; 
    connectionTesterClassName: 通过实现ConnectionTester或QueryConnectionTester的类来測试连接,类名需设置为全限定名。

    默觉得 com.mchange.v2.C3P0.impl.DefaultConnectionTester; 
    idleConnectionTestPeriod:隔多少秒检查全部连接池中的空暇连接,默觉得0表示不检查; 
    initialPoolSize:初始化时创建的连接数,应在minPoolSize与maxPoolSize之间取值。

    默觉得3; 
    maxIdleTime:最大空暇时间,超过空暇时间的连接将被丢弃。

    为0或负数则永不丢弃。默觉得0。 
    maxPoolSize:连接池中保留的最大连接数。

    默觉得15; 
    maxStatements:JDBC的标准參数。用以控制数据源内载入的PreparedStatement数量。

    但因为预缓存的Statement属 于单个Connection而不是整个连接池。

    所以设置这个參数须要考虑到多方面的因素。

    假设maxStatements与 maxStatementsPerConnection均为0,则缓存被关闭。默觉得0; 
    maxStatementsPerConnection:连接池内单个连接所拥有的最大缓存Statement数。

    默觉得0; 
    numHelperThreads:C3P0是异步操作的。缓慢的JDBC操作通过帮助进程完毕。扩展这些操作能够有效的提升性能,

    通过多线程实现多个操作同一时候被运行。

    默觉得3。 
    preferredTestQuery:定义全部连接測试都运行的測试语句。

    在使用连接測试的情况下这个參数能显著提高測试速度。

    測试的表必须在初始数据源的时候就存在。默觉得null。 
    propertyCycle: 用户改动系统配置參数运行前最多等待的秒数。默觉得300。 
    testConnectionOnCheckout:因性能消耗大请仅仅在须要的时候使用它。假设设为true那么在每一个connection提交的时候都 将校验其有效性。建议使用idleConnectionTestPeriod或automaticTestTable 
    等方法来提升连接測试的性能。默觉得false; 
    testConnectionOnCheckin:假设设为true那么在取得连接的同一时候将校验连接的有效性。

    默觉得false。
    四。JNDI

    这样的方式须要在Tomcat中server.xml中配置数据源,也就是把上面的数据配置放在server.xml中,同一时候须要在spring配置文件里进行jndi配置。很麻烦。

    一般不用。


  • 相关阅读:
    简单明了的带你理解springboot原理和三大核心注解
    Spring Boot(一):入门篇
    【Mysql优化】聚簇索引与非聚簇索引概念
    Mysql索引原理与优化
    Mysql全文索引的使用
    索引的优缺点,如何创建索引
    184 01 Android 零基础入门 03 Java常用工具类03 Java字符串 02 String类 04 例:字符串与byte(即:字节)数组间的相互转换
    183 01 Android 零基础入门 03 Java常用工具类03 Java字符串 02 String类 03 String常用方法(下)
    182 01 Android 零基础入门 03 Java常用工具类03 Java字符串 02 String类 02 String常用方法(上)
    181 01 Android 零基础入门 03 Java常用工具类03 Java字符串 02 String类 01 String常用方法简介
  • 原文地址:https://www.cnblogs.com/mthoutai/p/7230772.html
Copyright © 2020-2023  润新知