当前位置:  编程技术>java/j2ee

基于Java回顾之JDBC的使用详解

    来源: 互联网  发布时间:2014-10-25

    本文导语:  尽管在实际开发过程中,我们一般使用ORM框架来代替传统的JDBC,例如Hibernate或者iBatis,但JDBC是Java用来实现数据访问的基础,掌握它对于我们理解Java的数据操作流程很有帮助。 JDBC的全称是Java Database Connectivity。 JDBC对数据库进...

尽管在实际开发过程中,我们一般使用ORM框架来代替传统的JDBC,例如Hibernate或者iBatis,但JDBC是Java用来实现数据访问的基础,掌握它对于我们理解Java的数据操作流程很有帮助。

JDBC的全称是Java Database Connectivity。

JDBC对数据库进行操作的流程:
•连接数据库
•发送数据请求,即传统的CRUD指令
•返回操作结果集

JDBC中常用的对象包括:
•ConnectionManager
•Connection
•Statement
•CallableStatement
•PreparedStatement
•ResultSet
•SavePoint
一个简单示例
我们来看下面一个简单的示例,它使用JDK自带的Derby数据库,创建一张表,插入一些记录,然后将记录返回:

代码如下:

一个简单的JDBC示例
 private static void test1() throws SQLException
 {
     String driver = "org.apache.derby.jdbc.EmbeddedDriver";
     String dbURL = "jdbc:derby:EmbeddedDB;create=true";

     Connection con = null;
     Statement st = null;
     try
     {
         Class.forName(driver);
         con = DriverManager.getConnection(dbURL);
         st = con.createStatement();
         st.execute("create table foo(ID INT NOT NULL, NAME VARCHAR(30))");
         st.executeUpdate("insert into foo(ID,NAME) values(1, 'Zhang San')");

         ResultSet rs = st.executeQuery("select ID,NAME from foo");

         while(rs.next())
         {
             int id = rs.getInt("ID");
             String name = rs.getString("NAME");
             System.out.println("ID=" + id + "; NAME=" + name);
         }
     }
     catch(Exception ex)
     {
         ex.printStackTrace();
     }
     finally
     {
         if (st != null) st.close();
         if (con != null) con.close();
     }
 }

如何建立数据库连接
上面的示例代码中,建立数据库连接的部分如下:
代码如下:

String driver = "org.apache.derby.jdbc.EmbeddedDriver";
String dbURL = "jdbc:derby:EmbeddedDB;create=true";

Class.forName(driver);
con = DriverManager.getConnection(dbURL);


建立数据库连接的过程,可以分为两步:

1)加载数据库驱动,即上文中的driver以及Class.forName(dirver)

2)定位数据库连接字符串, 即dbURL以及DriverManager.getConnection(dbURL)

不同的数据库,对应的dirver和dbURL不同,但加载驱动和建立连接的方式是相同的,即只需要修改上面driver和dbURL的值就可以了。

自动加载数据库驱动
如果我们每次建立连接时,都要使用Class.forName(...)来手动加载数据库驱动,这样会很麻烦,我们可以通过配置文件的方式,来保存数据库驱动的信息。

我们可以在classpath中,即编译出来的.class的存放路径,添加如下文件:

代码如下:

META-INFservicesjava.sql.Driver

对应的内容就是JDBC驱动的全路径,也就是上面driver变量的值:
代码如下:

org.apache.derby.jdbc.EmbeddedDriver

接下来,我们在程序中,就不需要再显示的用Class.forName(...)来加载驱动了,它会被自动加载进来,当我们的数据库发生变化时,只需要修改这个文件就可以了,例如当我们的数据库由Derby变为MySQL时,只需要将上述的配置修改为:
代码如下:

com.mysql.jdbc.Driver

但是,需要注意一点,这里只是配置了JDBC驱动的全路径,并没有包含jar文件的信息,因此,我们还是需要将包含该驱动的jar文件手动的放置到程序的classpath中。

JDBC中的基本操作
对于数据库操作来说,CRUD操作应该是最常见的操作了, 即我们常说的增、删、查、改。

JDBC是使用Statement和ResultSet来完成这些操作的。

如何实现CRUD
下面是一个实现CRUD的示例:

代码如下:

JDBC实现基本的CRUD示例
 private static void insertTest() throws SQLException
 {
     String dbURL = "jdbc:mysql://localhost/test";
     Connection con = DriverManager.getConnection(dbURL, "root", "123");
     Statement st = con.createStatement();
     st.execute("insert into user(ID,NAME) values(1, 'Zhang San')");
     st.execute("insert into user(ID,NAME) values(2, 'Li Si')");
     st.execute("insert into user(ID,NAME) values(3, 'Wang Wu')");
     System.out.println("=====insert test=====");
     showUser(st);
     st.close();
     con.close();
 }

 private static void deleteTest() throws SQLException
 {
     String dbURL = "jdbc:mysql://localhost/test";
     Connection con = DriverManager.getConnection(dbURL, "root", "123");
     Statement st = con.createStatement();
     st.execute("delete from user where ID=3");
     System.out.println("=====delete test=====");
     showUser(st);
     st.close();
     con.close();
 }

 private static void updateTest() throws SQLException
 {
     String dbURL = "jdbc:mysql://localhost/test";
     Connection con = DriverManager.getConnection(dbURL, "root", "123");
     Statement st = con.createStatement();
     st.executeUpdate("update user set NAME='TEST' where ID=2");
     System.out.println("=====update test=====");
     showUser(st);
     st.close();
     con.close();
 }

 private static void showUser(Statement st) throws SQLException
 {
     ResultSet rs = st.executeQuery("select ID, NAME from user");
     while(rs.next())
     {
         int id = rs.getInt("ID");
         String name = rs.getString("NAME");
         System.out.println("ID:" + id + "; NAME=" + name);
     }
     rs.close();
 }

我们顺序调用上面的测试方法:
代码如下:

insertTest();
deleteTest();
updateTest();

执行结果如下:
代码如下:

=====insert test=====
ID:1; NAME=Zhang San
ID:2; NAME=Li Si
ID:3; NAME=Wang Wu
=====delete test=====
ID:1; NAME=Zhang San
ID:2; NAME=Li Si
=====update test=====
ID:1; NAME=Zhang San
ID:2; NAME=TEST

上面代码中的showUser方法会把user表中的所有记录打印出来。

如何调用存储过程
存储过程是做数据库开发时经常使用的技术,它可以通过节省编译时间的方式来提升系统性能,我们这里的示例使用MySQL数据库。

如何调用不带参数的存储过程
假设我们现在有一个简单的存储过程,它只是返回user表中的所有记录,存储过程如下:

代码如下:

CREATE DEFINER=`root`@`localhost` PROCEDURE `GetUser`()
BEGIN
select ID,NAME from user;
END

我们可以使用CallableStatement来调用存储过程:
代码如下:

调用存储过程示例一
 private static void execStoredProcedureTest() throws SQLException
 {
     String dbURL = "jdbc:mysql://localhost/test";
     Connection con = DriverManager.getConnection(dbURL, "root", "123");
     CallableStatement cst = con.prepareCall("call GetUser()");
     ResultSet rs = cst.executeQuery();
     while(rs.next())
     {
         int id = rs.getInt("ID");
         String name = rs.getString("NAME");
         System.out.println("ID:" + id + "; NAME=" + name);
     }
     rs.close();
     cst.close();
     con.close();
 }

它的执行结果如下:
代码如下:

ID:1; NAME=Zhang San
ID:2; NAME=TEST

如何调用带参数的存储过程
MySQL的存储过程中的参数分为三种:in/out/inout,我们可以把in看做入力参数,out看做出力参数,JDBC对这两种类型的参数设置方式不同:

1)in, JDBC使用类似于cst.set(1, 10)的方式来设置

2)out,JDBC使用类似于cst.registerOutParameter(2, Types.VARCHAR);的方式来设置

我们来看一个in参数的示例,假设我们希望返回ID为特定值的user信息,存储过程如下:

代码如下:

CREATE DEFINER=`root`@`localhost` PROCEDURE `GetUserByID`(in id int)
 BEGIN
 set @sqlstr=concat('select * from user where ID=', id);
 prepare psmt from @sqlstr;
 execute psmt;
 END

Java的调用代码如下:
代码如下:

JDBC调用存储过程示例二
 private static void execStoredProcedureTest2(int id) throws SQLException
 {
     String dbURL = "jdbc:mysql://localhost/test";
     Connection con = DriverManager.getConnection(dbURL, "root", "123");
     CallableStatement cst = con.prepareCall("call GetUserByID(?)");
     cst.setInt(1, id);
     ResultSet rs = cst.executeQuery();
     while(rs.next())
     {
         String name = rs.getString("NAME");
         System.out.println("ID:" + id + "; NAME=" + name);
     }
     rs.close();
     cst.close();
     con.close();
 }

我们执行下面的语句:
代码如下:

execStoredProcedureTest2(1);

结果如下:
代码如下:

ID:1; NAME=Zhang San

对于out类型的参数,调用方式类似,不再赘述。

获取数据库以及结果集的metadata信息
在JDBC中,我们不仅能够对数据进行操作,我们还能获取数据库以及结果集的元数据信息,例如数据库的名称、驱动信息、表信息;结果集的列信息等。

获取数据库的metadata信息
我们可以通过connection.getMetaData方法来获取数据库的元数据信息,它的类型是DatabaseMetaData。

代码如下:

获取数据库的元数据信息
 private static void test1() throws SQLException
 {
     String dbURL = "jdbc:mysql://localhost/mysql";
     Connection con = DriverManager.getConnection(dbURL, "root", "123");

     DatabaseMetaData dbmd = con.getMetaData();

     System.out.println("数据库:" + dbmd.getDatabaseProductName() + " " + dbmd.getDatabaseProductVersion());
     System.out.println("驱动程序:" + dbmd.getDriverName() + " " + dbmd.getDriverVersion());

     ResultSet rs = dbmd.getTables(null, null, null, null);
     System.out.println(String.format("|%-26s|%-9s|%-9s|%-9s|", "表名称","表类别","表类型","表模式"));       
     while(rs.next())
     {
         System.out.println(String.format("|%-25s|%-10s|%-10s|%-10s|",
                 rs.getString("TABLE_NAME"),rs.getString("TABLE_CAT"),
                 rs.getString("TABLE_TYPE"), rs.getString("TABLE_SCHEM")));
     }
 }

这里我们使用的数据库是MySQL中自带的默认数据库:mysql,它会记录整个数据库服务器中的一些信息。上述代码执行结果如下:
代码如下:

数据库:MySQL 5.5.28
驱动程序:MySQL-AB JDBC Driver mysql-connector-java-5.0.4 ( $Date: 2006-10-19 17:47:48 +0200 (Thu, 19 Oct 2006) $, $Revision: 5908 $ )
|表名称                       |表类别      |表类型      |表模式      |
|columns_priv             |mysql     |TABLE     |null      |
|db                       |mysql     |TABLE     |null      |
|event                    |mysql     |TABLE     |null      |
|func                     |mysql     |TABLE     |null      |
。。。

由于mysql中表比较多,上述结果只截取了一部分。

获取结果集的元数据信息
我们可以通过使用resultset.getMetaData方法来获取结果集的元数据信息,它的类型是ResultSetMetaData。

代码如下:

获取结果集的元数据信息
 private static void test2() throws SQLException
 {
     String dbURL = "jdbc:mysql://localhost/test";
     Connection con = DriverManager.getConnection(dbURL, "root", "123");
     Statement st = con.createStatement();
     ResultSet rs = st.executeQuery("select ID, NAME from user");
     ResultSetMetaData rsmd = rs.getMetaData();
     for (int i = 1; i

    
 
 

您可能感兴趣的文章:

  • java map(HashMap TreeMap)用法:初始化,遍历和排序详解
  • 哪位java同门师兄有《java2编程详解》电子文档,注意不是影印版
  • 请问哪儿有java2编程详解的电子书下载??本人急需!!跟贴有分!!!
  • 谁有JAVA的类库详解或下载地址?
  • 请问那里有《JAVA2编程详解》可以下载?
  • 《Java 2 编程详解》程序清单14.12中的一个问题。
  • 谁有电子版的《Java编程思想第二版(Thinking in java second)》和《Java2编程详解(special edition java2)》?得到给分
  • 移动开发 iis7站长之家
  • Java中的随机数详解
  • 深入分析Java内存区域的使用详解
  • Java加载JDBC驱动程序实例详解
  • Java代码重构的几种模式详解
  • JAVA中list,set,数组之间的转换详解
  • Java中关于int和Integer的区别详解
  • java equals函数用法详解
  • Java I/O技术之文件操作详解
  • java this super使用方法详解
  • java全角、半角字符的关系以及转换详解
  • 深入JAVA对象深度克隆的详解
  • 深入Java不可变类型的详解
  • 浅谈java中静态方法的重写问题详解
  • 基于Java回顾之网络通信的应用分析
  • 基于Java回顾之I/O的使用详解
  • 基于Java回顾之多线程详解
  • 基于Java回顾之反射的使用分析
  • 基于Java回顾之集合的总结概述
  • 基于Java回顾之多线程同步的使用详解
  •  
    本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
    本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • 使用java jdk中的LinkedHashMap实现简单的LRU算法
  • MySocketServer.java 使用或覆盖一个不鼓励使用的API???
  • java将类序列化并存储到mysql(使用hibernate)
  • JAVA中不赞成使用(Deprecated)的方法是否可以使用
  • 各位使用过JAVA的朋友们!JAVA好用吗?它有向VC那样的集成开发环境吗?
  • java 可以使用 可是javac不可以使用。老兄帮帮忙
  • 哪位知道如何用JAVA进行图形文件的缩放? 是使用JAVA2D 或是有第三方的软件?
  • java堆栈类使用实例(java中stack的使用方法)
  • env查看环境变量,JAVA_HOME明明在里面,但使用nutch时还是提示JAVA_HOME not set?
  • 如何使用linux下的java编译器????
  • 如何使用java这个命令?
  • 为什么使用cat输出的文本文件是中文的,使用java从文件读取出来时显示的是乱码?
  • linux 远程上使用java
  • UNIX下使用java运行class的问题
  • java:sun公司的联机帮助如何使用?
  • 请教如何使用Java编写的Applet程序关闭浏览器??
  • 怎么使用 JAVA 的包呀???
  • 针对使用java进行硬件编程
  • 使用editplus编写java如何编译成字节码文件,如何解释
  • 谁能告诉我哪里能找到java包内部类及方法使用介绍
  • 使用java时间的调查,谢谢大家
  • java命名空间java.sql类types的类成员方法: java_object定义及介绍
  • 我想学JAVA ,是买THINK IN JAVA 还是JAVA2核心技术:卷1 好???
  • java命名空间java.awt.datatransfer类dataflavor的类成员方法: imageflavor定义及介绍
  • 请问Java高手,Java的优势在那里??,Java主要适合于开发哪类应用程序
  • java命名空间java.lang.management类managementfactory的类成员方法: getcompilationmxbean定义及介绍
  • 如何将java.util.Date转化为java.sql.Date?数据库中Date类型对应于java的哪个Date呢
  • java命名空间java.lang.management接口runtimemxbean的类成员方法: getlibrarypath定义及介绍
  • 本人想学java,请问java程序员的待遇如何,和java主要有几个比较强的方向
  • java命名空间java.lang.management接口runtimemxbean的类成员方法: getstarttime定义及介绍
  • 我对JAVA一窍不通,可惜别人却给我一个Java的project,要我做一个安装程序,请问哪里有JAVA INSTALLER下载,而且我要不要安装java的sdk才能完成此项任务?




  • 特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3