`
yeshaoting
  • 浏览: 668744 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

[反射机制]建立数据库连接

    博客分类:
  • J2SE
 
阅读更多

 

 

11. 利用反射机制建立数据库连接

解析数据库数据源配置文件(.xml),利用反射机制将配置文件中设置的数据源参数设置到 Class 类实例中,然后将该 Class 类实例强制转换成对应的数据源类。

 

1. 自定义数据源配置文件data-source-config.xml

简单提出一些约束条件。这些约束在解析该数据源配置文件时用到。

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

 

<!-- quote from struts-config.xml -->

<!--

   

    数据源配置文件几点约束:

    1. <data-sources>节点下定义了一套数据源<data-source>[JDBC 2.0 Standard Extension]

    2. 节点拼写大小写敏感,目前有且只有三级节点

    3. 只允许有一个根节点<data-sources>

    4. 出现多个 id <data-source>节点,以第一个为准

   

    数据源查找方式:

    1. <data-source>节点数 < 1, 即节点数为0

       未设置数据源,报错

   

    2. 默认数据源方式

       <data-source>节点未设置 id 属性值或 id 属性值为null<data-source>

      

    3. 指定数据源方式

       匹配<data-source>节点 id 属性值

             

 -->

<data-sources>

    <data-source type="org.apache.commons.dbcp.BasicDataSource">

       <set-property property="driverClassName" value="com.mysql.jdbc.Driver" />

       <set-property property="url" value="jdbc:mysql://localhost:3306/mydb" />

       <set-property property="username" value="root" />

       <set-property property="password" value="root" />

       <set-property property="maxActive" value="30" />

       <set-property property="maxIdle" value="10" />

       <set-property property="maxWait" value="1000" />

    </data-source>

</data-sources>

 

 

2. 解析配置文件

利用 XML 解析工具包解析配置文件。本文采用 jdom 来解析配置文件。

全局变量:

/**

 * Copyright (c) 2011 Trusted Software and Mobile Computing(TSMC)

 * All right reserved.

 *

 * Created on Aug 19, 2011 6:37:38 PM

 * http://jarg.iteye.com/

 * Author: Jarg Yee <yeshaoting@gmail.com>

     */ 

 

 

    /** 配置文件路径 */

    private static final String CONFIG = "data-source-config.xml";

   

    /** 默认配置数据源 id 属性值 */

    private static final String DEFAULT_ID = "null";

   

    /** 配置文件节点属性名 */

    private static final String ATT_TYPE = "type";

    private static final String ATT_ID = "id";

    private static final String ATT_PROPERTY = "property";

    private static final String ATT_VALUE = "value";

    private static final String ATT_REF = "ref";

   

    /** 配置文件节点名 */

    private static final String NODE_DATA_SOURCES = "data-sources";

    private static final String NODE_DATA_SOURCE = "data-source";

    private static final String NODE_SET_PROPERTY = "set-property";

   

    /** 反射机制获取方法名前缀 */

    private static final String PREFIX_SET = "set";

    private static final String PREFIX_GET = "get";

   

    /** 二种基本类型 */

    private static final String TYPE_INT = "int";

    private static final String TYPE_LONG = "long";

   

 

2.1 初始化配置文件

加载自定路径的配置文件,该路径是相对于类加载目录的路径。

Eclipse C/S项目中相对于classpathbin目录,Eclipse B/S项目中相对于classpathWebRoot/classes目录。

关键代码: 

    /**

     * 初始化配置

     * */

    private void initConfig(String config)

    {

       InputStream in = this.getClass().getClassLoader().getResourceAsStream(config);

       SAXBuilder builder = new SAXBuilder();

      

      

       try

       {

           Document doc = builder.build(in);

           root = doc.getRootElement();

       }

       catch (Exception e)

       {

           System.out.println("配置文件" + config + "丢失");

           e.printStackTrace();

       }

    }

   

 

2.2 选择数据源节点

循环获取数据源节点<data-source>属性 id 值与传入的数据源节点 id 值匹配,获取对应的数据源节点。

关键代码:

    /**

     * 需要加上 "" ,否则无法与null匹配成功

     * 不知道什么原因

     * */ 

    for(int i=0; i<dataSources.size(); i++)

    {

       Element element = dataSources.get(i);

       if(id.equals("" + element.getAttributeValue(ATT_ID)))

       {

           dataSourceElement = element;

       }

    }

   

 

2.3 创建、设置、获取数据源实例

[创建数据源实例] 先获取数据源type属性值(声明数据源类完全限定名称),通过这个完全限定名称字符串创建 Class 类实例。

 

[设置数据源实例] 再获取当前数据源节点<datab-source>下所有属性设置节点<set-property>

然后获取每个属性设置节点<set-property>namevalue属性值,根据name值获取字段类型。

不同类型值转换过程通过getMatchValue()方法来实现,其用途是:

a. 利用反射机制获取对应的setter方法的方法getMethod(),需要setter方法参数类型

b. value属性值读出来的是String类型(可以看作是Object类型),需要转换成setter方法对应的类型值。

例如:org.apache.commons.dbcp.BasicDataSource.BasicDataSource setMinIdle()方法:

    public synchronized void setMinIdle(int minIdle)

 

[获取数据源实例] 最后,通过invoke()方法完成setter方法调用,将属性设置节点<set-property>属性值通过相应的setter方法设置到 Class 类实例相应的属性中。将 Class 类实例强制转换成 DataSource(所有数据源类的父类),返回。

 

关键代码:

    /**

     * 设置数据源数据

     * @param dataSourceElement Element - 选择的数据源节点

     * @throws Exception

     * */

    private DataSource newInstance(Element dataSourceElement) throws Exception

    {

       String type = dataSourceElement.getAttributeValue(ATT_TYPE);

       if(type == null)

       {

           throw new Exception("未定义数据源类型");

       }

 

       Class<?> clazz = Class.forName(type);

       Object obj = clazz.newInstance();

      

       List<Element> properties = dataSourceElement.getChildren(NODE_SET_PROPERTY);

      

       for(int i=0; i<properties.size(); i++)

       {

           Element property = properties.get(i);

           String name = property.getAttributeValue(ATT_PROPERTY);

           if(name == null)

           {

              throw new Exception("未定义属性名");

           }

          

           String value = property.getAttributeValue(ATT_VALUE);

           if(value == null)

           {

              throw new Exception("未定义属性值");

           }

          

           /** 为了获取参数类型 */

           Field field = clazz.getDeclaredField(name);

           Class<?> fieldType = field.getType();

          

           String methodName = getMethodName(PREFIX_SET, name);

           Method method = clazz.getMethod(methodName, fieldType);

           method.invoke(obj, getMatchValue(fieldType, value));

          

       }

       return (DataSource)obj;

    }

   

    /**

     * 获取与字段类型相匹配的值

     * */

    private Object getMatchValue(Class<?> fieldType, String value)

    {

      

       /**

        * 目前只有二类基本类型转换

        * */

       if(fieldType.getName().equals(TYPE_INT))

       {

           return Integer.parseInt(value);

       }

       else if(fieldType.getName().equals(TYPE_LONG))

       {

           return Long.parseLong(value);

       }

       else

           return value;

    }

   

 

2.4 建立数据库连接

通过上一步返回的数据源javax.sql.DataSource(这是一个接口)实例调用getConnection()方法建立数据库连接。

 

关键代码:

   

    /**

     * 获取指定数据源的数据库

     * @throws Exception

     * */

    protected static Connection getConnection(DataSourceConfig dataSourceConfig, String id)

           throws Exception

    {

       return dataSourceConfig.getDataSource(id).getConnection();

    }

   

 

2.5 提供获取数据库连接用户接口

封装具体的数据库内部实现,将相关方法权限设置为 protected

利用getConnection(String id)获取指定数据源的数据库连接。

 

关键代码:

 

    /**

     * 获取指定数据源的数据库连接

     * 不支持自定义用户名,密码方式

     * @param id String

     * */

    public Connection getConnection(String id)

    {

       Connection conn = null;

       try

       {

           conn = DataSourceConfig.getConnection(dataSourceConfig, id);

       }

       catch (Exception e)

       {

           e.printStackTrace();

       }

       return conn;

    }

   

 

  • ex2.rar (1011.9 KB)
  • 下载次数: 4
0
4
分享到:
评论

相关推荐

    j2ee学习路径 对初学者很有帮助

    反射机制 2:数据库(Oracle或者MySQL) SQL语句 多表连接,内外连接, 子查询等 管理表、视图、索引、序列、约束等 树状结构存储 存储过程、触发器 数据库设计三范式、 3:JDBC JDBC基础 连接池 树状结构存储与...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part4

     19.1.2 使用配置文件指定的数据库连接池  19.1.3 从容器中获得数据源  19.1.4 由Java应用本身提供数据库连接  19.2 配置事务类型  19.3 把SessionFactory与JNDI绑定  19.4 配置日志  19.5 使用XML格式的配置...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part2

     19.1.2 使用配置文件指定的数据库连接池  19.1.3 从容器中获得数据源  19.1.4 由Java应用本身提供数据库连接  19.2 配置事务类型  19.3 把SessionFactory与JNDI绑定  19.4 配置日志  19.5 使用XML格式的配置...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part3

     19.1.2 使用配置文件指定的数据库连接池  19.1.3 从容器中获得数据源  19.1.4 由Java应用本身提供数据库连接  19.2 配置事务类型  19.3 把SessionFactory与JNDI绑定  19.4 配置日志  19.5 使用XML格式的配置...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part1.rar

     19.1.2 使用配置文件指定的数据库连接池  19.1.3 从容器中获得数据源  19.1.4 由Java应用本身提供数据库连接  19.2 配置事务类型  19.3 把SessionFactory与JNDI绑定  19.4 配置日志  19.5 使用XML格式的配置...

    J2EE应用开发详解

    17 2.1 构建开发环境 17 2.1.1 安装JDK 17 2.1.2 安装Tomcat 21 2.1.3 安装Eclipse 23 2.2 配置开发环境 23 2.3 小结 26 第3章 Java的反射机制 27 3.1 Java反射API 27 3.2 加载类的实例 29 3.2.1 加载class对象的两...

    轻松学C#(图解版)

    第三篇是应用技术篇,主要介绍的是异常处理、文件和流、委托、事件、Lambda表达式、命名空间、预处理器、程序集、运行时类型标识、反射、特性、泛型、LINQ和数据库开发等。 =======================================...

    PHP和MySQL Web开发第4版pdf以及源码

    11.2.6 从数据库断开连接 11.3 将新信息放入数据库 11.4 使用Prepared语句 11.5 使用PHP与数据库交互的其他接口 11.5.1 使用常规的数据库接口:PEAR MDB2 11.6 进一步学习 11.7 下一章 第12章 MySQL高级管理...

    PHP和MySQL WEB开发(第4版)

    11.2.6 从数据库断开连接 11.3 将新信息放入数据库 11.4 使用Prepared语句 11.5 使用PHP与数据库交互的其他接口 11.5.1 使用常规的数据库接口:PEAR MDB2 11.6 进一步学习 11.7 下一章 第12章 MySQL高级管理 12.1 ...

    PHP和MySQL Web开发第4版

    11.2.6 从数据库断开连接 11.3 将新信息放入数据库 11.4 使用Prepared语句 11.5 使用PHP与数据库交互的其他接口 11.5.1 使用常规的数据库接口:PEAR MDB2 11.6 进一步学习 11.7 下一章 第12章 MySQL高级管理...

    jdbc基础和参考

    1.数据库连接的方式: ODBC:开放式数据库连接。 C语言实现的,提供语言和(基于SQL的)数据库进行交互的“一致性”的接口 JDBC:java版本的ODBC JDBC连接数据库的步骤: 1.注册驱动(加载驱动): 注册的方式: ...

    Spring.3.x企业应用开发实战(完整版).part2

    3.2.3 Java反射机制 3.3 资源访问利器 3.3.1 资源抽象接口 3.3.2 资源加载 3.4 BeanFactory和ApplicationContext 3.4.1 BeanFactory介绍 3.4.2 ApplicationContext介绍 3.4.3 父子容器 3.5 Bean的生命周期 3.5.1 ...

    Spring3.x企业应用开发实战(完整版) part1

    3.2.3 Java反射机制 3.3 资源访问利器 3.3.1 资源抽象接口 3.3.2 资源加载 3.4 BeanFactory和ApplicationContext 3.4.1 BeanFactory介绍 3.4.2 ApplicationContext介绍 3.4.3 父子容器 3.5 Bean的生命周期 3.5.1 ...

    asp.net知识库

    在ASP.NET中使用WINDOWS验证方式连接SQL SERVER数据库 改进ADO.Net数据库访问方式 ASP.NET 2.0 绑定高级技巧 简单实用的DataSet更新数据库的类+总结 [ADO.NET]由数据库触发器引发的问题 为ASP.NET封装的SQL数据库...

    java面试题

    52.8. 有几种开源的数据库连接池: 29 53. 描述一下JVM加载class文件的原理机制? 30 54. socket编程 30 54.1. 什么是TCP/IP、UDP? 30 54.2. Socket在哪里呢? 31 54.3. Socket是什么呢? 32 54.4. socket的实现步骤...

    华为HCIE-RS V3.0培训视频教程【共86集】.rar

    目录: 网盘文件,永久连接 01 OSPF部分-HCIE路由技术深入 02 OSPF部分-IP FRR 03 OSPF部分-OSPF RFC1583兼容 04 BGP部分-Peer Group 05 BGP部分-路由反射器 06 BGP部分-联盟 07 BGP部分-团体属性 08 BGP部分...

    21天学通Java-由浅入深

    162 8.5.8 重写equals方法 163 8.6 final与继承的关系 164 8.7 abstract与继承的关系 165 8.8 什么是多态 166 8.9 什么是枚举类 168 8.10 什么是反射机制 169 8.11 什么是泛型 170 8.12 综合练习 172 8.13 小结 172 ...

    Java开发技术大全 电子版

    3.2.7对象的释放和垃圾收集机制108 3.3成员变量的定义与使用109 3.3.1成员变量的定义109 3.3.2成员变量的访问权限110 3.3.3实例成员变量和静态成员变量114 3.4方法的定义和实现116 3.4.1方法的声明117 3.4.2...

Global site tag (gtag.js) - Google Analytics