`
senton
  • 浏览: 206681 次
  • 性别: Icon_minigender_1
  • 来自: 紫禁城
社区版块
存档分类
最新评论

使用数据库连接池和jdbc中调用存储过程

阅读更多

数据库连接池:
数据库连接不仅仅是在应用服务器与数据库之间建立一个Socket Connection,连接建立之后,还需要交换若干次数据(比如验证用户密码,权限等),然后,数据库开始初始化连接会话句柄,记录联机日志,为此连接分配相应的处理进程和系统资源。系统如此繁忙,如果我们只是简单的扔过去两个SQL语句,然后就将此连接抛弃,实在可惜,数据库连接池正是解决了这个问题。其基本原理就是在内部对象池中维护一定数量的数据库连接,并对外暴露数据库连接获取和返回的方法。

下面用几个小例子来讨论一下最常用的几个DataSource:
先建一个jdbc.properties属性文件:
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql:///it315
username=root
password=

再建一个XML配置文件,这里面有三种方法可以获取DataSource,包括Jakarta的BasicDataSource,ibatis的SimpleDataSource和Spring自带的DriverManagerDataSource:
<?xml version="1.0" encoding="gb2312"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>
 <!--使用PropertyPlaceholderConfigurer类,它告诉Spring从外部属性文件去装载一些配置信息-->
 <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
  <property name="location">
   <value>jdbc.properties</value>
  </property>
 </bean>

 <!--使用org.apache.commons.dbcp.BasicDataSource-->
 <!-- bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
  <property name="driverClassName">
  <value>${driverClassName}</value>
  </property>
  <property name="url">
  <value>${url}</value>
  </property>
  <property name="username">
  <value>${username}</value>
  </property>
  <property name="password">
  <value>${password}</value>
  </property>
  </bean-->

 <!-- 使用com.ibatis.common.jdbc.SimpleDataSource-->
 <!--
  <bean id="dataSource" class="com.ibatis.common.jdbc.SimpleDataSource">
  <constructor-arg>
  <props>
  <prop key="JDBC.Driver">${driverClassName}</prop>
  <prop key="JDBC.ConnectionURL">${url}</prop>
  <prop key="JDBC.Username">${username}</prop>
  <prop key="JDBC.Password">${password}</prop>
  </props>
  </constructor-arg>
  </bean>
 -->

 <!-- 使用org.springframework.jdbc.datasource.DriverManagerDataSource-->
 <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
  <property name="driverClassName">
   <value>${driverClassName}</value>
  </property>
  <property name="url">
   <value>${url}</value>
  </property>
  <property name="username">
   <value>${username}</value>
  </property>
  <property name="password">
   <value>${password}</value>
  </property>
 </bean>

</beans>

再建一个使用此连接池的测试类,这个类的代码几乎可以固定,要用不同的连接池只要改上面的XML文件就行了,运行结果都是一样的:
package cn.it315;

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

import javax.sql.DataSource;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class DataSourceExample {
 public void showAll() {
  Connection conn = null;
  PreparedStatement pstmt = null;
  DataSource ds = null;
  ResultSet rs = null;
  String sql = "select * from student";
  ApplicationContext application = new ClassPathXmlApplicationContext(
    "/applicationContext.xml");
  try {
   ds = (DataSource) application.getBean("dataSource");//从配置文件中读取出一个DataSource
   conn = ds.getConnection();
   pstmt = conn.prepareStatement(sql);
   rs = pstmt.executeQuery();
   System.out.println("ID\tName\tAddress\n");
   while (rs.next()) {
    System.out.println(rs.getInt(1) + "\t" + rs.getString(2) + "\t"
      + rs.getString(3));
   }
  } catch (Exception e) {
   e.printStackTrace();
  } finally {
   if (rs != null)
    try {
     rs.close();
    } catch (SQLException e) {
     e.printStackTrace();
    }
   if (pstmt != null)
    try {
     pstmt.close();
    } catch (SQLException e1) {
     e1.printStackTrace();
    }
   if (conn != null)
    try {
     conn.close();
    } catch (SQLException e) {
     e.printStackTrace();
    }
  }
 }

 public static void main(String[] args) {
  DataSourceExample ds = new DataSourceExample();
  ds.showAll();
 }

}

上面是用XML配置文件获取数据库连接池的方法。下面再介绍两种手工写代码的方法,当然我们还是用读属性文件的方式:
首先得有一个属性文件,这里用的就是上面那个jdbc.properties.
再写一个类来获取数据库连接池并使用它,这里用的是BasicDataSourceFactory:

package cn.itcast;

import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;

import javax.sql.DataSource;

import org.apache.commons.dbcp.BasicDataSourceFactory;

public class DataSourceExample {
 public Properties getProps() {
  Properties props = new Properties();
  InputStream ips = this.getClass()
    .getResourceAsStream("jdbc.properties");
  try {
   props.load(ips);
  } catch (IOException e) {
   e.printStackTrace();
  } finally {
   if (ips != null)
    try {
     ips.close();
    } catch (IOException e) {
     e.printStackTrace();
    }
  }

  return props;

 }

 public void showAll() {
  Properties props = getProps();
  Connection conn = null;
  PreparedStatement pstmt = null;
  ResultSet rs = null;
  String sql = "select * from student";

  DataSource dataSource = null;
  try {

   // 使用BasicDataSourceFactory获取数据源
   dataSource = BasicDataSourceFactory.createDataSource(props);
   conn = dataSource.getConnection();
   pstmt = conn.prepareStatement(sql);
   rs = pstmt.executeQuery();
   System.out.println("ID\tName\tAddress\n");
   while (rs.next()) {
    System.out.println(rs.getInt(1) + "\t" + rs.getString(2) + "\t"
      + rs.getString(3));
   }
  } catch (Exception e) {
   e.printStackTrace();
  } finally {
   if (rs != null)
    try {
     rs.close();
    } catch (SQLException e) {
     e.printStackTrace();
    }
   if (pstmt != null)
    try {
     pstmt.close();
    } catch (SQLException e1) {
     e1.printStackTrace();
    }
   if (conn != null)
    try {
     conn.close();
    } catch (SQLException e) {
     e.printStackTrace();
    }
  }
 }

 public static void main(String[] args) {
  DataSourceExample ds = new DataSourceExample();
  ds.showAll();
 }
}

再看一个Hibernate的DriverManagerConnectionProvider获取数据库连接池的方法:
package cn.itcast;

import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;

import org.hibernate.connection.DriverManagerConnectionProvider;

public class DataSourceExample {
 public Properties getProps() {
  Properties props = new Properties();
  InputStream ips = this.getClass().getResourceAsStream(
    "hibernate.properties");
  try {
   props.load(ips);
  } catch (IOException e) {
   e.printStackTrace();
  } finally {
   if (ips != null)
    try {
     ips.close();
    } catch (IOException e) {
     e.printStackTrace();
    }
  }

  return props;

 }

 public void showAll() {
  Properties props = getProps();
  Connection conn = null;
  PreparedStatement pstmt = null;
  ResultSet rs = null;
  String sql = "select * from student";

  DriverManagerConnectionProvider dataSource = new DriverManagerConnectionProvider();
  try {
   dataSource.configure(props);
   conn = dataSource.getConnection();
   pstmt = conn.prepareStatement(sql);
   rs = pstmt.executeQuery();
   System.out.println("ID\tName\tAddress\n");
   while (rs.next()) {
    System.out.println(rs.getInt(1) + "\t" + rs.getString(2) + "\t"
      + rs.getString(3));
   }
  } catch (Exception e) {
   e.printStackTrace();
  } finally {
   if (rs != null)
    try {
     rs.close();
    } catch (SQLException e) {
     e.printStackTrace();
    }
   if (pstmt != null)
    try {
     pstmt.close();
    } catch (SQLException e1) {
     e1.printStackTrace();
    }
   if (conn != null)
    try {
     conn.close();
    } catch (SQLException e) {
     e.printStackTrace();
    }
  }
 }

 public static void main(String[] args) {
  DataSourceExample ds = new DataSourceExample();
  ds.showAll();
 }
}


这几种方法的运行结果都是一样的。


使用CallableStatement调用存储过程,我们也用小例子来学习:
package cn.itcast;


import javax.sql.DataSource;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;

public class MainClass {
 
 //获取一个连接。现学现用,我们这里就用上面从数据库连接池获取连接的方法。
 //配置文件和属性文件这里就省略不写了,参考上面的例子:
 public static Connection getConnection() throws SQLException {
  ApplicationContext application = new ClassPathXmlApplicationContext(
    "/applicationContext.xml");
  DataSource ds = (DataSource) application.getBean("dataSource");//从配置文件中读取出一个DataSource
  return ds.getConnection();
 }

 public static void main(String[] args) {
  Connection conn = null;
  CallableStatement cstmt = null;
  ResultSet rs = null;

  try {
   conn = getConnection();

   // 调用mySql函数,用这种方式:{返回值=call 函数名(参数列表)}
   /*
     cstmt = conn.prepareCall("{?=call getName(?,?)}");
     //注册输出参数,这里是代表第一个问号。这里要注意,第一个参数的索引也是1。
     cstmt.registerOutParameter(1,Types.VARCHAR);
    
     cstmt.setInt(1,1);//设置第一个参数的值,注意:是第一个参数,并不是第一个问号,在这里是第二个问号
     cstmt.setString(2,"a");//设置第二个参数的值。
     cstmt.execute();
     System.out.println(cstmt.getString(1));
   */

   // 调用mysql存储过程,这种格式:{call 存储过程名(参数列表(包括输出和输入参数))}
   cstmt = conn.prepareCall("{call search(?,?,?)}");
   cstmt.setInt(3, 4);
   //设置第三个问号的值,因为这个参数是输入参数。其他两个是输出参数。
   //我们在下面用getXxx()的方法获取出来。
   cstmt.execute();//执行
   System.out.println("Name = " + cstmt.getString(1));//获取第一个输出参数
   System.out.println("Address = " + cstmt.getString(2));//获取第二个输出参数
  } catch (Exception e) {
   e.printStackTrace();
  } finally {
   if (rs != null)
    try {
     rs.close();
    } catch (SQLException e) {
     e.printStackTrace();
    }
   if (cstmt != null)
    try {
     cstmt.close();
    } catch (SQLException e) {
     e.printStackTrace();
    }
   if (conn != null)
    try {
     conn.close();
    } catch (SQLException e) {
     e.printStackTrace();
    }
  }

 }

两个小概念:
粗粒度:一个函数干很多事情
细粒度:一个函数干一件事,甚至一件事分为几个函数去干。

分享到:
评论

相关推荐

    JDBC 存储过程操作

    本项目聚焦于利用JDBC调用MySQL存储过程来操作数据库,这涉及到多个核心知识点,包括JDBC API的使用、存储过程的概念与应用以及数据库连接池的配置和管理。 首先,JDBC是Java语言与数据库交互的桥梁。通过JDBC API...

    jsp中调用存储过程的方法

    在实际应用中,为了提高代码的可维护性和避免硬编码,通常会将数据库连接配置、SQL语句等信息放在配置文件中,或者使用连接池管理数据库连接。此外,考虑到错误处理和异常捕获,你应该在每个可能出错的地方添加适当...

    在Java中调用存储过程详解

    4. 连接池:在实际应用中,建议使用连接池管理数据库连接,以提高性能和资源利用率。 总结,Java调用存储过程涉及到JDBC API的使用,理解存储过程的概念以及正确配置和使用`CallableStatement`对象是关键。通过熟练...

    java_proc.zip_jdbc 存储过程

    当我们需要在Java应用中调用数据库的存储过程时,通常会使用Java Database Connectivity (JDBC) API。本篇将详细介绍如何通过JDBC来调用存储过程。 首先,我们需要了解JDBC的基本概念。JDBC是Java中用于与关系型...

    Java数据库程序中的存储过程设计

    为了在Java中调用存储过程,可以使用`CallableStatement`接口。`CallableStatement`继承自`PreparedStatement`,特别适合用于调用数据库中的存储过程或函数。以下是一个简单的示例: ```java import java.sql....

    java调用存储过程

    - **连接池**:在大型应用中,使用连接池(如C3P0、HikariCP)管理数据库连接,可以提高系统性能并减少资源消耗。 - **数据库特定特性**:不同的数据库系统可能对存储过程的支持有所不同,例如Oracle支持PL/SQL,而...

    java 数据库编程宝典

    除了基本的CRUD(创建、读取、更新、删除)操作,本书还会探讨更复杂的查询技巧,如使用JOIN操作连接多表,以及如何编写存储过程和函数,并在Java中调用它们。 在性能优化方面,读者将了解到如何通过批处理、预编译...

    Java 数据库编程宝典

    4. **数据库连接池**:为了优化资源管理,开发中通常使用连接池来复用数据库连接。例如C3P0、HikariCP、Druid等,书中会介绍它们的工作机制及配置。 5. **ORM框架**:对象关系映射(ORM)如Hibernate和MyBatis,...

    Java开发实战从入门到精通视频教程下载第17章 Java数据库编程.zip

    8. **存储过程和函数**:了解如何在Java中调用数据库的存储过程和函数,以及如何定义和执行它们。 9. **数据库设计原则**:理解范式理论(1NF、2NF、3NF、BCNF等),以及如何根据业务需求进行合理的数据库设计。 ...

    java操作存储过程

    - 调整数据库连接池配置,确保足够的连接资源来执行存储过程。 - 对于有输出参数的存储过程,记得在Java代码中注册这些参数。 - 在调用存储过程时,正确处理可能抛出的异常,如SQL异常、数据类型不匹配等。 - ...

    java swing连接数据库以及三个jar包

    Java Swing 是Java GUI(图形用户界面)开发的一个重要库,它提供了一系列的...对于更复杂的数据库操作,如批处理、存储过程或连接池的使用,你可能需要进一步学习JDBC的高级特性或者使用ORM框架如Hibernate或MyBatis。

    在Java中如何调用存储过程.pdf

    在Java编程中,调用...在实际开发中,确保正确处理异常,并根据需求调整数据库连接池管理,以提高性能和资源利用率。此外,为了确保安全性,应避免硬编码数据库凭据,考虑使用连接池配置和数据源来管理数据库连接。

    java 调用存储过程

    此外,对于大型项目,推荐使用连接池来管理数据库连接,以提高性能和减少资源浪费。 `Procedure.java`文件可能是实现了上述步骤的一个Java类示例,而`Java.jpg`可能是一个关于Java调用存储过程的流程图或者代码截图...

    servlet3.0+jdbc demo

    封装通常包括连接池的使用,如Apache的DBCP或C3P0,它们能有效地管理数据库连接,提高性能。此外,还可能包含预编译SQL语句的使用(PreparedStatement),防止SQL注入攻击,并提高查询效率。 在Servlet中调用这些...

    java调用Oracle存储过程

    在Java中调用存储过程主要通过`CallableStatement`接口实现,它是`PreparedStatement`的子接口,专用于调用存储过程和函数。 以下是一个基本的步骤来调用Oracle存储过程: 1. **建立数据库连接**: 使用`...

    JSP数据库编程指南

    2. **JDBC连接池**:讨论如何使用像C3P0、Apache DBCP或HikariCP这样的连接池技术,以提高应用程序性能和资源管理。 3. **JSP内置对象和JDBC**:介绍如何使用JSP的request、response、session和application对象来...

    Java数据库高级编程宝典

    8. **存储过程与函数**: 学习如何在Java中调用数据库的存储过程和函数,理解其参数传递方式,以及如何处理返回值和结果集,可以提高程序的复杂性和效率。 9. **数据库设计与优化**: 包括数据库模式设计、范式理论、...

    Java and Databases

    书中会讲解如何在Java中调用存储过程,并讨论何时使用触发器。 7. **多线程与并发**: 在高并发环境下,正确地管理和同步数据库连接至关重要。书中会涵盖Java多线程和并发控制在数据库操作中的应用,如synchronized...

Global site tag (gtag.js) - Google Analytics