当前位置: 首页 > news >正文

JDBC 调用存储过程

引自友人blog: [url]http://blog.csdn.net/senton[/url]
 
数据库连接池:
数据库连接不仅仅是在应用服务器与数据库之间建立一个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" " [url]http://www.springframework.org/dtd/spring-beans.dtd[/url]">
<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();
    }
  }
 }
 

相关文章:

  • java web项目修改favicon.ico图标的方式
  • 字符串查找算法总结(暴力匹配、KMP 算法、Boyer-Moore 算法和 Sunday 算法)
  • $$$$GB2312-80区位编码表$$$$
  • CFD使用者应当了解的一些事情
  • C# 进程同步,通信
  • 第三份CS地图--沙漠之战
  • 构建基于分布式SOA架构的统一身份认证体系
  • 傻瓜式Linux之三:安装软件
  • Python 3.5 socket OSError: [Errno 101] Network is unreachable
  • 华章1-2月份新书简介(2017年)
  • 专业网站打包/解包asp工具(E文精装版本)!
  • 【健康医疗】4步完成数据分析报表,让医疗数据转化为生产力
  • ORACLE查找并解除死锁进程
  • 云计算那些事
  • 推荐几本书给大家
  • (ckeditor+ckfinder用法)Jquery,js获取ckeditor值
  • 《用数据讲故事》作者Cole N. Knaflic:消除一切无效的图表
  • 【EOS】Cleos基础
  • 【刷算法】求1+2+3+...+n
  • AWS实战 - 利用IAM对S3做访问控制
  • create-react-app项目添加less配置
  • Electron入门介绍
  • java8 Stream Pipelines 浅析
  • JS数组方法汇总
  • puppeteer stop redirect 的正确姿势及 net::ERR_FAILED 的解决
  • quasar-framework cnodejs社区
  • Spring思维导图,让Spring不再难懂(mvc篇)
  • SSH 免密登录
  • vue-cli3搭建项目
  • zookeeper系列(七)实战分布式命名服务
  • 回顾2016
  • 理清楚Vue的结构
  • 微信小程序填坑清单
  • 一些css基础学习笔记
  • 移动端 h5开发相关内容总结(三)
  • 机器人开始自主学习,是人类福祉,还是定时炸弹? ...
  • 支付宝花15年解决的这个问题,顶得上做出十个支付宝 ...
  • ​LeetCode解法汇总2696. 删除子串后的字符串最小长度
  • ​VRRP 虚拟路由冗余协议(华为)
  • !!java web学习笔记(一到五)
  • #git 撤消对文件的更改
  • #考研#计算机文化知识1(局域网及网络互联)
  • (003)SlickEdit Unity的补全
  • (1)常见O(n^2)排序算法解析
  • (17)Hive ——MR任务的map与reduce个数由什么决定?
  • (附源码)ssm高校社团管理系统 毕业设计 234162
  • (十八)devops持续集成开发——使用docker安装部署jenkins流水线服务
  • (四) 虚拟摄像头vivi体验
  • (算法)前K大的和
  • (转)大道至简,职场上做人做事做管理
  • (转)关于如何学好游戏3D引擎编程的一些经验
  • *上位机的定义
  • .bat批处理(四):路径相关%cd%和%~dp0的区别
  • .NET Core 项目指定SDK版本
  • .NET DevOps 接入指南 | 1. GitLab 安装