Spring数据源的灵活配置巧应用

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介:
Spring数据源的灵活配置巧应用
 
环境:
Java SE 1.5
Spring-2.5.1
mysql-connector-java-5.1.5.zip
Mysql 5.x
 
为了从数据库中取得数据,我们首先需要获取一个数据库连接。 Spring通过DataSource对象来完成这个工作。 DataSource是JDBC规范的一部分, 它被视为一个通用的数据库连接工厂。通过使用DataSource, Container或Framework可以将连接池以及事务管理的细节从应用代码中分离出来。 作为一个开发人员,在开发和测试产品的过程中,你可能需要知道连接数据库的细节。 但在产品实施时,你不需要知道这些细节。通常数据库管理员会帮你设置好数据源。
 
在使用Spring JDBC时,你既可以通过JNDI获得数据源,也可以自行配置数据源( 使用Spring提供的DataSource实现类)。使用后者可以更方便的脱离Web容器来进行单元测试。 这里我们将使用DriverManagerDataSource,不过DataSource有多种实现, 后面我们会讲到。使用DriverManagerDataSource和你以前获取一个JDBC连接 的做法没什么两样。你首先必须指定JDBC驱动程序的全限定名,这样DriverManager 才能加载JDBC驱动类,接着你必须提供一个url(因JDBC驱动而异,为了保证设置正确请参考相关JDBC驱动的文档), 最后你必须提供一个用户连接数据库的用户名和密码。
 
以上两段文字摘自Spring开发文档原文,下面我写的一个小的应用,用来测试Srping JDBC支持的效果。
 
下面这个测试要实现一个目标:通过获取Spring的数据源来查询MySQL数据库testdb的一个表t_user数据。

一、创建项目,加载程序用到的工具包和驱动。并在源代码目录中添加Spring的配置文件ApplicationContext.xml,配置内容如下:
<? xml  version ="1.0"  encoding ="gb2312" ?> 
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> 

< beans > 
    <!-- 数据库的数据源定义--> 
     < bean  id ="rptds"  class ="org.springframework.jdbc.datasource.DriverManagerDataSource"  destroy-method ="close" > 
         < property  name ="driverClassName" > 
             < value >com.mysql.jdbc.Driver </ value > 
         </ property > 
         < property  name ="url" > 
             < value >jdbc:mysql://localhost:3306/testdb </ value > 
         </ property > 
         < property  name ="username" > 
             < value >root </ value > 
         </ property > 
         < property  name ="password" > 
             < value >leizhimin </ value > 
         </ property > 
     </ bean > 
</ beans >
 
二、然后创建数据库环境:
 
create database if not exists testdb; 

DROP TABLE IF EXISTS t_user; 

CREATE TABLE t_user ( 
  id int(11) NOT NULL auto_increment, 
  firstname varchar(50) default NULL, 
  lastname varchar(50) default NULL, 
  zipcode varchar(10) default NULL, 
  tel varchar(20) default NULL, 
  address varchar(200) default NULL, 
  PRIMARY KEY  (id) 
) ENGINE=InnoDB DEFAULT CHARSET=gbk; 

insert  into t_user(id,firstname,lastname,zipcode,tel,address) values  
(1,'haha','hehe','234444','13577788999','阿斯地方'), 
(2,'lei','aaa','450000','13939012107','郑州市经三路');
 
三、Spring Bean容器环境获取工具类
 
package com.lavasoft.dbtest; 

import org.springframework.context.support.ClassPathXmlApplicationContext; 

/** 
* Created by IntelliJ IDEA. 
* File: ContextHelper.java 
* User: leizhimin 
* Date: 2008-2-21 14:20:46 
* Spring Bean容器环境获取工具类 
*/
 
public  final  class ContextHelper { 
     private  static ClassPathXmlApplicationContext _ctx; 

     static { 
        _ctx =  new ClassPathXmlApplicationContext( "ApplicationContext.xml"); 
    } 

     private ContextHelper() { 
    } 

     public  static ClassPathXmlApplicationContext getContext() { 
         return _ctx; 
    } 
}
 
三、写获取数据库工具类
 
package com.lavasoft.dbtest; 

import org.apache.commons.logging.Log; 
import org.apache.commons.logging.LogFactory; 

import javax.sql.DataSource; 
import java.sql.Connection; 
import java.sql.SQLException; 
import java.sql.CallableStatement; 

/** 
* Created by IntelliJ IDEA. 
* File: DBUtil.java 
* User: leizhimin 
* Date: 2008-2-21 14:26:30 
* 数据库工具 
*/
 
public  final  class DBUtil { 
     private  static  final Log log = LogFactory.getLog(DBUtil. class); 

     /** 
     * 获取系统的数据源 
     * 
     * @return DataSource 
     */
 
     public  static DataSource getDataSource() { 
        DataSource dataSource =  null
         try { 
            dataSource = (DataSource) ContextHelper.getContext().getBean( "rptds"); 
        }  catch (Exception e) { 
            log.error( "获取数据源出错,请检查Spring数据源配置!"); 
        } 
         return dataSource; 
    } 

     /** 
     * 获取数据库连接 
     * 
     * @return Connection 
     */
 
     public  static Connection makeConnection() { 
        Connection conn =  null
         try { 
            conn = getDataSource().getConnection(); 
        }  catch (SQLException e) { 
            log.error( "通过数据源获取数据库连接发生异常!"); 
            e.printStackTrace(); 
        } 
         return conn; 
    } 

     /** 
     * 执行没有参数的SQL过程 
     * 
     * @param procedureName 存储过程名字 
     * @return boolean      返回存储过程执行的结果,true表示执行成功,false表示执行失败. 
     */
 
     public  static  boolean executeBSDProcedure(String procedureName) { 
         boolean flag =  false
        String sqlStr =  "{call " + procedureName +  "()}"
        CallableStatement cs; 
        Connection conn = makeConnection(); 
         try { 
            cs = (CallableStatement) conn.prepareStatement(sqlStr); 
            cs.executeUpdate(sqlStr); 
            flag =  true
        }  catch (SQLException e) { 
            log.error( "调用存储过程" + sqlStr +  "失败!"); 
            e.printStackTrace(); 
        } 
         return flag; 
    } 
}
 
四、写测试类
 
package com.lavasoft.dbtest; 

import org.apache.commons.logging.Log; 
import org.apache.commons.logging.LogFactory; 

import java.sql.Connection; 
import java.sql.Statement; 
import java.sql.ResultSet; 
import java.sql.SQLException; 

/** 
* Created by IntelliJ IDEA. 
* File: Test.java 
* User: leizhimin 
* Date: 2008-2-21 14:41:49 
* Spring 数据源应用测试 
*/
 
public  class Test { 
     private  static  final Log log = LogFactory.getLog(Test. class); 

     public  static  void main(String args[]) { 
        Test.test(); 
    } 

     public  static  void test() { 
        String testSql =  "select * from t_user"
        Connection conn = DBUtil.makeConnection(); 
        Statement stmt =  null
         try { 
            stmt = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.CLOSE_CURSORS_AT_COMMIT); 
            ResultSet rs = stmt.executeQuery(testSql); 
             while (rs.next()) { 
                String firstName = rs.getString( "firstname"); 
                String lastName = rs.getString( "lastname"); 
                System.out.println(firstName +  " " + lastName); 
            } 
        }  catch (SQLException e) { 
            e.printStackTrace(); 
        }  finally { 
             if (stmt !=  null) { 
                 try { 
                    stmt.close(); 
                }  catch (SQLException e) { 
                    log.info( "关闭Statement对象出现异常!"); 
                    e.printStackTrace(); 
                } 
            } 
             if (conn !=  null) { 
                 try { 
                    conn.close(); 
                }  catch (SQLException e) { 
                    log.error( "关闭数据库连接失败!"); 
                    e.printStackTrace(); 
                } 
            } 
        } 
    } 
}
 
测试运行结果:
 
haha hehe 
lei aaa 

Process finished with exit code 0
 
五、数据源置换
Spring实现的DriverManagerDataSource并没有提供连接池的功能,只是用来作简单的单机连接测试,并不适合使用于真正的项目当中,可以考虑用比较成熟的数据连接池来取代。Apache DBCP连接池是不错,如要要替换,则需要加载DBCP相关的工具包。
<? xml  version ="1.0"  encoding ="gb2312" ?> 
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> 

< beans > 
    <!-- 数据库的数据源定义--> 
     < bean  id ="rptds"  class ="org.apache.commons.dbcp.BasicDataSource"  destroy-method ="close" > 
         < property  name ="driverClassName" > 
             < value >com.mysql.jdbc.Driver </ value > 
         </ property > 
         < property  name ="url" > 
             < value >jdbc:mysql://localhost:3306/testdb </ value > 
         </ property > 
         < property  name ="username" > 
             < value >root </ value > 
         </ property > 
         < property  name ="password" > 
             < value >leizhimin </ value > 
         </ property > 
     </ bean > 
</ beans >
 
现在所使用的是org.apache.commons.dbcp.BasicDataSource作为注入的DataSource实例,为了使用DBCP 的功能,您需要在Classpath路径中设定commons-dbcp.jar、commons-pool.jar与commons- collections.jar。注意到在dataSource上设定了"destroy-method"属性,如此可以确保BeanFactory在关闭时也一并关闭BasicDataSource。
六、使用JNDI数据源
 
如果您的Servlet容器提供了JNDI(Java Naming and Directory Interface)的DataSource,您也可以简单的换上这个DataSource:
<? xml  version ="1.0"  encoding ="gb2312" ?> 
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> 

< beans > 
    <!-- 数据库的数据源定义--> 
     < bean  id ="dataSource" 
           class ="org.springframework.indi.JndiObjectFactoryBean" > 
         < property  name ="jndiName" > 
             < value >jdbc/testds </ value > 
         </ property > 
     </ bean > 
</ beans >
 
为了使用org.springframework.indi.JndiObjectFactoryBean,您需要spring-context.jar,"jndiName"实际上要根据您所设定的JNDI查询名称。
 
参考资料:
Spring 2.0开发文档
Spring 技术手册

祝各位元宵节快乐!!!

本文转自 leizhimin 51CTO博客,原文链接:http://blog.51cto.com/lavasoft/62686,如需转载请自行联系原作者
相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
11天前
|
SQL Java 数据库连接
(自用)Spring常用配置
(自用)Spring常用配置
15 0
|
1月前
|
监控 Java 数据处理
【Spring云原生】Spring Batch:海量数据高并发任务处理!数据处理纵享新丝滑!事务管理机制+并行处理+实例应用讲解
【Spring云原生】Spring Batch:海量数据高并发任务处理!数据处理纵享新丝滑!事务管理机制+并行处理+实例应用讲解
|
1月前
|
SQL Java 数据库连接
挺详细的spring+springmvc+mybatis配置整合|含源代码
挺详细的spring+springmvc+mybatis配置整合|含源代码
40 1
|
25天前
|
安全 Java 数据安全/隐私保护
【深入浅出Spring原理及实战】「EL表达式开发系列」深入解析SpringEL表达式理论详解与实际应用
【深入浅出Spring原理及实战】「EL表达式开发系列」深入解析SpringEL表达式理论详解与实际应用
54 1
|
4天前
|
存储 安全 Java
第2章 Spring Security 的环境设置与基础配置(2024 最新版)(下)
第2章 Spring Security 的环境设置与基础配置(2024 最新版)(下)
13 0
|
4天前
|
安全 Java 数据库
第2章 Spring Security 的环境设置与基础配置(2024 最新版)(上)
第2章 Spring Security 的环境设置与基础配置(2024 最新版)
28 0
|
5天前
|
安全 Java Spring
Spring Security 5.7 最新配置细节(直接就能用),WebSecurityConfigurerAdapter 已废弃
Spring Security 5.7 最新配置细节(直接就能用),WebSecurityConfigurerAdapter 已废弃
18 0
|
5天前
|
安全 Java 应用服务中间件
江帅帅:Spring Boot 底层级探索系列 03 - 简单配置
江帅帅:Spring Boot 底层级探索系列 03 - 简单配置
19 0
江帅帅:Spring Boot 底层级探索系列 03 - 简单配置
|
11天前
|
JSON Java 数据库连接
属性注入掌握:Spring Boot配置属性的高级技巧与最佳实践
属性注入掌握:Spring Boot配置属性的高级技巧与最佳实践
18 1
|
11天前
|
Java 数据库连接 Spring
简化配置,提高灵活性:Spring中的参数化配置技巧
简化配置,提高灵活性:Spring中的参数化配置技巧
19 0